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 / RSA.pm < prev    next >
Encoding:
Perl POD Document  |  2001-04-24  |  2.2 KB  |  82 lines

  1. # $Id: RSA.pm,v 1.3 2001/04/17 00:55:19 btrott Exp $
  2.  
  3. package Net::SSH::Perl::Util::RSA;
  4. use strict;
  5.  
  6. use Net::SSH::Perl::Constants qw( SSH_CMSG_AUTH_RSA_RESPONSE );
  7. use Net::SSH::Perl::Util qw( :ssh1mp );
  8.  
  9. use Carp qw( croak );
  10. use Digest::MD5 qw( md5 );
  11. use Math::GMP;
  12.  
  13. sub _respond_to_rsa_challenge {
  14.     my($ssh, $challenge, $key) = @_;
  15.  
  16.     $challenge = _rsa_private_decrypt($challenge, $key);
  17.     my $buf = _mp_linearize($challenge, 32);
  18.     my $response = md5($buf, $ssh->session_id);
  19.  
  20.     $ssh->debug("Sending response to host key RSA challenge.");
  21.  
  22.     my $packet = $ssh->packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
  23.     $packet->put_chars($response);
  24.     $packet->send;
  25. }
  26.  
  27. sub _rsa_public_encrypt {
  28.     my($input, $key) = @_;
  29.     my $bits = Math::GMP::sizeinbase_gmp($input, 2);
  30.     my $input_len = int(($bits + 7) / 8);
  31.     my $len = int(($key->{rsa}{bits} + 7) / 8);
  32.  
  33.     my $aux = Math::GMP->new(2);
  34.     for my $i (2..$len-$input_len-2) {
  35.         my $byte = 0;
  36.         {
  37.             $byte = int rand 128;
  38.             redo if $byte == 0;
  39.         }
  40.         $aux = Math::GMP::mul_2exp_gmp($aux, 8);
  41.         Math::GMP::add_ui_gmp($aux, $byte);
  42.     }
  43.     $aux = Math::GMP::mul_2exp_gmp($aux, 8 * ($input_len + 1));
  44.     $aux = Math::GMP->new($aux + $input);
  45.  
  46.     _rsa_public($aux, $key);
  47. }
  48.  
  49. sub _rsa_public {
  50.     my($input, $key) = @_;
  51.     Math::GMP::powm_gmp($input, $key->{rsa}{e}, $key->{rsa}{n});
  52. }
  53.  
  54. sub _rsa_private_decrypt {
  55.     my($input, $key) = @_;
  56.     my $output = _rsa_private($input, $key->{rsa});
  57.     my $len = int(($key->{rsa}{bits} + 7) / 8);
  58.     my $res = _mp_linearize($output, $len);
  59.     unless (vec($res, 0, 8) == 0 && vec($res, 1, 8) == 2) {
  60.         croak "Bad result from rsa_private_decrypt";
  61.     }
  62.     my $i;
  63.     for ($i=2; $i<$len && vec($res, $i, 8); $i++) { }
  64.     Math::GMP::mod_2exp_gmp($output, 8 * ($len - $i - 1));
  65. }
  66.  
  67. sub _rsa_private {
  68.     my($input, $key) = @_;
  69.     my($dp, $dq, $p2, $q2, $k);
  70.  
  71.     $dp = $key->{d} % ($key->{p}-1);
  72.     $dq = $key->{d} % ($key->{q}-1);
  73.  
  74.     $p2 = Math::GMP::powm_gmp($input % $key->{p}, $dp, $key->{p});
  75.     $q2 = Math::GMP::powm_gmp($input % $key->{q}, $dq, $key->{q});
  76.  
  77.     $k = (($q2 - $p2) * $key->{u}) % $key->{q};
  78.     $p2 + ($key->{p} * $k);
  79. }
  80.  
  81. 1;
  82.