GPG signature injection

|
A new vulnerability has been published in GPG. Kind of an interesting flaw, actually:
OpenPGP messages are made up of packets.  The signed data is a packet,
the actual signature is a packet and there are several control packets
as well.  For example:

   O + D + S 

This describes a standard signed message made made up of a control
packet (O for one-pass signature packet), the actual signed data (D)
and the actual signature packet (S).  gpg checks that the signature S
is valid over the data D.  This is actually easy if not OpenPGP and
GnuPG would have a long tradition of changing the fromats.  PGP 2
versions used a different way of composing these packets:

   S + D

and early versions of gpg, released before RFC2440, even created

   D + S

i.e. without the one-pass packet.  Still this would all be easy to
process properly but in an ill-advised attempt to make things easier,
gpg allowed the processing of multiple signatures per file, like

   O1 + D1 + S1 + O2 + D2 + S2

where two standard signatures are concatenated.  Now when combining
this with the other variants of signatures, things get really messy
and it is not always possible to assocciate the signature (S) with the
signed data (D).  gpg checked that this all works but unfortunately
these checks are not sufficient enough.  The attack is to change a
standard message to inject faked data (F).  A simple case is this:

   F + O + D + S 

gpg now happily skips F for verification and does a proper signature
verification of D and if this succeeds, prints a positive result.
However when asked to output the actual signed data it will output the
concatenation of F + D and thus create the impression that both are
covered by the signature.  Depending on how gpg is invoked (in a
pipeline or using --output) it may even output just F and not at all
D.  There are several variants of the attack in where to put the faked
data.

The only correct solution to this problem is to get rid of the feature
to check concatenated signatures - this allows for strict checking of
valid packet composition.  This is what has been done in 1.4.2.2 and
in the forthcoming 1.4.3rc2.  These versions accept signatures only if
they are composed of

  O + D + S
  S + D
  
Cleartext signatures are of course also supported, they are similiar
to the O+D+S case.

At some level, this is just a coding error and these things happen. But at another level this is a function of a protocol design that emphasizes flexibility and having multiple ways to do things. The more potential options at any point in the protocol the harder it is to get the implementation right and the more likely it is that you'll end up with security-relevant defects.