Skip Menu |

This queue is for tickets about the Crypt-OpenPGP CPAN distribution.

Report information
The Basics
Id: 7735
Status: new
Priority: 0/
Queue: Crypt-OpenPGP

People
Owner: Nobody in particular
Requestors: ljm [...] slac.stanford.edu
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.03
Fixed in: (no value)



Subject: Can't encrypt or sign an empty message
The encrypt and sign methods in Crypt::OpenPGP version 1.03 will not encrypt an empty string or an empty file. I have attached a program, demo.pl, to demonstrate the problem. To use it, change the line, my $keyid = '<enter-your-16-hex-digit-keyid>'; to specify your /public/private key pair. I will also attach a patch which I believe fixes the problem.
#!/usr/local/bin/perl -w # Demonstrate problems encrypting an empty string or file # using the Crypt::OpenPGP Perl module use Crypt::OpenPGP; use Term::ReadKey; my $pgp = Crypt::OpenPGP->new; my $keyid = '<enter-your-16-hex-digit-keyid>'; my ($ciphertext, $signature); # Test encryption of a null string: $ciphertext = $pgp->encrypt( Data => '' , Recipients => $keyid , Armour => 1 ); if (defined $ciphertext) { print "\nEncryption of '':\n$ciphertext"; } else { warn "Encrytion of '' failed: ", $pgp->errstr; } # Test encryption of a null file: $ciphertext = $pgp->encrypt( Filename => '/dev/null' , Recipients => $keyid , Armour => 1 ); if (defined $ciphertext) { print "\nEncryption of /dev/null:\n$ciphertext"; } else { warn "Encryption of /dev/null failed: ", $pgp->errstr; } # Test signing of a null string: $signature = $pgp->sign( Data => '' , KeyID => $keyid , Detach => 1 , Armour => 1 , PassphraseCallback => \&passphrase_cb ); if (defined $signature ) { print "\nSignature of '':\n$signature"; } else { warn "Signing of '' failed: ", $pgp->errstr; } # Test signing of a null file: $signature = $pgp->sign( Filename => '/dev/null' , KeyID => $keyid , Detach => 1 , Armour => 1 , PassphraseCallback => \&passphrase_cb ); if (defined $signature ) { print "\nSignature of /dev/null:\n$signature"; } else { warn "Signing of /dev/null failed: ", $pgp->errstr; } # ----------------------------------------------------------------------- # # The following routines are copied from bin/pgplet # sub passphrase_cb { my($cert) = @_; my $prompt; if ($cert) { $prompt = sprintf qq( You need a passphrase to unlock the secret key for user "%s". %d-bit %s key, ID %s Enter passphrase: ), $cert->uid, $cert->key->size, $cert->key->alg, substr($cert->key_id_hex, -8, 8); } else { $prompt = "Enter passphrase: "; } prompt($prompt, '', 1); } sub prompt { my($prompt, $def, $noecho) = @_; print STDERR $prompt . ($def ? "[$def] " : ""); if ($noecho) { ReadMode('noecho'); } chomp(my $ans = ReadLine(0)); ReadMode('restore'); print STDERR "\n"; defined $ans && $ans ne '' ? $ans : $def; }
[guest - Tue Sep 21 21:12:37 2004]: Here's a patch which I believe fixes the problem.
*** OpenPGP.pm.orig 2002-12-09 17:43:00.000000000 -0800 --- OpenPGP.pm 2004-09-21 16:13:19.000000000 -0700 *************** *** 250,259 **** return $pgp->error( $pgp->errstr ); my($cert, $data); require Crypt::OpenPGP::Signature; ! unless ($data = $param{Data}) { ! my $file = $param{Filename} or ! return $pgp->error("Need either 'Data' or 'Filename' to sign"); ! $data = $pgp->_read_files($file) or return $pgp->error($pgp->errstr); } unless ($cert = $param{Key}) { my $kid = $param{KeyID} or return $pgp->error("No KeyID specified"); --- 250,261 ---- return $pgp->error( $pgp->errstr ); my($cert, $data); require Crypt::OpenPGP::Signature; ! unless (defined($data = $param{Data})) { ! my $file = $param{Filename}; ! return $pgp->error("Need either 'Data' or 'Filename' to encrypt") ! unless defined $file; ! $data = $pgp->_read_files($file); ! return $pgp->error($pgp->errstr) unless defined $data; } unless ($cert = $param{Key}) { my $kid = $param{KeyID} or return $pgp->error("No KeyID specified"); *************** *** 418,427 **** my($data); require Crypt::OpenPGP::Cipher; require Crypt::OpenPGP::Ciphertext; ! unless ($data = $param{Data}) { ! my $file = $param{Filename} or ! return $pgp->error("Need either 'Data' or 'Filename' to encrypt"); ! $data = $pgp->_read_files($file) or return $pgp->error($pgp->errstr); } my $ptdata; if ($param{SignKeyID}) { --- 420,431 ---- my($data); require Crypt::OpenPGP::Cipher; require Crypt::OpenPGP::Ciphertext; ! unless (defined($data = $param{Data})) { ! my $file = $param{Filename}; ! return $pgp->error("Need either 'Data' or 'Filename' to encrypt") ! unless defined $file; ! $data = $pgp->_read_files($file); ! return $pgp->error($pgp->errstr) unless defined $data; } my $ptdata; if ($param{SignKeyID}) { *** OpenPGP/Plaintext.pm.orig 2001-07-29 10:08:56.000000000 -0700 --- OpenPGP/Plaintext.pm 2004-09-21 12:02:20.000000000 -0700 *************** *** 19,25 **** sub init { my $pt = shift; my %param = @_; ! if (my $data = $param{Data}) { $pt->{data} = $data; $pt->{mode} = $param{Mode} || 'b'; $pt->{timestamp} = time; --- 19,25 ---- sub init { my $pt = shift; my %param = @_; ! if (defined(my $data = $param{Data})) { $pt->{data} = $data; $pt->{mode} = $param{Mode} || 'b'; $pt->{timestamp} = time;