home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Private.pm < prev    next >
Encoding:
Perl POD Document  |  2003-01-08  |  8.1 KB  |  322 lines

  1. #!/usr/bin/perl -sw
  2. ##
  3. ## Crypt::RSA::Key::Private 
  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: Private.pm,v 1.15 2001/09/25 14:11:22 vipul Exp $
  10.  
  11. package Crypt::RSA::Key::Private;
  12. use lib qw(lib);
  13. use strict; 
  14. use vars qw($AUTOLOAD $VERSION);
  15. use Crypt::RSA::Errorhandler;
  16. use Crypt::RSA;
  17. use Tie::EncryptedHash; 
  18. use Data::Dumper;
  19. use Math::Pari qw(PARI pari2pv Mod isprime lcm lift);
  20. use Carp;
  21. use vars qw(@ISA);
  22.  
  23. ($VERSION) = '$Revision: 1.15 $' =~ /\s(\d+\.\d+)\s/; 
  24. @ISA       = qw(Crypt::RSA::Errorhandler);
  25.  
  26.  
  27. sub new { 
  28.  
  29.     my ($class, %params) = @_; 
  30.     my $self    = { Version => $Crypt::RSA::Key::VERSION };
  31.     if ($params{Filename}) { 
  32.         bless $self, $class;
  33.         $self = $self->read (%params);
  34.         return bless $self, $class; 
  35.     } else { 
  36.         bless $self, $class;
  37.         $self->Identity ($params{Identity}) if $params{Identity};
  38.         $self->Cipher   ($params{Cipher}||"Blowfish");
  39.         $self->Password ($params{Password}) if $params{Password};
  40.         return $self;
  41.     } 
  42.  
  43.  
  44.  
  45. sub AUTOLOAD { 
  46.  
  47.     my ($self, $value) = @_;
  48.     my $key = $AUTOLOAD; $key =~ s/.*:://;
  49.     if ($key =~ /^(e|n|d|p|q|dp|dq|u|phi)$/) { 
  50.         if (ref $value eq 'Math::Pari') { 
  51.             $self->{private}{"_$key"} = $value;
  52.             $self->{Checked} = 0;
  53.         } elsif ($value && !(ref $value)) { 
  54.             if ($value =~ /^0x/) { 
  55.                 $self->{private}->{"_$key"} = 
  56.                 $self->{Checked} = 0;
  57.                     Math::Pari::_hex_cvt($value);
  58.             } else { $self->{private}{"_$key"} = PARI($value) } 
  59.         }
  60.         return $self->{private}{"_$key"} || 
  61.                $self->{private_encrypted}{"_$key"} || 
  62.                "";
  63.     } elsif ($key =~ /^Identity|Cipher|Password$/) { 
  64.         $self->{$key} = $value if $value; 
  65.         return $self->{$key};
  66.     } elsif ($key =~ /^Checked$/) { 
  67.         my ($package) = caller();
  68.         $self->{Checked} = $value if ($value && $package eq "Crypt::RSA::Key::Private") ;
  69.         return $self->{Checked};
  70.     }
  71.  
  72.  
  73. sub hide { 
  74.  
  75.     my ($self) = @_; 
  76.  
  77.     return undef unless $$self{Password};
  78.  
  79.     $self->{private_encrypted} = new Tie::EncryptedHash 
  80.             __password => $self->{Password},
  81.             __cipher   => $self->{Cipher};
  82.  
  83.     for (keys %{$$self{private}}) { 
  84.         $$self{private_encrypted}{$_} = pari2pv($$self{private}{$_});
  85.     }
  86.  
  87.     my $private = $self->{private_encrypted};
  88.     delete $private->{__password};
  89.     delete $$self{private};
  90.     delete $$self{Password};
  91.  
  92.  
  93.  
  94. sub reveal { 
  95.  
  96.     my ($self, %params) = @_; 
  97.     $$self{Password} = $params{Password} if $params{Password};
  98.     return undef unless $$self{Password};
  99.     $$self{private_encrypted}{__password} = $params{Password};
  100.     for (keys %{$$self{private_encrypted}}) { 
  101.         $$self{private}{$_} = PARI($$self{private_encrypted}{$_});
  102.     }
  103.  
  104. }
  105.  
  106.  
  107. sub check { 
  108.  
  109.     my ($self) = @_;
  110.  
  111.     return 1 if $self->{Checked};
  112.  
  113.     return $self->error ("Incomplete key.") unless 
  114.         ($self->n && $self->d) || ($self->n && $self->p && $self->q);
  115.  
  116.     if ($self->p && $self->q) { 
  117.         return $self->error ("n is not a number.") if $self->n =~ /\D/;
  118.         return $self->error ("p is not a number.") if $self->p =~ /\D/;
  119.         return $self->error ("p is not a number.") if $self->p =~ /\D/;
  120.         return $self->error ("n is not p*q."  ) unless $self->n == $self->p * $self->q;
  121.         return $self->error ("p is not prime.") unless isprime($self->p);
  122.         return $self->error ("q is not prime.") unless isprime($self->q);
  123.     }
  124.  
  125.     if ($self->e) { 
  126.         # d * e == 1 mod lcm(p-1, q-1)
  127.         return $self->error ("e is not a number.") if $self->e =~ /\D/;
  128.         my $k = lcm (($self->p -1), ($self->q -1));
  129.         my $K = Mod (1, $k); my $KI = lift($K * $self->d * $self->e);
  130.         return $self->error ("Bad `d'.") unless $KI == 1;
  131.     }
  132.  
  133.     if ($self->dp) {
  134.         # dp == d mod (p-1)
  135.         return $self->error ("Bad `dp'.") unless $self->dp == $self->d % ($self->p - 1);
  136.     }
  137.  
  138.     if ($self->dq) {
  139.         # dq == d mod (q-1)
  140.         return $self->error ("Bad `dq'.") unless $self->dq == $self->d % ($self->q - 1);
  141.     }
  142.  
  143.     if ($self->u && $self->q && $self->p) { 
  144.         my $m =  Mod (1,$self->q); $m = lift ($m / $self->p);
  145.         return $self->error ("Bad `u'.") unless $self->u == $m;
  146.     }
  147.  
  148.     $self->Checked(1);
  149.     return 1;
  150.  
  151. }
  152.  
  153.  
  154. sub DESTROY { 
  155.  
  156.     my $self = shift; 
  157.     delete $$self{private_encrypted}{__password}; 
  158.     delete $$self{private_encrypted};
  159.     delete $$self{private};
  160.     delete $$self{Password};
  161.     undef $self;
  162.  
  163. }
  164.  
  165.  
  166. sub write { 
  167.  
  168.     my ($self, %params) = @_; 
  169.     $self->hide();
  170.     my $string = $self->serialize (%params); 
  171.     open DISK, ">$params{Filename}" || 
  172.         croak "Can't open $params{Filename} for writing.";
  173.     print DISK $string;
  174.     close DISK;
  175.  
  176.  
  177.  
  178. sub read { 
  179.     my ($self, %params) = @_;
  180.     open DISK, $params{Filename} or 
  181.         croak "Can't open $params{Filename} to read.";
  182.     my @key = <DISK>; 
  183.     close DISK;
  184.     $self = $self->deserialize (String => \@key);
  185.     $self->reveal(%params);
  186.     return $self;
  187. }
  188.  
  189.  
  190. sub serialize { 
  191.  
  192.     my ($self, %params) = @_;
  193.     if ($$self{private}) {   # this is an unencrypted key
  194.         for (keys %{$$self{private}}) { 
  195.             $$self{private}{$_} = pari2pv($$self{private}{$_});
  196.         }
  197.     }
  198.     return Dumper $self; 
  199.  
  200.  
  201.  
  202. sub deserialize { 
  203.  
  204.     my ($self, %params) = @_; 
  205.     my $string = join'', @{$params{String}}; 
  206.     $string =~ s/\$VAR1 =//;
  207.     $self = eval $string;
  208.     if ($$self{private}) { # the key is unencrypted 
  209.         for (keys %{$$self{private}}) { 
  210.             $$self{private}{$_} = PARI($$self{private}{$_});
  211.         }
  212.         return $self;
  213.     }
  214.     my $private = new Tie::EncryptedHash; 
  215.     %$private = %{$$self{private_encrypted}};
  216.     $self->{private_encrypted} = $private;
  217.     return $self;
  218.  
  219. }
  220.  
  221.  
  222. 1;
  223.  
  224. =head1 NAME
  225.  
  226. Crypt::RSA::Key::Private -- RSA Private Key Management.
  227.  
  228. =head1 SYNOPSIS
  229.  
  230.     $key = new Crypt::RSA::Key::Private (
  231.                 Identity => 'Lord Banquo <banquo@lochaber.com>',
  232.                 Password => 'The earth hath bubbles',
  233.            );
  234.  
  235.     $key->hide();
  236.  
  237.     $key->write( Filename => 'rsakeys/banquo.private'  );
  238.  
  239.     $akey = new Crypt::RSA::Key::Private (
  240.                  Filename => 'rsakeys/banquo.private'
  241.                 );   
  242.  
  243.     $akey->reveal ( Password => 'The earth hath bubbles' );
  244.  
  245. =head1 DESCRIPTION
  246.  
  247. Crypt::RSA::Key::Private provides basic private key management
  248. functionality for Crypt::RSA private keys. Following methods are
  249. available:
  250.  
  251. =over 4 
  252.  
  253. =item B<new()>
  254.  
  255. The constructor. Takes a hash, usually with two arguments: C<Filename> and
  256. C<Password>. C<Filename> indicates a file from which the private key
  257. should be read. More often than not, private keys are kept encrypted with
  258. a symmetric cipher and MUST be decrypted before use. When a C<Password>
  259. argument is provided, the key is also decrypted before it is returned by
  260. C<new()>. Here's a complete list of arguments accepted by C<new()> (all of
  261. which are optional):
  262.  
  263. =over 4
  264.  
  265. =item Identity 
  266.  
  267. A string identifying the owner of the key. Canonically, a name and
  268. email address.
  269.  
  270. =item Filename 
  271.  
  272. Name of the file that contains the private key. 
  273.  
  274. =item Password
  275.  
  276. Password with which the private key is encrypted, or should be encrypted
  277. (in case of a new key).
  278.  
  279. =item Cipher 
  280.  
  281. Name of the symmetric cipher in which the private key is encrypted (or
  282. should be encrypted). The default is "Blowfish" and possible values
  283. include DES, IDEA, Twofish and other ciphers supported by Crypt::CBC.
  284.  
  285. =back
  286.  
  287. =item B<reveal()>
  288.  
  289. If the key is not decrypted at C<new()>, it can be decrypted by calling
  290. C<reveal()> with a C<Password> argument.
  291.  
  292. =item B<hide()>
  293.  
  294. C<hide()> causes the key to be encrypted by the chosen symmetric cipher
  295. and password.
  296.  
  297. =item B<write()>
  298.  
  299. Causes the key to be written to a disk file specified by the
  300. C<Filename> argument. C<write()> will call C<hide()> before writing the
  301. key to disk. If you wish to store the key in plain, don't specify a
  302. password at C<new()>.
  303.  
  304. =back
  305.  
  306. =head1 AUTHOR
  307.  
  308. Vipul Ved Prakash, E<lt>mail@vipul.netE<gt>
  309.  
  310. =head1 SEE ALSO
  311.  
  312. Crypt::RSA::Key(3), Crypt::RSA::Public(3)
  313.  
  314. =cut
  315.  
  316.  
  317.