| File | /usr/lib/perl5/vendor_perl/5.10.0/Crypt/RSA/Key.pm |
| Statements Executed | 27 |
| Statement Execution Time | 4.11ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 26.1ms | 61.3ms | Crypt::RSA::Key::BEGIN@15 |
| 1 | 1 | 1 | 5.92ms | 29.9ms | Crypt::RSA::Key::BEGIN@18 |
| 1 | 1 | 1 | 2.95ms | 8.76ms | Crypt::RSA::Key::BEGIN@16 |
| 1 | 1 | 1 | 2.77ms | 4.38ms | Crypt::RSA::Key::BEGIN@19 |
| 1 | 1 | 1 | 53µs | 64µs | Crypt::RSA::Key::BEGIN@12 |
| 1 | 1 | 1 | 31µs | 547µs | Crypt::RSA::Key::BEGIN@17 |
| 1 | 1 | 1 | 30µs | 208µs | Crypt::RSA::Key::BEGIN@13 |
| 1 | 1 | 1 | 29µs | 249µs | Crypt::RSA::Key::BEGIN@14 |
| 0 | 0 | 0 | 0s | 0s | Crypt::RSA::Key::generate |
| 0 | 0 | 0 | 0s | 0s | Crypt::RSA::Key::mod_inverse |
| 0 | 0 | 0 | 0s | 0s | Crypt::RSA::Key::new |
| Line | State ments |
Time on line |
Calls | Time in subs |
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 | 3 | 95µs | 2 | 76µs | # spent 64µs (53+12) within Crypt::RSA::Key::BEGIN@12 which was called
# once (53µs+12µs) by Crypt::RSA::BEGIN@18 at line 12 # spent 64µs making 1 call to Crypt::RSA::Key::BEGIN@12
# spent 12µs making 1 call to strict::import |
| 13 | 3 | 88µs | 2 | 385µs | # spent 208µs (30+177) within Crypt::RSA::Key::BEGIN@13 which was called
# once (30µs+177µs) by Crypt::RSA::BEGIN@18 at line 13 # spent 208µs making 1 call to Crypt::RSA::Key::BEGIN@13
# spent 177µs making 1 call to base::import |
| 14 | 3 | 92µs | 2 | 468µs | # spent 249µs (29+219) within Crypt::RSA::Key::BEGIN@14 which was called
# once (29µs+219µs) by Crypt::RSA::BEGIN@18 at line 14 # spent 249µs making 1 call to Crypt::RSA::Key::BEGIN@14
# spent 219µs making 1 call to base::import |
| 15 | 3 | 946µs | 2 | 61.5ms | # spent 61.3ms (26.1+35.2) within Crypt::RSA::Key::BEGIN@15 which was called
# once (26.1ms+35.2ms) by Crypt::RSA::BEGIN@18 at line 15 # spent 61.3ms making 1 call to Crypt::RSA::Key::BEGIN@15
# spent 192µs making 1 call to Exporter::import |
| 16 | 3 | 407µs | 2 | 9.03ms | # spent 8.76ms (2.95+5.81) within Crypt::RSA::Key::BEGIN@16 which was called
# once (2.95ms+5.81ms) by Crypt::RSA::BEGIN@18 at line 16 # spent 8.76ms making 1 call to Crypt::RSA::Key::BEGIN@16
# spent 280µs making 1 call to Exporter::import |
| 17 | 3 | 95µs | 2 | 1.06ms | # spent 547µs (31+515) within Crypt::RSA::Key::BEGIN@17 which was called
# once (31µs+515µs) by Crypt::RSA::BEGIN@18 at line 17 # spent 547µs making 1 call to Crypt::RSA::Key::BEGIN@17
# spent 515µs making 1 call to Math::Pari::import |
| 18 | 3 | 368µs | 2 | 29.9ms | # spent 29.9ms (5.92+24.0) within Crypt::RSA::Key::BEGIN@18 which was called
# once (5.92ms+24.0ms) by Crypt::RSA::BEGIN@18 at line 18 # spent 29.9ms making 1 call to Crypt::RSA::Key::BEGIN@18
# spent 11µs making 1 call to UNIVERSAL::import |
| 19 | 3 | 1.99ms | 2 | 4.39ms | # spent 4.38ms (2.77+1.61) within Crypt::RSA::Key::BEGIN@19 which was called
# once (2.77ms+1.61ms) by Crypt::RSA::BEGIN@18 at line 19 # spent 4.38ms making 1 call to Crypt::RSA::Key::BEGIN@19
# spent 8µs making 1 call to UNIVERSAL::import |
| 20 | |||||
| 21 | 1 | 3µs | $Crypt::RSA::Key::VERSION = '1.99'; | ||
| 22 | |||||
| 23 | 1 | 14µs | 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 | 16µs | 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 <macbeth@glamis.com>', | ||||
| 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<Size> | ||||
| 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<Password> | ||||
| 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<Identity> | ||||
| 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<Cipher> | ||||
| 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<Verbosity> | ||||
| 181 | |||||
| 182 | When set to 1, generate() will draw a progress display on STDOUT. | ||||
| 183 | |||||
| 184 | =item B<Filename> | ||||
| 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<KF> | ||||
| 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<SKF> | ||||
| 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<PKF> | ||||
| 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<ERROR HANDLING> 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, E<lt>mail@vipul.netE<gt> | ||||
| 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 |