File Coverage

blib/lib/Crypt/OpenPGP/Digest.pm
Criterion Covered Total %
statement 94 102 92.1
branch 5 12 41.6
condition 2 3 66.6
subroutine 30 32 93.7
pod 4 6 66.6
total 135 155 87.1


line stmt bran cond sub pod time code
1             package Crypt::OpenPGP::Digest;
2 6     6   22389 use strict;
  6         12  
  6         286  
3              
4 6     6   505 use Crypt::OpenPGP::ErrorHandler;
  6         10  
  6         214  
5 6     6   33 use base qw( Crypt::OpenPGP::ErrorHandler );
  6         9  
  6         904  
6              
7 6     6   35 use vars qw( %ALG %ALG_BY_NAME );
  6         10  
  6         3633  
8             %ALG = (
9             1 => 'MD5',
10             2 => 'SHA1',
11             3 => 'RIPEMD160',
12             8 => 'SHA256',
13             9 => 'SHA384',
14             10 => 'SHA512',
15             11 => 'SHA224',
16             );
17             %ALG_BY_NAME = map { $ALG{$_} => $_ } keys %ALG;
18              
19             sub new {
20 141     141 1 6084 my $class = shift;
21 141         284 my $alg = shift;
22 141   66     760 $alg = $ALG{$alg} || $alg;
23 141 50       693 return $class->error("Unsupported digest algorithm '$alg'")
24             unless $alg =~ /^\D/;
25 141         415 my $pkg = join '::', $class, $alg;
26             my $dig = bless { __alg => $alg,
27 141         1025 __alg_id => $ALG_BY_NAME{$alg} }, $pkg;
28 141         549 $dig->init(@_);
29             }
30              
31 0     0 0 0 sub init { $_[0] }
32 153     153 1 23338 sub hash { $_[0]->{md}->($_[1]) }
33              
34             sub alg {
35 17 100   17 1 2813 return $_[0]->{__alg} if ref($_[0]);
36 10 50       84 $ALG{$_[1]} || $_[1];
37             }
38              
39             sub alg_id {
40 7 50   7 1 31 return $_[0]->{__alg_id} if ref($_[0]);
41 0 0       0 $ALG_BY_NAME{$_[1]} || $_[1];
42             }
43              
44             sub supported {
45 0     0 0 0 my $class = shift;
46 0         0 my %s;
47 0         0 for my $did (keys %ALG) {
48 0         0 my $digest = $class->new($did);
49 0 0       0 $s{$did} = $digest->alg if $digest;
50             }
51 0         0 \%s;
52             }
53              
54             package Crypt::OpenPGP::Digest::MD5;
55 6     6   39 use strict;
  6         13  
  6         201  
56 6     6   32 use base qw( Crypt::OpenPGP::Digest );
  6         101  
  6         894  
57              
58             sub init {
59 4     4   8 my $dig = shift;
60 4         36 require Digest::MD5;
61 4         28 $dig->{md} = \&Digest::MD5::md5;
62 4         18 $dig;
63             }
64              
65             package Crypt::OpenPGP::Digest::SHA1;
66 6     6   35 use strict;
  6         11  
  6         221  
67 6     6   31 use base qw( Crypt::OpenPGP::Digest );
  6         7  
  6         879  
68              
69             sub init {
70 127     127   201 my $dig = shift;
71 127         4179 require Digest::SHA;
72 127         14138 $dig->{md} = \&Digest::SHA::sha1;
73 127         726 $dig;
74             }
75              
76             package Crypt::OpenPGP::Digest::RIPEMD160;
77 6     6   34 use strict;
  6         9  
  6         175  
78 6     6   30 use base qw( Crypt::OpenPGP::Digest );
  6         9  
  6         1086  
79              
80             sub init {
81 2     2   4 my $dig = shift;
82 2         655 require Crypt::RIPEMD160;
83 2     1   3473 $dig->{md} = sub { Crypt::RIPEMD160->hash($_[0]) };
  1         7  
84 2         6 $dig;
85             }
86              
87             package Crypt::OpenPGP::Digest::SHA224;
88 6     6   37 use strict;
  6         12  
  6         242  
89 6     6   31 use base qw( Crypt::OpenPGP::Digest );
  6         8  
  6         887  
90              
91             sub init {
92 2     2   1069 my $dig = shift;
93 2         12 require Digest::SHA;
94 2         14 $dig->{md} = \&Digest::SHA::sha224;
95 2         6 $dig;
96             }
97              
98             package Crypt::OpenPGP::Digest::SHA256;
99 6     6   40 use strict;
  6         9  
  6         214  
100 6     6   32 use base qw( Crypt::OpenPGP::Digest );
  6         10  
  6         808  
101              
102             sub init {
103 2     2   4 my $dig = shift;
104 2         9 require Digest::SHA;
105 2         11 $dig->{md} = \&Digest::SHA::sha256;
106 2         6 $dig;
107             }
108              
109             package Crypt::OpenPGP::Digest::SHA384;
110 6     6   37 use strict;
  6         9  
  6         203  
111 6     6   30 use base qw( Crypt::OpenPGP::Digest );
  6         11  
  6         821  
112              
113             sub init {
114 2     2   4 my $dig = shift;
115 2         15 require Digest::SHA;
116 2         17 $dig->{md} = \&Digest::SHA::sha384;
117 2         8 $dig;
118             }
119              
120             package Crypt::OpenPGP::Digest::SHA512;
121 6     6   45 use strict;
  6         9  
  6         204  
122 6     6   31 use base qw( Crypt::OpenPGP::Digest );
  6         143  
  6         787  
123              
124             sub init {
125 2     2   4 my $dig = shift;
126 2         710 require Digest::SHA;
127 2         3987 $dig->{md} = \&Digest::SHA::sha512;
128 2         7 $dig;
129             }
130              
131              
132             1;
133             __END__
134              
135             =head1 NAME
136              
137             Crypt::OpenPGP::Digest - PGP message digest factory
138              
139             =head1 SYNOPSIS
140              
141             use Crypt::OpenPGP::Digest;
142              
143             my $alg = 'SHA1';
144             my $dgst = Crypt::OpenPGP::Digest->new( $alg );
145             my $data = 'foo bar';
146             my $hashed_data = $dgst->hash($data);
147              
148             =head1 DESCRIPTION
149              
150             I<Crypt::OpenPGP::Digest> is a factory class for PGP message digest
151             objects. All digest objects are subclasses of this class and share a
152             common interface; when creating a new digest object, the object is
153             blessed into the subclass to take on algorithm-specific functionality.
154              
155             A I<Crypt::OpenPGP::Digest> object wraps around a function reference
156             providing the actual digest implementation (eg. I<Digest::MD::md5> for
157             an MD5 digest). This allows all digest objects to share a common
158             interface and a simple instantiation method.
159              
160             =head1 USAGE
161              
162             =head2 Crypt::OpenPGP::Digest->new($digest)
163              
164             Creates a new message digest object of type I<$digest>; I<$digest> can
165             be either the name of a digest algorithm (in I<Crypt::OpenPGP>
166             parlance) or the numeric ID of the algorithm (as defined in the
167             OpenPGP RFC). Using an algorithm name is recommended, for the simple
168             reason that it is easier to understand quickly (not everyone knows
169             the algorithm IDs).
170              
171             Valid digest names are: C<MD5>, C<SHA1>, and C<RIPEMD160>.
172              
173             Returns the new digest object on success. On failure returns C<undef>;
174             the caller should check for failure and call the class method I<errstr>
175             if a failure occurs. A typical reason this might happen is an
176             unsupported digest name or ID.
177              
178             =head2 $dgst->hash($data)
179              
180             Creates a message digest hash of the data I<$data>, a string of
181             octets, and returns the digest.
182              
183             =head2 $dgst->alg
184              
185             Returns the name of the digest algorithm (as listed above in I<new>).
186              
187             =head2 $dgst->alg_id
188              
189             Returns the numeric ID of the digest algorithm.
190              
191             =head1 AUTHOR & COPYRIGHTS
192              
193             Please see the Crypt::OpenPGP manpage for author, copyright, and
194             license information.
195              
196             =cut