[openpgp] Re: PQC requires urgent semantic cleanup

Daniel Huigens <[email protected]> Mon, 01 Dec 2025 15:37:11 +0000
Newsgroups gmane.ietf.openpgp
Message-ID <uk_tc8pwVFUCj5TIY7M6c_hJfyILQbaJ9tVAO7KTPEpjfSMYGRy-a4AZxybo4RgHssY2BlHwaZRCvOzZNOXKVggb7fJ8_dizc-CrWy5EQic=@protonmail.com>
Hi Andrew & all (again),

After swapping back into my brain the discussion from [1] on this topic,
I'm not sure I fully agree with the problem and solution proposed here.

To be clear, I agree that these semantics of OpenPGP are underspecified,
and therefore the interop test suite expectations are insufficiently
backed up by the spec. So, I still agree that removing them for now
would be reasonable, however, I'm not sure we should push the spec
(and then the test expectations) in the other direction (at least
for some of the issues you mentioned).


To be explicit about the problem we're solving, the issue is that if you
clean up self-signatures to remove all except the latest one, then
message signatures created before the latest self-signature become
invalid.

This is however only a problem if:
1. You verify an old message signature after having cleaned up a
   certificate yourself, or
2. You update a certificate from a key server (that has cleaned it up)
   by overwriting your local cert rather than merging them, and then
   verify an old signature
3. The key owner sends you a cold email (or you don't have their cert
   for another reason) and then updatest their key right after
4. The key owner is signing long-lived artifacts such as software
   packages, and wants to clean up their certificate without
   invalidating old signatures.

There are a bunch of possible solutions to this:
1. In the case of message signatures, as the verifier, record the
   verification result (perhaps using a persistent symmetric key to
   store the verification result) and refer back to it later rather than
   re-verifying old signatures.
2. When updating certs from a keyserver, merge them rather than copying
   them. This allows the keyserver to prune old signatures for new users
   (who are unlikely to need them) without breaking old signatures for
   old users that already had the cert (and thus are more likely to have
   received old message signatures as well).
3. When cleaning up certificates, only remove old signatures when the
   newest signature is older than some grace period (e.g. a week) to
   make it less likely that you receive an old/delayed message right
   after you've cleaned up the cert.
4. When distributing long-lived artifacts, re-sign them when updating
   the certificate.
5. When updating the certificate, keep the binding signature timestamps
   the same (or bump them by one second to make it clear that the
   signature is newer) rather than setting them to the current time
   (this is a bit of a hack but it is e.g. what Sequoia does already,
   as well as Proton CA, if that's a thing you care about :)).
6. Specify the semantics and update implementations to not require a
   self-signature that predates the message signature being validated
   (as you're proposing).

Now - I don't want to claim outright that any of options 1-5 are
strictly better than option 6, but I do think option 6 is perhaps the
most heavy-handed so we should consider the others first.


Also because, in some of the relevant interop test suite results,
such as [2], the majority of implementations actually agree with the
current test expectations, _including GnuPG_, only excluding PGPy
(which does not implement revocations at all :s) and since recently
rPGP (which was updated to match the behavior suggested by
draft-gallagher-openpgp-signatures).

The reason GnuPG agrees in that case is not because it matches the test
suite's semantics, but rather because it sees the subkey revocation and
applies it to all signatures (even those predating it). In other words,
it doesn't seem to implement the concept of "soft" revocations
correctly (or at all). RNP is also in this category for some test cases
(but not others).

I don't think we want to throw out the concept of soft revocations
(as both RFC9580 and draft-gallagher-openpgp-signatures require it),
so then if we implement the proposed change in our implementations, we
would start accepting the signature (unlike most other implementations),
which sounds risky.

It also means we need to convince 6 implementations (including GnuPG)
to flip their behavior on that particular test, which sounds more
difficult than asking 2 (rPGP and PGPy). Though, you could argue that
GnuPG and RNP still need to implement soft revocations (properly),
which then would lead to further changes being necessary, which evens
the playing field a bit.

In any case, at least for our implementations, I would prefer not to
implement this change and explore the other mentioned options first.


I agree, however, with the proposal to get rid of un-revocation /
re-legitimization, partially because it's much more poorly supported
(only Sequoia and PGPainless implement it properly; gopenpgp has a
partial implementaiton).

For my opinion on expiring revocations; see my previous email :)

And, it should be obvious but as always, thanks for pushing forward the
clarification of the semantics of OpenPGP!

Best,
Daniel

_______________________________________________
openpgp mailing list -- [email protected]
To unsubscribe send an email to [email protected]