[Webfunds-devel] PGP clearsig grottiness

Ian Grigg iang@systemics.com
Tue, 19 Oct 1999 09:43:14 -0400 (AST)


There is a kludge in the signing format that relates to
the CRLF that is at the end before the signature.  I hit
this in the recent rewrite of the contract store, as
signatures were not being handled properly, and I ended
up having to try multiple combinations to get it to work.

The following is a reasonable explanation of the kludge,
which I'm saving here for the record.  I hope it's the
final word.

iang



Date: Tue, 19 Oct 1999 12:03:37 +0200
From: Thomas Roessler <roessler@guug.de>
To: Dave Del Torto <ddt@lsd.com>
Cc: Jon Callas <jon@callas.org>, Werner Koch <wk@gnupg.org>,
        ietf-open-pgp@imc.org
Subject: Re: Moving forward

On 1999-10-18 18:41:17 -0700, Dave Del Torto wrote:

> At 10:58 PM -0700 1999-10-17, Jon Callas wrote:

> >A summary of the problem is that that 2440 does not cover the case where
> >a clear-signed message does not end with a CRLF or is of length zero.

As I read the text, it does (RFC 2440, 7.1):

|   As with binary signatures on text documents, a cleartext
|   signature is calculated on the text using canonical <CR><LF> line
|   endings.  The line ending (i.e. the <CR><LF>) before the
|   '-----BEGIN PGP SIGNATURE-----' line that terminates the signed
|   text is not considered part of the signed text.

Actually, the construction is analogous to what MIME does with
multipart separator lines, see RFC 2046 section 5.1.1:

|   NOTE: The CRLF preceding the boundary delimiter line is
|   conceptually attached to the boundary so that it is possible to
|   have a part that does not end with a CRLF (line break).  Body
|   parts that must be considered to end with line breaks, therefore,
|   must have two CRLFs preceding the boundary delimiter line, the
|   first of which is part of the preceding body part, and the second
|   of which is part of the encapsulation boundary.

That is, OpenPGP implementations MUST add

		  <cr><lf><delimiter line><cr><lf>

when creating cleartext signatures, and MUST calculate the signature
over the text PRECEDING the <cr><lf> sequence which starts the
separator.

Thus, a "-----BEGIN PGP SIGNATURE-----" delimiter without a
preceding CRLF is just nonsense, and possibly part of signed text.

A quick test with pgp 2.6.3in, gpg 0.9.8a-snap1999-06-30, and pgp5
("PGP for Personal Privacy Version: unix50i1b") indicates that at
least these implementations actually seem to be working the way
suggested by the text and the analogy with MIME.

More precisely, I generated a simple text file which lacked the
final new line character.  I clearsigned it with pgp 2.6.3in.  The
signature was correctly verified by pgp2, gpg, and pgp5.  Then, I
added another new line in front of the delimiter line, and all
implementations correctly warned me that this was a bad signature.

> My memory may be faulty, but I believe that both RFC 1991 and our
> OpenPGP/MIME draft simply implicitly assume that you can't have a
> length-zero message, because it makes no sense to provide a digital
> signature on _nothing_.

In the PGP/MIME draft, we don't really have to deal with this, since
we just take what MIME gives us, make sure MIME line endings are
correct (namely CRLF), and pass the rest to PGP.  

Additionally, with PGP/MIME, there is always at least one CRLF to be
signed: A multipart/signed MIME body MUST have two subparts, the
first of arbitrary type, the second of type
application/pgp-signature.  Since the signature is calculated over
the MIME representation of the first body part, our worst case is an
empty text/plain body part, including headers.  This can (worst case
again) be represented by one empty line which terminates
the (empty) MIME header.

Example:

| From: Thomas Roessler <roessler@guug.de>
| To: Thomas Roessler <roessler@sobolev.rhein.de>
| Subject: stupid test message
| Message-ID: <19991019115455.A27180@sobolev.rhein.de>
| Mime-Version: 1.0
| Content-Type: multipart/signed; micalg=pgp-md5;
| 	protocol="application/pgp-signature"; boundary="Q68bSM7Ycu6FN28Q"
|
| 
| --Q68bSM7Ycu6FN28Q
| 
| 
| --Q68bSM7Ycu6FN28Q
| Content-Type: application/pgp-signature
| 
| -----BEGIN PGP MESSAGE-----
| Version: 2.6.3in
| 
| iQEVAwUBOAxAbNImKUTOasbBAQGcxQf+KhjjzhxUo2RTCauKm+5znAXFWOtZAyVe
| 3mxuRJvJPDTjocEo/aDwHzekhqssLhPI0LD62R96LvKHM6nbYRJyG4pByf8VH2lI
| C2bWpSw7QFqBjJgBC8Z6+qD/hAdvdNbduNJ2kUPiX8npuVdj8RyWNDJ3xyk+TPQh
| vTbnGjwAeIgnygstZpKW8feBMFLi3SZ57qlc1Gen5r1srruNPYykPUoqpmjROe9j
| r6U4P17V1aKUzJts/b4RF+MKiO3ebQf5NbplWkMVvqdR0VNOYpddDZiqzYMkoIYb
| 3TcMUAzGcp1iRetd5mIezcJKJ6bIgPwdaZyvbuAW8lQ8LhZkn5uqqg==
| =37F7
| -----END PGP MESSAGE-----
| 
| --Q68bSM7Ycu6FN28Q--