File Coverage

blib/lib/Net/SSH/Perl/Util/RSA.pm
Criterion Covered Total %
statement 21 63 33.3
branch 0 4 0.0
condition 0 6 0.0
subroutine 7 12 58.3
pod n/a
total 28 85 32.9


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