Subject: | verify doesn't like OpenPGP cleartext signatures |
Hello,
The attached script illustrates a problem we've seen with cleartext
signatures. Although the RFC1991 "type" of the signature is 01 (clear
text), the Crypt::OpenPGP::verify function does not canonicalize the
input before hashing it.
The GnuPG options to generate the signature were:
gpg --no-force-v3-sigs -bat foo.txt
The patch attached, whilst a little hackish, seems to fix the problem
without breaking any of the tests in the test suite.
Subject: | canonical-sig-fix.patch |
--- lib/Crypt/OpenPGP.pm.orig 2006-08-10 18:28:43.000000000 +1200
+++ lib/Crypt/OpenPGP.pm 2006-08-10 18:28:47.000000000 +1200
@@ -355,9 +355,10 @@
} else {
return $pgp->error("SigFile contents are strange");
}
+ my @pte = ($sig->{type} == 1 ? (Mode => "t") : () );
unless ($data) {
if ($param{Data}) {
- $data = Crypt::OpenPGP::Plaintext->new( Data => $param{Data} );
+ $data = Crypt::OpenPGP::Plaintext->new( Data => $param{Data}, @pte );
}
else {
## if no Signature or detached sig in SigFile
@@ -366,7 +367,7 @@
my $fdata = $pgp->_read_files(@files);
return $pgp->error("Reading data files failed: " . $pgp->errstr)
unless defined $fdata;
- $data = Crypt::OpenPGP::Plaintext->new( Data => $fdata );
+ $data = Crypt::OpenPGP::Plaintext->new( Data => $fdata, @pte );
}
}
my($cert, $kb);
Subject: | cleartext-test.pl |
#!/usr/bin/perl -w
use strict;
use Crypt::OpenPGP;
my $message = <<TXT;
In this nothing text file I will shamelessly plug some NZ music
labels.
www.goldenbayrecords.com
www.ccrecords.co.nz
www.loop.co.nz
Massive.
TXT
my $sig = <<SIG;
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
iEYEARECAAYFAkTazoQACgkQ/AZAiGayWEPszACgkiVtVVaumYmEWn2ueosdN/Ar
vP8An0nq8PiuhROTDsIQ7xR4C54mAYCm
=3VTv
-----END PGP SIGNATURE-----
SIG
open(X, ">msg.txt");
print X $message;
close X;
open(X, ">msg.txt.asc");
print X $sig;
close X;
system("gpg", "--verify", "msg.txt.asc", "msg.txt");
my $key = `gpg --export -a 0x66b25843`;
my $keyring = new Crypt::OpenPGP::KeyRing(Data => $key);
my $kb = $keyring->find_keyblock_by_index(-1) or return;
my $cert = $kb->signing_key or return;
$cert->uid($kb->primary_uid);
my $sig_data = Crypt::OpenPGP::Message->new( Data => $sig );
use Data::Dumper;
print Dumper $sig_data;
my $pgp = Crypt::OpenPGP->new( );
print "now verifying with Crypt::OpenPGP\n";
my $valid = $pgp->verify( Data => $message,
Signature => $sig,
Key => $cert,
);
print("Crypt::OpenPGP thinks it's valid? ".($valid ? "Yes" : "No")
.".\n");