Subject: | [PATCH] Avoid dependencies on Math::Pari |
Math::Pari is hard for most Linux distributions to build because it
requires its own copy of libpari and won't build with a system copy.
(This has been a persistent problem for Debian.) Since Crypt::RSA is
probably going to be moving away from Math::Pari, the only dependency of
Crypt::OpenPGP left that uses it is Crypt::Random.
I'm attaching a patch that will allow the use of Bytes::Random::Secure if
Crypt::Random is not available. I have added two functions to
Crypt::OpenPGP::Util that abstract the differences between the two
modules. The testsuite continues to pass for me on Debian amd64/sid.
If you would rather, you can pull from git://github.com/bk2204/Crypt-
OpenPGP.git non-pari.
Subject: | non-pari.patch |
diff --git a/lib/Crypt/OpenPGP.pm b/lib/Crypt/OpenPGP.pm
index cbf40d4..75fb644 100644
--- a/lib/Crypt/OpenPGP.pm
+++ b/lib/Crypt/OpenPGP.pm
@@ -11,6 +11,7 @@ use Crypt::OpenPGP::Plaintext;
use Crypt::OpenPGP::Message;
use Crypt::OpenPGP::PacketFactory;
use Crypt::OpenPGP::Config;
+use Crypt::OpenPGP::Util;
use Crypt::OpenPGP::ErrorHandler;
use base qw( Crypt::OpenPGP::ErrorHandler );
@@ -455,8 +456,7 @@ sub encrypt {
Crypt::OpenPGP::Compressed->errstr);
$ptdata = Crypt::OpenPGP::PacketFactory->save($cdata);
}
- require Crypt::Random;
- my $key_data = Crypt::Random::makerandom_octet( Length => 32 );
+ my $key_data = Crypt::OpenPGP::Util::get_random_bytes(32);
my $sym_alg = $param{Cipher} ?
Crypt::OpenPGP::Cipher->alg_id($param{Cipher}) : DEFAULT_CIPHER;
my(@sym_keys);
diff --git a/lib/Crypt/OpenPGP/Certificate.pm b/lib/Crypt/OpenPGP/Certificate.pm
index 72d344b..b5d7092 100644
--- a/lib/Crypt/OpenPGP/Certificate.pm
+++ b/lib/Crypt/OpenPGP/Certificate.pm
@@ -329,8 +329,7 @@ sub lock {
my($passphrase) = @_;
my $cipher = Crypt::OpenPGP::Cipher->new($cert->{cipher});
my $sym_key = $cert->{s2k}->generate($passphrase, $cipher->keysize);
- require Crypt::Random;
- $cert->{iv} = Crypt::Random::makerandom_octet( Length => 8 );
+ $cert->{iv} = Crypt::OpenPGP::Util::get_random_bytes(8);
$cipher->init($sym_key, $cert->{iv});
my @sec = $cert->{key}->secret_props;
if ($cert->{version} < 4) {
diff --git a/lib/Crypt/OpenPGP/Ciphertext.pm b/lib/Crypt/OpenPGP/Ciphertext.pm
index 4b76e0a..27bcffc 100644
--- a/lib/Crypt/OpenPGP/Ciphertext.pm
+++ b/lib/Crypt/OpenPGP/Ciphertext.pm
@@ -1,6 +1,7 @@
package Crypt::OpenPGP::Ciphertext;
use strict;
+use Crypt::OpenPGP::Util;
use Crypt::OpenPGP::Cipher;
use Crypt::OpenPGP::Constants qw( DEFAULT_CIPHER
PGP_PKT_ENCRYPTED
@@ -24,11 +25,10 @@ sub init {
if ((my $key = $param{SymKey}) && (my $data = $param{Data})) {
$enc->{is_mdc} = $param{MDC} || 0;
$enc->{version} = 1;
- require Crypt::Random;
my $alg = $param{Cipher} || DEFAULT_CIPHER;
my $cipher = Crypt::OpenPGP::Cipher->new($alg, $key);
my $bs = $cipher->blocksize;
- my $pad = Crypt::Random::makerandom_octet( Length => $bs );
+ my $pad = Crypt::OpenPGP::Util::get_random_bytes($bs);
$pad .= substr $pad, -2, 2;
$enc->{ciphertext} = $cipher->encrypt($pad);
$cipher->sync unless $enc->{is_mdc};
diff --git a/lib/Crypt/OpenPGP/Key/Public/ElGamal.pm b/lib/Crypt/OpenPGP/Key/Public/ElGamal.pm
index d848f90..a00cfeb 100644
--- a/lib/Crypt/OpenPGP/Key/Public/ElGamal.pm
+++ b/lib/Crypt/OpenPGP/Key/Public/ElGamal.pm
@@ -55,10 +55,7 @@ sub gen_k {
my $bits = 198;
my $p_minus1 = $p - 1;
- 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);
+ my $k = Crypt::OpenPGP::Util::get_random_bigint($bits);
while (1) {
last if Math::BigInt::bgcd($k, $p_minus1) == 1;
$k++;
diff --git a/lib/Crypt/OpenPGP/S2k.pm b/lib/Crypt/OpenPGP/S2k.pm
index 0ce398c..bd246f3 100644
--- a/lib/Crypt/OpenPGP/S2k.pm
+++ b/lib/Crypt/OpenPGP/S2k.pm
@@ -4,6 +4,7 @@ use strict;
use Crypt::OpenPGP::Buffer;
use Crypt::OpenPGP::Digest;
use Crypt::OpenPGP::ErrorHandler;
+use Crypt::OpenPGP::Util;
use base qw( Crypt::OpenPGP::ErrorHandler );
use vars qw( %TYPES );
@@ -95,8 +96,7 @@ sub init {
}
else {
$s2k->{hash_alg} = DEFAULT_DIGEST;
- require Crypt::Random;
- $s2k->{salt} = Crypt::Random::makerandom_octet( Length => 8 );
+ $s2k->{salt} = Crypt::OpenPGP::Util::get_random_bytes(8);
}
if ($s2k->{hash_alg}) {
$s2k->{hash} = Crypt::OpenPGP::Digest->new($s2k->{hash_alg});
@@ -130,8 +130,7 @@ sub init {
}
else {
$s2k->{hash_alg} = DEFAULT_DIGEST;
- require Crypt::Random;
- $s2k->{salt} = Crypt::Random::makerandom_octet( Length => 8 );
+ $s2k->{salt} = Crypt::OpenPGP::Util::get_random_bytes(8);
$s2k->{count} = 96;
}
if ($s2k->{hash_alg}) {
diff --git a/lib/Crypt/OpenPGP/SessionKey.pm b/lib/Crypt/OpenPGP/SessionKey.pm
index a4bbb8f..4c86d42 100644
--- a/lib/Crypt/OpenPGP/SessionKey.pm
+++ b/lib/Crypt/OpenPGP/SessionKey.pm
@@ -88,11 +88,12 @@ sub decrypt {
sub _encode {
my $class = shift;
- require Crypt::Random;
my($sym_key, $sym_alg, $size) = @_;
my $padlen = "$size" - length($sym_key) - 2 - 2 - 2;
- my $pad = Crypt::Random::makerandom_octet( Length => $padlen,
- Skip => chr(0) );
+ my $pad = "\0";
+ while ($pad =~ tr/\0//) {
+ $pad = Crypt::OpenPGP::Util::get_random_bytes($padlen);
+ }
bin2mp(pack 'na*na*n', 2, $pad, $sym_alg, $sym_key,
unpack('%16C*', $sym_key));
}
diff --git a/lib/Crypt/OpenPGP/Util.pm b/lib/Crypt/OpenPGP/Util.pm
index 3398c35..579d80a 100644
--- a/lib/Crypt/OpenPGP/Util.pm
+++ b/lib/Crypt/OpenPGP/Util.pm
@@ -99,6 +99,34 @@ sub _ensure_bigint {
return $num;
}
+sub get_random_bytes {
+ my $length = shift;
+ if (eval 'require Crypt::Random; 1;') {
+ return Crypt::Random::makerandom_octet( Length => $length);
+ }
+ elsif (eval 'require Bytes::Random::Secure; 1;') {
+ return Bytes::Random::Secure::random_bytes($length);
+ }
+ else {
+ die "No random source available!";
+ }
+}
+
+sub get_random_bigint {
+ my $bits = shift;
+ if (eval 'require Crypt::Random; 1;') {
+ my $pari = Crypt::Random::makerandom( Size => $bits, Strength => 0 );
+ return Math::BigInt->new($pari);
+ }
+ elsif (eval 'require Bytes::Random::Secure; 1;') {
+ my $hex = Bytes::Random::Secure::random_bytes_hex($bits / 8);
+ return Math::BigInt->new("0x$hex");
+ }
+ else {
+ die "No random source available!";
+ }
+}
+
1;
__END__