As reported at https://mailarchive.ietf.org/arch/msg/openpgp/RLMBugGhg_c9xT7zmDrkBklRZB8/ i noticed that GnuPG declines to validate an OpenPGP Signed Message if the signature is text-mode (Signature Type ID 0x01), but the Literal Data Packet ("LDP") is binary (format b), while the contents of the LDP are not CRLF-delimited.
You can see this with the following public key:
-----BEGIN PGP PUBLIC KEY BLOCK----- xjMEZ7k39xYJKwYBBAHaRw8BAQdAOfCju+pxXLXR2WU7ItL1LdlJFfubUeXQPk33 sqDgebXNCHRlc3Qga2V5wo8EEBYIADcCGQEFAme5N/cCGwMICwkIBwoNDAsFFQoJ CAsCFgIBJxYhBOJ0yfrr3tklx77Q+E/elLAX9VxrAAoJEE/elLAX9VxrJKcBAPzY 8Ct8qZ2xbzMXMtHrnR+a2kYLVDA9U8xPtrzQOUcOAPoDW17PxLj0IyZBS7ewb2Zt bbZ7yHLYYKmrF2mAyBOiCA== =UNOn -----END PGP PUBLIC KEY BLOCK-----
Here is just such a message:
-----BEGIN PGP MESSAGE----- xA0DAQoWT96UsBf1XGsBywtiAAAAAAB0ZXN0CsJ1BAEWCgAdFiEE4nTJ+uve2SXH vtD4T96UsBf1XGsFAme5OzsACgkQT96UsBf1XGtKWAEAjmR2dUu8Jsvq+j3QArUQ J549CNsbbuHLLAhaE0C2zZMBAJD4hLT9KXxnpTINCAcgZfytWChkNP+qKqb4pV5N ItsH =OYzj -----END PGP MESSAGE-----
this message is described by gpg --list-packets as:
# off=0 ctb=c4 tag=4 hlen=2 plen=13 new-ctb :onepass_sig packet: keyid 4FDE94B017F55C6B version 3, sigclass 0x01, digest 10, pubkey 22, last=1 # off=15 ctb=cb tag=11 hlen=2 plen=11 new-ctb :literal data packet: mode b (62), created 0, name="", raw data: 5 bytes # off=28 ctb=c2 tag=2 hlen=2 plen=117 new-ctb :signature packet: algo 22, keyid 4FDE94B017F55C6B version 4, created 1740192571, md5len 0, sigclass 0x01 digest algo 10, begin of digest 4a 58 hashed subpkt 33 len 21 (issuer fpr v4 E274C9FAEBDED925C7BED0F84FDE94B017F55C6B) hashed subpkt 2 len 4 (sig created 2025-02-22) subpkt 16 len 8 (issuer key ID 4FDE94B017F55C6B) data: [256 bits] data: [256 bits]
If you replace the LDP with an LDP that ends in CRLF (regardless of whether it is tagged with a b or t or u or m or whatever format octet), then gpg and gpgv will successfully validate the Signed Message.
For example, this message is otherwise identical, but with \r prefixing the`\n` (and GnuPG does indicate that the signature is valid):
-----BEGIN PGP MESSAGE----- xA0DAQoWT96UsBf1XGsBywxiAAAAAAB0ZXN0DQrCdQQBFgoAHRYhBOJ0yfrr3tkl x77Q+E/elLAX9VxrBQJnuTs7AAoJEE/elLAX9VxrSlgBAI5kdnVLvCbL6vo90AK1 ECeePQjbG27hyywIWhNAts2TAQCQ+IS0/Sl8Z6UyDQgHIGX8rVgoZDT/qiqm+KVe TSLbBw== =mMS9 -----END PGP MESSAGE-----
It seems to me that when validating a text-mode signature in an OpenPGP in the context of a "Signed Message", if the LDP is marked binary (or indeed, even if it isn't), if the contents of the LDP are not in CRLF mode, it should be digested after converting to CRLF mode.
The specs don't seem to say one way or the other about whether such a construction is valid or not, and afaict, other OpenPGP implementations (including RNP) will do the conversion themselves and correctly validate the signature.
text-format LDPs are by spec supposed to be stored in CRLF mode already. But binary-format LDPs have no such requirement.
So, there are maybe two different simple, consistent outcomes that could be seen as aligning with the specifications here:
- reject all Signed Messages that combine a binary-format literal data packet and a text-mode signature
- when digesting a binary literal data packet for a text-mode signature, convert the contents into CRLF line ending.
instead, GnuPG does:
- digest the bytestream of the literal data packet directly when evaluating a text-mode signature, regardless of format indicator, without converting to CRLF.