From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
To: Notmuch Mail <notmuch@notmuchmail.org>
Subject: [PATCH v2 1/9] lib: index PKCS7 SignedData parts
Date: Tue, 12 May 2020 18:29:31 -0400 [thread overview]
Message-ID: <20200512222939.372093-2-dkg@fifthhorseman.net> (raw)
In-Reply-To: <20200512222939.372093-1-dkg@fifthhorseman.net>
When we are indexing, we should treat SignedData parts the same way
that we treat a multipart object, indexing the wrapped part as a
distinct MIME object.
Unfortunately, this means doing some sort of cryptographic
verification whose results we throw away, because GMime doesn't offer
us any way to unwrap without doing signature verification.
I've opened https://github.com/jstedfast/gmime/issues/67 to request
the capability from GMime but for now, we'll just accept the
additional performance hit.
As we do this indexing, we also apply the "signed" tag, by analogy
with how we handle multipart/signed messages. These days, that kind
of change should probably be done with a property instead, but that's
a different set of changes. This one is just for consistency.
Note that we are currently *only* handling signedData parts, which are
basically clearsigned messages. PKCS#7 parts can also be
envelopedData and authEnvelopedData (which are effectively encryption
layers), and compressedData (which afaict isn't implemented anywhere,
i've never encountered it). We're laying the groundwork for indexing
these other S/MIME types here, but we're only dealing with signedData
for now.
Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
---
lib/index.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++++
test/T355-smime.sh | 2 --
2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/lib/index.cc b/lib/index.cc
index 158ba5cf..bbf13dc5 100644
--- a/lib/index.cc
+++ b/lib/index.cc
@@ -372,6 +372,12 @@ _index_encrypted_mime_part (notmuch_message_t *message, notmuch_indexopts_t *ind
GMimeMultipartEncrypted *part,
_notmuch_message_crypto_t *msg_crypto);
+static void
+_index_pkcs7_part (notmuch_message_t *message,
+ notmuch_indexopts_t *indexopts,
+ GMimeObject *part,
+ _notmuch_message_crypto_t *msg_crypto);
+
/* Callback to generate terms for each mime part of a message. */
static void
_index_mime_part (notmuch_message_t *message,
@@ -466,6 +472,11 @@ _index_mime_part (notmuch_message_t *message,
goto DONE;
}
+ if (GMIME_IS_APPLICATION_PKCS7_MIME (part)) {
+ _index_pkcs7_part (message, indexopts, part, msg_crypto);
+ goto DONE;
+ }
+
if (! (GMIME_IS_PART (part))) {
_notmuch_database_log (notmuch_message_get_database (message),
"Warning: Not indexing unknown mime part: %s.\n",
@@ -608,6 +619,52 @@ _index_encrypted_mime_part (notmuch_message_t *message,
}
+static void
+_index_pkcs7_part (notmuch_message_t *message,
+ notmuch_indexopts_t *indexopts,
+ GMimeObject *part,
+ _notmuch_message_crypto_t *msg_crypto)
+{
+ GMimeApplicationPkcs7Mime *pkcs7;
+ GMimeSecureMimeType p7type;
+ GMimeObject *mimeobj = NULL;
+ GMimeSignatureList *sigs = NULL;
+ GError *err = NULL;
+ notmuch_database_t *notmuch = NULL;
+
+ pkcs7 = GMIME_APPLICATION_PKCS7_MIME (part);
+ p7type = g_mime_application_pkcs7_mime_get_smime_type (pkcs7);
+ notmuch = notmuch_message_get_database (message);
+ _index_content_type (message, part);
+
+ if (p7type == GMIME_SECURE_MIME_TYPE_SIGNED_DATA) {
+ sigs = g_mime_application_pkcs7_mime_verify (pkcs7, GMIME_VERIFY_NONE, &mimeobj, &err);
+ if (sigs == NULL) {
+ _notmuch_database_log (notmuch, "Failed to verify PKCS#7 SignedData during indexing. (%d:%d) [%s]\n",
+ err->domain, err->code, err->message);
+ g_error_free (err);
+ goto DONE;
+ }
+ _notmuch_message_add_term (message, "tag", "signed");
+ GMimeObject *toindex = mimeobj;
+ if (_notmuch_message_crypto_potential_payload (msg_crypto, mimeobj, part, 0) &&
+ msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL) {
+ toindex = _notmuch_repair_crypto_payload_skip_legacy_display (mimeobj);
+ if (toindex != mimeobj)
+ notmuch_message_add_property (message, "index.repaired", "skip-protected-headers-legacy-display");
+ }
+ _index_mime_part (message, indexopts, toindex, msg_crypto);
+ } else {
+ _notmuch_database_log (notmuch, "Cannot currently handle PKCS#7 smime-type '%s'\n",
+ g_mime_object_get_content_type_parameter (part, "smime-type"));
+ }
+ DONE:
+ if (mimeobj)
+ g_object_unref (mimeobj);
+ if (sigs)
+ g_object_unref (sigs);
+}
+
static notmuch_status_t
_notmuch_message_index_user_headers (notmuch_message_t *message, GMimeMessage *mime_message)
{
diff --git a/test/T355-smime.sh b/test/T355-smime.sh
index f8e8e396..a7eecedf 100755
--- a/test/T355-smime.sh
+++ b/test/T355-smime.sh
@@ -132,13 +132,11 @@ expected=''
test_expect_equal "$expected" "$output"
test_begin_subtest "know the MIME type of the embedded part in PKCS#7 SignedData"
-test_subtest_known_broken
output=$(notmuch search --output=messages 'mimetype:text/plain')
expected=id:smime-onepart-signed@protected-headers.example
test_expect_equal "$expected" "$output"
test_begin_subtest "PKCS#7 SignedData message is tagged 'signed'"
-test_subtest_known_broken
output=$(notmuch dump id:smime-onepart-signed@protected-headers.example)
expected='#notmuch-dump batch-tag:3 config,properties,tags
+inbox +signed +unread -- id:smime-onepart-signed@protected-headers.example'
--
2.26.2
next prev parent reply other threads:[~2020-05-12 22:31 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-12 22:29 Handle PKCS#7 S/MIME messages v2 Daniel Kahn Gillmor
2020-05-12 22:29 ` Daniel Kahn Gillmor [this message]
2020-05-23 11:57 ` [PATCH v2 1/9] lib: index PKCS7 SignedData parts David Bremner
2020-05-12 22:29 ` [PATCH v2 2/9] smime: Identify encrypted S/MIME parts during indexing Daniel Kahn Gillmor
2020-05-12 22:29 ` [PATCH v2 3/9] cli: include wrapped part of PKCS#7 SignedData in the MIME tree Daniel Kahn Gillmor
2020-05-12 22:29 ` [PATCH v2 4/9] cli/show: If a leaf part has children, show them instead of omitting Daniel Kahn Gillmor
2020-05-12 22:29 ` [PATCH v2 5/9] cli/reply: Ignore PKCS#7 wrapper parts when replying Daniel Kahn Gillmor
2020-05-12 22:29 ` [PATCH v2 6/9] crypto: Make _notmuch_crypto_decrypt take a GMimeObject Daniel Kahn Gillmor
2020-05-12 22:29 ` [PATCH v2 7/9] crypto: handle PKCS#7 envelopedData in _notmuch_crypto_decrypt Daniel Kahn Gillmor
2020-05-12 22:29 ` [PATCH v2 8/9] smime: Pass PKCS#7 envelopedData to node_decrypt_and_verify Daniel Kahn Gillmor
2020-05-12 22:29 ` [PATCH v2 9/9] smime: Index cleartext of envelopedData when requested Daniel Kahn Gillmor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://notmuchmail.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200512222939.372093-2-dkg@fifthhorseman.net \
--to=dkg@fifthhorseman.net \
--cc=notmuch@notmuchmail.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhetil.org/notmuch.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).