On Sun 2025-11-09 12:49:14 +0000, Frank Seifferth wrote:
> I believe that in theory it should be possible to model the behaviour
> described in the autocrypt spec as a notmuch query. However, at the very
> least, this would require the "first seen" date to be made available in
> the notmuch query syntax.
Hm, does notmuch even store that information about each Message-ID or file?
> I am also not sure if it would be worth it to follow the autocrypt spec
> to the letter.
I agree that there's no need to *limit* notmuch to the Autocrypt
recommendation algorithm. The Autocrypt spec itself proposes that it is
a "recommendation" (not mandatory) [0], and has guidance about diverging
from it.
[0]
https://docs.autocrypt.org/level1.html#provide-a-recommendation-for-message-encryption
But if we're talking about a subcommand named "notmuch autocrypt" it'd
be nice to make sure that at least that subcommand identifies the the
Autocrypt recommendation, even if some other part of a notmuch-based MUA
decides to vary from it.
Alternatively, we could choose to name it something else :)
> Delta Chat recently moved away from the autocrypt spec
> to the extend that one could be tempted to argue that they broke their
> autocrypt support.
My understanding is that Deltachat is moving away from the e-mail
address as the primary identifier for a peer contacts, and to the
OpenPGP certificate as the primary identifier. So they don't need the
Autocrypt recommendation ("for this e-mail address, please give me an
OpenPGP certificate and a recommendation about message encryption
defaults") at all. Instead, when composing a message in delta, the
contacts all already have OpenPGP certificates (by definition) and the
default is that every message is encrypted.
I don't think a more traditional MUA (such as most of those that involve
notmuch) is in the position to make a comparable transition though.
Traditional MUAs lean heavily on the e-mail address as peer identifier,
and have to deal with cleartext messages (both incoming and outgoing) as
well.
> the security aspects of autocrypt boil down to something like: "At
> least using this key won't be worse privacy than using no key at all."
This was actually quite close to the motto of Autocrypt when we were
working on it: "Autocrypt: It's probably better than not doing it", so
i'm glad that came through! ☺ But the Autocrypt recommendation and
peerstate are pretty finely calibrated to work together for an MUA that
wants a better-than-nothing answer to that question, intended to not
only improve privacy, but also to reduce the risks of footguns like
encrypting messages to people who can't decrypt them.
If a cryptographic MUA sends an undecryptable message, that's a pretty
big papercut. Most users will decide that encrypting mail is too
painful and stop using it, or turn off the encryption feature entirely ☹
> I myself started only this year to actually use gpg -- I had previously
> heard that it was hard and unpleasant -- and I was very surprised by
> what I perceived to be a very straight-forward UX. Obviously, I am only
> using a very small subset of gpg. Basically, the only thing I use it for
> is importing and listing keys. First, I imported my secret key via what
> is now available as
>
> notmuch autocrypt --import-secret-key
>
> I then started importing other peoples' keys via one of
>
> gpg --locate-external-keys EMAIL...
> notmuch autocrypt --locate-keys EMAIL...
> curl URL | gpg --import
> cat FILE | gpg --import
>
> Finally, I sometimes have a look at my two keyrings via
>
> gpg --list-secret-keys
> gpg --list-keys
>
> Everything else (i.e. message encryption, signing, decryption, signature
> verification) is already handled very well by notmuch and bower (the
> notmuch frontend I use). I also entirely ignore the trust level of keys;
> and my manual key handling is mostly a mix of TOFU and delegation of
> trust to the CA certificate infrastructure of HTTPS requests. But at
> least it works(tm) pretty well in practice.
What you're describing here i would describe as "stateful OpenPGP" --
and i agree, it *looks* like it works™ pretty well in practice.
The rough corners come up in places where the assumptions the various
parties sharing the state don't match each other (or don't match the
mechanism used to store the state in the first place. For example, if
someone can mutate that state in a way that you don't expect, then they
might be able to convince you to do things that harm either the privacy
or availability of your e-mail. I'll come back to this below, where you
talk about input validation.
On the flip side, if we can have a reasonable pass at answering the
autocrypt recommendation, then we don't need "stateful" OpenPGP at all
(we can just use the recommendation directly, in combination with a
pointer to the user's own secret key material), and it should be
relatively easy to map notmuch and bower into a stateless OpenPGP
implementation, of which there are now many.
> as long as this tooling is not supported by both notmuch and bower, I
> don't see much of a point in supporting it in notmuch-autocrypt. I
> also think that it makes sense to prioritize support for a single
> setup first, before thinking about supporting additional backends.
I think we might be able to have our cake and eat it too. What if we
could identify the valid autocrypt recommendation, *and* make it easy to
feed it into gpg for those that want that?
Making it possible to produce the Autocrypt recommendation should make
it easier to move to other OpenPGP implementations. But maybe we need
to work on both in parallel.
> https://tilde.club/~seifferth/repos/notmuch-autocrypt-old/
thanks, this is super interesting background work as well.
I got stalled on this years ago just trying to fit the autocrypt peers
table into the notmuch database, so i know the feeling ☹ I like that
you've taken a couple different approaches at making this work.
> Yes, the security implications of using notmuch-autocrypt in its current
> form are pretty daunting. I figured that this might be acceptable for a
> rough prototype. But if notmuch-autocrypt sees any real use, we should
> definitely add proper input validation -- which would require parsing the
> OpenPGP certificate to confirm that it conforms to the subset specified
> in the autocrypt spec; and that the OpenPGP certificate actually specifies
> the same User ID we would expect from its context.
Autocrypt explicitly says that the user ID field in the OpenPGP
certificate is "decorative", and is neither required to be present nor
matching. But because of the way that GnuPG handles "stateful OpenPGP",
the user ID has to match the e-mail address exactly for it to be safe to
inject the certificate in the "keyring".
Then i suppose we also need to be able to reason about what other inputs
might be modifying this shared state, and how (or whether) we update the
state if we receive new certificates from a given peer.
We also need to be able to identify that newer messages *without* an
Autocrypt header have come in from the same sender, so that a peer can
safely turn Autocrypt off.
> 1. If `notmuch new` would add `tag:autocrypt` to messages that contain
> an autocrypt header, I could a) use this tag to make the query for
> `notmuch autocrypt --locate-keys` more efficient and b) I could easily
> notice that a peer is using autocrypt even if my notmuch frontend knows
> nothing of autocrypt semantics.
This ought to be a fairly straightforward and achievable task. The only
issue is that it might need to trigger a re-indexing (if someone wants
to evaluate their old mailstore). But you could also just start
indexing new messages and be OK with the fact that you'll only start
identifying Autocrypt messages going forward. That's still "probably
better than not doing it".
Want to try to produce such a patch for notmuch? I'd be happy to
collaborate on it.
> 2. If `notmuch show` could be used to dump the effective header of an
> encrypted message (e.g. inlining protected headers), notmuch-autocrypt
> would not need to do this kind of message parsing itself.
I like this as well -- what if it produced the per-message output when
--format is sexp or json? we could have a simple "autocrypt" label that
contains keydata and prefer-encrypt. Doing this fix here would also
mean that we could include Autocrypt headers from inside the
cryptographic envelope, on an encrypted message.
I'd also be happy to collaborate on this.
> 3. If notmuch was aware of Autocrypt-Gossip headers, notmuch-autocrypt
> could potentially use the key gossip extension to autocrypt to
> find even more autocrypt keys. The problem with "Autocrypt-Gossip"
> headers is that they can appear in any message (whereas "Autocrypt"
> headers for peer@example.net should only appear in messages
> `from:peer@example.net`). If I could query notmuch with something like:
>
> notmuch search property:autocrypt-gossip=peer@example.net
>
> this would allow notmuch-autocrypt to efficiently locate such headers.
I like this one too, but i think it maybe we can tackle it once the
other two pieces are complete.
Then we should try to map out what the new subcommand actually looks
like!
--dkg