From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
To: Notmuch Mail <notmuch@notmuchmail.org>
Subject: [PATCH 04/20] util/crypto: _notmuch_message_crypto: tracks message-wide crypto state
Date: Fri, 11 May 2018 01:55:28 -0400 [thread overview]
Message-ID: <20180511055544.13676-5-dkg@fifthhorseman.net> (raw)
In-Reply-To: <20180511055544.13676-1-dkg@fifthhorseman.net>
E-mail encryption and signatures reported by notmuch are at the MIME
part level. This makes sense in the dirty details, but for users we
need to have a per-message conception of the cryptographic state of
the e-mail. (see
https://dkg.fifthhorseman.net/blog/e-mail-cryptography.html for more
discussion of why this is important).
The object created in this patch is a useful for tracking the
cryptographic state of the underlying message as a whole, based on a
depth-first search of the message's MIME structure.
---
util/crypto.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
util/crypto.h | 55 ++++++++++++++++++++++++++++++++
2 files changed, 142 insertions(+)
diff --git a/util/crypto.c b/util/crypto.c
index 9d3b6dad..b040cc56 100644
--- a/util/crypto.c
+++ b/util/crypto.c
@@ -219,3 +219,90 @@ _notmuch_crypto_decrypt (bool *attempted,
#endif
return ret;
}
+
+
+_notmuch_message_crypto_t *
+_notmuch_message_crypto_new (void *ctx)
+{
+ return talloc_zero (ctx, _notmuch_message_crypto_t);
+}
+
+
+notmuch_status_t
+_notmuch_message_crypto_set_sig_list (_notmuch_message_crypto_t *msg_crypto, GMimeSignatureList *sigs)
+{
+ if (!msg_crypto)
+ return NOTMUCH_STATUS_NULL_POINTER;
+
+ /* Signatures that arrive after a payload part during DFS are not
+ * part of the cryptographic envelope: */
+ if (msg_crypto->payload_encountered)
+ return NOTMUCH_STATUS_SUCCESS;
+
+ if (msg_crypto->sig_list)
+ g_object_unref (msg_crypto->sig_list);
+
+ msg_crypto->sig_list = sigs;
+ if (sigs)
+ g_object_ref (sigs);
+
+ if (msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL)
+ msg_crypto->signature_encrypted = true;
+
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
+
+notmuch_status_t
+_notmuch_message_crypto_potential_payload (_notmuch_message_crypto_t *msg_crypto, GMimeObject *payload, GMimeObject *parent, int childnum)
+{
+ if (!msg_crypto || !payload)
+ return NOTMUCH_STATUS_NULL_POINTER;
+
+ /* only fire on the first payload part encountered */
+ if (msg_crypto->payload_encountered)
+ return NOTMUCH_STATUS_SUCCESS;
+
+ /* the first child of multipart/encrypted that matches the
+ * encryption protocol should be "control information" metadata,
+ * not payload. So we skip it. (see
+ * https://tools.ietf.org/html/rfc1847#page-8) */
+ if (parent && GMIME_IS_MULTIPART_ENCRYPTED (parent) && childnum == GMIME_MULTIPART_ENCRYPTED_VERSION) {
+ const char *enc_type = g_mime_object_get_content_type_parameter (parent, "protocol");
+ GMimeContentType *ct = g_mime_object_get_content_type (payload);
+ if (ct) {
+ const char *part_type = g_mime_content_type_get_mime_type (ct);
+ if (part_type && strcmp (part_type, enc_type) == 0)
+ return NOTMUCH_STATUS_SUCCESS;
+ }
+ }
+
+ msg_crypto->payload_encountered = true;
+
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
+
+notmuch_status_t
+_notmuch_message_crypto_successful_decryption (_notmuch_message_crypto_t *msg_crypto)
+{
+ if (!msg_crypto)
+ return NOTMUCH_STATUS_NULL_POINTER;
+
+ if (!msg_crypto->payload_encountered)
+ msg_crypto->decryption_status = NOTMUCH_MESSAGE_DECRYPTED_FULL;
+ else if (msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_NONE)
+ msg_crypto->decryption_status = NOTMUCH_MESSAGE_DECRYPTED_PARTIAL;
+
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
+
+void
+_notmuch_message_crypto_cleanup (_notmuch_message_crypto_t *msg_crypto)
+{
+ if (!msg_crypto)
+ return;
+ if (msg_crypto->sig_list)
+ g_object_unref (msg_crypto->sig_list);
+}
diff --git a/util/crypto.h b/util/crypto.h
index c384601c..02c8793a 100644
--- a/util/crypto.h
+++ b/util/crypto.h
@@ -34,4 +34,59 @@ _notmuch_crypto_get_gmime_ctx_for_protocol (_notmuch_crypto_t *crypto,
void
_notmuch_crypto_cleanup (_notmuch_crypto_t *crypto);
+
+
+/* The user probably wants to know if the entire message was in the
+ * clear. When replying, the MUA probably wants to know whether there
+ * was any part decrypted in the message. And when displaying to the
+ * user, we probably only want to display "encrypted message" if the
+ * entire message was covered by encryption. */
+typedef enum {
+ NOTMUCH_MESSAGE_DECRYPTED_NONE = 0,
+ NOTMUCH_MESSAGE_DECRYPTED_PARTIAL,
+ NOTMUCH_MESSAGE_DECRYPTED_FULL,
+} _notmuch_message_decryption_status_t;
+
+/* description of the cryptographic state of a given message overall;
+ * for use by simple user agents.
+ */
+typedef struct _notmuch_message_crypto {
+ /* encryption status: partial, full, none */
+ _notmuch_message_decryption_status_t decryption_status;
+ /* FIXME: can we show what key(s) a fully-encrypted message was
+ * encrypted to? This data is not necessarily cryptographically
+ * reliable; even when we decrypt, we might not know which public
+ * key was used (e.g. if we're using a session key). */
+
+ /* signature status of the whole message (either the whole message
+ * is signed, or it is not) -- this means that partially-signed
+ * messages will get no signature status. */
+ GMimeSignatureList * sig_list;
+ /* if part of the message was signed, and the MUA is clever, it
+ * can determine on its own exactly which part and try to make
+ * more sense of it. */
+
+ /* mark this flag once we encounter a payload (i.e. something that
+ * is not part of the cryptographic envelope) */
+ bool payload_encountered;
+
+ /* if both signed and encrypted, was the signature encrypted? */
+ bool signature_encrypted;
+} _notmuch_message_crypto_t;
+
+_notmuch_message_crypto_t *
+_notmuch_message_crypto_new (void *ctx);
+
+void
+_notmuch_message_crypto_cleanup (_notmuch_message_crypto_t *msg_crypto);
+
+notmuch_status_t
+_notmuch_message_crypto_set_sig_list (_notmuch_message_crypto_t *msg_crypto, GMimeSignatureList *sigs);
+
+notmuch_status_t
+_notmuch_message_crypto_successful_decryption (_notmuch_message_crypto_t *msg_crypto);
+
+notmuch_status_t
+_notmuch_message_crypto_potential_payload (_notmuch_message_crypto_t *msg_crypto, GMimeObject *payload, GMimeObject *parent, int childnum);
+
#endif
--
2.17.0
next prev parent reply other threads:[~2018-05-11 5:56 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-11 5:55 Protected headers in notmuch Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 01/20] test: new test framework to compare json parts Daniel Kahn Gillmor
2018-06-06 1:06 ` David Bremner
2018-06-06 14:49 ` Daniel Kahn Gillmor
2018-06-06 16:21 ` David Bremner
2018-06-06 20:18 ` Daniel Kahn Gillmor
2018-06-07 8:39 ` Tomi Ollila
2018-05-11 5:55 ` [PATCH 02/20] crypto: Avoid pretending to verify signatures on unsigned encrypted mail Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 03/20] cli/show: pass the siglist directly to the sigstatus sprinter Daniel Kahn Gillmor
2018-05-11 5:55 ` Daniel Kahn Gillmor [this message]
2018-06-15 10:16 ` [PATCH 04/20] util/crypto: _notmuch_message_crypto: tracks message-wide crypto state David Bremner
2018-06-28 21:15 ` Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 05/20] cli: expose message-wide crypto status from mime-node Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 06/20] mime-node: track whole-message crypto state while walking the tree Daniel Kahn Gillmor
2018-06-15 10:52 ` David Bremner
2018-05-11 5:55 ` [PATCH 07/20] cli/show: emit new whole-message crypto status output Daniel Kahn Gillmor
2018-06-15 23:47 ` David Bremner
2018-06-29 15:41 ` Daniel Kahn Gillmor
2018-06-29 15:46 ` David Bremner
2018-05-11 5:55 ` [PATCH 08/20] cli/show: emit headers after emitting body Daniel Kahn Gillmor
2018-06-16 0:30 ` David Bremner
2018-05-11 5:55 ` [PATCH 09/20] util/crypto: add information about the payload part Daniel Kahn Gillmor
2018-06-25 1:15 ` David Bremner
2018-06-30 2:05 ` Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 10/20] cli/show: add tests for viewing protected headers Daniel Kahn Gillmor
2018-06-25 1:31 ` David Bremner
2018-06-30 2:17 ` Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 11/20] cli/show: emit payload subject instead of outside subject Daniel Kahn Gillmor
2018-06-29 0:40 ` David Bremner
2018-07-13 20:29 ` Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 12/20] cli/show: add information about which headers were protected Daniel Kahn Gillmor
2018-06-29 0:58 ` David Bremner
2018-05-11 5:55 ` [PATCH 13/20] test: add test for missing external subject Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 14/20] test: show cryptographic envelope information for signed mails Daniel Kahn Gillmor
2018-06-29 11:38 ` David Bremner
2018-05-11 5:55 ` [PATCH 15/20] cli/reply: ensure encrypted Subject: line does not leak in the clear Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 16/20] cli: introduce flags for format_headers_sprinter Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 17/20] cli/reply: add --protected-subject boolean flag Daniel Kahn Gillmor
2018-06-29 11:51 ` David Bremner
2018-05-11 5:55 ` [PATCH 18/20] indexing: record protected subject when indexing cleartext Daniel Kahn Gillmor
2018-06-02 17:59 ` Jameson Graef Rollins
2018-05-11 5:55 ` [PATCH 19/20] test: protected headers should work when both encrypted and signed Daniel Kahn Gillmor
2018-05-11 5:55 ` [PATCH 20/20] test: after reindexing, only legitimate protected subjects are searchable Daniel Kahn Gillmor
2018-06-02 18:25 ` Protected headers in notmuch Jameson Graef Rollins
2018-06-02 19:20 ` David Bremner
2018-06-03 13:44 ` Daniel Kahn Gillmor
2018-06-06 1:10 ` David Bremner
2018-06-03 18:14 ` Jameson Graef Rollins
2018-07-25 6:01 ` David Bremner
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=20180511055544.13676-5-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).