|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Protocol::TLS::Client;  | 
| 
2
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
170040
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
    | 
| 
3
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
    | 
| 
4
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use Carp;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
115
 | 
    | 
| 
5
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
522
 | 
 use Protocol::TLS::Trace qw(tracer bin2hex);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
    | 
| 
6
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
547
 | 
 use Protocol::TLS::Utils qw(load_cert load_priv_key);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
    | 
| 
7
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
584
 | 
 use Protocol::TLS::Context;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
    | 
| 
8
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
540
 | 
 use Protocol::TLS::Connection;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
9
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1332
 | 
 use Protocol::TLS::Constants qw(const_name :state_types :end_types :c_types  | 
| 
10
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
   :versions :hs_types :ciphers cipher_type :alert_desc :hash_alg :sign_alg);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
13
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
42201
 | 
     my ( $class, %opts ) = @_;  | 
| 
14
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     my $self = bless { %opts, sid => {} }, $class;  | 
| 
15
 | 
2
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
17
 | 
     if ( exists $opts{cert_file} && exists $opts{key_file} ) {  | 
| 
16
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->{cert} = load_cert( $opts{cert_file} );  | 
| 
17
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->{key}  = load_priv_key( $opts{key_file} );  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
19
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     $self;  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new_connection {  | 
| 
23
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
4384
 | 
     my ( $self, $server_name, %opts ) = @_;  | 
| 
24
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     croak "Specify server name of host" unless defined $server_name;  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
26
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
     my $ctx = Protocol::TLS::Context->new( type => CLIENT );  | 
| 
27
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     $ctx->{key}  = $self->{key}  if exists $self->{key};  | 
| 
28
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     $ctx->{cert} = $self->{cert} if exists $self->{cert};  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
30
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     my $con = Protocol::TLS::Connection->new($ctx);  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Grab random session_id from cache (if exists)  | 
| 
33
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     if ( exists $self->{sid}->{$server_name} ) {  | 
| 
34
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         my $s   = $self->{sid}->{$server_name};  | 
| 
35
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         my $sid = ( keys %$s )[0];  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $ctx->{proposed} = {  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             session_id  => $sid,  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             tls_version => $s->{$sid}->{tls_version},  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ciphers     => [ $s->{$sid}->{cipher} ],  | 
| 
41
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
             compression => [ $s->{$sid}->{compression} ],  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $ctx->{proposed} = {  | 
| 
46
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
             session_id => '',  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ciphers    => [  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_NULL_SHA256,  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 TLS_RSA_WITH_NULL_SHA,  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ],  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             tls_version => TLS_v12,  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             compression => [0],  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     if ( exists $opts{on_data} ) {  | 
| 
57
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         $ctx->{on_data} = $opts{on_data};  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
60
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     $ctx->enqueue( [ CTYPE_HANDSHAKE, HSTYPE_CLIENT_HELLO, $ctx->{proposed} ] );  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $ctx->{on_change_state} = sub {  | 
| 
63
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
 
 | 
26
 | 
         my ( $ctx, $prev_state, $new_state ) = @_;  | 
| 
64
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
         tracer->debug( "State changed from "  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               . const_name( 'state_types', $prev_state ) . " to "  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               . const_name( 'state_types', $new_state ) );  | 
| 
67
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
     };  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # New session  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $ctx->state_cb(  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         STATE_HS_HALF,  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
73
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
4
 | 
             my $ctx    = shift;  | 
| 
74
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             my $p      = $ctx->{pending};  | 
| 
75
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
             my $pro    = $ctx->{proposed};  | 
| 
76
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
             my $sp     = $p->{securityParameters};  | 
| 
77
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             my $crypto = $ctx->crypto;  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # Server invalidate our session  | 
| 
80
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
             if ( $pro->{session_id} ne '' ) {  | 
| 
81
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 delete $self->{sid}->{$server_name}->{ $pro->{session_id} };  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
84
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
             my $pub_key = $crypto->cert_pubkey( $p->{cert}->[0] );  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
             if ( exists $p->{client_cert} ) {  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $ctx->enqueue(  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     [  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         CTYPE_HANDSHAKE,  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         HSTYPE_CERTIFICATE,  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         exists $ctx->{cert} ? $ctx->{cert} : ()  | 
| 
92
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     ]  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 );  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
             my ( $da, $ca, $mac ) = cipher_type( $p->{cipher} );  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
98
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
             if ( $da eq 'RSA' ) {  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 my $preMasterSecret =  | 
| 
100
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
                   pack( "n", $p->{tls_version} ) . $crypto->random(46);  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $sp->{master_secret} = $crypto->PRF(  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $preMasterSecret,  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     "master secret",  | 
| 
105
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
                     $sp->{client_random} . $sp->{server_random}, 48  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 );  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
108
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
                 my $encoded =  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   $crypto->rsa_encrypt( $pub_key, $preMasterSecret );  | 
| 
110
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1001
 | 
                 $ctx->enqueue(  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     [ CTYPE_HANDSHAKE, HSTYPE_CLIENT_KEY_EXCHANGE, $encoded ] );  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
114
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 die "not implemented";  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
2
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
10
 | 
             if ( exists $p->{client_cert} && exists $ctx->{cert} ) {  | 
| 
118
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my ( $sign, $hash_n, $alg_n, $hash, $alg );  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $alg = $crypto->cert_pubkeyalg( $ctx->{cert} );  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
122
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
                 if ( $alg && exists &{"SIGN_$alg"} ) {  | 
| 
 
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
123
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
                     no strict 'refs';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
742
 | 
    | 
| 
124
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $alg_n = &{"SIGN_$alg"};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ($alg) {  | 
| 
127
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     die "algotithm $alg not implemented";  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
130
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     die "cert error";  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
133
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my $sah = $p->{client_cert}->{sah};  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
135
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 for my $i ( 0 .. @$sah / 2 - 1 ) {  | 
| 
136
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     if ( $sah->[ $i * 2 + 1 ] == $alg_n ) {  | 
| 
137
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         $hash_n = $sah->[ $i * 2 ];  | 
| 
138
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         $hash = const_name( 'hash_alg', $sah->[ $i * 2 ] );  | 
| 
139
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         $hash =~ s/HASH_//;  | 
| 
140
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         tracer->debug("Selected $alg, $hash");  | 
| 
141
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         last;  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
145
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 if ( $alg eq 'RSA' ) {  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $sign = $crypto->rsa_sign( $ctx->{key}, $hash,  | 
| 
147
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         join '', @{ $p->{hs_messages} } );  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
150
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     die "algotithm $alg not implemented";  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $ctx->enqueue(  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     [  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         CTYPE_HANDSHAKE, HSTYPE_CERTIFICATE_VERIFY,  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         $hash_n,         $alg_n,  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         $sign  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     ]  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 );  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
             $ctx->enqueue( [CTYPE_CHANGE_CIPHER_SPEC],  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 [ CTYPE_HANDSHAKE, HSTYPE_FINISHED, $ctx->finished ] );  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
165
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
     );  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $ctx->state_cb( STATE_SESS_RESUME,  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
169
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
             my $ctx = shift;  | 
| 
170
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
             my $p   = $ctx->{pending};  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #my $pro    = $ctx->{proposed};  | 
| 
173
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
             my $sp = $p->{securityParameters};  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
175
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             my $s = $self->{sid}->{$server_name}->{ $p->{session_id} };  | 
| 
176
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
             $p->{tls_version} = $s->{tls_version};  | 
| 
177
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
             $p->{cipher}      = $s->{cipher};  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $sp->{$_}         = $s->{securityParameters}->{$_}  | 
| 
179
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
               for keys %{ $s->{securityParameters} },  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               tracer->debug( "Resume session: " . bin2hex( $p->{session_id} ) );  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
183
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     );  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $ctx->state_cb( STATE_HS_RESUME,  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
187
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
2
 | 
             my $ctx = shift;  | 
| 
188
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             $ctx->enqueue( [CTYPE_CHANGE_CIPHER_SPEC],  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 [ CTYPE_HANDSHAKE, HSTYPE_FINISHED, $ctx->finished ] );  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
191
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
     );  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $ctx->state_cb( STATE_OPEN,  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
195
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
6
 | 
             my $ctx = shift;  | 
| 
196
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             my $p   = $ctx->{pending};  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # add sid to client's cache  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $self->{sid}->{$server_name}->{ $p->{session_id} } =  | 
| 
200
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
               $ctx->copy_pending;  | 
| 
201
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
             tracer->debug( "Saved sid:\n" . bin2hex( $p->{session_id} ) );  | 
| 
202
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
             $ctx->{session_id}  = $p->{session_id};  | 
| 
203
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
             $ctx->{tls_version} = $p->{tls_version};  | 
| 
204
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
             $ctx->clear_pending;  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # Handle callbacks  | 
| 
207
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
             if ( exists $opts{on_handshake_finish} ) {  | 
| 
208
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
                 $opts{on_handshake_finish}->($ctx);  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
211
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     );  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     $con;  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |