Difference between clearsign and detached signatures?

TJ gnupg at iam.tj
Sat Aug 30 19:50:47 CEST 2014


I've finally pinned down the issue. The manipulation of the plaintext by clearsign results in the message digest
being calculated on different plaintext, as per RFC4880 7.1 Dash-Escaped Text:

"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."

The issue stems from the different ways that DOS/Windows and *nix handle line-endings. In DOS/Windows <CR><LF> is the line separator
whereas in *nix it is the line terminator. DOS/Windows doesn't require a line-separator at the end of the last line of a text file,
whereas *nix requires a line terimantor.

I used 3 plaintext test-cases to isolate the issue:

Release        : A Debian APT archive Release file (all lines end with LF including the last line)
Release.CRLF   : 'Release' with all line endings converted to CRLF
Release.CRLF.2 : 'Release.CRLF' with the final CRLF removed

"gpg --debug-all --detach-sign --armor ..." does not modify the plaintext before generated the message digest (see "dbgmd-00001.sign").
"gpg --debug-all --clearsign ... Release.CRLF.2" does *not* modify the plaintext (see "dbgmd-00001-clearsign").
"gpg --debug-all --clearsign ... Release.CRLF" modifies the plaintext by removing the final CRLF pair (see "dbgmd-00001-clearsign").
"gpg --debug-all --clearsign ... Release" modifies the plaintext, replacing all LF with CRLF and removing the last lines terminator
   (see "dbgmd-00001-clearsign").

So to use a detached signature to verify using clearsign format the plaintext must be pre-formatted to be identical to the
clearsign generated plaintext form:

gpg --debug-all --digest-algo SHA512 --detach-sign --armor --local-user 3591FB89 --output Release.gpg <(sed 's/$/\r/' Release | head -c -2)

gpg --verify <(echo -e "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA512\n\n$(sed 's/$/\r/' Release | head -c -2)\n$(cat Release.gpg)")

# gpg: Signature made Sat 30 Aug 2014 18:41:52 BST using RSA key ID 3591FB89
# gpg: Good signature from "Test Key (gnupg 1.4.16 Ubuntu 14.04 amd64) <detached at signature.org>"

gpg --verify <(echo -e "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA512\n\n$(cat Release)\n$(cat Release.gpg)")

# gpg: Signature made Sat 30 Aug 2014 18:41:52 BST using RSA key ID 3591FB89
# gpg: Good signature from "Test Key (gnupg 1.4.16 Ubuntu 14.04 amd64) <detached at signature.org>"

Unfortunately, for plaintext that hasn't been pre-formatted, it means gpg needs modifying in order for it to correctly verify clearsign
input that embeds a detached signature rather than a clearsign signature.



More information about the Gnupg-users mailing list