aboutsummaryrefslogtreecommitdiff
path: root/lib/index.cc
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2020-05-12 18:29:31 -0400
committerDavid Bremner <david@tethera.net>2020-05-22 22:10:46 -0300
commit38bd0df922aa1c9ac98154f6d3dc3e30255ad47e (patch)
treebcd895f759c2c77bfac26f82d84df6e174b1f184 /lib/index.cc
parent78800929641fb79e758baa60d02216ed2ea941d0 (diff)
lib: index PKCS7 SignedData parts
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>
Diffstat (limited to 'lib/index.cc')
-rw-r--r--lib/index.cc57
1 files changed, 57 insertions, 0 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)
{