Consider the following:
$ ./gpgcompose --pk-esk neal --pk-esk --session-key new werner --encrypted-mdc
--literal --value foo | gpg2 -d
gpg: encrypted with 2048-bit RSA key, ID 0x1E0FE11D664D7444, created 2014-01-02
"Werner Koch <wk@gnupg.org>"
gpg: encrypted with 2048-bit RSA key, ID 0xC2B819056C652598, created 2015-04-07
"Neal H. Walfield <neal@walfield.org>"
gpg: packet(1) with unknown version 34
gpg: WARNING: encrypted message has been manipulated!
This creates a PK-ESK for me, it then creates a PK-ESK for werner with a new
session key and encrypts the data with Werner's session key. When I decrypt it
(using the first PK-ESK), I get junk, which gpg interprets as an OpenPGP message
(see above).
This could be largely avoided if we implemented OpenPGP's simple integrity check
(making sure the bytes at blocksize-2 and blocksize-1 match the bytes at
blocksize and blocksize + 1). Interestingly, we do this check when the session
key is extracted from an SK-ESK packet (from decrypt_data in decrypt-data.c):
if (dek->symmetric && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) ) { rc = gpg_error (GPG_ERR_BAD_KEY); goto leave; }
Why don't we do this when the session key is taken from a PK-ESK packet?