File Coverage

lib/Crypt/RSA/Key.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -sw
2             ##
3             ## Crypt::RSA::Keys
4             ##
5             ## Copyright (c) 2001, Vipul Ved Prakash. All rights reserved.
6             ## This code is free software; you can redistribute it and/or modify
7             ## it under the same terms as Perl itself.
8             ##
9             ## $Id: Key.pm,v 1.13 2001/05/25 00:20:40 vipul Exp $
10              
11             package Crypt::RSA::Key;
12 5     5   26162 use strict;
  5         11  
  5         182  
13 5     5   25 use base 'Class::Loader';
  5         11  
  5         21839  
14             use base 'Crypt::RSA::Errorhandler';
15             use Crypt::Primes qw(rsaparams);
16             use Crypt::RSA::DataFormat qw(bitsize);
17             use Math::Pari qw(PARI Mod lift);
18             use Crypt::RSA::Key::Private;
19             use Crypt::RSA::Key::Public;
20              
21             $Crypt::RSA::Key::VERSION = '1.99';
22              
23             my %MODMAP = (
24             Native_PKF => { Module => "Crypt::RSA::Key::Public" },
25             Native_SKF => { Module => "Crypt::RSA::Key::Private" },
26             SSH_PKF => { Module => "Crypt::RSA::Key::Public::SSH" },
27             SSH_SKF => { Module => "Crypt::RSA::Key::Private::SSH" },
28             );
29              
30              
31             sub new {
32             my $class = shift;
33             my $self = {};
34             bless $self, $class;
35             $self->_storemap ( %MODMAP );
36             return $self;
37             }
38              
39              
40             sub generate {
41              
42             my ($self, %params) = @_;
43              
44             my $key;
45             unless ($params{q} && $params{p} && $params{e}) {
46              
47             return $self->error ("Missing argument.") unless $params{Size};
48              
49             return $self->error ("Keysize too small.") if
50             $params{Size} < 48;
51              
52             return $self->error ("Odd keysize.") if
53             $params{Size} % 2;
54              
55             my $size = int($params{Size}/2);
56             my $verbosity = $params{Verbosity} || 0;
57              
58             my $cbitsize = 0;
59             while (!($cbitsize)) {
60             $key = rsaparams ( Size => $size, Verbosity => $verbosity );
61             my $n = $$key{p} * $$key{q};
62             $cbitsize = 1 if bitsize($n) == $params{Size}
63             }
64              
65             }
66              
67             if ($params{KF}) {
68             $params{PKF} = { Name => "$params{KF}_PKF" };
69             $params{SKF} = { Name => "$params{KF}_SKF" }
70             }
71              
72             my $pubload = $params{PKF} ? $params{PKF} : { Name => "Native_PKF" };
73             my $priload = $params{SKF} ? $params{SKF} : { Name => "Native_SKF" };
74              
75             my $pubkey = $self->_load (%$pubload) ||
76             return $self->error ("Couldn't load the public key module.");
77             my $prikey = $self->_load ((%$priload), Args => ['Cipher' => $params{Cipher}, 'Password', $params{Password} ]) ||
78             return $self->error ("Couldn't load the private key module.");
79             $pubkey->Identity ($params{Identity});
80             $prikey->Identity ($params{Identity});
81              
82             $pubkey->e ($$key{e} || $params{e});
83             $prikey->e ($$key{e} || $params{e});
84             $prikey->p ($$key{p} || $params{p});
85             $prikey->q ($$key{q} || $params{q});
86              
87             $prikey->phi (($prikey->p - 1) * ($prikey->q - 1));
88             my $m = Mod (1, $prikey->phi);
89              
90             $prikey->d (lift($m/$pubkey->e));
91             $prikey->n ($prikey->p * $prikey->q);
92             $pubkey->n ($prikey->n);
93              
94             $prikey->dp ($prikey->d % ($prikey->p - 1));
95             $prikey->dq ($prikey->d % ($prikey->q - 1));
96             $prikey->u (mod_inverse($prikey->p, $prikey->q));
97              
98             return $self->error ("d is too small. Regenerate.") if
99             bitsize($prikey->d) < 0.25 * bitsize($prikey->n);
100              
101             $$key{p} = 0; $$key{q} = 0; $$key{e} = 0; $m = 0;
102              
103             if ($params{Filename}) {
104             $pubkey->write (Filename => "$params{Filename}.public");
105             $prikey->write (Filename => "$params{Filename}.private");
106             }
107              
108             return ($pubkey, $prikey);
109              
110             }
111              
112              
113             sub mod_inverse {
114             my($a, $n) = @_;
115             my $m = Mod(1, $n);
116             lift($m / $a);
117             }
118              
119              
120             1;
121              
122             =head1 NAME
123              
124             Crypt::RSA::Key - RSA Key Pair Generator.
125              
126             =head1 SYNOPSIS
127              
128             my $keychain = new Crypt::RSA::Key;
129             my ($public, $private) = $keychain->generate (
130             Identity => 'Lord Macbeth ',
131             Size => 2048,
132             Password => 'A day so foul & fair',
133             Verbosity => 1,
134             ) or die $keychain->errstr();
135              
136             =head1 DESCRIPTION
137              
138             This module provides a method to generate an RSA key pair.
139              
140             =head1 METHODS
141              
142             =head2 new()
143              
144             Constructor.
145              
146             =head2 generate()
147              
148             generate() generates an RSA key of specified bitsize. It returns a list of
149             two elements, a Crypt::RSA::Key::Public object that holds the public part
150             of the key pair and a Crypt::RSA::Key::Private object that holds that
151             private part. On failure, it returns undef and sets $self->errstr to
152             appropriate error string. generate() takes a hash argument with the
153             following keys:
154              
155             =over 4
156              
157             =item B
158              
159             Bitsize of the key to be generated. This should be an even integer > 48.
160             Bitsize is a mandatory argument.
161              
162             =item B
163              
164             String with which the private key will be encrypted. If Password is not
165             provided the key will be stored unencrypted.
166              
167             =item B
168              
169             A string that identifies the owner of the key. This string usually takes
170             the form of a name and an email address. The identity is not bound to the
171             key with a signature. However, a future release or another module will
172             provide this facility.
173              
174             =item B
175              
176             The block cipher which is used for encrypting the private key. Defaults to
177             `Blowfish'. Cipher could be set to any value that works with Crypt::CBC(3)
178             and Tie::EncryptedHash(3).
179              
180             =item B
181              
182             When set to 1, generate() will draw a progress display on STDOUT.
183              
184             =item B
185              
186             The generated key pair will be written to disk, in $Filename.public and
187             $Filename.private files, if this argument is provided. Disk writes can be
188             deferred by skipping this argument and achieved later with the write()
189             method of Crypt::RSA::Key::Public(3) and Crypt::RSA::Key::Private(3).
190              
191             =item B
192              
193             A string that specifies the key format. As of this writing, two key
194             formats, `Native' and `SSH', are supported. KF defaults to `Native'.
195              
196             =item B
197              
198             Secret (Private) Key Format. Instead of specifying KF, the user could
199             choose to specify secret and public key formats separately. The value for
200             SKF can be a string ("Native" or "SSH") or a hash reference that specifies
201             a module name, its constructor and constructor arguments. The specified
202             module is loaded with Class::Loader(3) and must be interface compatible
203             with Crypt::RSA::Key::Private(3).
204              
205             =item B
206              
207             Public Key Format. This option is like SKF but for the public key.
208              
209             =back
210              
211             =head1 ERROR HANDLING
212              
213             See B in Crypt::RSA(3) manpage.
214              
215             =head1 BUGS
216              
217             There's an inefficiency in the way generate() ensures the key pair is
218             exactly Size bits long. This will be fixed in a future release.
219              
220             =head1 AUTHOR
221              
222             Vipul Ved Prakash, Email@vipul.netE
223              
224             =head1 SEE ALSO
225              
226             Crypt::RSA(3), Crypt::RSA::Key::Public(3), Crypt::RSA::Key::Private(3),
227             Crypt::Primes(3), Tie::EncryptedHash(3), Class::Loader(3)
228              
229             =cut
230              
231