File Coverage

blib/lib/IO/Stream/MatrixSSL/Client.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             ## no critic (Capitalization)
2             package IO::Stream::MatrixSSL::Client;
3              
4 1     1   3997 use warnings;
  1         2  
  1         29  
5 1     1   4 use strict;
  1         1  
  1         27  
6 1     1   5 use Carp;
  1         1  
  1         68  
7              
8 1     1   4 use version; our $VERSION = qv('1.1.0'); # update POD & Changes & README
  1         3  
  1         6  
9              
10             # update DEPENDENCIES in POD & Makefile.PL & README
11 1     1   646 use IO::Stream::const;
  0            
  0            
12             use IO::Stream::MatrixSSL::const;
13             use Crypt::MatrixSSL 1.83;
14             use File::ShareDir;
15             use Scalar::Util qw( weaken );
16              
17             use base qw( IO::Stream::MatrixSSL );
18              
19             use constant trusted_CA
20             => File::ShareDir::dist_file('IO-Stream-MatrixSSL', 'ca-bundle.crt');
21              
22              
23             # FIXME documentation: cb_validate->cb, default value for trusted_CA
24             sub new {
25             my ($class, $opt) = @_;
26             my $self = bless {
27             crt => undef, # filename(s) with server certificate(s)
28             key => undef, # filename with server private key
29             pass => undef, # password to decrypt private key
30             trusted_CA => trusted_CA, # filename(s) with trusted root CA cert(s)
31             cb => undef, # callback for validating certificate
32             %{$opt},
33             out_buf => q{}, # modified on: OUT
34             out_pos => undef, # modified on: OUT
35             out_bytes => 0, # modified on: OUT
36             in_buf => q{}, # modified on: IN
37             in_bytes => 0, # modified on: IN
38             ip => undef, # modified on: RESOLVED
39             is_eof => undef, # modified on: EOF
40             _param => [], # param for cb
41             # TODO Make this field public and add feature 'restore session'.
42             _ssl_session=> undef, # MatrixSSL 'sessionId' object
43             _ssl => undef, # MatrixSSL 'session' object
44             _ssl_keys => undef, # MatrixSSL 'keys' object
45             _handshaked => 0, # flag, will be true after handshake
46             _want_write => undef,
47             _t => undef,
48             _cb_t => undef,
49             }, $class;
50             my $this = $self;
51             weaken($this);
52             $self->{_cb_t} = sub { $this->T() };
53             # Initialize SSL.
54             # TODO OPTIMIZATION Cache {_ssl_keys}.
55             matrixSslReadKeys($self->{_ssl_keys}, $self->{crt}, $self->{key},
56             $self->{pass}, $self->{trusted_CA})
57             == 0 or croak 'matrixSslReadKeys: wrong {crt}, {key}, {pass} or {trusted_CA}?';
58             matrixSslNewSession($self->{_ssl}, $self->{_ssl_keys},
59             $self->{_ssl_session}, 0)
60             == 0 or croak 'matrixSslNewSession: wrong {_ssl_session}?';
61             matrixSslEncodeClientHello($self->{_ssl}, $self->{out_buf}, 0)
62             == 0 or croak 'matrixSslEncodeClientHello';
63             # Prepare first param for cb.
64             $self->{_param}[0] = $self;
65             weaken $self->{_param}[0];
66             if (defined $self->{cb}) {
67             matrixSslSetCertValidator($self->{_ssl}, $self->{cb}, $self->{_param});
68             }
69             return $self;
70             }
71              
72             sub PREPARE {
73             my ($self, $fh, $host, $port) = @_;
74             if (!defined $host) { # ... else timer will be set on CONNECTED
75             $self->{_t} = EV::timer(TOHANDSHAKE, 0, $self->{_cb_t});
76             }
77             # Prepare second param for cb.
78             my $io = $self;
79             while ($io->{_master}) {
80             $io = $io->{_master};
81             }
82             $self->{_param}[1] = $io;
83             weaken $self->{_param}[1];
84             $self->{_slave}->PREPARE($fh, $host, $port);
85             $self->{_slave}->WRITE(); # output 'client hello'
86             return;
87             }
88              
89              
90             1;