File Coverage

blib/lib/Crypt/Random/Provider/egd.pm
Criterion Covered Total %
statement 22 54 40.7
branch 2 24 8.3
condition 0 18 0.0
subroutine 7 9 77.7
pod 0 3 0.0
total 31 108 28.7


line stmt bran cond sub pod time code
1             ##
2             ## Copyright (c) 1998-2025, Vipul Ved Prakash. All rights reserved.
3             ## This code is free software; you can redistribute it and/or modify
4             ## it under the same terms as Perl itself.
5              
6 3     3   16 use strict;
  3         4  
  3         101  
7 3     3   10 use warnings;
  3         3  
  3         185  
8             package Crypt::Random::Provider::egd;
9              
10 3     3   1547 use IO::Socket;
  3         65544  
  3         13  
11 3     3   1512 use Carp;
  3         5  
  3         205  
12 3     3   16 use Math::Pari qw(pari2num);
  3         6  
  3         26  
13              
14             our $VERSION = '1.57';
15              
16             sub _defaultsource {
17              
18 5     5   9 my $source;
19 5         15 for my $d (qw( /var/run/egd-pool /dev/egd-pool /etc/entropy )) {
20 15 50       2889 if (IO::Socket::UNIX->new(Peer => $d)) { $source = $d; last }
  0         0  
  0         0  
21             }
22 5         1034 return $source;
23              
24             }
25              
26              
27             sub new {
28              
29 0     0 0 0 my ($class, %args) = @_;
30 0   0     0 my $self = { Source => $args{Source} || $args{Device} || $args{Filename} };
31 0 0       0 $$self{Source} = $class->_defaultsource() unless $$self{Source};
32 0 0       0 croak "egd entropy pool file not found.\n" unless $$self{Source};
33 0         0 return bless $self, $class;
34              
35             }
36              
37              
38             sub get_data {
39            
40 0     0 0 0 my ( $self, %params ) = @_;
41 0   0     0 my $class = ref $self || $self;
42 0 0       0 $self = {} unless ref $self;
43            
44             my $bytes = $params{Length} ||
45 0   0     0 (int( pari2num($params{ Size }) / 8) + 1);
46 0   0     0 my $dev = $params{Source} || $$self{Source};
47 0         0 my $skip = $params{Skip};
48              
49 0 0 0     0 croak "$dev doesn't exist. aborting." unless $dev && -e $dev;
50              
51 0         0 my $s = IO::Socket::UNIX->new(Peer => $dev);
52 0 0       0 croak "couldn't talk to egd. $!" unless $s;
53              
54 0         0 my($r, $read) = ('', 0);
55 0         0 while ($read < $bytes) {
56 0         0 my $msg = pack "CC", 0x01, 1;
57 0         0 $s->syswrite($msg, length $msg);
58 0         0 my $rt;
59 0         0 my $nread = $s->sysread($rt, 1);
60 0 0       0 croak "read from entropy socket failed" unless $nread == 1;
61 0         0 my $count = unpack("C", $rt);
62 0         0 $nread = $s->sysread($rt, $count);
63 0 0       0 croak "couldn't get all the requested entropy. aborting."
64             unless $nread == $count;
65 0 0 0     0 unless ($skip && $skip =~ /\Q$rt\E/) {
66 0 0       0 if ($params{Verbosity}) { print '.' unless $read % 2 }
  0 0       0  
67 0         0 $r .= $rt;
68 0         0 $read++;
69             }
70             }
71              
72 0         0 $r;
73             }
74              
75              
76             sub available {
77            
78 5     5 0 12 my $class = shift;
79 5 50       20 return 1 if $class->_defaultsource();
80 5         58 return;
81              
82             }
83              
84              
85             1;
86              
87