diff --git a/lib/Crypt/OpenPGP.pm b/lib/Crypt/OpenPGP.pm index a90deb9..ddc00de 100644 --- a/lib/Crypt/OpenPGP.pm +++ b/lib/Crypt/OpenPGP.pm @@ -20,6 +20,53 @@ use File::Spec; use vars qw( %COMPAT ); +# HACK FOR PERFORMANCE +# Crypt::DSA::Util prefers /dev/random which can be slow sometimes. Let's try +# /dev/urandom if it's available to speed things up. +# Lame but it works... +{ + use Carp; + use Fcntl; + use Crypt::DSA::Util; + no warnings 'redefine'; + + sub Crypt::DSA::Util::makerandom { + warn "Using hacked version of Crypt::DSA::Util::makerandom\n"; + my %param = @_; + my $size = $param{Size}; + my $bytes = int($size / 8) + 1; + my $r = ''; + + my $dev_rand = '/dev/random'; + if (-r '/dev/urandom') { + $dev_rand = '/dev/urandom'; + } + + if ( sysopen my $fh, $dev_rand, O_RDONLY ) { + my $read = 0; + while ($read < $bytes) { + my $got = sysread $fh, my($chunk), $bytes - $read; + next unless $got; + die "Error: $!" if $got == -1; + $r .= $chunk; + $read = length $r; + } + close $fh; + } + elsif ( require Data::Random ) { + $r .= Data::Random::rand_chars( set=>'numeric' ) for 1..$bytes; + } + else { + croak "makerandom requires $dev_rand or Data::Random"; + } + my $down = $size - 1; + $r = unpack 'H*', pack 'B*', '0' x ( $size % 8 ? 8 - $size % 8 : 0 ) . + '1' . unpack "b$down", $r; + Math::BigInt->new('0x' . $r); + } +} +# /HACK + ## pgp2 and pgp5 do not trim trailing whitespace from "canonical text" ## signatures, only from cleartext signatures. ## See: diff --git a/lib/Crypt/OpenPGP/Util.pm b/lib/Crypt/OpenPGP/Util.pm index 6d82b53..4b5639d 100644 --- a/lib/Crypt/OpenPGP/Util.pm +++ b/lib/Crypt/OpenPGP/Util.pm @@ -102,6 +102,29 @@ sub _ensure_bigint { sub get_random_bytes { my $length = shift; if (eval 'require Crypt::Random; 1;') { + # HACK FOR PERFORMANCE + # In Crypt::Random::Seed::new dev_random is tried before dev_urandom, + # so let's override that method to check urandom first and then fall + # back on dev_random. + # Lame but it works... + { + no warnings 'redefine'; + + use Crypt::Random::Seed; + + sub Crypt::Random::Seed::_try_dev_random { + warn "Using hacked version of Crypt::Random::Seed::_try_dev_random\n"; + if (-r "/dev/urandom") { + return ('/dev/urandom', sub { Crypt::Random::Seed::__read_file('/dev/urandom', @_); }, 0, 0); + } + elsif (-r "/dev/random") { + my $blocking = ($^O eq 'freebsd') ? 0 : 1; + return ('/dev/random', sub { Crypt::Random::Seed::__read_file('/dev/random', @_); }, $blocking, 1); + } + return; + } + } + # /HACK return Crypt::Random::makerandom_octet( Length => $length); } elsif (eval 'require Bytes::Random::Secure; 1;') {