unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
To: Notmuch Mail <notmuch@notmuchmail.org>
Subject: [PATCH 1/9] lib: index PKCS7 SignedData parts
Date: Thu, 30 Apr 2020 16:13:20 -0400	[thread overview]
Message-ID: <20200430201328.725651-2-dkg@fifthhorseman.net> (raw)
In-Reply-To: <20200430201328.725651-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 117fa2b9..01e53e33 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

  reply	other threads:[~2020-04-30 20:15 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-30 20:13 Handle PKCS#7 S/MIME messages Daniel Kahn Gillmor
2020-04-30 20:13 ` Daniel Kahn Gillmor [this message]
2020-04-30 20:13 ` [PATCH 2/9] smime: Identify encrypted S/MIME parts during indexing Daniel Kahn Gillmor
2020-04-30 20:13 ` [PATCH 3/9] cli: include wrapped part of PKCS#7 SignedData in the MIME tree Daniel Kahn Gillmor
2020-04-30 20:13 ` [PATCH 4/9] cli/show: If a leaf part has children, show them instead of omitting Daniel Kahn Gillmor
2020-04-30 20:13 ` [PATCH 5/9] cli/reply: Ignore PKCS#7 wrapper parts when replying Daniel Kahn Gillmor
2020-04-30 20:13 ` [PATCH 6/9] crypto: Make _notmuch_crypto_decrypt take a GMimeObject Daniel Kahn Gillmor
2020-04-30 20:13 ` [PATCH 7/9] crypto: handle PKCS#7 envelopedData in _notmuch_crypto_decrypt Daniel Kahn Gillmor
2020-04-30 20:13 ` [PATCH 8/9] smime: Pass PKCS#7 envelopedData to node_decrypt_and_verify Daniel Kahn Gillmor
2020-04-30 20:13 ` [PATCH 9/9] smime: Index cleartext of envelopedData when requested Daniel Kahn Gillmor
2020-05-01 21:15 ` Handle PKCS#7 S/MIME messages Tomi Ollila
2020-05-04 19:16   ` Daniel Kahn Gillmor
2020-05-05  8:32     ` Tomi Ollila
2020-05-05 18:07       ` David Bremner
2020-05-06 23:54       ` [PATCH 1/2] test-lib: mark function variables as local Daniel Kahn Gillmor
2020-05-06 23:54         ` [PATCH 2/2] smime: tests of X.509 certificate validity are known-broken on GMime < 3.2.7 Daniel Kahn Gillmor
2020-05-07 20:54           ` Tomi Ollila
2020-05-12 22:20           ` [PATCH 2/2 v2] " Daniel Kahn Gillmor
2020-05-21 23:29             ` David Bremner
2020-05-22  0:41               ` Daniel Kahn Gillmor
2020-05-22  0:42               ` [PATCH 2/2 v3] " Daniel Kahn Gillmor
2020-05-23 11:56                 ` David Bremner
2020-05-07  7:31         ` [PATCH 1/2] test-lib: mark function variables as local Tomi Ollila
2020-05-08 20:04           ` Daniel Kahn Gillmor
2020-05-08 23:24         ` [PATCH 1/2 v2] " Daniel Kahn Gillmor
2020-05-09  7:09           ` Tomi Ollila
2020-05-09 11:47           ` David Bremner
2020-05-10 18:03             ` Daniel Kahn Gillmor
2020-05-10 19:02               ` David Bremner
2020-05-12 22:14             ` 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=20200430201328.725651-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).