Page MenuHome GnuPG

gpg fails to recognize signatures if signer's user ID subpacket is present with the critical bit set
Closed, WontfixPublic

Description

Consider this test OpenPGP certificate:

And this cleartext inline signed document, made by that certificate:

.

Attempting to validate the signature with GnuPG 2.2.27 yields:

gpg: Signature made Tue 09 Feb 2021 12:45:30 AM EST
gpg:                using EDDSA key B3B5920B69AE83EDA7F6E09029555318E7E16B39
gpg:                issuer "test@example.org"
gpg: assuming bad signature from key 29555318E7E16B39 due to an unknown critical bit
gpg: BAD signature from "test <test@example.org>" [unknown]

gpg --list-packets shows the signature with this info:

# off=0 ctb=88 tag=2 hlen=2 plen=135
:signature packet: algo 22, keyid 29555318E7E16B39
	version 4, created 1612849530, md5len 0, sigclass 0x01
	digest algo 8, begin of digest 50 d0
	hashed subpkt 33 len 21 (issuer fpr v4 B3B5920B69AE83EDA7F6E09029555318E7E16B39)
	hashed subpkt 2 len 4 (sig created 2021-02-09)
	critical hashed subpkt 28 len 16 (signer's user ID)
	subpkt 16 len 8 (issuer key ID 29555318E7E16B39)
	data: [255 bits]
	data: [256 bits]

So the only critical hashed subpacket is the "signer's User ID". But GnuPG knows what the "issuer user ID subpacket" is and how to interpret it. It should not reject the signature due to the "critical" bit being set on that subpacket.

Most OpenPGP tools that i'm aware of (including GnuPG 2.2.27) do *not* set the critical bit on this particular subpacket. But GnuPG should still be capable of accepting such a subpacket in a signature without rejecting it due to its critical bit being set.

Details

Version
2.2.27

Event Timeline

werner claimed this task.
werner added a subscriber: werner.

Without any defined semantic it is not proper to ignore a critical bit. The software which created this keyblock seems to aim for incompatibility.

RFC 4880 says:

Bit 7 of the subpacket type is the "critical" bit. If set, it denotes that the subpacket is one that is critical for the evaluator of the signature to recognize. If a subpacket is encountered that is marked critical but is unknown to the evaluating software, the evaluator SHOULD consider the signature to be in error.

An evaluator may "recognize" a subpacket, but not implement it. The purpose of the critical bit is to allow the signer to tell an evaluator that it would prefer a new, unknown feature to generate an error than be ignored.

However, GnuPG does know the semantics of the subpacket -- it represents the User ID that made a given signature. This can be useful in some contexts, and surely GnuPG knows what to do with it (for example, it knows how to fetch the signing certificate via a WKD URL as derived from the User ID in question). FWIW, I agree that *why* anyone would mark this particular subpacket as critical here is unclear. But it does seem that GnuPG can recognize the packet and knows its semantics.

Critical attributes are well known from CMS and X.509 and some have a history which can only be described as cargo cult. We should not allow them in the OpenPGP ecosystem without giving them a specific semantic aside from "we do something with it".

I think you're saying "GnuPG will reject all subpackets marked with a critical flag unless there is a specific known semantic for *criticality* for that subpacket" Am I understanding that right? Is there a published list of criticality semantics that GnuPG is willing to accept? How do those semantics differ from standard semantics for the packet in question?

Or are you suggesting that there are certain subpacket types which *must always* be marked as critical; and any subpacket type not in that group *must never* be marked as critical?