line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::SSH::Perl::Util::RSA; |
2
|
1
|
|
|
1
|
|
8
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
28
|
|
3
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
27
|
|
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
5
|
use Net::SSH::Perl::Constants qw( SSH_CMSG_AUTH_RSA_RESPONSE ); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
6
|
|
6
|
1
|
|
|
1
|
|
6
|
use Net::SSH::Perl::Util qw( :ssh1mp ); |
|
1
|
|
|
|
|
2
|
|
|
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
|
|
|
|
|
39
|
|
10
|
1
|
|
|
1
|
|
5
|
use Math::GMP; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
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; |