Skip Menu |
 

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

Report information
The Basics
Id: 68018
Status: open
Priority: 0/
Queue: Crypt-OpenPGP

People
Owner: Nobody in particular
Requestors: brobison [...] gmail.com
Cc:
AdminCc:

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



Subject: 1.06 Crypt::OpenPGP::encrypt hangs in OpenPGP/Key/Public/ElGamal.pm:gen_k()
Date: Sat, 7 May 2011 23:55:35 -0500
To: bug-Crypt-OpenPGP [...] rt.cpan.org
From: Brian Robison <brobison [...] gmail.com>
Download (untitled) / with headers
text/plain 1.4k
Here's a skeletal test case, with specific keys redacted: ----- #!/usr/bin/perl -w use Crypt::OpenPGP; my $pub_key = <PUB_KEY>; my $sec_key = <SEC_KEY>; my $key_id = <KEY_ID>; my $passphrase = shift; die "Usage: $0 passphrase" if (! $passphrase); my $data = "this is a test"; my $new_crypt = &encrypt($key_id, $pub_key, $data); sub encrypt { my ($key_id, $pub_key, $data) = @_; my $pubring = Crypt::OpenPGP::KeyRing->new(Data => $pub_key); my $pgp = Crypt::OpenPGP->new(PubRing => $pubring); # This hangs! return $pgp->encrypt( KeyID => $key_id, Data => $data, Armour => 1, ); } ----- I found the problem in OpenPGP/Key/Public/ElGamal.pm:gen_k(): sub gen_k { my($p) = @_; ## XXX choose bitsize based on bitsize of $p my $bits = 198; my $p_minus1 = $p - 1; # --- LINE 58: BUG! --- require Crypt::Random; my $k = Crypt::Random::makerandom( Size => $bits, Strength => 0 ); # We get back a Math::Pari object, but need a Math::BigInt $k = Math::BigInt->new($k); while (1) { last if Math::BigInt::bgcd($k, $p_minus1) == 1; $k++; } $k; } At line 58, $p_minus is actually an "inf" perl int, Math::BigInt::bgcd() returns NaN, and the loop never exits. Replacing line 58 with the following solved the problem (not necessarily the best fix, but it shows the point): my $p_minus1 = Math::BigInt->new($p); $p_minus1->bsub(1); Here're the additional details: Distribution: Crypt-OpenPGP-1.06 Perl: v5.10.1 OS: FreeBSD 8.2-STABLE
Download (untitled) / with headers
text/plain 185b
I'm also running into this error on perl 5.8.8. It also appears to be broken in 1.05. encrypt() works if I roll back to 1.04. Any chance of getting a release to fix this? Thanks! :-)
From: Christian Ruppert <idl0r [...] qasl.de>
Download (untitled) / with headers
text/plain 1.7k
On Sun May 08 00:55:45 2011, brobison@gmail.com wrote: Show quoted text
> Here's a skeletal test case, with specific keys redacted: > > ----- > #!/usr/bin/perl -w > > use Crypt::OpenPGP; > > my $pub_key = <PUB_KEY>; > my $sec_key = <SEC_KEY>; > > my $key_id = <KEY_ID>; > > my $passphrase = shift; > die "Usage: $0 passphrase" if (! $passphrase); > > my $data = "this is a test"; > my $new_crypt = &encrypt($key_id, $pub_key, $data); > > sub encrypt { > my ($key_id, $pub_key, $data) = @_; > my $pubring = Crypt::OpenPGP::KeyRing->new(Data => $pub_key); > my $pgp = Crypt::OpenPGP->new(PubRing => $pubring); > > # This hangs! > return $pgp->encrypt( > KeyID => $key_id, > Data => $data, > Armour => 1, > ); > } > ----- > > I found the problem in OpenPGP/Key/Public/ElGamal.pm:gen_k(): > > sub gen_k { > my($p) = @_; > ## XXX choose bitsize based on bitsize of $p > my $bits = 198; > my $p_minus1 = $p - 1; # --- LINE 58: BUG! --- > > require Crypt::Random; > my $k = Crypt::Random::makerandom( Size => $bits, Strength => 0 ); > # We get back a Math::Pari object, but need a Math::BigInt > $k = Math::BigInt->new($k); > while (1) { > last if Math::BigInt::bgcd($k, $p_minus1) == 1; > $k++; > } > $k; > } > > At line 58, $p_minus is actually an "inf" perl int, Math::BigInt::bgcd() > returns NaN, and the loop never exits. > > Replacing line 58 with the following solved the problem (not
necessarily the Show quoted text
> best fix, but it shows the point): > > my $p_minus1 = Math::BigInt->new($p); > $p_minus1->bsub(1); > > Here're the additional details: > > Distribution: Crypt-OpenPGP-1.06 > Perl: v5.10.1 > OS: FreeBSD 8.2-STABLE
Confirmed and the proposed "fix" helps.
Hm, I just did some tests with 1.03 and 1.06 and I am not sure if that is related but: Create a new RSA key using gpg --gen-key (in my case size 4096) and one Elgamal key (in my case size 3072). Export the public keys using "gpg --export --armor $keyid >testkey". #!/usr/bin/perl -w use strict; use Crypt::OpenPGP::KeyRing; use Crypt::OpenPGP; my $key; open(my $fh, '<', $ARGV[0]) or die "Error: $!\n"; { local $/ = undef; $key = <$fh>; } close($fh); my $pubring = new Crypt::OpenPGP::KeyRing(Data => $key); my $pgp = new Crypt::OpenPGP(PubRing => $pubring); my $encrypted = $pgp->encrypt(Data => "foobar", Recipients => "@", Cipher => "CAST5", Armour => 1); Run that little test script with both keys and both versions. The encryption with RSA in 1.06 is *almost* as fast as in 1.03 (IMHO slightly slower) but now do the same with the ElGamal one. In 1.03 it's pretty fast and takes about a second or so but then try it with 1.06 and the "fix" above. perl test.pl testkey3 49.64s user 0.84s system 89% cpu 56.258 total So it is noticable slower than in 1.03. (Haven't tried 1.04 or 1.05).


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.