File Coverage

blib/lib/Crypt/OpenPGP/Key.pm
Criterion Covered Total %
statement 156 156 100.0
branch 5 8 62.5
condition 5 9 55.5
subroutine 52 52 100.0
pod 10 12 83.3
total 228 237 96.2


line stmt bran cond sub pod time code
1             package Crypt::OpenPGP::Key;
2 6     6   137 use strict;
  6         11  
  6         196  
3              
4 6     6   36 use Carp qw( confess );
  6         9  
  6         358  
5 6     6   41 use Crypt::OpenPGP::ErrorHandler;
  6         12  
  6         158  
6 6     6   33 use base qw( Crypt::OpenPGP::ErrorHandler );
  6         7  
  6         503  
7              
8 5     5   29 use vars qw( %ALG %ALG_BY_NAME );
  5         8  
  5         3192  
9             %ALG = (
10             1 => 'RSA',
11             16 => 'ElGamal',
12             17 => 'DSA',
13             );
14             %ALG_BY_NAME = map { $ALG{$_} => $_ } keys %ALG;
15              
16             sub new {
17 134     134 0 241 my $class = shift;
18 134         210 my $alg = shift;
19 134   66     580 $alg = $ALG{$alg} || $alg;
20 134         442 my $pkg = join '::', $class, $alg;
21 5     5   1965 eval "use $pkg;";
  5     5   15  
  5     5   117  
  5     5   1327  
  5     5   10  
  5     6   109  
  5     5   1376  
  5     5   10  
  5     5   107  
  5     5   32  
  5     5   7  
  5     5   91  
  5     4   40  
  5     4   9  
  5     4   109  
  6     4   1527  
  6     4   12  
  6     4   133  
  5     4   644  
  5     4   10  
  5     4   94  
  5     4   37  
  5     2   9  
  5     1   114  
  5     1   645  
  5     1   12  
  5     1   121  
  5     1   568  
  5     1   11  
  5     1   112  
  5     1   875  
  5     1   12  
  5         119  
  5         36  
  5         10  
  5         108  
  4         24  
  4         8  
  4         78  
  4         26  
  4         7  
  4         78  
  4         29  
  4         10  
  4         89  
  4         31  
  4         9  
  4         103  
  4         27  
  4         9  
  4         83  
  4         23  
  4         5  
  4         69  
  4         22  
  4         6  
  4         66  
  4         24  
  4         8  
  4         77  
  4         26  
  4         8  
  4         79  
  4         23  
  4         7  
  4         79  
  134         11669  
  2         621  
  2         16  
  2         39  
  1         2  
  1         25  
  1         8  
  1         2  
  1         32  
  1         10  
  1         2  
  1         26  
  1         9  
  1         3  
  1         55  
  1         9  
  1         2  
  1         159  
  1         8  
  1         3  
  1         23  
  1         7  
  1         1  
  1         21  
  1         6  
  1         2  
  1         21  
  1         7  
  1         2  
  1         21  
  1         6  
  1         3  
  1         19  
  1         6  
  1         4  
  1         19  
22 134 50       584 return $class->error("Unsupported algorithm '$alg': $@") if $@;
23 134         1011 my @valid = $pkg->all_props;
24 134         388 my %valid = map { $_ => 1 } @valid;
  493         1243  
25             my $key = bless { __valid => \%valid, __alg => $alg,
26 134         1022 __alg_id => $ALG_BY_NAME{$alg} }, $pkg;
27 134         684 $key->init(@_);
28             }
29              
30             sub keygen {
31 4     4 1 856 my $class = shift;
32 4         16 my $alg = shift;
33 4   33     28 $alg = $ALG{$alg} || $alg;
34 4         40 my $pkg = join '::', __PACKAGE__, 'Public', $alg;
35 4         354 eval "use $pkg;";
36 4 50       19 return $class->error("Unsupported algorithm '$alg': $@") if $@;
37 4         50 my($pub_data, $sec_data) = $pkg->keygen(@_);
38 4 100 66     49 return $class->error("Key generation failed: " . $class->errstr)
39             unless $pub_data && $sec_data;
40 3         7 my $pub_pkg = join '::', __PACKAGE__, 'Public';
41 3         62 my $pub = $pub_pkg->new($alg, $pub_data);
42 3         13 my $sec_pkg = join '::', __PACKAGE__, 'Secret';
43 3         17 my $sec = $sec_pkg->new($alg, $sec_data);
44 3         34 ($pub, $sec);
45             }
46              
47 1     1 0 8 sub init { $_[0] }
48              
49 1     1 1 9 sub check { 1 }
50              
51 6     6 1 62 sub alg { $_[0]->{__alg} }
52 28     28 1 371 sub alg_id { $_[0]->{__alg_id} }
53              
54 1     1 1 2 sub size { 0 }
55 18     18 1 95 sub bytesize { int(($_[0]->size + 7) / 8) }
56              
57       1 1   sub public_key { }
58 1     1 1 5 sub is_secret { 0 }
59              
60 25     25 1 119 sub can_encrypt { 0 }
61 1     1 1 12 sub can_sign { 0 }
62              
63       1     sub DESTROY { }
64              
65 5     5   56 use vars qw( $AUTOLOAD );
  5         10  
  5         687  
66             sub AUTOLOAD {
67 238     238   12513 my $key = shift;
68 238         1529 (my $meth = $AUTOLOAD) =~ s/.*:://;
69             confess "Can't call method $meth on Key $key"
70 238 50       1114 unless $key->{__valid}{$meth};
71 238         1374 $key->{key_data}->$meth(@_);
72             }
73              
74             1;
75             __END__
76              
77             =head1 NAME
78              
79             Crypt::OpenPGP::Key - OpenPGP key factory
80              
81             =head1 SYNOPSIS
82              
83             use Crypt::OpenPGP::Key;
84             my($pub, $sec) = Crypt::OpenPGP::Key->keygen('DSA', Size => 1024);
85              
86             use Crypt::OpenPGP::Key::Public;
87             my $pubkey = Crypt::OpenPGP::Key::Public->new('DSA');
88              
89             use Crypt::OpenPGP::Key::Secret;
90             my $seckey = Crypt::OpenPGP::Key::Secret->new('RSA');
91              
92             =head1 DESCRIPTION
93              
94             I<Crypt::OpenPGP::Key> provides base class functionality for all
95             I<Crypt::OpenPGP> public and secret keys. It functions as a factory
96             class for key generation and key instantiation.
97              
98             The only time you will ever use I<Crypt::OpenPGP::Key> directly is
99             to generate a key-pair; in all other scenarios--for example, when
100             instantiating a new key object--you should use either
101             I<Crypt::OpenPGP::Key::Public> or I<Crypt::OpenPGP::Key::Secret>,
102             depending on whether the key is public or secret, respectively.
103              
104             =head1 KEY GENERATION
105              
106             =head2 Crypt::OpenPGP::Key->keygen( $type, %arg )
107              
108             Generates a new key-pair of public key algorithm I<$type>. Returns
109             a public and a secret key, each blessed into the appropriate
110             implementation class. Returns an empty list on failure, in which case
111             you should call the class method I<errstr> to determine the error.
112              
113             Valid values for type are C<DSA>, C<RSA>, and C<ElGamal>.
114              
115             I<%arg> can contain:
116              
117             =over 4
118              
119             =item * Size
120              
121             Bitsize of the key to be generated. This should be an even integer;
122             there is no low end currently set, but for the sake of security
123             I<Size> should be at least 1024 bits.
124              
125             This is a required argument.
126              
127             =item * Verbosity
128              
129             Set to a true value to enable a status display during key generation;
130             since key generation is a relatively length process, it is helpful
131             to have an indication that some action is occurring.
132              
133             I<Verbosity> is 0 by default.
134              
135             =back
136              
137             =head1 METHODS
138              
139             I<Crypt::OpenPGP::Key> is not meant to be used directly (unless you
140             are generating keys; see I<KEY GENERATION>, above); instead you should
141             use the subclasses of this module. There are, however, useful interface
142             methods that are shared by all subclasses.
143              
144             =head2 Key Data Access
145              
146             Each public-key algorithm has different key data associated with it.
147             For example, a public DSA key has 4 attributes: I<p>, I<q>, I<g>, and
148             I<y>. A secret DSA key has the same attributes as a public key, and
149             in addition it has an attribute I<x>.
150              
151             All of the key data attributes can be accessed by calling methods of
152             the same name on the I<Key> object. For example:
153              
154             my $q = $dsa_key->q;
155              
156             The attributes for each public-key algorithm are:
157              
158             =over 4
159              
160             =item * RSA
161              
162             Public key: I<n>, I<e>
163              
164             Secret key: I<n>, I<e>, I<d>, I<p>, I<q>, I<u>
165              
166             =item * DSA
167              
168             Public key: I<p>, I<q>, I<g>, I<y>
169              
170             Secret key: I<p>, I<q>, I<g>, I<y>, I<x>
171              
172             =item * ElGamal
173              
174             Public key: I<p>, I<g>, I<y>
175              
176             Secret key: I<p>, I<g>, I<y>, I<x>
177              
178             =back
179              
180             =head2 $key->check
181              
182             Check the key data to determine if it is valid. For example, an RSA
183             secret key would multiply the values of I<p> and I<q> and verify that
184             the product is equal to the value of I<n>. Returns true if the key
185             is valid, false otherwise.
186              
187             Not all public key algorithm implementations implement a I<check>
188             method; for those that don't, I<check> will always return true.
189              
190             =head2 $key->size
191              
192             Returns the "size" of the key. The definition of "size" depends on
193             the public key algorithm; for example, DSA defines the size of a key
194             as the bitsize of the value of I<p>.
195              
196             =head2 $key->bytesize
197              
198             Whereas I<size> will return a bitsize of the key, I<bytesize> returns
199             the size in bytes. This value is defined as C<int((bitsize(key)+7)/8)>.
200              
201             =head2 $key->is_secret
202              
203             Returns true if the key I<$key> is a secret key, false otherwise.
204              
205             =head2 $key->public_key
206              
207             Returns the public part of the key I<$key>. If I<$key> is already a
208             public key, I<$key> is returned; otherwise a new public key object
209             (I<Crypt::OpenPGP::Key::Public>) is constructed, and the public values
210             from the secret key are copied into the public key. The new public
211             key is returned.
212              
213             =head2 $key->can_encrypt
214              
215             Returns true if the key algorithm has encryption/decryption
216             capabilities, false otherwise.
217              
218             =head2 $key->can_sign
219              
220             Returns true if the key algorithm has signing/verification
221             capabilities, false otherwise.
222              
223             =head2 $key->alg
224              
225             Returns the name of the public key algorithm.
226              
227             =head2 $key->alg_id
228              
229             Returns the number ID of the public key algorithm.
230              
231             =head1 AUTHOR & COPYRIGHTS
232              
233             Please see the Crypt::OpenPGP manpage for author, copyright, and
234             license information.
235              
236             =cut