File Coverage

blib/lib/IO/Socket/SSL.pm
Criterion Covered Total %
statement 1491 2001 74.5
branch 782 1410 55.4
condition 365 677 53.9
subroutine 151 202 74.7
pod 56 86 65.1
total 2845 4376 65.0


line stmt bran cond sub pod time code
1             #vim: set sts=4 sw=4 ts=8 ai:
2             #
3             # IO::Socket::SSL:
4             # provide an interface to SSL connections similar to IO::Socket modules
5             #
6             # Current Code Shepherd: Steffen Ullrich
7             # Code Shepherd before: Peter Behroozi,
8             #
9             # The original version of this module was written by
10             # Marko Asplund, , who drew from
11             # Crypt::SSLeay (Net::SSL) by Gisle Aas.
12             #
13              
14             package IO::Socket::SSL;
15              
16             our $VERSION = '2.099';
17              
18 89     89   3137636 use IO::Socket;
  89         1317813  
  89         365  
19 89     89   57865 use Net::SSLeay 1.46;
  89         379500  
  89         4341  
20 89     89   130356 use IO::Socket::SSL::PublicSuffix;
  89         302  
  89         3612  
21 89     89   639 use Exporter ();
  89         123  
  89         1891  
22 89     89   299 use Errno qw( EWOULDBLOCK EAGAIN ETIMEDOUT EINTR EPIPE EPERM );
  89         119  
  89         11702  
23 89     89   462 use Carp;
  89         113  
  89         5081  
24 89     89   554 use Scalar::Util qw(weaken blessed dualvar);
  89         257  
  89         6619  
25 89     89   467 use Symbol;
  89         120  
  89         3690  
26 89     89   307 use strict;
  89         116  
  89         3731  
27              
28             my $use_threads;
29             BEGIN {
30 89     89   321 require Config;
31 89         14532 $use_threads = $Config::Config{usethreads};
32             }
33              
34              
35             # results from commonly used constant functions from Net::SSLeay for fast access
36             my $Net_SSLeay_ERROR_WANT_READ = Net::SSLeay::ERROR_WANT_READ();
37             my $Net_SSLeay_ERROR_WANT_WRITE = Net::SSLeay::ERROR_WANT_WRITE();
38             my $Net_SSLeay_ERROR_SYSCALL = Net::SSLeay::ERROR_SYSCALL();
39             my $Net_SSLeay_ERROR_SSL = Net::SSLeay::ERROR_SSL();
40             my $Net_SSLeay_VERIFY_NONE = Net::SSLeay::VERIFY_NONE();
41             my $Net_SSLeay_VERIFY_PEER = Net::SSLeay::VERIFY_PEER();
42              
43              
44 89     89   508 use constant SSL_VERIFY_NONE => &Net::SSLeay::VERIFY_NONE;
  89         265  
  89         545  
45 89     89   14729 use constant SSL_VERIFY_PEER => &Net::SSLeay::VERIFY_PEER;
  89         135  
  89         425  
46 89     89   10631 use constant SSL_VERIFY_FAIL_IF_NO_PEER_CERT => Net::SSLeay::VERIFY_FAIL_IF_NO_PEER_CERT();
  89         128  
  89         360  
47 89     89   10477 use constant SSL_VERIFY_CLIENT_ONCE => Net::SSLeay::VERIFY_CLIENT_ONCE();
  89         125  
  89         322  
48              
49             # from openssl/ssl.h; should be better in Net::SSLeay
50 89     89   9178 use constant SSL_SENT_SHUTDOWN => 1;
  89         124  
  89         2699  
51 89     89   294 use constant SSL_RECEIVED_SHUTDOWN => 2;
  89         129  
  89         2642  
52              
53 89     89   294 use constant SSL_OCSP_NO_STAPLE => 0b00001;
  89         116  
  89         2353  
54 89     89   264 use constant SSL_OCSP_MUST_STAPLE => 0b00010;
  89         126  
  89         2412  
55 89     89   258 use constant SSL_OCSP_FAIL_HARD => 0b00100;
  89         132  
  89         2426  
56 89     89   337 use constant SSL_OCSP_FULL_CHAIN => 0b01000;
  89         116  
  89         2396  
57 89     89   275 use constant SSL_OCSP_TRY_STAPLE => 0b10000;
  89         306  
  89         8210  
58              
59             # capabilities of underlying Net::SSLeay/openssl
60             my $can_client_sni; # do we support SNI on the client side
61             my $can_server_sni; # do we support SNI on the server side
62             my $can_multi_cert; # RSA and ECC certificate in same context
63             my $can_npn; # do we support NPN (obsolete)
64             my $can_alpn; # do we support ALPN
65             my $can_ecdh; # do we support ECDH key exchange
66             my $set_groups_list; # SSL_CTX_set1_groups_list || SSL_CTX_set1_curves_list || undef
67             my $can_ocsp; # do we support OCSP
68             my $can_ocsp_staple; # do we support OCSP stapling
69             my $can_tckt_keycb; # TLS ticket key callback
70             my $can_pha; # do we support PHA
71             my $session_upref; # SSL_SESSION_up_ref is implemented
72             my %sess_cb; # SSL_CTX_sess_set_(new|remove)_cb
73             my $check_partial_chain; # use X509_V_FLAG_PARTIAL_CHAIN if available
74             my $auto_retry; # (clear|set)_mode SSL_MODE_AUTO_RETRY with OpenSSL 1.1.1+ with non-blocking
75             my $ssl_mode_release_buffers = 0; # SSL_MODE_RELEASE_BUFFERS if available
76             my $can_ciphersuites; # support for SSL_CTX_set_ciphersuites (TLS 1.3)
77             my $can_client_psk; # work as PSK client
78             my $can_server_psk; # work as PSK server
79              
80             my $openssl_version;
81             my $netssleay_version;
82              
83             BEGIN {
84 89     89   696 $openssl_version = Net::SSLeay::OPENSSL_VERSION_NUMBER();
85 89     89   579 $netssleay_version = do { no warnings; $Net::SSLeay::VERSION + 0.0; };
  89         182  
  89         40061  
  89         8972  
  89         481  
86 89         214 $can_client_sni = $openssl_version >= 0x10000000;
87 89         183 $can_server_sni = defined &Net::SSLeay::get_servername;
88 89   33     1773 $can_npn = defined &Net::SSLeay::P_next_proto_negotiated &&
89             ! Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER");
90             # LibreSSL 2.6.1 disabled NPN by keeping the relevant functions
91             # available but removed the actual functionality from these functions.
92 89         203 $can_alpn = defined &Net::SSLeay::CTX_set_alpn_protos;
93 89 0 0     256 $can_ecdh =
    0          
    50          
94             ($openssl_version >= 0x1010000f) ? 'auto' :
95             defined(&Net::SSLeay::CTX_set_ecdh_auto) ? 'can_auto' :
96             (defined &Net::SSLeay::CTX_set_tmp_ecdh &&
97             # There is a regression with elliptic curves on 1.0.1d with 64bit
98             # http://rt.openssl.org/Ticket/Display.html?id=2975
99             ( $openssl_version != 0x1000104f
100             || length(pack("P",0)) == 4 )) ? 'tmp_ecdh' :
101             '';
102 89 0       235 $set_groups_list =
    50          
103             defined &Net::SSLeay::CTX_set1_groups_list ? \&Net::SSLeay::CTX_set1_groups_list :
104             defined &Net::SSLeay::CTX_set1_curves_list ? \&Net::SSLeay::CTX_set1_curves_list :
105             undef;
106 89   33     344 $can_multi_cert = $can_ecdh
107             && $openssl_version >= 0x10002000;
108 89   33     793 $can_ocsp = defined &Net::SSLeay::OCSP_cert2ids
109             # OCSP got broken in 1.75..1.77
110             && ($netssleay_version < 1.75 || $netssleay_version > 1.77);
111 89   33     545 $can_ocsp_staple = $can_ocsp
112             && defined &Net::SSLeay::set_tlsext_status_type;
113 89   33     512 $can_tckt_keycb = defined &Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb
114             && $netssleay_version >= 1.80;
115 89         177 $can_pha = defined &Net::SSLeay::CTX_set_post_handshake_auth;
116 89         150 $can_ciphersuites = defined &Net::SSLeay::CTX_set_ciphersuites;
117 89         149 $can_client_psk = defined &Net::SSLeay::CTX_set_psk_client_callback;
118 89         611 $can_server_psk = defined &Net::SSLeay::CTX_set_psk_server_callback;
119              
120 89 50       310 if (defined &Net::SSLeay::SESSION_up_ref) {
121 89         159 $session_upref = 1;
122             }
123              
124 89 50 33     582 if ($session_upref
      33        
125             && defined &Net::SSLeay::CTX_sess_set_new_cb
126             && defined &Net::SSLeay::CTX_sess_set_remove_cb) {
127 89         311 %sess_cb = (
128             new => \&Net::SSLeay::CTX_sess_set_new_cb,
129             remove => \&Net::SSLeay::CTX_sess_set_remove_cb,
130             );
131             }
132              
133 89 50 33     344 if (my $c = defined &Net::SSLeay::CTX_get0_param
134             && eval { Net::SSLeay::X509_V_FLAG_PARTIAL_CHAIN() }) {
135             $check_partial_chain = sub {
136 300         656 my $ctx = shift;
137 300         1884 my $param = Net::SSLeay::CTX_get0_param($ctx);
138 300         1360 Net::SSLeay::X509_VERIFY_PARAM_set_flags($param, $c);
139 89         8833 };
140             }
141              
142 89 50       270 if (!defined &Net::SSLeay::clear_mode) {
143             # assume SSL_CTRL_CLEAR_MODE being 78 since it was always this way
144             *Net::SSLeay::clear_mode = sub {
145 40     40   101 my ($ctx,$opt) = @_;
146 40         223 Net::SSLeay::ctrl($ctx,78,$opt,0);
147 89         366 };
148             }
149              
150 89 50       256 if ($openssl_version >= 0x10101000) {
151             # openssl 1.1.1 enabled SSL_MODE_AUTO_RETRY by default, which is bad for
152             # non-blocking sockets
153             my $mode_auto_retry =
154             # was always 0x00000004
155 89   50     140 eval { Net::SSLeay::MODE_AUTO_RETRY() } || 0x00000004;
156             $auto_retry = sub {
157 369         7004 my ($ssl,$on) = @_;
158 369 100       1091 if ($on) {
159 329         1943 Net::SSLeay::set_mode($ssl, $mode_auto_retry);
160             } else {
161 40         290 Net::SSLeay::clear_mode($ssl, $mode_auto_retry);
162             }
163             }
164 89         7739 }
165 89 50       245 if ($openssl_version >= 0x10000000) {
166             # ssl/ssl.h:#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
167 89         35923 $ssl_mode_release_buffers = 0x00000010;
168             }
169             }
170              
171             my $algo2digest = do {
172             my %digest;
173             sub {
174             my $digest_name = shift;
175             return $digest{$digest_name} ||= do {
176             Net::SSLeay::SSLeay_add_ssl_algorithms();
177             Net::SSLeay::EVP_get_digestbyname($digest_name)
178             or die "Digest algorithm $digest_name is not available";
179             };
180             }
181             };
182              
183             my $CTX_tlsv1_3_new;
184             if ( defined &Net::SSLeay::CTX_set_min_proto_version
185             and defined &Net::SSLeay::CTX_set_max_proto_version
186             and my $tls13 = eval { Net::SSLeay::TLS1_3_VERSION() }
187             ) {
188             $CTX_tlsv1_3_new = sub {
189             my $ctx = Net::SSLeay::CTX_new();
190             return $ctx if Net::SSLeay::CTX_set_min_proto_version($ctx,$tls13)
191             && Net::SSLeay::CTX_set_max_proto_version($ctx,$tls13);
192             Net::SSLeay::CTX_free($ctx);
193             return;
194             };
195             }
196              
197             # global defaults
198             my %DEFAULT_SSL_ARGS = (
199             SSL_check_crl => 0,
200             # TLS 1.1 and lower are deprecated with RFC 8996
201             SSL_version => 'SSLv23:!TLSv1:!TLSv1_1:!SSLv3:!SSLv2',
202             SSL_verify_callback => undef,
203             SSL_verifycn_scheme => undef, # fallback cn verification
204             SSL_verifycn_publicsuffix => undef, # fallback default list verification
205             #SSL_verifycn_name => undef, # use from PeerAddr/PeerHost - do not override in set_args_filter_hack 'use_defaults'
206             SSL_npn_protocols => undef, # meaning depends whether on server or client side
207             SSL_alpn_protocols => undef, # list of protocols we'll accept/send, for example ['http/1.1','spdy/3.1']
208              
209             # rely on system default but be sure to disable some definitely bad ones
210             SSL_cipher_list => 'DEFAULT !EXP !MEDIUM !LOW !eNULL !aNULL !RC4 !DES !MD5 !PSK !SRP',
211             );
212              
213             my %DEFAULT_SSL_CLIENT_ARGS = (
214             %DEFAULT_SSL_ARGS,
215             SSL_verify_mode => SSL_VERIFY_PEER,
216              
217             SSL_ca_file => undef,
218             SSL_ca_path => undef,
219             );
220              
221             # set values inside _init to work with perlcc, RT#95452
222             my %DEFAULT_SSL_SERVER_ARGS;
223              
224             # Initialization of OpenSSL internals
225             # This will be called once during compilation - perlcc users might need to
226             # call it again by hand, see RT#95452
227             {
228             sub init {
229             # library_init returns false if the library was already initialized.
230             # This way we can find out if the library needs to be re-initialized
231             # inside code compiled with perlcc
232 177 100   177 0 134815 Net::SSLeay::library_init() or return;
233              
234 89         7058 Net::SSLeay::load_error_strings();
235 89         365 Net::SSLeay::OpenSSL_add_all_digests();
236 89         754 Net::SSLeay::randomize();
237              
238             %DEFAULT_SSL_SERVER_ARGS = (
239             %DEFAULT_SSL_ARGS,
240             SSL_verify_mode => SSL_VERIFY_NONE,
241             SSL_honor_cipher_order => 1, # trust server to know the best cipher
242 89 0       264254 SSL_dh => do {
    0          
    50          
243 89         1367 my $bio = Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem());
244             # generated with: openssl dhparam 2048
245 89         573 Net::SSLeay::BIO_write($bio,<<'DH');
246             -----BEGIN DH PARAMETERS-----
247             MIIBCAKCAQEAr8wskArj5+1VCVsnWt/RUR7tXkHJ7mGW7XxrLSPOaFyKyWf8lZht
248             iSY2Lc4oa4Zw8wibGQ3faeQu/s8fvPq/aqTxYmyHPKCMoze77QJHtrYtJAosB9SY
249             CN7s5Hexxb5/vQ4qlQuOkVrZDiZO9GC4KaH9mJYnCoAsXDhDft6JT0oRVSgtZQnU
250             gWFKShIm+JVjN94kGs0TcBEesPTK2g8XVHK9H8AtSUb9BwW2qD/T5RmgNABysApO
251             Ps2vlkxjAHjJcqc3O+OiImKik/X2rtBTZjpKmzN3WWTB0RJZCOWaLlDO81D01o1E
252             aZecz3Np9KIYey900f+X7zC2bJxEHp95ywIBAg==
253             -----END DH PARAMETERS-----
254             DH
255 89         3047 my $dh = Net::SSLeay::PEM_read_bio_DHparams($bio);
256 89         487 Net::SSLeay::BIO_free($bio);
257 89 50       426 $dh or die "no DH";
258 89         1374 $dh;
259             },
260             (
261             $can_ecdh eq 'auto' ? () : # automatically enabled by openssl
262             $can_ecdh eq 'can_auto' ? (SSL_ecdh_curve => 'auto') :
263             $can_ecdh eq 'tmp_ecdh' ? ( SSL_ecdh_curve => 'prime256v1' ) :
264             (),
265             )
266             );
267             }
268             # Call it once at compile time and try it at INIT.
269             # This should catch all cases of including the module, e.g. 'use' (INIT) or
270             # 'require' (compile time) and works also with perlcc
271             {
272 89     89   605 no warnings;
  89         124  
  89         17117  
273 88     88   10308885 INIT { init() }
274             init();
275             }
276             }
277              
278             # global defaults which can be changed using set_defaults
279             # either key/value can be set or it can just be set to an external hash
280             my $GLOBAL_SSL_ARGS = {};
281             my $GLOBAL_SSL_CLIENT_ARGS = {};
282             my $GLOBAL_SSL_SERVER_ARGS = {};
283              
284             # hack which is used to filter bad settings from used modules
285             my $FILTER_SSL_ARGS = undef;
286              
287              
288             # get constants for SSL_OP_NO_* now, instead calling the related functions
289             # every time we setup a connection
290             my %SSL_OP_NO;
291             for(qw( SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv11:TLSv1_1 TLSv1_2 TLSv12:TLSv1_2
292             TLSv1_3 TLSv13:TLSv1_3 )) {
293             my ($k,$op) = m{:} ? split(m{:},$_,2) : ($_,$_);
294             my $sub = "Net::SSLeay::OP_NO_$op";
295             local $SIG{__DIE__};
296 89     89   583 $SSL_OP_NO{$k} = eval { no strict 'refs'; &$sub } || 0;
  89         132  
  89         15183  
297             }
298              
299             # Make SSL_CTX_clear_options accessible through SSL_CTX_ctrl unless it is
300             # already implemented in Net::SSLeay
301             if (!defined &Net::SSLeay::CTX_clear_options) {
302             *Net::SSLeay::CTX_clear_options = sub {
303 20     20   104 my ($ctx,$opt) = @_;
304             # 77 = SSL_CTRL_CLEAR_OPTIONS
305 20         141 Net::SSLeay::CTX_ctrl($ctx,77,$opt,0);
306             };
307             }
308              
309             # Try to work around problems with alternative trust path by default, RT#104759
310             my $DEFAULT_X509_STORE_flags = 0;
311             {
312             local $SIG{__DIE__};
313             eval { $DEFAULT_X509_STORE_flags |= Net::SSLeay::X509_V_FLAG_TRUSTED_FIRST() };
314             }
315              
316             our $DEBUG;
317             our $SSL_ERROR;
318              
319             {
320             # These constants will be used in $! at return from SSL_connect,
321             # SSL_accept, _generic_(read|write), thus notifying the caller
322             # the usual way of problems. Like with EWOULDBLOCK, EINPROGRESS..
323             # these are especially important for non-blocking sockets
324              
325             my $x = $Net_SSLeay_ERROR_WANT_READ;
326 89     89   533 use constant SSL_WANT_READ => dualvar( \$x, 'SSL wants a read first' );
  89         145  
  89         7459  
327             my $y = $Net_SSLeay_ERROR_WANT_WRITE;
328 89     89   497 use constant SSL_WANT_WRITE => dualvar( \$y, 'SSL wants a write first' );
  89         173  
  89         45659  
329              
330             our @EXPORT = qw(
331             SSL_WANT_READ SSL_WANT_WRITE SSL_VERIFY_NONE SSL_VERIFY_PEER
332             SSL_VERIFY_FAIL_IF_NO_PEER_CERT SSL_VERIFY_CLIENT_ONCE
333             SSL_OCSP_NO_STAPLE SSL_OCSP_TRY_STAPLE SSL_OCSP_MUST_STAPLE
334             SSL_OCSP_FAIL_HARD SSL_OCSP_FULL_CHAIN
335             $SSL_ERROR GEN_DNS GEN_IPADD
336             );
337             }
338              
339             my @caller_force_inet4; # in case inet4 gets forced we store here who forced it
340              
341             my $IOCLASS;
342             my $family_key; # 'Domain'||'Family'
343             our @ISA;
344             BEGIN {
345             # declare @ISA depending of the installed socket class
346              
347             # try to load inet_pton from Socket or Socket6 and make sure it is usable
348 89     89   630 local $SIG{__DIE__}; local $SIG{__WARN__}; # be silent
  89         391  
349             my $ip6 = eval {
350             require Socket;
351             Socket->VERSION(1.95);
352             Socket::inet_pton( AF_INET6(),'::1') && AF_INET6() or die;
353             Socket->import( qw/inet_pton NI_NUMERICHOST NI_NUMERICSERV/ );
354             # behavior different to Socket6::getnameinfo - wrap
355             *_getnameinfo = sub {
356 0     0   0 my ($err,$host,$port) = Socket::getnameinfo(@_) or return;
357 0         0 return if $err;
358 0         0 return ($host,$port);
359             };
360             'Socket';
361 89   50     323 } || eval {
362             require Socket6;
363             Socket6::inet_pton( AF_INET6(),'::1') && AF_INET6() or die;
364             Socket6->import( qw/inet_pton NI_NUMERICHOST NI_NUMERICSERV/ );
365             # behavior different to Socket::getnameinfo - wrap
366             *_getnameinfo = sub { return Socket6::getnameinfo(@_); };
367             'Socket6';
368             } || undef;
369              
370             # try IO::Socket::IP or IO::Socket::INET6 for IPv6 support
371 89         175 $family_key = 'Domain'; # traditional
372 89 50       289 if ($ip6) {
373             # if we have IO::Socket::IP >= 0.31 we will use this in preference
374             # because it can handle both IPv4 and IPv6
375 89 100       134 if ( eval {
    50          
376 89         52491 require IO::Socket::IP;
377 88         1250046 IO::Socket::IP->VERSION(0.31)
378             }) {
379 88         1487 @ISA = qw(IO::Socket::IP);
380 88         4760 constant->import( CAN_IPV6 => "IO::Socket::IP" );
381 88         284 $family_key = 'Family';
382 88         187 $IOCLASS = "IO::Socket::IP";
383              
384             # if we have IO::Socket::INET6 we will use this not IO::Socket::INET
385             # because it can handle both IPv4 and IPv6
386             # require at least 2.62 because of several problems before that version
387 1         327 } elsif( eval { require IO::Socket::INET6; IO::Socket::INET6->VERSION(2.62) } ) {
  0         0  
388 0         0 @ISA = qw(IO::Socket::INET6);
389 0         0 constant->import( CAN_IPV6 => "IO::Socket::INET6" );
390 0         0 $IOCLASS = "IO::Socket::INET6";
391             } else {
392 1         3 $ip6 = ''
393             }
394             }
395              
396             # fall back to IO::Socket::INET for IPv4 only
397 89 100       499 if (!$ip6) {
398 1         16 @ISA = qw(IO::Socket::INET);
399 1         1 $IOCLASS = "IO::Socket::INET";
400 1         28 constant->import(CAN_IPV6 => '');
401 1 50       3 if (!defined $ip6) {
402 0         0 constant->import(NI_NUMERICHOST => 1);
403 0         0 constant->import(NI_NUMERICSERV => 2);
404             }
405             }
406              
407             #Make $DEBUG another name for $Net::SSLeay::trace
408 89         317 *DEBUG = \$Net::SSLeay::trace;
409              
410             #Compatibility
411 89         22161 *ERROR = \$SSL_ERROR;
412             }
413              
414              
415             sub DEBUG {
416 0 0   0 0 0 $DEBUG or return;
417 0         0 my (undef,$file,$line,$sub) = caller(1);
418 0 0       0 if ($sub =~m{^IO::Socket::SSL::(?:error|(_internal_error))$}) {
419 0 0       0 (undef,$file,$line) = caller(2) if $1;
420             } else {
421 0         0 (undef,$file,$line) = caller;
422             }
423 0         0 my $msg = shift;
424 0 0       0 $file = '...'.substr( $file,-17 ) if length($file)>20;
425 0 0       0 $msg = sprintf $msg,@_ if @_;
426 0         0 print STDERR "DEBUG: $file:$line: $msg\n";
427             }
428              
429             BEGIN {
430             # import some constants from Net::SSLeay or use hard-coded defaults
431             # if Net::SSLeay isn't recent enough to provide the constants
432 89     89   435 my %const = (
433             NID_CommonName => 13,
434             GEN_DNS => 2,
435             GEN_IPADD => 7,
436             );
437 89         512 while ( my ($name,$value) = each %const ) {
438 89     89   726 no strict 'refs';
  89         133  
  89         10047  
439 267   33 567   2404 *{$name} = UNIVERSAL::can( 'Net::SSLeay', $name ) || sub { $value };
  267         1752  
  567         2561  
440             }
441              
442 89         208 *idn_to_ascii = \&IO::Socket::SSL::PublicSuffix::idn_to_ascii;
443 89         1066078 *idn_to_unicode = \&IO::Socket::SSL::PublicSuffix::idn_to_unicode;
444             }
445              
446             my $OPENSSL_LIST_SEPARATOR = $^O =~m{^(?:(dos|os2|mswin32|netware)|vms)$}i
447             ? $1 ? ';' : ',' : ':';
448             my $CHECK_SSL_PATH = sub {
449             my %args = (@_ == 1) ? ('',@_) : @_;
450             for my $type (keys %args) {
451             my $path = $args{$type};
452             if (!$type) {
453             delete $args{$type};
454             $type = (ref($path) || -d $path) ? 'SSL_ca_path' : 'SSL_ca_file';
455             $args{$type} = $path;
456             }
457              
458             next if ref($path) eq 'SCALAR' && ! $$path;
459             if ($type eq 'SSL_ca_file') {
460             die "SSL_ca_file $path can't be used: $!"
461             if ! open(my $fh,'<',$path);
462             } elsif ($type eq 'SSL_ca_path') {
463             $path = [ split($OPENSSL_LIST_SEPARATOR,$path) ] if !ref($path);
464             my @err;
465             for my $d (ref($path) ? @$path : $path) {
466             if (! -d $d) {
467             push @err, "SSL_ca_path $d does not exist";
468             } elsif (! opendir(my $dh,$d)) {
469             push @err, "SSL_ca_path $d is not accessible: $!"
470             } else {
471             @err = ();
472             last
473             }
474             }
475             die "@err" if @err;
476             }
477             }
478             return %args;
479             };
480              
481              
482             {
483             my %default_ca;
484             my $ca_detected; # 0: never detect, undef: need to (re)detect
485             my $openssldir;
486              
487             sub default_ca {
488 187 100   187 1 6108 if (@_) {
489             # user defined default CA or reset
490 3 50       124 if ( @_ > 1 ) {
    50          
491 0         0 %default_ca = @_;
492 0         0 $ca_detected = 0;
493             } elsif ( my $path = shift ) {
494 3         54 %default_ca = $CHECK_SSL_PATH->($path);
495 3         7 $ca_detected = 0;
496             } else {
497 0         0 $ca_detected = undef;
498             }
499             }
500 187 100       1612 return %default_ca if defined $ca_detected;
501              
502             # SSLEAY_DIR was 5 up to OpenSSL 1.1, then switched to 4 and got
503             # renamed to OPENSSL_DIR. Unfortunately it is not exported as constant
504             # by Net::SSLeay so we use the fixed number.
505 54 50 33     2785 $openssldir ||=
    50          
506             Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} ? $1 :
507             Net::SSLeay::SSLeay_version(4) =~m{^OPENSSLDIR: "(.+)"$} ? $1 :
508             'cannot-determine-openssldir-from-ssleay-version';
509              
510             # (re)detect according to openssl crypto/cryptlib.h
511             my $dir = $ENV{SSL_CERT_DIR}
512 54   33     1497 || ( $^O =~m{vms}i ? "SSLCERTS:":"$openssldir/certs" );
513 54 50       4461 if ( opendir(my $dh,$dir)) {
514 54         12310 FILES: for my $f ( grep { m{^[a-f\d]{8}(\.\d+)?$} } readdir($dh) ) {
  15930         27393  
515 54 50       3515 open( my $fh,'<',"$dir/$f") or next;
516 54         2023 while (my $line = <$fh>) {
517 54 50       700 $line =~m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next;
518 54         279 $default_ca{SSL_ca_path} = $dir;
519 54         1085 last FILES;
520             }
521             }
522             }
523             my $file = $ENV{SSL_CERT_FILE}
524 54   33     1687 || ( $^O =~m{vms}i ? "SSLCERTS:cert.pem":"$openssldir/cert.pem" );
525 54 50       2375 if ( open(my $fh,'<',$file)) {
526 54         2146 while (my $line = <$fh>) {
527 54 50       521 $line =~m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next;
528 54         238 $default_ca{SSL_ca_file} = $file;
529 54         163 last;
530             }
531             }
532              
533 54 0 33     223 $default_ca{SSL_ca_file} = Mozilla::CA::SSL_ca_file() if ! %default_ca && do {
534 0         0 local $SIG{__DIE__};
535 0         0 eval { require Mozilla::CA; 1 };
  0         0  
  0         0  
536             };
537              
538 54         118 $ca_detected = 1;
539 54         1502 return %default_ca;
540             }
541             }
542              
543              
544             # Export some stuff
545             # inet4|inet6|debug will be handled by myself, everything
546             # else will be handled the Exporter way
547             sub import {
548 177     177   261115 my $class = shift;
549              
550 177         334 my @export;
551 177         591 foreach (@_) {
552 1 50       18 if ( /^inet4$/i ) {
    50          
    50          
553             # explicitly fall back to inet4
554 0         0 @ISA = 'IO::Socket::INET';
555 0         0 @caller_force_inet4 = caller(); # save for warnings for 'inet6' case
556             } elsif ( /^inet6$/i ) {
557             # check if we have already ipv6 as base
558 0 0 0     0 if ( ! UNIVERSAL::isa( $class, 'IO::Socket::INET6')
559             and ! UNIVERSAL::isa( $class, 'IO::Socket::IP' )) {
560             # either we don't support it or we disabled it by explicitly
561             # loading it with 'inet4'. In this case re-enable but warn
562             # because this is probably an error
563 0         0 if ( CAN_IPV6 ) {
564 0         0 @ISA = ( CAN_IPV6 );
565 0         0 warn "IPv6 support re-enabled in __PACKAGE__, got disabled in file $caller_force_inet4[1] line $caller_force_inet4[2]";
566             } else {
567             die "INET6 is not supported, install IO::Socket::IP";
568             }
569             }
570             } elsif ( /^:?debug(\d+)/ ) {
571 1         4 $DEBUG=$1;
572             } else {
573 2         8 push @export,$_
574             }
575             }
576              
577 177         69144 @_ = ( $class,@export );
578 175         4454696 goto &Exporter::import;
579             }
580              
581             my %SSL_OBJECT;
582             my %CREATED_IN_THIS_THREAD;
583 0     0   0 sub CLONE { %CREATED_IN_THIS_THREAD = (); }
584              
585             # all keys specific for the current state of the socket
586             # these should be removed on close
587             my %all_my_conn_keys = map { $_ => 1 } qw(
588             _SSL_fileno
589             _SSL_object
590             _SSL_opened
591             _SSL_opening
592             _SSL_read_closed
593             _SSL_write_closed
594             _SSL_rawfd
595             _SSL_bio_socket
596             _SSL_bio_sub
597             );
598              
599             my %all_my_conn_and_cert_keys = (
600             %all_my_conn_keys,
601             _SSL_certificate => 1,
602             );
603              
604             # all keys used internally, these should be cleaned up at end
605             # but not already on close
606             my %all_my_keys = (
607             %all_my_conn_and_cert_keys,
608             map { $_ => 1 } qw(
609             _SSL_arguments
610             _SSL_ctx
611             _SSL_ioclass_upgraded
612             _SSL_last_err
613             _SSL_ocsp_verify
614             _SSL_servername
615             _SSL_msg_callback
616             )
617             );
618              
619              
620             # we have callbacks associated with contexts, but have no way to access the
621             # current SSL object from these callbacks. To work around this
622             # CURRENT_SSL_OBJECT will be set before calling Net::SSLeay::{connect,accept}
623             # and reset afterwards, so we have access to it inside _internal_error.
624             my $CURRENT_SSL_OBJECT;
625              
626             # You might be expecting to find a new() subroutine here, but that is
627             # not how IO::Socket::INET works. All configuration gets performed in
628             # the calls to configure() and either connect() or accept().
629              
630             #Call to configure occurs when a new socket is made using
631             #IO::Socket::INET. Returns false (empty list) on failure.
632             sub configure {
633 141     141 0 3796558 my ($self, $arg_hash) = @_;
634 141 50       1220 return _invalid_object() unless($self);
635              
636             # force initial blocking
637             # otherwise IO::Socket::SSL->new might return undef if the
638             # socket is nonblocking and it fails to connect immediately
639             # for real nonblocking behavior one should create a nonblocking
640             # socket and later call connect explicitly
641 141         819 my $blocking = delete $arg_hash->{Blocking};
642              
643             # because Net::HTTPS simple redefines blocking() to {} (e.g.
644             # return undef) and IO::Socket::INET does not like this we
645             # set Blocking only explicitly if it was set
646 141 100       906 $arg_hash->{Blocking} = 1 if defined ($blocking);
647              
648             # close newly created socket on SSL fail
649 141 50       1527 $arg_hash->{SSL_keepSocketOnError} = 0 if !exists $arg_hash->{SSL_keepSocketOnError};
650 141 100       994 $self->configure_SSL($arg_hash) || return;
651              
652 140 100 66     1891 if ($arg_hash->{$family_key} ||= $arg_hash->{Domain} || $arg_hash->{Family}) {
      66        
653             # Hack to work around the problem that IO::Socket::IP defaults to
654             # AI_ADDRCONFIG which creates problems if we have only the loopback
655             # interface. If we already know the family this flag is more harmful
656             # then useful.
657             $arg_hash->{GetAddrInfoFlags} = 0 if $IOCLASS eq 'IO::Socket::IP'
658 72 50 33     987 && ! defined $arg_hash->{GetAddrInfoFlags};
659             }
660 140 100       1576 return $self->_internal_error("@ISA configuration failed",0)
661             if ! $self->SUPER::configure($arg_hash);
662              
663 127 100 66     18646 $self->blocking(0) if defined $blocking && !$blocking;
664 127         1651 return $self;
665             }
666              
667             sub configure_SSL {
668 304     304 0 2777 my ($self, $arg_hash) = @_;
669              
670 304   50     7143 $arg_hash->{Proto} ||= 'tcp';
671 304         1831 my $is_server = $arg_hash->{SSL_server};
672 304 100       1663 if ( ! defined $is_server ) {
673 216   100     3906 $is_server = $arg_hash->{SSL_server} = $arg_hash->{Listen} || 0;
674             }
675              
676             # add user defined defaults, maybe after filtering
677 304 50       2005 $FILTER_SSL_ARGS->($is_server,$arg_hash) if $FILTER_SSL_ARGS;
678              
679             # keep socket open on error by default when just upgrading
680 304 100       2209 $arg_hash->{SSL_keepSocketOnError} = 1 if !exists $arg_hash->{SSL_keepSocketOnError};
681              
682             # cleanup in case there was something left, but leave BIO socket
683 304         3372 _cleanup_ssl($self, undef, '_SSL_bio_socket');
684 304         559 ${*$self}{_SSL_opened} = $is_server;
  304         775  
685 304         542 ${*$self}{_SSL_arguments} = $arg_hash;
  304         781  
686              
687             # this adds defaults to $arg_hash as a side effect!
688 304 100       6430 ${*$self}{'_SSL_ctx'} = IO::Socket::SSL::SSL_Context->new($arg_hash)
  304         2392  
689             or return;
690              
691 303         1286 return $self;
692             }
693              
694              
695             sub _skip_rw_error {
696 163     163   604 my ($self,$ssl,$rv) = @_;
697 163         817 my $err = Net::SSLeay::get_error($ssl,$rv);
698 163 100       699 if ( $err == $Net_SSLeay_ERROR_WANT_READ) {
    100          
699 84         375 $SSL_ERROR = SSL_WANT_READ;
700             } elsif ( $err == $Net_SSLeay_ERROR_WANT_WRITE) {
701 2         18 $SSL_ERROR = SSL_WANT_WRITE;
702             } else {
703 77         266 return $err;
704             }
705 86   100     1014 $! ||= EWOULDBLOCK;
706 86 50       419 ${*$self}{_SSL_last_err} = [$SSL_ERROR,4] if ref($self);
  86         499  
707 86         446 Net::SSLeay::ERR_clear_error();
708 86         248 return 0;
709             }
710              
711              
712             # Call to connect occurs when a new client socket is made using IO::Socket::*
713             sub connect {
714 97   50 97 1 11432 my $self = shift || return _invalid_object();
715 97 50       198 return $self if ${*$self}{'_SSL_opened'}; # already connected
  97         450  
716              
717 97 50       228 if ( ! ${*$self}{'_SSL_opening'} ) {
  97         362  
718             # call SUPER::connect if the underlying socket is not connected
719             # if this fails this might not be an error (e.g. if $! = EINPROGRESS
720             # and socket is nonblocking this is normal), so keep any error
721             # handling to the client
722 97 50       393 $DEBUG>=2 && DEBUG('socket not yet connected' );
723 97 50       1375 $self->SUPER::connect(@_) || return;
724 97 50       15726 $DEBUG>=2 && DEBUG('socket connected' );
725              
726             # IO::Socket works around systems, which return EISCONN or similar
727             # on non-blocking re-connect by returning true, even if $! is set
728             # but it does not clear $!, so do it here
729 97         701 $! = undef;
730              
731             # don't continue with connect_SSL if SSL_startHandshake is set to 0
732 97         247 my $sh = ${*$self}{_SSL_arguments}{SSL_startHandshake};
  97         958  
733 97 100 66     696 return $self if defined $sh && ! $sh;
734             }
735 82         575 return $self->connect_SSL;
736             }
737              
738              
739             sub connect_SSL {
740 199     199 1 5085907 my $self = shift;
741 199 100 50     1560 my $args = @_>1 ? {@_}: $_[0]||{};
742 199 50       407 return $self if ${*$self}{'_SSL_opened'}; # already connected
  199         1082  
743              
744 199         668 my ($ssl,$ctx);
745 199 100       546 if ( ! ${*$self}{'_SSL_opening'} ) {
  199         846  
746             # start ssl connection
747 197 50       615 $DEBUG>=2 && DEBUG('ssl handshake not started' );
748 197         416 ${*$self}{'_SSL_opening'} = 1;
  197         788  
749 197         370 my $arg_hash = ${*$self}{'_SSL_arguments'};
  197         509  
750              
751 197         376 my $biosock = ${*$self}{_SSL_bio_socket};
  197         519  
752 197 50 33     937 die "cannot upgrade socket in-place with SSL BIO" if $args->{SSL_usebio} && !$biosock;
753              
754 197         325 $ctx = ${*$self}{'_SSL_ctx'}; # Reference to real context
  197         488  
755 197         773 $ssl = ${*$self}{'_SSL_object'} = Net::SSLeay::new($ctx->{context})
756 197   50     5484 || return $self->error("SSL structure creation failed");
757 197 50       641 $CREATED_IN_THIS_THREAD{$ssl} = 1 if $use_threads;
758 197         1291 $SSL_OBJECT{$ssl} = [$self,0];
759 197         691 weaken($SSL_OBJECT{$ssl}[0]);
760              
761 197 100       727 if ($ctx->{session_cache}) {
762 12   66     57 $arg_hash->{SSL_session_key} ||= do {
763             my $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost}
764 6   66     63 || $self->_update_peer;
765 6   66     25 my $port = $arg_hash->{PeerPort} || $arg_hash->{PeerService};
766 6 50       36 $port ? "$host:$port" : $host;
767             }
768             }
769              
770 197 100       693 if ($biosock) {
771 3         30 ${*$self}{_SSL_fileno} = fileno($biosock);
  3         9  
772 3         14 _bio_attach($self);
773             } else {
774 194         868 my $fileno = ${*$self}{_SSL_fileno} = fileno($self);
  194         634  
775 194 50       599 return $self->_internal_error("Socket has no fileno",9)
776             if ! defined $fileno;
777 194 50       4350 Net::SSLeay::set_fd($ssl, $fileno)
778             || return $self->error("SSL filehandle association failed");
779             }
780              
781 197 50 33     1823 set_msg_callback($self) if $DEBUG>=2 || ${*$self}{_SSL_msg_callback};
  197         1191  
782              
783 197 50       671 if ( $can_client_sni ) {
    0          
784 197         392 my $host;
785 197 100 100     2019 if ( exists $arg_hash->{SSL_hostname} ) {
    100          
786             # explicitly given
787             # can be set to undef/'' to not use extension
788             $host = $arg_hash->{SSL_hostname}
789 17         55 } elsif ( $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} ) {
790             # implicitly given
791 85         483 $host =~s{:[a-zA-Z0-9_\-]+$}{};
792             # should be hostname, not IPv4/6
793 85 50 33     589 $host = undef if $host !~m{[a-z_]}i or $host =~m{:};
794             }
795             # define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
796             # define TLSEXT_NAMETYPE_host_name 0
797 197 100       536 if ($host) {
798 17 50       46 $DEBUG>=2 && DEBUG("using SNI with hostname $host");
799 17         104 Net::SSLeay::ctrl($ssl,55,0,$host);
800             } else {
801 180 50       627 $DEBUG>=2 && DEBUG("not using SNI because hostname is unknown");
802             }
803             } elsif ( $arg_hash->{SSL_hostname} ) {
804 0         0 return $self->_internal_error(
805             "Client side SNI not supported for this openssl",9);
806             } else {
807 0 0       0 $DEBUG>=2 && DEBUG("not using SNI because openssl is too old");
808             }
809              
810 197 100 100     2037 $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} || $self->_update_peer;
811 197 100       1174 if ( $ctx->{verify_name_ref} ) {
812             # need target name for update
813             my $host = $arg_hash->{SSL_verifycn_name}
814 114   100     500 || $arg_hash->{SSL_hostname};
815 114 100       469 if ( ! defined $host ) {
816 64 50 66     341 if ( $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} ) {
817 64         707 $host =~s{^
818             (
819             (?:[^:\[]+) | # ipv4|host
820             (?:\[(?:.*)\]) # [ipv6|host]
821             )
822             (:[\w\-]+)? # optional :port
823             $}{$1}x; # ipv4|host|ipv6
824             }
825             }
826 114         218 ${$ctx->{verify_name_ref}} = $host;
  114         328  
827             }
828              
829 197         483 my $ocsp = $ctx->{ocsp_mode};
830 197 50       1303 if ( $ocsp & SSL_OCSP_NO_STAPLE ) {
    50          
    100          
831             # don't try stapling
832             } elsif ( ! $can_ocsp_staple ) {
833 0 0       0 croak("OCSP stapling not support") if $ocsp & SSL_OCSP_MUST_STAPLE;
834             } elsif ( $ocsp & (SSL_OCSP_TRY_STAPLE|SSL_OCSP_MUST_STAPLE)) {
835             # staple by default if verification enabled
836 114         231 ${*$self}{_SSL_ocsp_verify} = undef;
  114         342  
837 114         4810 Net::SSLeay::set_tlsext_status_type($ssl,
838             Net::SSLeay::TLSEXT_STATUSTYPE_ocsp());
839 114 50       8475 $DEBUG>=2 && DEBUG("request OCSP stapling");
840             }
841              
842 197 100 100     997 if ($ctx->{session_cache} and my $session =
843             $ctx->{session_cache}->get_session($arg_hash->{SSL_session_key})
844             ) {
845 7         29 Net::SSLeay::set_session($ssl, $session);
846             }
847             }
848              
849 199   66     773 $ssl ||= ${*$self}{'_SSL_object'};
  2         29  
850 199         633 my $dobio = ${*$self}{'_SSL_bio_sub'};
  199         832  
851              
852 199         1403 $SSL_ERROR = $! = undef;
853             my $timeout = exists $args->{Timeout}
854             ? $args->{Timeout}
855 199 100       590 : ${*$self}{io_socket_timeout}; # from IO::Socket
  197         743  
856 199 100 66     996 if ( defined($timeout) && $timeout>0 && $self->blocking(0) ) {
      66        
857 11 50       156 $DEBUG>=2 && DEBUG( "set socket to non-blocking to enforce timeout=$timeout" );
858             # timeout was given and socket was blocking
859             # enforce timeout with now non-blocking socket
860             } else {
861             # timeout does not apply because invalid or socket non-blocking
862 188         350 $timeout = undef;
863 188 50       1337 $auto_retry && $auto_retry->($ssl,$self->blocking);
864             }
865              
866 199   66     806 my $start = defined($timeout) && time();
867             {
868 199         341 retry_after_dobio:
  231         606  
869             $SSL_ERROR = undef;
870 231         455 $CURRENT_SSL_OBJECT = $self;
871 231 50       759 $DEBUG>=3 && DEBUG("call Net::SSLeay::connect" );
872 231         3725110 my $rv = Net::SSLeay::connect($ssl);
873 231         1272 $CURRENT_SSL_OBJECT = undef;
874 231 50       1036 $DEBUG>=3 && DEBUG("done Net::SSLeay::connect -> $rv" );
875 231 100       1126 if ( $rv < 0 ) {
    50          
876 69         362 my $err = $self->_skip_rw_error( $ssl,$rv );
877 69 100 100     406 if (!$err && $dobio) {
878 18 50       47 goto retry_after_dobio if $dobio->($self,
879             $SSL_ERROR == SSL_WANT_READ,
880             $SSL_ERROR == SSL_WANT_WRITE,
881             \$err);
882             }
883 51 100       159 if ($err) {
884 34         461 $self->error("SSL connect attempt failed");
885 34         63 delete ${*$self}{'_SSL_opening'};
  34         127  
886 34         68 ${*$self}{'_SSL_opened'} = -1;
  34         78  
887 34 50       112 $DEBUG>=1 && DEBUG( "fatal SSL error: $SSL_ERROR" );
888 34         204 return $self->fatal_ssl_error();
889             }
890              
891 17 50       64 $DEBUG>=2 && DEBUG('ssl handshake in progress' );
892             # connect failed because handshake needs to be completed
893             # if socket was non-blocking or no timeout was given return with this error
894 17 100       52 return if ! defined($timeout);
895              
896             # wait until socket is readable or writable
897 15         27 my $rv;
898 15 50       37 if ( $timeout>0 ) {
899 15         38 my $vec = '';
900 15         91 vec($vec,$self->fileno,1) = 1;
901 15 50       53 $DEBUG>=2 && DEBUG( "waiting for fd to become ready: $SSL_ERROR" );
902 15 0       5657412 $rv =
    50          
903             $SSL_ERROR == SSL_WANT_READ ? select( $vec,undef,undef,$timeout) :
904             $SSL_ERROR == SSL_WANT_WRITE ? select( undef,$vec,undef,$timeout) :
905             undef;
906             } else {
907 0 0       0 $DEBUG>=2 && DEBUG("handshake failed because no more time" );
908 0         0 $! = ETIMEDOUT
909             }
910 15 100       192 if ( ! $rv ) {
911 1 50       5 $DEBUG>=2 && DEBUG("handshake failed because socket did not became ready" );
912             # failed because of timeout, return
913 1   50     15 $! ||= ETIMEDOUT;
914 1         2 delete ${*$self}{'_SSL_opening'};
  1         12  
915 1         3 ${*$self}{'_SSL_opened'} = -1;
  1         4  
916 1         9 $self->blocking(1); # was blocking before
917             return
918 1         27 }
919              
920             # socket is ready, try non-blocking connect again after recomputing timeout
921 14 50       109 $DEBUG>=2 && DEBUG("socket ready, retrying connect" );
922 14         53 my $now = time();
923 14         47 $timeout -= $now - $start;
924 14         65 $start = $now;
925 14         50 redo;
926              
927             } elsif ( $rv == 0 ) {
928 0         0 delete ${*$self}{'_SSL_opening'};
  0         0  
929 0 0       0 $DEBUG>=2 && DEBUG("connection failed - connect returned 0" );
930 0         0 $self->error("SSL connect attempt failed because of handshake problems" );
931 0         0 ${*$self}{'_SSL_opened'} = -1;
  0         0  
932 0         0 return $self->fatal_ssl_error();
933             }
934             }
935              
936 162 50       548 $DEBUG>=2 && DEBUG('ssl handshake done' );
937             # ssl connect successful
938 162         330 delete ${*$self}{'_SSL_opening'};
  162         1317  
939 162         403 ${*$self}{'_SSL_opened'}=1;
  162         574  
940 162 100       569 if (defined($timeout)) {
941 8         52 $self->blocking(1); # reset back to blocking
942 8         176 $! = undef; # reset errors from non-blocking
943             }
944              
945 162   66     618 $ctx ||= ${*$self}{'_SSL_ctx'};
  2         11  
946              
947             # _SSL_ocsp_verify is set only when a staple was received and fully
948             # verified. A missing staple and a broken/unverifiable staple both leave it
949             # undef, so MUST_STAPLE treats both identically as "no usable staple".
950 162 50       315 if ( my $ocsp_result = ${*$self}{_SSL_ocsp_verify} ) {
  162 50       1455  
951             # got result from OCSP stapling
952 0 0       0 if ( $ocsp_result->[0] > 0 ) {
    0          
953 0 0       0 $DEBUG>=3 && DEBUG("got OCSP success with stapling");
954             # successful validated
955             } elsif ( $ocsp_result->[0] < 0 ) {
956             # Permanent problem with validation because certificate
957             # is either self-signed or the issuer cannot be found.
958             # Ignore here, because this will cause other errors too.
959 0 0       0 $DEBUG>=3 && DEBUG("got OCSP failure with stapling: %s",
960             $ocsp_result->[1]);
961             } else {
962             # definitely revoked
963 0 0       0 $DEBUG>=3 && DEBUG("got OCSP revocation with stapling: %s",
964             $ocsp_result->[1]);
965 0         0 $self->_internal_error($ocsp_result->[1],5);
966 0         0 return $self->fatal_ssl_error();
967             }
968             } elsif ( $ctx->{ocsp_mode} & SSL_OCSP_MUST_STAPLE ) {
969 0         0 $self->_internal_error("did not receive the required stapled OCSP response",5);
970 0         0 return $self->fatal_ssl_error();
971             }
972              
973 162 0 33     632 if (!%sess_cb and $ctx->{session_cache}
      0        
974             and my $session = Net::SSLeay::get1_session($ssl)) {
975             $ctx->{session_cache}->add_session(
976 0         0 ${*$self}{_SSL_arguments}{SSL_session_key},
977 0         0 $session
978             );
979             }
980              
981 162         348 tie *{$self}, "IO::Socket::SSL::SSL_HANDLE", $self;
  162         3555  
982              
983 162         1353 return $self;
984             }
985              
986             # called if PeerAddr is not set in ${*$self}{'_SSL_arguments'}
987             # this can be the case if start_SSL is called with a normal IO::Socket::INET
988             # so that PeerAddr|PeerPort are not set from args
989             # returns PeerAddr
990             sub _update_peer {
991 98     98   185 my $self = shift;
992 98         179 my $arg_hash = ${*$self}{'_SSL_arguments'};
  98         260  
993 98         271 eval {
994 98         776 my $sockaddr = getpeername( $self );
995 98         601 my $af = sockaddr_family($sockaddr);
996 95 50       278 if( CAN_IPV6 && $af == AF_INET6 ) {
997 0         0 my (undef, $host, $port) = _getnameinfo($sockaddr,
998             NI_NUMERICHOST | NI_NUMERICSERV);
999 0         0 $arg_hash->{PeerPort} = $port;
1000 0         0 $arg_hash->{PeerAddr} = $host;
1001             } else {
1002 95         1366 my ($port,$addr) = sockaddr_in( $sockaddr);
1003 95         1548 $arg_hash->{PeerPort} = $port;
1004 95         807 $arg_hash->{PeerAddr} = inet_ntoa( $addr );
1005             }
1006             }
1007             }
1008              
1009             #Call to accept occurs when a new client connects to a server using
1010             #IO::Socket::SSL
1011             sub accept {
1012 67   50 67 1 130705 my $self = shift || return _invalid_object();
1013 67   50     2607 my $class = shift || 'IO::Socket::SSL';
1014              
1015 67         409 my $socket = ${*$self}{'_SSL_opening'};
  67         1861  
1016 67 50       909 if ( ! $socket ) {
1017             # underlying socket not done
1018 67 50       763 $DEBUG>=2 && DEBUG('no socket yet' );
1019 67   50     2508 $socket = $self->SUPER::accept($class) || return;
1020 67 50       1330711 $DEBUG>=2 && DEBUG('accept created normal socket '.$socket );
1021              
1022             # don't continue with accept_SSL if SSL_startHandshake is set to 0
1023 67         284 my $sh = ${*$self}{_SSL_arguments}{SSL_startHandshake};
  67         607  
1024 67 100 66     714 if (defined $sh && ! $sh) {
1025 19         109 $socket = _setup_accepted_socket($self,$socket);
1026 19 50       67 $DEBUG>=2 && DEBUG('will not start SSL handshake yet');
1027 19 50       93 return wantarray ? ($socket, getpeername($socket) ) : $socket
1028             }
1029             }
1030              
1031 48 100       610 $self->accept_SSL($socket) || return;
1032 44 50       160 $DEBUG>=2 && DEBUG('accept_SSL ok' );
1033              
1034 44 100       306 return wantarray ? ($socket, getpeername($socket) ) : $socket;
1035             }
1036              
1037             sub _setup_accepted_socket {
1038 67     67   255 my ($self,$socket) = @_;
1039 67         136 my $args = ${*$self}{_SSL_arguments};
  67         255  
1040 67         156 my $biosock = ${*$self}{_SSL_bio_socket};
  67         282  
1041 67   33     1408 my $usebio = $biosock || $args->{SSL_usebio};
1042 67 50 0     332 if ($socket != $self) {
    0          
1043 67 50       382 $socket = _bio_wrap_socket(blessed($self), $biosock = $socket) if $usebio;
1044 67         151 ${*$socket}{_SSL_ctx} = ${*$self}{_SSL_ctx};
  67         297  
  67         226  
1045 67         3693 ${*$socket}{_SSL_arguments} = { %$args, SSL_server => 0 };
  67         401  
1046             } elsif ($usebio && !$biosock) {
1047 0         0 die "cannot upgrade socket in-place with SSL BIO"
1048             }
1049 67         327 return $socket;
1050             }
1051              
1052             sub accept_SSL {
1053 137     137 1 10228593 my $self = shift;
1054 137 100 100     1734 my $socket = ( @_ && UNIVERSAL::isa( $_[0], 'IO::Handle' )) ? shift : $self;
1055 137 100 50     1779 my $args = @_>1 ? {@_}: $_[0]||{};
1056              
1057 137         840 my $ssl;
1058 137 100       688 if ( ! ${*$self}{'_SSL_opening'} ) {
  137         824  
1059 134 50       596 $DEBUG>=2 && DEBUG('starting sslifying' );
1060 134 100       727 $socket = _setup_accepted_socket($self,$socket) if $socket != $self;
1061 134         268 ${*$self}{'_SSL_opening'} = $socket;
  134         900  
1062              
1063 134         778 $ssl = ${*$socket}{_SSL_object} =
1064             Net::SSLeay::new(${*$socket}{_SSL_ctx}{context})
1065 134   50     305 || return $socket->error("SSL structure creation failed");
1066 134 50       527 $CREATED_IN_THIS_THREAD{$ssl} = 1 if $use_threads;
1067 134         1023 $SSL_OBJECT{$ssl} = [$socket,1];
1068 134         484 weaken($SSL_OBJECT{$ssl}[0]);
1069              
1070 134         930 my $fileno = ${*$socket}{_SSL_fileno} = fileno($socket);
  134         616  
1071 134 100       517 if (${*$socket}{_SSL_bio_socket}) {
  134         527  
1072 3         13 _bio_attach($socket);
1073             } else {
1074 131 50       508 return $socket->_internal_error("Socket has no fileno",9)
1075             if ! defined $fileno;
1076 131 50       3061 Net::SSLeay::set_fd($ssl, $fileno)
1077             || return $socket->error("SSL filehandle association failed");
1078             }
1079              
1080 134 50 33     1286 set_msg_callback($self) if $DEBUG>=2 || ${*$self}{_SSL_msg_callback};
  134         867  
1081             }
1082              
1083 137   66     600 $ssl ||= ${*$socket}{_SSL_object};
  3         15  
1084 137         257 my $dobio = ${*$socket}{_SSL_bio_sub};
  137         575  
1085              
1086 137         1318 $SSL_ERROR = $! = undef;
1087             #$DEBUG>=2 && DEBUG('calling ssleay::accept' );
1088              
1089             my $timeout = exists $args->{Timeout}
1090             ? $args->{Timeout}
1091 137 100       591 : ${*$self}{io_socket_timeout}; # from IO::Socket
  128         368  
1092 137 100 66     1121 if ( defined($timeout) && $timeout>0 && $socket->blocking(0) ) {
      66        
1093             # timeout was given and socket was blocking
1094             # enforce timeout with now non-blocking socket
1095             } else {
1096             # timeout does not apply because invalid or socket non-blocking
1097 123         227 $timeout = undef;
1098 123 50       957 $auto_retry && $auto_retry->($ssl,$socket->blocking);
1099             }
1100              
1101 137   66     972 my $start = defined($timeout) && time();
1102             {
1103 137         260 retry_after_dobio:
  162         347  
1104             $SSL_ERROR = undef;
1105 162         625 $CURRENT_SSL_OBJECT = $self;
1106 162         6438945 my $rv = Net::SSLeay::accept($ssl);
1107 162         1020 $CURRENT_SSL_OBJECT = undef;
1108 162 50       878 $DEBUG>=3 && DEBUG( "Net::SSLeay::accept -> $rv" );
1109 162 100       982 if ( $rv < 0 ) {
    50          
1110 46         429 my $err = $socket->_skip_rw_error( $ssl,$rv );
1111 46 100 100     669 if (!$err && $dobio) {
1112 9 50       32 goto retry_after_dobio if $dobio->($self,
1113             $SSL_ERROR == SSL_WANT_READ,
1114             $SSL_ERROR == SSL_WANT_WRITE,
1115             \$err);
1116             }
1117 37 100       143 if ($err) {
1118 17         219 $socket->error("SSL accept attempt failed");
1119 17         28 delete ${*$self}{'_SSL_opening'};
  17         55  
1120 17         36 ${*$socket}{'_SSL_opened'} = -1;
  17         47  
1121 17         140 return $socket->fatal_ssl_error();
1122             }
1123              
1124             # accept failed because handshake needs to be completed
1125             # if socket was non-blocking or no timeout was given return with this error
1126 20 100       72 return if ! defined($timeout);
1127              
1128             # wait until socket is readable or writable
1129 17         33 my $rv;
1130 17 50       58 if ( $timeout>0 ) {
1131 17         137 my $vec = '';
1132 17         101 vec($vec,$socket->fileno,1) = 1;
1133 17 0       5041791 $rv =
    50          
1134             $SSL_ERROR == SSL_WANT_READ ? select( $vec,undef,undef,$timeout) :
1135             $SSL_ERROR == SSL_WANT_WRITE ? select( undef,$vec,undef,$timeout) :
1136             undef;
1137             } else {
1138 0         0 $! = ETIMEDOUT
1139             }
1140 17 100       131 if ( ! $rv ) {
1141             # failed because of timeout, return
1142 1   50     34 $! ||= ETIMEDOUT;
1143 1         4 delete ${*$self}{'_SSL_opening'};
  1         14  
1144 1         4 ${*$socket}{'_SSL_opened'} = -1;
  1         31  
1145 1         24 $socket->blocking(1); # was blocking before
1146             return
1147 1         35 }
1148              
1149             # socket is ready, try non-blocking accept again after recomputing timeout
1150 16         58 my $now = time();
1151 16         41 $timeout -= $now - $start;
1152 16         25 $start = $now;
1153 16         63 redo;
1154              
1155             } elsif ( $rv == 0 ) {
1156 0         0 $socket->error("SSL accept attempt failed because of handshake problems" );
1157 0         0 delete ${*$self}{'_SSL_opening'};
  0         0  
1158 0         0 ${*$socket}{'_SSL_opened'} = -1;
  0         0  
1159 0         0 return $socket->fatal_ssl_error();
1160             }
1161             }
1162              
1163 116 50       507 $DEBUG>=2 && DEBUG('handshake done, socket ready' );
1164             # socket opened
1165 116         243 delete ${*$self}{'_SSL_opening'};
  116         1081  
1166 116         362 ${*$socket}{'_SSL_opened'} = 1;
  116         567  
1167 116 100       468 if (defined($timeout)) {
1168 12         211 $socket->blocking(1); # reset back to blocking
1169 12         238 $! = undef; # reset errors from non-blocking
1170             }
1171              
1172 116         286 tie *{$socket}, "IO::Socket::SSL::SSL_HANDLE", $socket;
  116         2268  
1173              
1174 116         682 return $socket;
1175             }
1176              
1177             sub _bio_wrap_socket {
1178 6     6   16 my ($class,$upper_socket) = @_;
1179 6         87 my $self = bless gensym(),$class;
1180 6         484 ${*$self}{_SSL_bio_socket} = $upper_socket;
  6         106  
1181 6         29 return $self;
1182             }
1183              
1184             sub _bio_attach {
1185 6     6   9 my $self = shift;
1186 6 50       11 my $ssl = ${*$self}{_SSL_object} or die "no SSL object for BIO attach";
  6         24  
1187              
1188 6         72 my $rbio = Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem());
1189 6         22 my $wbio = Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem());
1190 6         29 Net::SSLeay::set_bio($ssl, $rbio, $wbio);
1191 6         116 my $wbuf = ''; # BIO_read(wbio) but not syswrite yet
1192 6         15 my $rbuf = ''; # collect full TLS record before BIO_write($rbio)
1193              
1194 6         124 ${*$self}{_SSL_bio_sub} = sub {
1195 61     61   155 my ($self,$read,$write,$r_err) = @_;
1196 61 50       79 my $biosock = ${*$self}{_SSL_bio_socket} or die "no BIO socket";
  61         210  
1197 61         104 my $rv = 0;
1198              
1199 61   66     373 while ($wbuf ne '' or Net::SSLeay::BIO_pending($wbio)>0) {
1200 21 50       54 if ($wbuf eq '') {
1201 21         521 my $buf = Net::SSLeay::BIO_read($wbio);
1202 21 50 33     126 if (!defined $buf or $buf eq '') {
1203 0         0 last; # nothing new to write
1204             } else {
1205 21         50 $wbuf .= $buf;
1206             }
1207             }
1208 21         1053 my $n = syswrite($biosock,$wbuf);
1209 21 50       88 if ($n) {
    0          
1210 21         44 substr($wbuf,0,$n,'');
1211 21   100     110 $rv += $write || 0;
1212 21         142 $write = 0; # count only once but continue to flush wbuf
1213             } elsif (!defined $n) {
1214 0 0 0     0 goto socket_error if !$!{EAGAIN} && !$!{EWOULDBLOCK};
1215 0         0 last;
1216             } else {
1217             # should not return 0 with non-empty wbuf, treat as error
1218 0         0 goto socket_error;
1219             }
1220             }
1221              
1222             # $read should only be requested on SSL_WANT_READ. It will only feed a
1223             # single and complete TLS record into the BIO since it is unknown if
1224             # more data are actually wanted by the TLS layer
1225              
1226             {
1227 61 100       85 $read or last;
  61         124  
1228              
1229             # read (remaining part of) single TLS record
1230 45         219 my $need = 5-length($rbuf); # TLS record start
1231 45         62 my $n;
1232 45         96 while ($need>0) {
1233 45         2085732 $n = sysread($biosock,$rbuf,$need,length($rbuf));
1234 45 50       211 goto full_read_failed if !$n;
1235 45         118 $need -= $n;
1236             }
1237 45         168 $need = unpack("x3n", $rbuf); # extract length of record
1238 45         120 while ($need>0) {
1239 45         342 $n = sysread($biosock,$rbuf,$need,length($rbuf));
1240 45 50       123 goto full_read_failed if !$n;
1241 45         149 $need -= $n;
1242             }
1243             # full TLS record read -> send to BIO
1244 45 50       282 Net::SSLeay::BIO_write($rbio,$rbuf)>0 or die "BIO_write failed";
1245 45         107 $rbuf = '';
1246 45         74 $rv += $read;
1247 45         83 last;
1248              
1249             full_read_failed: # $n == 0|undef
1250 0 0 0     0 if (defined $n) { # $n==0
    0          
1251             # signal EOF
1252             # XXX not available in Net::SSLeay, propagate via r_err
1253             # Net::SSLeay::BIO_set_mem_eof_return($rbio, 0);
1254 0         0 $$r_err = $Net_SSLeay_ERROR_SSL;
1255             } elsif ($!{EAGAIN} || $!{EWOULDBLOCK}) {
1256             # retry later
1257             } else {
1258 0         0 goto socket_error; # fatal
1259             }
1260             }
1261 61         1038 return $rv;
1262              
1263 0         0 socket_error:
1264             # unavailable - Net::SSLeay::BIO_set_mem_eof_return($rbio, 0);
1265             $$r_err = $Net_SSLeay_ERROR_SSL;
1266 0 0       0 $DEBUG>=2 && DEBUG("biosock error: $!" );
1267 0         0 return;
1268 6         189 };
1269             }
1270              
1271              
1272             # support user defined message callback but also internal debugging
1273             sub _msg_callback {
1274             ## my ($direction, $ssl_ver, $content_type, $buf, $len, $ssl, $userp) = @_;
1275 0 0   0   0 IO::Socket::SSL::Trace::ossl_trace(@_) if $DEBUG>=2;
1276 0   0     0 my $self = ($SSL_OBJECT{$_[5]} || return)->[0] || return;
1277 0 0       0 if (my $cb = ${*$self}{_SSL_msg_callback}) {
  0         0  
1278 0         0 my ($sub,@arg) = @$cb;
1279 0         0 $sub->($self, @_[0..5], @arg);
1280             }
1281             }
1282              
1283             my $ssleay_set_msg_callback = defined &Net::SSLeay::set_msg_callback
1284             && \&Net::SSLeay::set_msg_callback;
1285              
1286             sub set_msg_callback {
1287 0     0 1 0 my $self = shift;
1288 0 0       0 if (@_) {
1289 0 0       0 if ($_[0]) {
1290             # enable user defined callback: ($cb,@arg)
1291 0 0       0 die "no support for msg callback with this version of Net::SSLeay/OpenSSL"
1292             if !$ssleay_set_msg_callback;
1293 0         0 ${*$self}{_SSL_msg_callback} = [@_];
  0         0  
1294             } else {
1295             # disable user defined callback
1296 0         0 delete ${*$self}{_SSL_msg_callback};
  0         0  
1297             }
1298             }
1299              
1300             # activate user set callback and/or internal for debugging
1301 0 0 0     0 if ($ssleay_set_msg_callback and my $ssl = ${*$self}{_SSL_object}) {
  0         0  
1302             $ssleay_set_msg_callback->($ssl,
1303 0 0 0     0 ($DEBUG>=2 || ${*$self}{_SSL_msg_callback})? \&_msg_callback : undef)
1304             }
1305             }
1306              
1307              
1308             ####### I/O subroutines ########################
1309              
1310             sub blocking {
1311 719     719 1 1634 my $self = shift;
1312 719 100 100     1131 { @_ && $auto_retry && $auto_retry->(${*$self}{_SSL_object} || last, @_); }
  719   66     3425  
1313 719 100       1215 if (my $biosock = ${*$self}{_SSL_bio_socket}) {
  719         2579  
1314 17         143 return $biosock->blocking(@_);
1315             } else {
1316 702         6395 return $self->SUPER::blocking(@_);
1317             }
1318             }
1319              
1320             sub _generic_read {
1321 6261     6261   11244 my ($self, $ssl, $justpeek, $read_func, undef, $length, $offset) = @_;
1322 6261         8267 my $buffer = \$_[4];
1323              
1324 6261         8012 my ($data,$dobio);
1325 6261         7334 while (1) {
1326 6277         13481 $SSL_ERROR = $! = undef;
1327 6277         4979821 ($data, my $err) = $read_func->($ssl, $length);
1328 6277 100       61676 last if defined $data; # read success
1329              
1330 42 50       449 $err = $self->_skip_rw_error($ssl, defined($err) ? $err:-1);
1331 42 100       216 if (!$err) {
1332 18 100 100     45 $dobio = ${*$self}{_SSL_bio_sub} || 0 if !defined $dobio;
1333 18 100       46 if ($dobio) {
1334             # retry after successfully reading from underlying fd on BIO
1335 16 50       40 redo if $dobio->($self, 1, $SSL_ERROR == SSL_WANT_WRITE, \$err);
1336             }
1337 2 50       11 return if !$err; # see $SSL_ERROR/$! for details of rw-error
1338             }
1339              
1340             # OpenSSL 1.1.0c+ : EOF can now result in SSL_read returning -1 and SSL_ERROR_SYSCALL
1341             # OpenSSL 3.0 : EOF can now result in SSL_read returning -1 and SSL_ERROR_SSL
1342 24 50 33     278 if (not $! and $err == $Net_SSLeay_ERROR_SSL || $err == $Net_SSLeay_ERROR_SYSCALL) {
      66        
1343             # treat as EOF
1344 8         23 $data = '';
1345             # clear the "unexpected eof while reading" error (OpenSSL 3.0+)
1346 8         78 Net::SSLeay::ERR_clear_error();
1347 8         18 last;
1348             }
1349              
1350 16         93 $self->error("SSL read error"); # generic not recoverable error
1351 16         53 return;
1352             }
1353              
1354 6243 100       11801 $$buffer = '' if !defined $$buffer;
1355 6243   100     18937 $offset ||= 0;
1356 6243 100       9704 if ($offset>length($$buffer)) {
1357 1         6 $$buffer.="\0" x ($offset-length($$buffer)); #mimic behavior of read
1358             }
1359              
1360 6243         7639 $length = length($data);
1361 6243 100 100     9807 if (!$length && !$justpeek) {
1362 14         120 my $status = Net::SSLeay::get_shutdown($ssl);
1363 14 100       82 if ($status & SSL_RECEIVED_SHUTDOWN) {
1364 7 100       44 if ($status & SSL_SENT_SHUTDOWN) {
    100          
1365             # fully done, close SSL object - no need to call shutdown again
1366 3         33 $self->stop_SSL(SSL_no_shutdown => 1);
1367 4         66 } elsif (my $cb = ${*$self}{_SSL_arguments}{SSL_on_peer_shutdown}) {
1368             # Mark as half done but leave further handling to callback
1369 1         29 ${*$self}{_SSL_read_closed} = 1;
  1         6  
1370 1         21 return $cb->($self);
1371             } else {
1372             # Half done, send also close notify
1373             # Don't destruct _SSL_object since code might still rely on
1374             # having access to it. Leave this to explicit stop_SSL or close.
1375 3         88 local $SIG{PIPE} = 'IGNORE';
1376 3         21 $SSL_ERROR = $! = undef;
1377 3         282 Net::SSLeay::shutdown($ssl);
1378 3 100       20 $dobio->($self,0,0,\(my $err)) if $dobio; # flush write
1379             # Use "-1" to mark as automatic closed and thus require action
1380             # before reading/sending plain data
1381 3         9 ${*$self}{_SSL_read_closed} = ${*$self}{_SSL_write_closed} = -1;
  3         40  
  3         24  
1382             }
1383             }
1384 13         156 return 0;
1385             }
1386              
1387 6229         9584 substr($$buffer, $offset, length($$buffer), $data);
1388 6229         22874 return $length;
1389             }
1390              
1391             # This is only needed in case of a one sided SSL shutdown, i.e. if the fd is
1392             # still tied and has SSL_object, but needs to read or write in plain in one
1393             # direction. Here it will fdopen the SSL fd, thus loosing the class and tie.
1394             sub _rawfd {
1395 2     2   4 my $self = shift;
1396             return ${*$self}{_SSL_bio_socket}
1397 2   33     3 || (${*$self}{_SSL_rawfd} ||= do { open(my $fh,'+<&=',$self); $fh });
1398             }
1399              
1400             # peek to check if a non-SSL read would lead to more data
1401             # This is used with incomplete SSL_shutdown initiated by peer, so that one can
1402             # return EOF but not plain data until stop_SSL is locally called too
1403             sub _handle_read_closed_unack {
1404 3     3   10 my ($self,$rc) = @_;
1405             # reading eof is fine, reading plain data is not
1406 3         8 my ($buf,$rv);
1407 3         7 my $biosock = ${*$self}{_SSL_bio_socket};
  3         12  
1408 3 50 66     100 if ($biosock and UNIVERSAL::can($biosock,'peek')) {
1409             # upper IO::Socket::SSL?
1410 0         0 $rv = $biosock->peek($buf,1);
1411             } else {
1412 3   66     78 $rv = recv($biosock || $self, $buf,1,MSG_PEEK);
1413             }
1414 3 50       13 return if ! defined $rv;
1415 3 100       12 return 0 if $buf eq '';
1416 2         7 $! = EPERM;
1417 2         16 return;
1418             }
1419              
1420             sub read {
1421 6     6 0 28 my $self = shift;
1422 6   50     9 my $rc = ${*$self}{_SSL_read_closed} || 0;
1423 6 50 33     22 if (my $ssl = !$rc && ${*$self}{_SSL_object}) {
1424 6 100       20 return _generic_read($self, $ssl, 0,
1425             $self->blocking ? \&Net::SSLeay::ssl_read_all : \&Net::SSLeay::read,
1426             @_);
1427             }
1428              
1429 0 0       0 return _handle_read_closed_unack($self) if $rc<0;
1430              
1431             # fall back to plain read if we are not required to use SSL yet
1432 0 0       0 if (my $biosock = ${*$self}{_SSL_bio_socket}) {
  0         0  
1433 0         0 return $biosock->read(@_);
1434             } else {
1435 0 0       0 return ($rc ? _rawfd($self) : $self)->SUPER::read(@_);
1436             }
1437             }
1438              
1439             # contrary to the behavior of read sysread can read partial data
1440             sub sysread {
1441 6170     6170 1 8071 my $self = shift;
1442 6170   100     7349 my $rc = ${*$self}{_SSL_read_closed} || 0;
1443 6170 100 100     10830 if (my $ssl = !$rc && ${*$self}{_SSL_object}) {
1444 6167         11779 return _generic_read( $self, $ssl, 0, \&Net::SSLeay::read, @_ );
1445             }
1446              
1447 3 100       42 return _handle_read_closed_unack($self) if $rc<0;
1448              
1449             # fall back to plain sysread if we are not required to use SSL yet
1450 1 50       2 if (my $biosock = ${*$self}{_SSL_bio_socket}) {
  1         5  
1451 1         24 return $biosock->sysread(@_);
1452             } else {
1453 0 0       0 return ($rc ? _rawfd($self) : $self)->SUPER::sysread(@_);
1454             }
1455             }
1456              
1457             sub peek {
1458 94     94 1 8543 my $self = shift;
1459 94   100     163 my $rc = ${*$self}{_SSL_read_closed} || 0;
1460 94 100 100     428 if (my $ssl = !$rc && ${*$self}{_SSL_object}) {
1461 88         645 return _generic_read( $self, $ssl, 1, \&Net::SSLeay::peek, @_ );
1462             }
1463              
1464 6 100       27 return _handle_read_closed_unack($self) if $rc<0;
1465              
1466             # fall back to plain peek if we are not required to use SSL yet
1467 5         56 my $fd = ${*$self}{_SSL_bio_socket};
  5         21  
1468 5 50 33     46 return $fd->peek(@_) if $fd && UNIVERSAL::can($fd,'peek');
1469 5   33     57 $fd ||= $self;
1470             # emulate peek with recv(...,MSG_PEEK) - peek(buf,len,offset)
1471 5 50       119 return if ! defined recv($fd,my $buf,$_[1],MSG_PEEK);
1472 5 50       70 $_[0] = $_[2] ? substr($_[0],0,$_[2]).$buf : $buf;
1473 5         20 return length($buf);
1474             }
1475              
1476              
1477             sub _generic_write {
1478 9617     9617   16765 my ($self, $ssl, $write_all, undef, $length, $offset) = @_;
1479 9617         12258 my $buffer = \$_[3];
1480              
1481 9617         10933 my $buf_len = length($$buffer);
1482 9617   66     14121 $length ||= $buf_len;
1483 9617   100     24987 $offset ||= 0;
1484 9617 50       13546 return $self->_internal_error("Invalid offset for SSL write",9)
1485             if $offset>$buf_len;
1486 9617 50       13252 return 0 if ($offset == $buf_len);
1487              
1488 9617         9644 my $written;
1489 9617         19578 retry_after_dobio:
1490             $SSL_ERROR = $! = undef;
1491 9617 100       12671 if ( $write_all ) {
1492 63 50       232 my $data = $length < $buf_len-$offset ? substr($$buffer, $offset, $length) : $$buffer;
1493 63         3297 ($written, my $errs) = Net::SSLeay::ssl_write_all($ssl, $data);
1494             # ssl_write_all returns number of bytes written
1495 63 50 33     39701 $written = undef if ! $written && $errs;
1496             } else {
1497 9554         137515 $written = Net::SSLeay::write_partial( $ssl,$offset,$length,$$buffer );
1498             # write_partial does SSL_write which returns -1 on error
1499 9554 100       19239 $written = undef if $written <= 0;
1500             }
1501 9617 100       14604 if ( !defined($written) ) {
1502 4 100       27 if ( my $err = $self->_skip_rw_error( $ssl,-1 )) {
1503             # if $! is not set with ERROR_SYSCALL then report as EPIPE
1504 2 50 50     38 $! ||= EPIPE if $err == $Net_SSLeay_ERROR_SYSCALL;
1505 2         68 $self->error("SSL write error ($err)");
1506             }
1507             }
1508              
1509 9617 100       11467 if (my $dobio = ${*$self}{_SSL_bio_sub}) {
  9617         25746  
1510             # write new data to underlying BIO, retry a both written is undef and
1511             # now BIO was successfully read or written (dobio returns 2)
1512 7   50     28 my $wr = !defined($written) && ($SSL_ERROR == SSL_WANT_READ) && 2;
1513 7         15 my $err;
1514             goto retry_after_dobio if
1515 7 50       69 $dobio->($self,$wr,!defined($written) ? 2:1,\$err) >=2;
    50          
1516 7 50       25 if ($err) {
1517             # error handling similar to above with !defined $written
1518 0   0     0 $! ||= EPIPE;
1519 0         0 $self->error("SSL write error ($err)");
1520             }
1521             }
1522 9617         27426 return $written;
1523             }
1524              
1525             # if socket is blocking write() should return only on error or
1526             # if all data are written
1527             sub write {
1528 64     64 1 260 my $self = shift;
1529 64   50     123 my $wc = ${*$self}{_SSL_write_closed} || 0;
1530 64 50 33     284 if (my $ssl = !$wc && ${*$self}{_SSL_object}) {
1531 64         280 return _generic_write( $self, $ssl, scalar($self->blocking),@_ );
1532             }
1533              
1534             # don't write plain after automtic SSL shutdown
1535 0 0       0 if ($wc<0) {
1536 0         0 $! = EPERM;
1537 0         0 return;
1538             }
1539              
1540             # fall back to plain write if we are not required to use SSL yet
1541 0 0       0 if (my $biosock = ${*$self}{_SSL_bio_socket}) {
  0         0  
1542 0         0 return $biosock->write(@_);
1543             } else {
1544 0 0       0 return ($wc ? _rawfd($self) : $self)->SUPER::write(@_);
1545             }
1546             }
1547              
1548             # contrary to write syswrite() returns already if only
1549             # a part of the data is written
1550             sub syswrite {
1551 9559     9559 1 11771 my $self = shift;
1552 9559   100     9767 my $wc = ${*$self}{_SSL_write_closed} || 0;
1553 9559 100 100     15882 if (my $ssl = !$wc && ${*$self}{_SSL_object}) {
1554 9553         14528 return _generic_write($self,$ssl,0,@_);
1555             }
1556              
1557             # don't write plain after automtic SSL shutdown
1558 6 100       43 if ($wc<0) {
1559 2         7 $! = EPERM;
1560 2         10 return;
1561             }
1562              
1563             # fall back to plain syswrite if we are not required to use SSL yet
1564 4 100       10 if (my $biosock = ${*$self}{_SSL_bio_socket}) {
  4         26  
1565 2         40 return $biosock->syswrite(@_);
1566             } else {
1567 2 50       23 return ($wc ? _rawfd($self) : $self)->SUPER::syswrite(@_);
1568             }
1569             }
1570              
1571             sub print {
1572 61     61 0 302579 my $self = shift;
1573 61   50     1051 my $string = join(($, or ''), @_, ($\ or ''));
      50        
1574 61         428 return $self->write( $string );
1575             }
1576              
1577             sub printf {
1578 2     2 0 11 my ($self,$format) = (shift,shift);
1579 2         48 return $self->write(sprintf($format, @_));
1580             }
1581              
1582             sub getc {
1583 2     2 0 738 my ($self, $buffer) = (shift, undef);
1584 2 50       11 return $buffer if $self->read($buffer, 1, 0);
1585             }
1586              
1587             sub readline {
1588 92     92 0 197 my $self = shift;
1589 92 50       144 ${*$self}{_SSL_object} or return $self->SUPER::getline;
  92         483  
1590              
1591 92 100 100     890 if ( not defined $/ or wantarray) {
1592             # read all and split
1593              
1594 7         60 my $buf = '';
1595 7         13 while (1) {
1596 14         81 my $rv = $self->sysread($buf,2**16,length($buf));
1597 14 50       78 if ( ! defined $rv ) {
    100          
1598 0 0       0 next if $! == EINTR; # retry
1599 0 0 0     0 last if $! == EWOULDBLOCK || $! == EAGAIN; # use everything so far
1600 0         0 return; # return error
1601             } elsif ( ! $rv ) {
1602             last
1603 7         22 }
1604             }
1605              
1606 7 100       80 if ( ! defined $/ ) {
    100          
    100          
1607 2         25 return $buf
1608             } elsif ( ref($/)) {
1609 1         1 my $size = ${$/};
  1         3  
1610 1 50       4 die "bad value in ref \$/: $size" unless $size>0;
1611 1         54 return $buf=~m{\G(.{1,$size})}g;
1612             } elsif ( $/ eq '' ) {
1613 1         28 return $buf =~m{\G(.*\n\n+|.+)}g;
1614             } else {
1615 3         439 return $buf =~m{\G(.*$/|.+)}g;
1616             }
1617             }
1618              
1619             # read only one line
1620 85 100       263 if ( ref($/) ) {
1621 1         2 my $size = ${$/};
  1         19  
1622             # read record of $size bytes
1623 1 50       7 die "bad value in ref \$/: $size" unless $size>0;
1624 1         16 my $buf = '';
1625 1         5 while ( $size>length($buf)) {
1626 1         67 my $rv = $self->sysread($buf,$size-length($buf),length($buf));
1627 1 50       11 if ( ! defined $rv ) {
    50          
1628 0 0       0 next if $! == EINTR; # retry
1629 0 0 0     0 last if $! == EWOULDBLOCK || $! == EAGAIN; # use everything so far
1630 0         0 return; # return error
1631             } elsif ( ! $rv ) {
1632             last
1633 0         0 }
1634             }
1635 1         8 return $buf;
1636             }
1637              
1638 84 100       579 my ($delim0,$delim1) = $/ eq '' ? ("\n\n","\n"):($/,'');
1639              
1640             # find first occurrence of $delim0 followed by as much as possible $delim1
1641 84         188 my $buf = '';
1642 84         238 my $eod = 0; # pointer into $buf after $delim0 $delim1*
1643 84 50       347 my $ssl = $self->_get_ssl_object or return;
1644 84         157 while (1) {
1645              
1646             # wait until we have more data or eof
1647              
1648             # use $self->peek to also fill ssl pending from BIO
1649 88         683 $self->peek(my $poke,1);
1650 88 100 100     723 if ( ! defined $poke or $poke eq '' ) {
1651 26 100       174 next if $! == EINTR;
1652             }
1653              
1654 87         170 my $skip = 0;
1655              
1656             # peek into available data w/o reading
1657             # use directly Net::SSLeay::{pending,peek} to only get what is inside
1658             # current SSL object
1659 87         416 my $pending = Net::SSLeay::pending($ssl);
1660 87 100 66     905 if ( $pending and
1661             ( my $pb = Net::SSLeay::peek( $ssl,$pending )) ne '' ) {
1662 62         194 $buf .= $pb
1663             } else {
1664 25 100       256 return $buf eq '' ? ():$buf;
1665             }
1666 62 50       197 if ( !$eod ) {
1667 62         164 my $pos = index( $buf,$delim0 );
1668 62 100       159 if ( $pos<0 ) {
1669 3         8 $skip = $pending
1670             } else {
1671 59         121 $eod = $pos + length($delim0); # pos after delim0
1672             }
1673             }
1674              
1675 62 100       150 if ( $eod ) {
1676 59 100       174 if ( $delim1 ne '' ) {
1677             # delim0 found, check for as much delim1 as possible
1678 1         4 while ( index( $buf,$delim1,$eod ) == $eod ) {
1679 2         4 $eod+= length($delim1);
1680             }
1681             }
1682 59         221 $skip = $pending - ( length($buf) - $eod );
1683             }
1684              
1685             # remove data from $self which I already have in buf
1686 62         272 while ( $skip>0 ) {
1687 62 50       316 if ($self->sysread(my $p,$skip,0)) {
1688 62         111 $skip -= length($p);
1689 62         174 next;
1690             }
1691 0 0       0 $! == EINTR or last;
1692             }
1693              
1694 62 50 66     502 if ( $eod and ( $delim1 eq '' or $eod < length($buf))) {
      100        
1695             # delim0 found and there can be no more delim1 pending
1696             last
1697 59         122 }
1698             }
1699 59         435 return substr($buf,0,$eod);
1700             }
1701              
1702             sub close {
1703 278   50 278 1 2695 my $self = shift || return _invalid_object();
1704 278 50       2967 my $close_args = (ref($_[0]) eq 'HASH') ? $_[0] : {@_};
1705              
1706 278 50       2476 return if ! $self->stop_SSL(
1707             SSL_fast_shutdown => 1,
1708             %$close_args,
1709             _SSL_ioclass_downgrade => 0,
1710             );
1711              
1712 278 100       2287 if ( ! $close_args->{_SSL_in_DESTROY} ) {
1713 67         134 my $biosock = ${*$self}{_SSL_bio_socket};
  67         210  
1714 67         322 _cleanup_ssl($self,\%all_my_conn_keys);
1715 67   66     1292 return ($biosock||$self)->SUPER::close;
1716             }
1717 211         612 return 1;
1718             }
1719              
1720             sub is_SSL {
1721 23     23 1 40454 my $self = pop;
1722 23 100       41 return if !${*$self}{_SSL_object};
  23         170  
1723 20         77 return (${*$self}{_SSL_read_closed} ? '':'r') .
1724 20 100       39 (${*$self}{_SSL_write_closed} ? '':'w');
  20 100       122  
1725             }
1726              
1727             sub stop_SSL {
1728 335   50 335 1 6850 my $self = shift || return _invalid_object();
1729 335 50       2848 my $stop_args = (ref($_[0]) eq 'HASH') ? $_[0] : {@_};
1730 335 100       887 $stop_args->{SSL_no_shutdown} = 1 if ! ${*$self}{_SSL_opened};
  335         1658  
1731 335         879 my $dobio = ${*$self}{_SSL_bio_sub};
  335         1256  
1732              
1733 335 100       819 if (my $ssl = ${*$self}{'_SSL_object'}) {
  335         1547  
1734 332 50       583 if (delete ${*$self}{'_SSL_opening'}) {
  332 100       1722  
1735             # just destroy the object further below
1736             } elsif ( ! $stop_args->{SSL_no_shutdown} ) {
1737 117         530 my $status = Net::SSLeay::get_shutdown($ssl);
1738              
1739             my $timeout =
1740             not($self->blocking) ? undef :
1741             exists $stop_args->{Timeout} ? $stop_args->{Timeout} :
1742 117 50       462 ${*$self}{io_socket_timeout}; # from IO::Socket
  110 100       5040  
1743 117 100       479 if ($timeout) {
1744 3         9 $self->blocking(0);
1745 3         31 $timeout += time();
1746             }
1747              
1748 117         340 while (1) {
1749 195 100 100     1390 if ( $status & SSL_SENT_SHUTDOWN and
      100        
1750             # don't care for received if fast shutdown
1751             $status & SSL_RECEIVED_SHUTDOWN
1752             || $stop_args->{SSL_fast_shutdown}) {
1753             # shutdown complete
1754 66         193 last;
1755             }
1756 129 100 50     288 if ((${*$self}{'_SSL_opened'}||0) <= 0) {
1757             # not really open, thus don't expect shutdown to return
1758             # something meaningful
1759 51         109 last;
1760             }
1761              
1762             # initiate or complete shutdown
1763 78         1841 local $SIG{PIPE} = 'IGNORE';
1764              
1765 80         305 retry_after_dobio:
1766             $SSL_ERROR = $! = undef;
1767 80         162224 my $rv = Net::SSLeay::shutdown($ssl);
1768 80 100       447 $dobio->($self,0,0,\(my $err)) if $dobio; # flush writes
1769 80 100       307 if ( $rv < 0 ) {
1770             # non-blocking socket?
1771 2 50       6 if ( ! $timeout ) {
1772 2         7 my $err = $self->_skip_rw_error( $ssl,$rv );
1773 2 50 33     10 if (!$err && $dobio) {
1774 2 50       8 goto retry_after_dobio if $dobio->($self,
1775             $SSL_ERROR == SSL_WANT_READ,
1776             $SSL_ERROR == SSL_WANT_WRITE,
1777             \$err);
1778             }
1779 0 0       0 if ($err) {
1780             # if $! is not set with ERROR_SYSCALL then report as EPIPE
1781 0 0 0     0 $! ||= EPIPE if $err == $Net_SSLeay_ERROR_SYSCALL;
1782 0         0 $self->error("SSL shutdown error ($err)");
1783             }
1784             # need to try again
1785 0         0 return;
1786             }
1787              
1788             # don't use _skip_rw_error so that existing error does
1789             # not get cleared
1790 0         0 my $wait = $timeout - time();
1791 0 0       0 last if $wait<=0;
1792 0         0 vec(my $vec = '',fileno($self),1) = 1;
1793 0         0 my $err = Net::SSLeay::get_error($ssl,$rv);
1794 0 0       0 if ( $err == $Net_SSLeay_ERROR_WANT_READ) {
    0          
1795 0         0 select($vec,undef,undef,$wait)
1796             } elsif ( $err == $Net_SSLeay_ERROR_WANT_WRITE) {
1797 0         0 select(undef,$vec,undef,$wait)
1798             } else {
1799 0 0       0 if ($err) {
1800             # if $! is not set with ERROR_SYSCALL then report as EPIPE
1801 0 0 0     0 $! ||= EPIPE if $err == $Net_SSLeay_ERROR_SYSCALL;
1802 0         0 $self->error("SSL shutdown error ($err)");
1803             }
1804 0         0 last;
1805             }
1806             }
1807              
1808 78         172 $status |= SSL_SENT_SHUTDOWN;
1809 78 100       878 $status |= SSL_RECEIVED_SHUTDOWN if $rv>0;
1810             }
1811 117 100       576 $self->blocking(1) if $timeout;
1812 117 100       473 if (not($status & SSL_RECEIVED_SHUTDOWN)) {
1813             # not yet fully closed, mark only write as closed
1814 76         435 ${*$self}{_SSL_write_closed} = 1;
  76         334  
1815 76         393 return $self;
1816             }
1817             }
1818             }
1819              
1820 259   66     625 my $original_socket = ${*$self}{_SSL_bio_socket} || $self;
1821              
1822             # FIXME this is fragile
1823             # FIXME There might still be data inside dobio.wbuf
1824 259         1462 _cleanup_ssl($self, \%all_my_conn_and_cert_keys, '_SSL_bio_socket');
1825 259 100 66     1219 if ($stop_args->{'SSL_ctx_free'} and
1826 2         14 my $ctx = delete ${*$self}{_SSL_ctx}) {
1827 2         33 $ctx->DESTROY();
1828             }
1829              
1830              
1831 259 100       874 if ( ! $stop_args->{_SSL_in_DESTROY} ) {
1832 48 100       183 my $downgrade = $dobio ? 0: $stop_args->{_SSL_ioclass_downgrade};
1833 48 100 66     467 if ( $downgrade || ! defined $downgrade ) {
1834             # rebless to original class from start_SSL
1835 31 100       58 if ( my $orig_class = delete ${*$self}{'_SSL_ioclass_upgraded'} ) {
  31         140  
1836 24         213 bless $self,$orig_class;
1837             # FIXME: if original class was tied too we need to restore the tie
1838             # remove all _SSL related from *$self
1839 24         52 my @sslkeys = grep { m{^_?SSL_} } keys %{*$self};
  160         696  
  24         139  
1840 24 50       99 _cleanup_ssl($self,{map { $_ => 1 } @sslkeys}) if @sslkeys;
  64         200  
1841             }
1842             }
1843             }
1844 259         1215 return $original_socket;
1845             }
1846              
1847             sub _cleanup_ssl {
1848 654     654   3544 my ($self,$keys,@except) = @_;
1849 654   100     3845 $keys ||= \%all_my_keys;
1850 654 100       1884 if (@except) {
1851 563         16621 $keys = { %$keys };
1852 563         4790 delete @{$keys}{@except};
  563         1727  
1853             }
1854              
1855             # if we have BIO socket we don't untie on removing _SSL_object but need to
1856             # untie later if we remove _SSL_bio_socket
1857 654         1432 my $untie;
1858 654 100       1171 if (${*$self}{_SSL_bio_socket}) {
  654         4435  
1859 14 100       86 $keys = { %$keys } if ! @except;
1860 14 100       94 if (!$keys->{_SSL_bio_socket}) {
1861             # if existing _SSL_bio_socket should not be deleted, then don't
1862             # delete _SSL_fileno either
1863 12         28 delete $keys->{_SSL_fileno};
1864             } else {
1865 2         9 $untie = 1; # deferred untie on BIO delete
1866 2         11 $keys->{_SSL_fileno} = 1; # deferred remove of _SSL_fileno
1867             }
1868             };
1869 654 100 100     3571 if ($keys->{_SSL_object} and my $ssl = ${*$self}{_SSL_object}) {
  630         2960  
1870 310         14125 Net::SSLeay::free($ssl);
1871 310         1139 delete $SSL_OBJECT{$ssl};
1872 310         1544 delete $CREATED_IN_THIS_THREAD{$ssl};
1873 310         746 $untie = 1;
1874             }
1875              
1876 654 100 100     3002 if ($keys->{_SSL_certificate} and
1877 563         2900 my $cert = delete ${*$self}{_SSL_certificate}) {
1878 34         663 Net::SSLeay::X509_free($cert);
1879             }
1880              
1881             # don't cleanup _SSL_ctx here, will only be explicitly done when stop_SSL is
1882             # used with SSL_ctx_free
1883              
1884 654         3426 delete @{*$self}{keys %$keys};
  654         2584  
1885 654 50       1569 ${*$self}{_SSL_opened} = 0 if exists ${*$self}{_SSL_opened};
  0         0  
  654         2016  
1886              
1887             # keep tied in case of kept BIO since we cannot IO on the untied filehandle
1888 654 100 100     4100 untie(*$self) if $untie && !${*$self}{_SSL_bio_socket};
  311         5647  
1889             }
1890              
1891              
1892              
1893             sub fileno {
1894 9705     9705 0 94614 my $self = shift;
1895 9705         11281 my $fn = ${*$self}{'_SSL_fileno'};
  9705         17924  
1896 9705 100       21939 return defined($fn) ? $fn : $self->SUPER::fileno();
1897             }
1898              
1899              
1900             ####### IO::Socket::SSL specific functions #######
1901             # get access to SSL handle for use with Net::SSLeay. Use with caution!
1902             sub _get_ssl_object {
1903 242     242   7815 my $self = shift;
1904 242   33     608 return ${*$self}{'_SSL_object'} ||
1905             IO::Socket::SSL->_internal_error("Undefined SSL object",9);
1906             }
1907              
1908             # get access to SSL handle for use with Net::SSLeay. Use with caution!
1909             sub _get_ctx_object {
1910 0     0   0 my $self = shift;
1911 0         0 my $ctx_object = ${*$self}{_SSL_ctx};
  0         0  
1912 0   0     0 return $ctx_object && $ctx_object->{context};
1913             }
1914              
1915             # default error for undefined arguments
1916             sub _invalid_object {
1917 0     0   0 return IO::Socket::SSL->_internal_error("Undefined IO::Socket::SSL object",9);
1918             }
1919              
1920              
1921             sub pending {
1922 1     1 1 2 my $self = shift;
1923 1   50     3 my $rv = Net::SSLeay::pending(${*$self}{_SSL_object} || return);
1924 1 50       2 if (my $outer = ${*$self}{_SSL_bio_socket}) {
  1         3  
1925 0 0       0 $rv += $outer->pending if UNIVERSAL::can($outer,'pending');
1926             }
1927 1         4 return $rv;
1928             }
1929              
1930             sub start_SSL {
1931 164     164 1 20994032 my ($class,$socket) = (shift,shift);
1932 164 50       2610 return $class->_internal_error("Not a socket",9) if ! ref($socket); # glob or object
1933 164 100       4001 my $arg_hash = @_ == 1 ? $_[0] : {@_};
1934 164 100       1955 my %to = exists $arg_hash->{Timeout} ? ( Timeout => delete $arg_hash->{Timeout} ) :();
1935 164         832 my $original_class = blessed($socket);
1936              
1937 164         845 my $usebio = $arg_hash->{SSL_usebio};
1938 164 50       4008 my $original_fileno = (UNIVERSAL::can($socket, "fileno"))
1939             ? $socket->fileno : CORE::fileno($socket);
1940 164 100 100     4349 return $class->_internal_error("Socket has no fileno",9)
1941             if !$usebio && ! defined $original_fileno;
1942              
1943 163 100       931 if ($usebio) {
1944 6         110 $socket = _bio_wrap_socket($class,$socket);
1945 6         30 $original_class = undef;
1946             } else {
1947 157         1106 bless $socket, $class;
1948             }
1949              
1950 163 50       2469 if (!$socket->configure_SSL($arg_hash)) {
1951 0 0       0 bless($socket, $original_class) if $original_class;
1952 0         0 return;
1953             }
1954              
1955 163         287 ${*$socket}{'_SSL_fileno'} = $original_fileno;
  163         547  
1956 163 100       508 ${*$socket}{'_SSL_ioclass_upgraded'} = $original_class
  162         585  
1957             if $class ne $original_class;
1958              
1959 163         454 my $start_handshake = $arg_hash->{SSL_startHandshake};
1960 163 100 66     682 if ( ! defined($start_handshake) || $start_handshake ) {
1961             # if we have no callback force blocking mode
1962 159 50       448 $DEBUG>=2 && DEBUG( "start handshake" );
1963 159         1677 my $was_blocking = $socket->blocking(1);
1964 159         2051 my $result = ${*$socket}{'_SSL_arguments'}{SSL_server}
1965 159 100       3893 ? $socket->accept_SSL(%to)
1966             : $socket->connect_SSL(%to);
1967 159 50       773 $socket->blocking(0) if ! $was_blocking;
1968 159 100       1003 if ( $result ) {
1969 123         1040 return $socket;
1970             } else {
1971             # upgrade to SSL failed, downgrade socket to original class
1972 36 50       316 bless($socket,$original_class) if $original_class;
1973 36         656 return;
1974             }
1975             } else {
1976 4 50       15 $DEBUG>=2 && DEBUG( "don't start handshake: $socket" );
1977 4         24 return $socket; # just return upgraded socket
1978             }
1979             }
1980              
1981             sub new_from_fd {
1982 1     1 1 856 my ($class, $fd) = (shift,shift);
1983             # Check for accidental inclusion of MODE in the argument list
1984 1 50       5 if (length($_[0]) < 4) {
1985 1         3 (my $mode = $_[0]) =~ tr/+<>//d;
1986 1 50       4 shift unless length($mode);
1987             }
1988 1   50     36 my $handle = $ISA[0]->new_from_fd($fd, '+<')
1989             || return($class->error("Could not create socket from file descriptor."));
1990              
1991             # Annoying workaround for Perl 5.6.1 and below:
1992 1         154 $handle = $ISA[0]->new_from_fd($handle, '+<');
1993              
1994 1         115 return $class->start_SSL($handle, @_);
1995             }
1996              
1997              
1998             sub dump_peer_certificate {
1999 1   50 1 1 7 my $ssl = shift()->_get_ssl_object || return;
2000 1         9 return Net::SSLeay::dump_peer_certificate($ssl);
2001             }
2002              
2003             if ( defined &Net::SSLeay::get_peer_cert_chain
2004             && $netssleay_version >= 1.58 ) {
2005             *peer_certificates = sub {
2006 0     0   0 my $self = shift;
2007 0   0     0 my $ssl = $self->_get_ssl_object || return;
2008 0         0 my @chain = Net::SSLeay::get_peer_cert_chain($ssl);
2009 0 0 0     0 @chain = () if @chain && !$self->peer_certificate; # work around #96013
2010 0 0       0 if ( ${*$self}{_SSL_arguments}{SSL_server} ) {
  0         0  
2011             # in the client case the chain contains the peer certificate,
2012             # in the server case not
2013             # this one has an increased reference counter, the other not
2014 0 0       0 if ( my $peer = Net::SSLeay::get_peer_certificate($ssl)) {
2015 0         0 Net::SSLeay::X509_free($peer);
2016 0         0 unshift @chain, $peer;
2017             }
2018             }
2019 0         0 return @chain;
2020              
2021             }
2022             } else {
2023             *peer_certificates = sub {
2024             die "peer_certificates needs Net::SSLeay>=1.58";
2025             }
2026             }
2027              
2028             {
2029             my %dispatcher = (
2030             issuer => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name( shift )) },
2031             subject => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name( shift )) },
2032             commonName => sub {
2033             my $cn = Net::SSLeay::X509_NAME_get_text_by_NID(
2034             Net::SSLeay::X509_get_subject_name( shift ), NID_CommonName);
2035             $cn;
2036             },
2037             subjectAltNames => sub { Net::SSLeay::X509_get_subjectAltNames( shift ) },
2038             );
2039              
2040             # alternative names
2041             $dispatcher{authority} = $dispatcher{issuer};
2042             $dispatcher{owner} = $dispatcher{subject};
2043             $dispatcher{cn} = $dispatcher{commonName};
2044              
2045             sub peer_certificate {
2046 79     79 1 2257 my ($self,$field,$reload) = @_;
2047 79 50       328 my $ssl = $self->_get_ssl_object or return;
2048              
2049 0         0 Net::SSLeay::X509_free(delete ${*$self}{_SSL_certificate})
2050 79 0 33     209 if $reload && ${*$self}{_SSL_certificate};
  0         0  
2051 79         785 my $cert = ${*$self}{_SSL_certificate}
2052 79 100 100     140 ||= Net::SSLeay::get_peer_certificate($ssl)
2053             or return $self->error("Could not retrieve peer certificate");
2054              
2055 77 100       207 if ($field) {
2056 17 50       92 my $sub = $dispatcher{$field} or croak
2057             "invalid argument for peer_certificate, valid are: ".join( " ",keys %dispatcher ).
2058             "\nMaybe you need to upgrade your Net::SSLeay";
2059 17         111 return $sub->($cert);
2060             } else {
2061 60         195 return $cert
2062             }
2063             }
2064              
2065             sub sock_certificate {
2066 6     6 1 140 my ($self,$field) = @_;
2067 6   50     20 my $ssl = $self->_get_ssl_object || return;
2068 6   50     16 my $cert = Net::SSLeay::get_certificate( $ssl ) || return;
2069 6 100       13 if ($field) {
2070 4 50       23 my $sub = $dispatcher{$field} or croak
2071             "invalid argument for sock_certificate, valid are: ".join( " ",keys %dispatcher ).
2072             "\nMaybe you need to upgrade your Net::SSLeay";
2073 4         33 return $sub->($cert);
2074             } else {
2075 2         24 return $cert
2076             }
2077             }
2078              
2079              
2080             # known schemes, possible attributes are:
2081             # - wildcards_in_alt (0, 'full_label', 'anywhere')
2082             # - wildcards_in_cn (0, 'full_label', 'anywhere')
2083             # - check_cn (0, 'always', 'when_only')
2084             # unfortunately there are a lot of different schemes used, see RFC 6125 for a
2085             # summary, which references all of the following except RFC4217/ftp
2086              
2087             my %scheme = (
2088             none => {}, # do not check
2089             # default set is a superset of all the others and thus worse than a more
2090             # specific set, but much better than not verifying name at all
2091             default => {
2092             wildcards_in_cn => 'anywhere',
2093             wildcards_in_alt => 'anywhere',
2094             check_cn => 'always',
2095             ip_in_cn => 1,
2096             },
2097             );
2098              
2099             for(qw(
2100             rfc2818
2101             rfc3920 xmpp
2102             rfc4217 ftp
2103             )) {
2104             $scheme{$_} = {
2105             wildcards_in_cn => 'anywhere',
2106             wildcards_in_alt => 'anywhere',
2107             check_cn => 'when_only',
2108             }
2109             }
2110              
2111             for(qw(www http)) {
2112             $scheme{$_} = {
2113             wildcards_in_cn => 'anywhere',
2114             wildcards_in_alt => 'anywhere',
2115             check_cn => 'when_only',
2116             ip_in_cn => 4,
2117             }
2118             }
2119              
2120             for(qw(
2121             rfc4513 ldap
2122             )) {
2123             $scheme{$_} = {
2124             wildcards_in_cn => 0,
2125             wildcards_in_alt => 'full_label',
2126             check_cn => 'always',
2127             };
2128             }
2129              
2130             for(qw(
2131             rfc2595 smtp
2132             rfc4642 imap pop3 acap
2133             rfc5539 nntp
2134             rfc5538 netconf
2135             rfc5425 syslog
2136             rfc5953 snmp
2137             )) {
2138             $scheme{$_} = {
2139             wildcards_in_cn => 'full_label',
2140             wildcards_in_alt => 'full_label',
2141             check_cn => 'always'
2142             };
2143             }
2144             for(qw(
2145             rfc5971 gist
2146             )) {
2147             $scheme{$_} = {
2148             wildcards_in_cn => 'full_label',
2149             wildcards_in_alt => 'full_label',
2150             check_cn => 'when_only',
2151             };
2152             }
2153              
2154             for(qw(
2155             rfc5922 sip
2156             )) {
2157             $scheme{$_} = {
2158             wildcards_in_cn => 0,
2159             wildcards_in_alt => 0,
2160             check_cn => 'always',
2161             };
2162             }
2163              
2164              
2165             # function to verify the hostname
2166             #
2167             # as every application protocol has its own rules to do this
2168             # we provide some default rules as well as a user-defined
2169             # callback
2170              
2171             sub verify_hostname_of_cert {
2172 209     209 0 723 my $identity = shift;
2173 209         319 my $cert = shift;
2174 209   100     1060 my $scheme = shift || 'default';
2175 209         349 my $publicsuffix = shift;
2176 209 50       540 if ( ! ref($scheme) ) {
2177 209 50       471 $DEBUG>=3 && DEBUG( "scheme=$scheme cert=$cert" );
2178 209   33     1159 $scheme = $scheme{$scheme} || croak("scheme $scheme not defined");
2179             }
2180              
2181 209 50       543 return 1 if ! %$scheme; # 'none'
2182 209         1426 $identity =~s{\.+$}{}; # ignore absolutism
2183              
2184             # get data from certificate
2185 209         922 my $commonName = $dispatcher{cn}->($cert);
2186 209         579 my @altNames = $dispatcher{subjectAltNames}->($cert);
2187 209 50       617 $DEBUG>=3 && DEBUG("identity=$identity cn=$commonName alt=@altNames" );
2188              
2189 209 50       817 if ( my $sub = $scheme->{callback} ) {
2190             # use custom callback
2191 0         0 return $sub->($identity,$commonName,@altNames);
2192             }
2193              
2194             # is the given hostname an IP address? Then we have to convert to network byte order [RFC791][RFC2460]
2195              
2196 209         345 my $ipn;
2197 209 100       1759 if ( CAN_IPV6 and $identity =~m{:} ) {
    100          
2198             # no IPv4 or hostname have ':' in it, try IPv6.
2199 12 100       38 $identity =~m{[^\da-fA-F:\.]} and return; # invalid characters in name
2200 9 50       38 $ipn = inet_pton(AF_INET6,$identity) or return; # invalid name
2201             } elsif ( my @ip = $identity =~m{^(\d+)(?:\.(\d+)\.(\d+)\.(\d+)|[\d\.]*)$} ) {
2202             # check for invalid IP/hostname
2203 55 100 66     372 return if 4 != @ip or 4 != grep { defined($_) && $_<256 } @ip;
  220 100       830  
2204 52         320 $ipn = pack("CCCC",@ip);
2205             } else {
2206             # assume hostname, check for umlauts etc
2207 142 100       548 if ( $identity =~m{[^a-zA-Z0-9_.\-]} ) {
2208 5 50       17 $identity =~m{\0} and return; # $identity has \\0 byte
2209 5 50       37 $identity = idn_to_ascii($identity)
2210             or return; # conversation to IDNA failed
2211 5 100       876 $identity =~m{[^a-zA-Z0-9_.\-]}
2212             and return; # still junk inside
2213             }
2214             }
2215              
2216             # do the actual verification
2217             my $check_name = sub {
2218 289     289   755 my ($name,$identity,$wtyp,$publicsuffix) = @_;
2219 289         847 $name =~s{\.+$}{}; # ignore absolutism
2220 289 100       628 $name eq '' and return;
2221 288   100     632 $wtyp ||= '';
2222 288         407 my $pattern;
2223             ### IMPORTANT!
2224             # We accept only a single wildcard and only for a single part of the FQDN
2225             # e.g. *.example.org does match www.example.org but not bla.www.example.org
2226             # The RFCs are in this regard unspecific but we don't want to have to
2227             # deal with certificates like *.com, *.co.uk or even *
2228             # see also http://nils.toedtmann.net/pub/subjectAltName.txt .
2229             # Also, we fall back to full_label matches if the identity is an IDNA
2230             # name, see RFC6125 and the discussion at
2231             # http://bugs.python.org/issue17997#msg194950
2232 288 100 100     1888 if ( $wtyp eq 'anywhere' and $name =~m{^([a-zA-Z0-9_\-]*)\*(.+)} ) {
    100 100        
2233 116 100 100     647 return if $1 ne '' and substr($identity,0,4) eq 'xn--'; # IDNA
2234 112         5715 $pattern = qr{^\Q$1\E[a-zA-Z0-9_\-]+\Q$2\E$}i;
2235             } elsif ( $wtyp =~ m{^(?:full_label|leftmost)$}
2236             and $name =~m{^\*(\..+)$} ) {
2237 26         459 $pattern = qr{^[a-zA-Z0-9_\-]+\Q$1\E$}i;
2238             } else {
2239 146         1170 return lc($identity) eq lc($name);
2240             }
2241 138 100       1217 if ( $identity =~ $pattern ) {
2242 56 50       1006 $publicsuffix = IO::Socket::SSL::PublicSuffix->default
2243             if ! defined $publicsuffix;
2244 56 50       215 return 1 if $publicsuffix eq '';
2245 56         300 my @labels = split( m{\.+}, $identity );
2246 56         268 my $tld = $publicsuffix->public_suffix(\@labels,+1);
2247 56 50       847 return 1 if @labels > ( $tld ? 0+@$tld : 1 );
    100          
2248             }
2249 97         449 return;
2250 201         2194 };
2251              
2252              
2253 201         384 my $alt_dnsNames = 0;
2254 201         514 while (@altNames) {
2255 347         928 my ($type, $name) = splice (@altNames, 0, 2);
2256 347 100 100     1570 if ( $ipn and $type == GEN_IPADD ) {
    100 100        
2257             # exact match needed for IP
2258             # $name is already packed format (inet_xton)
2259 53 100       771 return 1 if $ipn eq $name;
2260              
2261             } elsif ( ! $ipn and $type == GEN_DNS ) {
2262 201         485 $name =~s/\s+$//; $name =~s/^\s+//;
  201         465  
2263 201         327 $alt_dnsNames++;
2264 201 100       512 $check_name->($name,$identity,$scheme->{wildcards_in_alt},$publicsuffix)
2265             and return 1;
2266             }
2267             }
2268              
2269 117 100 66     701 if ( $scheme->{check_cn} eq 'always' or
      100        
2270             $scheme->{check_cn} eq 'when_only' and !$alt_dnsNames ) {
2271 103 100       210 if ( ! $ipn ) {
    50          
2272 88 100       188 $check_name->($commonName,$identity,$scheme->{wildcards_in_cn},$publicsuffix)
2273             and return 1;
2274             } elsif ( $scheme->{ip_in_cn} ) {
2275 15 100       29 if ( $identity eq $commonName ) {
2276             return 1 if
2277             $scheme->{ip_in_cn} == 4 ? length($ipn) == 4 :
2278 5 0       39 $scheme->{ip_in_cn} == 6 ? length($ipn) == 16 :
    50          
    100          
2279             1;
2280             }
2281             }
2282             }
2283              
2284 70         765 return 0; # no match
2285             }
2286             }
2287              
2288             sub verify_hostname {
2289 41     41 1 1396 my $self = shift;
2290 41         69 my $host = shift;
2291 41         125 my $cert = $self->peer_certificate;
2292 41         118 return verify_hostname_of_cert( $host,$cert,@_ );
2293             }
2294              
2295              
2296             sub get_servername {
2297 8     8 1 128 my $self = shift;
2298 8   33     16 return ${*$self}{_SSL_servername} ||= do {
  8         83  
2299 8 50       46 my $ssl = $self->_get_ssl_object or return;
2300 8         72 Net::SSLeay::get_servername($ssl);
2301             };
2302             }
2303              
2304             sub get_fingerprint_bin {
2305 21     21 1 51 my ($self,$algo,$cert,$key_only) = @_;
2306 21 50 66     152 $cert ||= $self->peer_certificate or return;
2307 21 100 50     163 return $key_only
      50        
2308             ? Net::SSLeay::X509_pubkey_digest($cert, $algo2digest->($algo || 'sha256'))
2309             : Net::SSLeay::X509_digest($cert, $algo2digest->($algo || 'sha256'));
2310             }
2311              
2312             sub get_fingerprint {
2313 21     21 1 255 my ($self,$algo,$cert,$key_only) = @_;
2314 21   100     147 $algo ||= 'sha256';
2315 21 50       75 my $fp = get_fingerprint_bin($self,$algo,$cert,$key_only) or return;
2316 21 100       306 return $algo.'$'.($key_only ? 'pub$':'').unpack('H*',$fp);
2317             }
2318              
2319             sub get_cipher {
2320 11   50 11 1 98 my $ssl = shift()->_get_ssl_object || return;
2321 11         52 return Net::SSLeay::get_cipher($ssl);
2322             }
2323              
2324             sub get_sslversion {
2325 34   50 34 1 781 my $ssl = shift()->_get_ssl_object || return;
2326 34 50       193 my $version = Net::SSLeay::version($ssl) or return;
2327             return
2328 34 0       458 $version == 0x0304 ? 'TLSv1_3' :
    0          
    0          
    50          
    100          
    100          
    100          
2329             $version == 0x0303 ? 'TLSv1_2' :
2330             $version == 0x0302 ? 'TLSv1_1' :
2331             $version == 0x0301 ? 'TLSv1' :
2332             $version == 0x0300 ? 'SSLv3' :
2333             $version == 0x0002 ? 'SSLv2' :
2334             $version == 0xfeff ? 'DTLS1' :
2335             undef;
2336             }
2337              
2338             sub get_sslversion_int {
2339 0   0 0 1 0 my $ssl = shift()->_get_ssl_object || return;
2340 0         0 return Net::SSLeay::version($ssl);
2341             }
2342              
2343             sub get_session_reused {
2344 3   50 3 1 42 return Net::SSLeay::session_reused(
2345             shift()->_get_ssl_object || return);
2346             }
2347              
2348             if ($can_ocsp) {
2349 89     89   1003 no warnings 'once';
  89         244  
  89         150842  
2350             *ocsp_resolver = sub {
2351 0     0   0 my $self = shift;
2352 0   0     0 my $ssl = $self->_get_ssl_object || return;
2353 0         0 my $ctx = ${*$self}{_SSL_ctx};
  0         0  
2354             return IO::Socket::SSL::OCSP_Resolver->new(
2355             $ssl,
2356             $ctx->{ocsp_cache} ||= IO::Socket::SSL::OCSP_Cache->new,
2357             $ctx->{ocsp_mode} & SSL_OCSP_FAIL_HARD,
2358             @_ ? \@_ :
2359 0 0 0     0 $ctx->{ocsp_mode} & SSL_OCSP_FULL_CHAIN ? [ $self->peer_certificates ]:
    0          
2360             [ $self->peer_certificate ]
2361             );
2362             };
2363             }
2364              
2365             sub errstr {
2366 52     52 1 90 my $self = shift;
2367 52   33     486 my $oe = ref($self) && ${*$self}{_SSL_last_err};
2368 52 50 0     298 return $oe ? $oe->[0] : $SSL_ERROR || '';
2369             }
2370              
2371             sub fatal_ssl_error {
2372 51     51 0 135 my $self = shift;
2373 51         92 my $error_trap = ${*$self}{'_SSL_arguments'}->{'SSL_error_trap'};
  51         235  
2374 51         234 $@ = $self->errstr;
2375 51         129 my $saved_error = $SSL_ERROR;
2376 51 100 66     344 if (defined $error_trap and ref($error_trap) eq 'CODE') {
    100 66        
2377 1         6 $error_trap->($self, $self->errstr()."\n".$self->get_ssleay_error());
2378 50         354 } elsif ( ${*$self}{'_SSL_ioclass_upgraded'}
2379 16         70 || ${*$self}{_SSL_arguments}{SSL_keepSocketOnError}) {
2380             # downgrade only
2381 34 50       102 $DEBUG>=3 && DEBUG('downgrading SSL only, not closing socket' );
2382 34         158 $self->stop_SSL;
2383             } else {
2384             # kill socket
2385 16         147 $self->close
2386             }
2387 51 50       1791 $SSL_ERROR = $saved_error if $saved_error;
2388 51         387 return;
2389             }
2390              
2391             sub get_ssleay_error {
2392             #Net::SSLeay will print out the errors itself unless we explicitly
2393             #undefine $Net::SSLeay::trace while running print_errs()
2394 1     1 0 15 local $Net::SSLeay::trace;
2395 1   50     22 return Net::SSLeay::print_errs('SSL error: ') || '';
2396             }
2397              
2398             # internal errors, e.g. unsupported features, hostname check failed etc
2399             # _SSL_last_err contains severity so that on error chains we can decide if one
2400             # error should replace the previous one or if this is just a less specific
2401             # follow-up error, e.g. configuration failed because certificate failed because
2402             # hostname check went wrong:
2403             # 0 - fallback errors
2404             # 4 - errors bubbled up from OpenSSL (sub error, r/w error)
2405             # 5 - hostname or OCSP verification failed
2406             # 9 - fatal problems, e.g. missing feature, no fileno...
2407             # _SSL_last_err and SSL_ERROR are only replaced if the error has a higher
2408             # severity than the previous one
2409              
2410             sub _internal_error {
2411 103     103   729 my ($self, $error, $severity) = @_;
2412 103         602 $error = dualvar( -1, $error );
2413 103 100 100     496 $self = $CURRENT_SSL_OBJECT if !ref($self) && $CURRENT_SSL_OBJECT;
2414 103 100       280 if (ref($self)) {
2415 101         144 my $oe = ${*$self}{_SSL_last_err};
  101         476  
2416 101 100 100     704 if (!$oe || $oe->[1] <= $severity) {
2417 71         239 ${*$self}{_SSL_last_err} = [$error,$severity];
  71         330  
2418 71         202 $SSL_ERROR = $error;
2419 71 50       274 $DEBUG && DEBUG("local error: $error");
2420             } else {
2421 30 50       84 $DEBUG && DEBUG("ignoring less severe local error '$error', keep '$oe->[0]'");
2422             }
2423             } else {
2424 2         7 $SSL_ERROR = $error;
2425 2 50       7 $DEBUG && DEBUG("global error: $error");
2426             }
2427 103         435 return;
2428             }
2429              
2430             # OpenSSL errors
2431             sub error {
2432 71     71 1 387 my ($self, $error) = @_;
2433 71         177 my @err;
2434 71         427 while ( my $err = Net::SSLeay::ERR_get_error()) {
2435 51         746 push @err, Net::SSLeay::ERR_error_string($err);
2436 51 50       254 $DEBUG>=2 && DEBUG( $error."\n".$self->get_ssleay_error());
2437             }
2438 71 100       362 $error .= ' '.join(' ',@err) if @err;
2439 71 50       382 return $self->_internal_error($error,4) if $error;
2440 0         0 return;
2441             }
2442              
2443             sub _errstack {
2444 5     5   30 my @err;
2445 5         104 while (my $err = Net::SSLeay::ERR_get_error()) {
2446 14         149 push @err, Net::SSLeay::ERR_error_string($err);
2447             }
2448 5         51 return @err;
2449             }
2450              
2451 7     7 0 822 sub can_client_sni { return $can_client_sni }
2452 6     6 0 7588 sub can_server_sni { return $can_server_sni }
2453 2     2 0 10 sub can_multi_cert { return $can_multi_cert }
2454 2     2 0 2442 sub can_npn { return $can_npn }
2455 2     2 0 2416 sub can_alpn { return $can_alpn }
2456 2     2 0 2362 sub can_ecdh { return $can_ecdh }
2457 4     4 0 185 sub can_ipv6 { return CAN_IPV6 }
2458 1     1 0 12 sub can_ocsp { return $can_ocsp }
2459 1     1 0 1312 sub can_ticket_keycb { return $can_tckt_keycb }
2460 0     0 0 0 sub can_pha { return $can_pha }
2461 2   50 2 0 36 sub can_partial_chain { return $check_partial_chain && 1 }
2462 0     0 0 0 sub can_ciphersuites { return $can_ciphersuites }
2463             sub can_psk {
2464 1     1 0 130 my %can;
2465 1 50       4 $can{client}=1 if $can_client_psk;
2466 1 50       5 $can{server}=1 if $can_server_psk;
2467 1 50       4 return %can ? \%can : undef
2468             }
2469 0     0 0 0 sub can_nested_ssl { return { SSL_usebio => 1 } }
2470              
2471             sub DESTROY {
2472 324 50   324   77765978 my $self = shift or return;
2473 324 100       1001 if (my $ssl = ${*$self}{_SSL_object}) {
  324         2305  
2474 211         1322 delete $SSL_OBJECT{$ssl};
2475 211 50 33     1004 if (!$use_threads or delete $CREATED_IN_THIS_THREAD{$ssl}) {
2476 211         2170 $self->close(_SSL_in_DESTROY => 1, SSL_no_shutdown => 1);
2477             }
2478             }
2479 324         2766 delete @{*$self}{keys %all_my_keys};
  324         729019  
2480             }
2481              
2482              
2483             #######Extra Backwards Compatibility Functionality#######
2484 1     1 1 193 sub socket_to_SSL { IO::Socket::SSL->start_SSL(@_); }
2485 1     1 1 4996 sub socketToSSL { IO::Socket::SSL->start_SSL(@_); }
2486 0     0 1 0 sub kill_socket { shift->close }
2487              
2488 1     1 1 35 sub issuer_name { return(shift()->peer_certificate("issuer")) }
2489 1     1 1 3 sub subject_name { return(shift()->peer_certificate("subject")) }
2490 0     0 1 0 sub get_peer_certificate { return shift() }
2491              
2492             sub context_init {
2493 2 50   2 1 3324 return($GLOBAL_SSL_ARGS = (ref($_[0]) eq 'HASH') ? $_[0] : {@_});
2494             }
2495              
2496             sub set_default_context {
2497 1     1 1 155 $GLOBAL_SSL_ARGS->{'SSL_reuse_ctx'} = shift;
2498             }
2499              
2500             sub set_default_session_cache {
2501 0     0 1 0 $GLOBAL_SSL_ARGS->{SSL_session_cache} = shift;
2502             }
2503              
2504              
2505             {
2506             my $set_defaults = sub {
2507             my $args = shift;
2508             for(my $i=0;$i<@$args;$i+=2 ) {
2509             my ($k,$v) = @{$args}[$i,$i+1];
2510             if ( $k =~m{^SSL_} ) {
2511             $_->{$k} = $v for(@_);
2512             } elsif ( $k =~m{^(name|scheme)$} ) {
2513             $_->{"SSL_verifycn_$k"} = $v for (@_);
2514             } elsif ( $k =~m{^(callback|mode)$} ) {
2515             $_->{"SSL_verify_$k"} = $v for(@_);
2516             } else {
2517             $_->{"SSL_$k"} = $v for(@_);
2518             }
2519             }
2520             };
2521             sub set_defaults {
2522 0     0 1 0 my %args = @_;
2523 0         0 $set_defaults->(\@_,
2524             $GLOBAL_SSL_ARGS,
2525             $GLOBAL_SSL_CLIENT_ARGS,
2526             $GLOBAL_SSL_SERVER_ARGS
2527             );
2528             }
2529             { # deprecated API
2530 89     89   696 no warnings;
  89         209  
  89         55689  
2531             *set_ctx_defaults = \&set_defaults;
2532             }
2533             sub set_client_defaults {
2534 0     0 1 0 my %args = @_;
2535 0         0 $set_defaults->(\@_, $GLOBAL_SSL_CLIENT_ARGS );
2536             }
2537             sub set_server_defaults {
2538 0     0 1 0 my %args = @_;
2539 0         0 $set_defaults->(\@_, $GLOBAL_SSL_SERVER_ARGS );
2540             }
2541             }
2542              
2543             sub set_args_filter_hack {
2544 0     0 1 0 my $sub = shift;
2545 0 0       0 if ( ref $sub ) {
    0          
2546 0         0 $FILTER_SSL_ARGS = $sub;
2547             } elsif ( $sub eq 'use_defaults' ) {
2548             # override args with defaults
2549             $FILTER_SSL_ARGS = sub {
2550 0     0   0 my ($is_server,$args) = @_;
2551 0 0       0 %$args = ( %$args, $is_server
2552             ? ( %DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_SERVER_ARGS )
2553             : ( %DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_CLIENT_ARGS )
2554             );
2555             }
2556 0         0 }
2557             }
2558              
2559             sub next_proto_negotiated {
2560 2     2 1 355 my $self = shift;
2561 2 50       14 return $self->_internal_error("NPN not supported in Net::SSLeay",9) if ! $can_npn;
2562 2   50     20 my $ssl = $self->_get_ssl_object || return;
2563 2         13 return Net::SSLeay::P_next_proto_negotiated($ssl);
2564             }
2565              
2566             sub alpn_selected {
2567 2     2 1 140 my $self = shift;
2568 2 50       8 return $self->_internal_error("ALPN not supported in Net::SSLeay",9) if ! $can_alpn;
2569 2   50     338 my $ssl = $self->_get_ssl_object || return;
2570 2         16 return Net::SSLeay::P_alpn_selected($ssl);
2571             }
2572              
2573             sub opened {
2574 5     5 1 818 my $self = shift;
2575 5   66     54 return IO::Handle::opened($self) && ${*$self}{'_SSL_opened'};
2576             }
2577              
2578             sub opening {
2579 0     0 0 0 my $self = shift;
2580 0         0 return ${*$self}{'_SSL_opening'};
  0         0  
2581             }
2582              
2583 0     0 0 0 sub want_read { shift->errstr == SSL_WANT_READ }
2584 0     0 0 0 sub want_write { shift->errstr == SSL_WANT_WRITE }
2585              
2586              
2587             #Redundant IO::Handle functionality
2588 1     1 1 897 sub getline { return(scalar shift->readline()) }
2589             sub getlines {
2590 1 50   1 1 6 return(shift->readline()) if wantarray();
2591 0         0 croak("Use of getlines() not allowed in scalar context");
2592             }
2593              
2594             #Useless IO::Handle functionality
2595 0     0 1 0 sub truncate { croak("Use of truncate() not allowed with SSL") }
2596 0     0 1 0 sub stat { croak("Use of stat() not allowed with SSL" ) }
2597 0     0 1 0 sub setbuf { croak("Use of setbuf() not allowed with SSL" ) }
2598 0     0 1 0 sub setvbuf { croak("Use of setvbuf() not allowed with SSL" ) }
2599 0     0 1 0 sub fdopen { croak("Use of fdopen() not allowed with SSL" ) }
2600              
2601             #Unsupported socket functionality
2602 0     0 1 0 sub ungetc { croak("Use of ungetc() not implemented in IO::Socket::SSL") }
2603 0     0 1 0 sub send { croak("Use of send() not implemented in IO::Socket::SSL; use print/printf/syswrite instead") }
2604 0     0 1 0 sub recv { croak("Use of recv() not implemented in IO::Socket::SSL; use read/sysread instead") }
2605              
2606             package IO::Socket::SSL::SSL_HANDLE;
2607 89     89   1619 use strict;
  89         649  
  89         3331  
2608 89     89   879 use Errno 'EBADF';
  89         482  
  89         30860  
2609             *weaken = *IO::Socket::SSL::weaken;
2610              
2611             sub TIEHANDLE {
2612 278     278   1637 my ($class, $handle) = @_;
2613 278         1590 weaken($handle);
2614 278         2416 bless \$handle, $class;
2615             }
2616              
2617 6092     6092   10042011 sub READ { ${shift()}->sysread(@_) }
  6092         12607  
2618 90     90   14715 sub READLINE { ${shift()}->readline(@_) }
  90         972  
2619 1     1   745 sub GETC { ${shift()}->getc(@_) }
  1         6  
2620              
2621 51     51   9035 sub PRINT { ${shift()}->print(@_) }
  51         540  
2622 1     1   20 sub PRINTF { ${shift()}->printf(@_) }
  1         5  
2623 9558     9558   11517669 sub WRITE { ${shift()}->syswrite(@_) }
  9558         18315  
2624              
2625 9527     9527   274849 sub FILENO { ${shift()}->fileno(@_) }
  9527         19527  
2626              
2627 0     0   0 sub TELL { $! = EBADF; return -1 }
  0         0  
2628 0     0   0 sub BINMODE { return 0 } # not perfect, but better than not implementing the method
2629              
2630             sub CLOSE { #<---- Do not change this function!
2631 44     44   18052 my $ssl = ${$_[0]};
  44         173  
2632 44         133 local @_;
2633 44         396 $ssl->close();
2634             }
2635              
2636              
2637             package IO::Socket::SSL::SSL_Context;
2638 89     89   806 use Carp;
  89         227  
  89         5968  
2639 89     89   552 use strict;
  89         134  
  89         4240  
2640              
2641             my %CTX_CREATED_IN_THIS_THREAD;
2642             *DEBUG = *IO::Socket::SSL::DEBUG;
2643             *_errstack = \&IO::Socket::SSL::_errstack;
2644              
2645 89     89   385 use constant SSL_MODE_ENABLE_PARTIAL_WRITE => 1;
  89         147  
  89         6435  
2646 89     89   470 use constant SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER => 2;
  89         117  
  89         5663  
2647              
2648 89     89   375 use constant FILETYPE_PEM => Net::SSLeay::FILETYPE_PEM();
  89         193  
  89         748  
2649 89     89   15671 use constant FILETYPE_ASN1 => Net::SSLeay::FILETYPE_ASN1();
  89         200  
  89         396  
2650              
2651             my $DEFAULT_SSL_OP = &Net::SSLeay::OP_ALL
2652             | &Net::SSLeay::OP_SINGLE_DH_USE
2653             | ($can_ecdh ? &Net::SSLeay::OP_SINGLE_ECDH_USE : 0);
2654              
2655              
2656             # get access to SSL handle for use with Net::SSLeay. Use with caution!
2657 0     0   0 sub _get_ctx_object { shift->{context} }
2658              
2659             # Note that the final object will actually be a reference to the scalar
2660             # (C-style pointer) returned by Net::SSLeay::CTX_*_new() so that
2661             # it can be blessed.
2662             sub new {
2663 313     313   30414 my $class = shift;
2664             #DEBUG( "$class @_" );
2665 313 100       2285 my $arg_hash = (ref($_[0]) eq 'HASH') ? $_[0] : {@_};
2666              
2667 313         947 my $is_server = $arg_hash->{SSL_server};
2668 313 100       13313 my %defaults = $is_server
2669             ? (%DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_ARGS, %$GLOBAL_SSL_SERVER_ARGS)
2670             : (%DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_ARGS, %$GLOBAL_SSL_CLIENT_ARGS);
2671 313 100       1719 if ( $defaults{SSL_reuse_ctx} ) {
2672             # ignore default context if there are args to override it
2673             delete $defaults{SSL_reuse_ctx}
2674 6 50       26 if grep { m{^SSL_(?!verifycn_name|hostname)$} } keys %$arg_hash;
  28         108  
2675             }
2676 313 50       4889 %$arg_hash = ( %defaults, %$arg_hash ) if %defaults;
2677              
2678 313 100       2375 if (my $ctx = $arg_hash->{'SSL_reuse_ctx'}) {
2679 26 100       195 if ($ctx->isa('IO::Socket::SSL::SSL_Context')) {
    50          
2680 24 50       150 return $ctx if $ctx->{context};
2681 2         3 } elsif (eval { $ctx = ${*$ctx}{_SSL_ctx} }) {
  2         30  
2682             # reuse context from existing SSL object
2683 2         7 return $ctx;
2684             }
2685 0         0 die "invalid context to reuse: $ctx";
2686             }
2687              
2688             # common problem forgetting to set SSL_use_cert
2689             # if client cert is given by user but SSL_use_cert is undef, assume that it
2690             # should be set
2691 287 100 100     4222 if ( ! $is_server && ! defined $arg_hash->{SSL_use_cert}
      100        
      66        
2692 370         2058 && ( grep { $arg_hash->{$_} } qw(SSL_cert SSL_cert_file))
2693 12         58 && ( grep { $arg_hash->{$_} } qw(SSL_key SSL_key_file)) ) {
2694 6         50 $arg_hash->{SSL_use_cert} = 1
2695             }
2696              
2697             # if any of SSL_ca* is set don't set the other SSL_ca*
2698             # from defaults
2699 287 100       1929 if ( $arg_hash->{SSL_ca} ) {
    50          
    100          
2700             $arg_hash->{SSL_ca_file} ||= undef
2701             $arg_hash->{SSL_ca_path} ||= undef
2702 34   50     304 } elsif ( $arg_hash->{SSL_ca_path} ) {
      33        
2703             $arg_hash->{SSL_ca_file} ||= undef
2704 0   0     0 } elsif ( $arg_hash->{SSL_ca_file} ) {
2705 69   50     761 $arg_hash->{SSL_ca_path} ||= undef;
2706             }
2707              
2708             # add library defaults
2709 287 100       1795 $arg_hash->{SSL_use_cert} = $is_server if ! defined $arg_hash->{SSL_use_cert};
2710              
2711              
2712             # Avoid passing undef arguments to Net::SSLeay
2713 287   66     5352 defined($arg_hash->{$_}) or delete($arg_hash->{$_}) for(keys %$arg_hash);
2714              
2715             # check SSL CA, cert etc arguments
2716             # some apps set keys '' to signal that it is not set, replace with undef
2717 287         1094 for (qw( SSL_cert SSL_cert_file SSL_key SSL_key_file
2718             SSL_ca SSL_ca_file SSL_ca_path
2719             SSL_fingerprint )) {
2720             $arg_hash->{$_} = undef if defined $arg_hash->{$_}
2721 2296 50 66     6104 and $arg_hash->{$_} eq '';
2722             }
2723 287         842 for(qw(SSL_cert_file SSL_key_file)) {
2724 574 100       1838 defined( my $file = $arg_hash->{$_} ) or next;
2725 152 100       1039 for my $f (ref($file) eq 'HASH' ? values(%$file):$file ) {
2726 184 50       9820 die "$_ $f can't be used: $!" if ! open(my $fh,'<',$f)
2727             }
2728             }
2729              
2730 287   100     2241 my $verify_mode = $arg_hash->{SSL_verify_mode} || 0;
2731 287 100       1353 if ( $verify_mode != $Net_SSLeay_VERIFY_NONE) {
    50          
2732 106         371 for (qw(SSL_ca_file SSL_ca_path)) {
2733 212   100     1609 $CHECK_SSL_PATH->($_ => $arg_hash->{$_} || next);
2734             }
2735             } elsif ( $verify_mode ne '0' ) {
2736             # some users use the string 'SSL_VERIFY_PEER' instead of the constant
2737 0         0 die "SSL_verify_mode must be a number and not a string";
2738             }
2739              
2740 287         1921 my $self = bless {},$class;
2741              
2742 287         697 my $vcn_scheme = delete $arg_hash->{SSL_verifycn_scheme};
2743 287         663 my $vcn_publicsuffix = delete $arg_hash->{SSL_verifycn_publicsuffix};
2744 287 50 100     3602 if ( ! $is_server and $verify_mode & 0x01 and
      66        
      100        
2745             ! $vcn_scheme || $vcn_scheme ne 'none' ) {
2746              
2747             # gets updated during configure_SSL
2748 103         336 my $verify_name;
2749 103         710 $self->{verify_name_ref} = \$verify_name;
2750              
2751 103         293 my $vcb = $arg_hash->{SSL_verify_callback};
2752             $arg_hash->{SSL_verify_callback} = sub {
2753 187     187   633 my ($ok,$ctx_store,$certname,$error,$cert,$depth) = @_;
2754 187 100       488 $ok = $vcb->($ok,$ctx_store,$certname,$error,$cert,$depth) if $vcb;
2755 187 100       2984 $ok or return 0;
2756              
2757 177 100       627 return $ok if $depth != 0;
2758              
2759 90   33     432 my $host = $verify_name || ref($vcn_scheme) && $vcn_scheme->{callback} && 'unknown';
2760 90 50       382 if ( ! $host ) {
2761 0 0       0 if ( $vcn_scheme ) {
2762 0         0 IO::Socket::SSL->_internal_error(
2763             "Cannot determine peer hostname for verification",8);
2764 0         0 return 0;
2765             }
2766 0         0 warn "Cannot determine hostname of peer for verification. ".
2767             "Disabling default hostname verification for now. ".
2768             "Please specify hostname with SSL_verifycn_name and better set SSL_verifycn_scheme too.\n";
2769 0         0 return $ok;
2770             }
2771              
2772              
2773             # verify name
2774 90         879 my $rv = IO::Socket::SSL::verify_hostname_of_cert(
2775             $host,$cert,$vcn_scheme,$vcn_publicsuffix );
2776 90 100       321 if ( ! $rv ) {
2777 17         218 IO::Socket::SSL->_internal_error(
2778             "hostname verification failed",5);
2779             }
2780 90         222 return $rv;
2781 103         1619 };
2782             }
2783              
2784 287 100       938 if ($is_server) {
2785 100 50 33     842 if ($arg_hash->{SSL_ticket_keycb} && !$can_tckt_keycb) {
2786 0         0 warn "Ticket Key Callback is not supported - ignoring option SSL_ticket_keycb\n";
2787 0         0 delete $arg_hash->{SSL_ticket_keycb};
2788             }
2789             }
2790              
2791              
2792 287         568 my $ssl_op = $DEFAULT_SSL_OP;
2793              
2794 287         564 my $ver;
2795 287         6976 for (split(/\s*:\s*/,$arg_hash->{SSL_version})) {
2796 1266 50       6302 m{^(!?)(?:(SSL(?:v2|v3|v23|v2/3))|(TLSv1(?:_?[123])?))$}i
2797             or croak("invalid SSL_version specified");
2798 1266         3868 my $not = $1;
2799 1266   66     12978 ( my $v = lc($2||$3) ) =~s{^(...)}{\U$1};
2800 1266 100       2565 if ( $not ) {
2801 979         2515 $ssl_op |= $SSL_OP_NO{$v};
2802             } else {
2803 287 50 33     1042 croak("cannot set multiple SSL protocols in SSL_version")
2804             if $ver && $v ne $ver;
2805 287         590 $ver = $v;
2806 287         901 $ver =~s{/}{}; # interpret SSLv2/3 as SSLv23
2807 287         1006 $ver =~s{(TLSv1)(\d)}{$1\_$2}; # TLSv1_1
2808             }
2809             }
2810              
2811 287 100       7285 my $ctx_new_sub =
    100          
    100          
    100          
    50          
    100          
    100          
2812             $ver eq 'TLSv1_3' ? $CTX_tlsv1_3_new :
2813             UNIVERSAL::can( 'Net::SSLeay',
2814             $ver eq 'SSLv2' ? 'CTX_v2_new' :
2815             $ver eq 'SSLv3' ? 'CTX_v3_new' :
2816             $ver eq 'TLSv1' ? 'CTX_tlsv1_new' :
2817             $ver eq 'TLSv1_1' ? 'CTX_tlsv1_1_new' :
2818             $ver eq 'TLSv1_2' ? 'CTX_tlsv1_2_new' :
2819             'CTX_new'
2820             )
2821             or return IO::Socket::SSL->_internal_error("SSL Version $ver not supported",9);
2822              
2823             # For SNI in server mode we need a separate context for each certificate.
2824 286         773 my %ctx;
2825 286 100       866 if ($is_server) {
2826 100         550 my %sni;
2827 100         320 for my $opt (qw(SSL_key SSL_key_file SSL_cert SSL_cert_file)) {
2828 400 100       1183 my $val = $arg_hash->{$opt} or next;
2829 193 100       645 if ( ref($val) eq 'HASH' ) {
2830 12         36 while ( my ($host,$v) = each %$val ) {
2831 44         122 $sni{lc($host)}{$opt} = $v;
2832             }
2833             }
2834             }
2835 100         832 while (my ($host,$v) = each %sni) {
2836 22 100       258 $ctx{$host} = $host =~m{%} ? $v : { %$arg_hash, %$v };
2837             }
2838             }
2839 286 100       1939 $ctx{''} = $arg_hash if ! %ctx;
2840              
2841 286         1459 for my $host (sort keys %ctx) {
2842 302         708 my $arg_hash = delete $ctx{$host};
2843 302         638 my $ctx;
2844 302 100       1046 if ($host =~m{^([^%]*)%}) {
2845 2 50       8 $ctx = $ctx{$1} or return IO::Socket::SSL->error(
2846             "SSL Context init for $host failed - no config for $1");
2847 2 50       6 if (my @k = grep { !m{^SSL_(?:cert|key)(?:_file)?$} }
  4         20  
2848             keys %$arg_hash) {
2849 0         0 return IO::Socket::SSL->error(
2850             "invalid keys @k in configuration '$host' of additional certs");
2851             }
2852 2 50       6 $can_multi_cert or return IO::Socket::SSL->error(
2853             "no support for both RSA and ECC certificate in same context");
2854 2         4 $host = $1;
2855 2         22 goto just_configure_certs;
2856             }
2857              
2858 300 50       313766 $ctx = $ctx_new_sub->() or return
2859             IO::Socket::SSL->error("SSL Context init failed");
2860 300 50       1582 $CTX_CREATED_IN_THIS_THREAD{$ctx} = 1 if $use_threads;
2861 300         984 $ctx{$host} = $ctx; # replace value in %ctx with real context
2862              
2863             # SSL_OP_CIPHER_SERVER_PREFERENCE
2864 300 100       1505 $ssl_op |= 0x00400000 if $arg_hash->{SSL_honor_cipher_order};
2865              
2866 300 100 100     2848 if ($ver eq 'SSLv23' && !($ssl_op & $SSL_OP_NO{SSLv3})) {
2867             # At least LibreSSL disables SSLv3 by default in SSL_CTX_new.
2868             # If we really want SSL3.0 we need to explicitly allow it with
2869             # SSL_CTX_clear_options.
2870 20         456 Net::SSLeay::CTX_clear_options($ctx,$SSL_OP_NO{SSLv3});
2871             }
2872              
2873 300         2086 Net::SSLeay::CTX_set_options($ctx,$ssl_op);
2874              
2875             # enable X509_V_FLAG_PARTIAL_CHAIN if possible (OpenSSL 1.1.0+)
2876 300 50       3246 $check_partial_chain && $check_partial_chain->($ctx);
2877              
2878             # if we don't set session_id_context if client certificate is expected
2879             # client session caching will fail
2880             # if user does not provide explicit id just use the stringification
2881             # of the context
2882 300 100 66     2436 if($arg_hash->{SSL_server} and my $id =
      100        
2883             $arg_hash->{SSL_session_id_context} ||
2884             ( $arg_hash->{SSL_verify_mode} & 0x01 ) && "$ctx" ) {
2885 9         53 Net::SSLeay::CTX_set_session_id_context($ctx,$id,length($id));
2886             }
2887              
2888             # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER makes syswrite return if at least one
2889             # buffer was written and not block for the rest
2890             # SSL_MODE_ENABLE_PARTIAL_WRITE can be necessary for non-blocking because we
2891             # cannot guarantee, that the location of the buffer stays constant
2892             Net::SSLeay::CTX_set_mode( $ctx,
2893             SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
2894             SSL_MODE_ENABLE_PARTIAL_WRITE |
2895 300 50       2066 ($arg_hash->{SSL_mode_release_buffers} ? $ssl_mode_release_buffers : 0)
2896             );
2897              
2898 300 100       1010 if ( my $proto_list = $arg_hash->{SSL_npn_protocols} ) {
2899 3 50       9 return IO::Socket::SSL->_internal_error("NPN not supported in Net::SSLeay",9)
2900             if ! $can_npn;
2901 3 100       8 if($arg_hash->{SSL_server}) {
2902             # on server side SSL_npn_protocols means a list of advertised protocols
2903 2         52 Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, $proto_list);
2904             } else {
2905             # on client side SSL_npn_protocols means a list of preferred protocols
2906             # negotiation algorithm used is "as-openssl-implements-it"
2907 1         67 Net::SSLeay::CTX_set_next_proto_select_cb($ctx, $proto_list);
2908             }
2909             }
2910              
2911 300 100       848 if ( my $proto_list = $arg_hash->{SSL_alpn_protocols} ) {
2912 3 50       8 return IO::Socket::SSL->_internal_error("ALPN not supported in Net::SSLeay",9)
2913             if ! $can_alpn;
2914 3 100       10 if($arg_hash->{SSL_server}) {
2915 2         16 Net::SSLeay::CTX_set_alpn_select_cb($ctx, $proto_list);
2916             } else {
2917 1         53 Net::SSLeay::CTX_set_alpn_protos($ctx, $proto_list);
2918             }
2919             }
2920              
2921 300 50       963 if ($arg_hash->{SSL_ticket_keycb}) {
2922 0         0 my $cb = $arg_hash->{SSL_ticket_keycb};
2923 0 0       0 ($cb,my $arg) = ref($cb) eq 'CODE' ? ($cb):@$cb;
2924 0         0 Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($ctx,$cb,$arg);
2925             }
2926              
2927 300 100       875 if ($arg_hash->{SSL_psk}) {
2928 15         33 my $psk = $arg_hash->{SSL_psk};
2929 15 100       33 if ($arg_hash->{SSL_server}) {
2930 1 50       2 $can_server_psk or return IO::Socket::SSL->_internal_error(
2931             "no support for server side PSK");
2932             Net::SSLeay::CTX_set_psk_server_callback($ctx, sub {
2933 0     0   0 my ($ssl,$identity,$psklen) = @_;
2934 0 0       0 if (ref($psk) eq 'HASH') {
2935 0   0     0 return $psk->{$identity} || $psk->{''} ||
2936             IO::Socket::SSL->_internal_error(
2937             "no PSK for given identity '$identity' and no default");
2938             } else {
2939 0         0 return $psk;
2940             }
2941 1         21 });
2942             } else {
2943 14 50       50 $can_client_psk or return IO::Socket::SSL->_internal_error(
2944             "no support for client side PSK");
2945             Net::SSLeay::CTX_set_psk_client_callback($ctx, sub {
2946 14     14   36 my $hint = shift;
2947 14         25 my ($i,$p);
2948 14 50       67 if (ref($psk) eq 'HASH') {
    100          
2949 0 0       0 $hint = '' if ! defined $hint;
2950 0 0       0 $p = $psk->{$hint} or return IO::Socket::SSL->_internal_error(
2951             "no PSK for given hint '$hint'");
2952 0         0 $i = $hint;
2953             } elsif (ref($psk)) { # [identity,psk]
2954 12         41 ($i,$p) = @$psk;
2955             } else {
2956 2         23 ($i,$p) = ('io_socket_ssl', $psk)
2957             }
2958             # for some reason this expects the PSK in hex whereas the server
2959             # side function expects the PSK in binary
2960 14         149690 return ($i, unpack("H*",$p));
2961 14         220 });
2962             }
2963             }
2964              
2965             # Try to apply SSL_ca even if SSL_verify_mode is 0, so that they can be
2966             # used to verify OCSP responses.
2967             # If applying fails complain only if verify_mode != VERIFY_NONE.
2968 300 100 100     4301 if ( $arg_hash->{SSL_ca}
    50 66        
2969             || defined $arg_hash->{SSL_ca_file}
2970             || defined $arg_hash->{SSL_ca_path} ) {
2971 117         319 my $file = $arg_hash->{SSL_ca_file};
2972 117 50 33     455 $file = undef if ref($file) eq 'SCALAR' && ! $$file;
2973 117         218 my $dir = $arg_hash->{SSL_ca_path};
2974 117 50 33     376 $dir = undef if ref($dir) eq 'SCALAR' && ! $$dir;
2975 117 100       409 if ( $arg_hash->{SSL_ca} ) {
2976 34         109 my $store = Net::SSLeay::CTX_get_cert_store($ctx);
2977 34         89 for (@{$arg_hash->{SSL_ca}}) {
  34         120  
2978 37 50       312 Net::SSLeay::X509_STORE_add_cert($store,$_) or
2979             return IO::Socket::SSL->error(
2980             "Failed to add certificate to CA store");
2981             }
2982             }
2983 117 50       334 $dir = join($OPENSSL_LIST_SEPARATOR,@$dir) if ref($dir);
2984 117 50 66     62661 if ( $file || $dir and ! Net::SSLeay::CTX_load_verify_locations(
      50        
      50        
      66        
2985             $ctx, $file || '', $dir || '')) {
2986 0 0       0 return IO::Socket::SSL->error(
2987             "Invalid certificate authority locations")
2988             if $verify_mode != $Net_SSLeay_VERIFY_NONE;
2989             }
2990             } elsif ( my %ca = IO::Socket::SSL::default_ca()) {
2991             # no CA path given, continue with system defaults
2992 183         460 my $dir = $ca{SSL_ca_path};
2993 183 50       493 $dir = join($OPENSSL_LIST_SEPARATOR,@$dir) if ref($dir);
2994 183 50 50     9621880 if (! Net::SSLeay::CTX_load_verify_locations( $ctx,
      100        
      33        
2995             $ca{SSL_ca_file} || '',$dir || '')
2996             && $verify_mode != $Net_SSLeay_VERIFY_NONE) {
2997 0         0 return IO::Socket::SSL->error(
2998             "Invalid default certificate authority locations")
2999             }
3000             }
3001              
3002 300 100 100     3527 if ($is_server && ($verify_mode & $Net_SSLeay_VERIFY_PEER)) {
3003 9 50       26 if ($arg_hash->{SSL_client_ca}) {
3004 0         0 for (@{$arg_hash->{SSL_client_ca}}) {
  0         0  
3005 0 0       0 return IO::Socket::SSL->error(
3006             "Failed to add certificate to client CA list") if
3007             ! Net::SSLeay::CTX_add_client_CA($ctx,$_);
3008             }
3009             }
3010 9 50       24 if ($arg_hash->{SSL_client_ca_file}) {
3011             my $list = Net::SSLeay::load_client_CA_file(
3012 0 0       0 $arg_hash->{SSL_client_ca_file}) or
3013             return IO::Socket::SSL->error(
3014             "Failed to load certificate to client CA list");
3015 0         0 Net::SSLeay::CTX_set_client_CA_list($ctx,$list);
3016             }
3017             }
3018              
3019 300         1094 my $X509_STORE_flags = $DEFAULT_X509_STORE_flags;
3020 300 50       1417 if ($arg_hash->{'SSL_check_crl'}) {
3021 0         0 $X509_STORE_flags |= Net::SSLeay::X509_V_FLAG_CRL_CHECK();
3022 0 0       0 if ($arg_hash->{'SSL_crl_file'}) {
3023 0         0 my $bio = Net::SSLeay::BIO_new_file($arg_hash->{'SSL_crl_file'}, 'r');
3024 0         0 my $crl = Net::SSLeay::PEM_read_bio_X509_CRL($bio);
3025 0         0 Net::SSLeay::BIO_free($bio);
3026 0 0       0 if ( $crl ) {
3027 0         0 Net::SSLeay::X509_STORE_add_crl(Net::SSLeay::CTX_get_cert_store($ctx), $crl);
3028 0         0 Net::SSLeay::X509_CRL_free($crl);
3029             } else {
3030 0         0 return IO::Socket::SSL->error("Invalid certificate revocation list");
3031             }
3032             }
3033             }
3034              
3035             Net::SSLeay::X509_STORE_set_flags(
3036 300 50       3283 Net::SSLeay::CTX_get_cert_store($ctx),
3037             $X509_STORE_flags
3038             ) if $X509_STORE_flags;
3039              
3040             Net::SSLeay::CTX_set_default_passwd_cb($ctx,$arg_hash->{SSL_passwd_cb})
3041 300 100       1151 if $arg_hash->{SSL_passwd_cb};
3042              
3043 302         989 just_configure_certs:
3044             my ($havekey,$havecert);
3045 302 100       1969 if ( my $x509 = $arg_hash->{SSL_cert} ) {
    100          
3046             # binary, e.g. X509*
3047             # we have either a single certificate or a list with
3048             # a chain of certificates
3049 31 100       148 my @x509 = ref($x509) eq 'ARRAY' ? @$x509: ($x509);
3050 31         83 my $cert = shift @x509;
3051 31 50       1973 Net::SSLeay::CTX_use_certificate( $ctx,$cert )
3052             || return IO::Socket::SSL->error("Failed to use Certificate");
3053 31         106 foreach my $ca (@x509) {
3054 1 50       20 Net::SSLeay::CTX_add_extra_chain_cert( $ctx,$ca )
3055             || return IO::Socket::SSL->error("Failed to use Certificate");
3056             }
3057 31         114 $havecert = 'OBJ';
3058             } elsif ( my $f = $arg_hash->{SSL_cert_file} ) {
3059             # try to load chain from PEM or certificate from ASN1
3060 90         226 my @err;
3061 90 100       49459 if (Net::SSLeay::CTX_use_certificate_chain_file($ctx,$f)) {
    100          
3062 87         718 $havecert = 'PEM';
3063             } elsif (do {
3064 3         154 push @err, [ PEM => _errstack() ];
3065 3         613 Net::SSLeay::CTX_use_certificate_file($ctx,$f,FILETYPE_ASN1)
3066             }) {
3067 1         5 $havecert = 'DER';
3068             } else {
3069 2         19 push @err, [ DER => _errstack() ];
3070             # try to load certificate, key and chain from PKCS12 file
3071 2         8719 my ($key,$cert,@chain) = Net::SSLeay::P_PKCS12_load_file($f,1);
3072 2 50 66     79 if (!$cert and $arg_hash->{SSL_passwd_cb}
      33        
3073             and defined( my $pw = $arg_hash->{SSL_passwd_cb}->(0))) {
3074 1         12457 ($key,$cert,@chain) = Net::SSLeay::P_PKCS12_load_file($f,1,$pw);
3075             }
3076 2         28 PKCS12: while ($cert) {
3077 2 50       151 Net::SSLeay::CTX_use_certificate($ctx,$cert) or last;
3078             # Net::SSLeay::P_PKCS12_load_file is implemented using
3079             # OpenSSL PKCS12_parse which according to the source code
3080             # returns the chain with the last CA certificate first (i.e.
3081             # reverse order as in the PKCS12 file). This is not
3082             # documented but given the age of this function we'll assume
3083             # that this will stay this way in the future.
3084 2         43 while (my $ca = pop @chain) {
3085 0 0       0 next if Net::SSLeay::CTX_add_extra_chain_cert($ctx,$ca);
3086             # failed - free everything not added yet and exit loop
3087 0         0 Net::SSLeay::X509_free($ca);
3088 0         0 Net::SSLeay::X509_free($_) for @chain;
3089 0         0 last PKCS12;
3090             }
3091 2 50 33     124 last if $key && ! Net::SSLeay::CTX_use_PrivateKey($ctx,$key);
3092 2         13 $havecert = 'PKCS12';
3093 2         24 last;
3094             }
3095 2 50       11 $havekey = 'PKCS12' if $key;
3096 2 50       15 Net::SSLeay::X509_free($cert) if $cert;
3097 2 50       66 Net::SSLeay::EVP_PKEY_free($key) if $key;
3098             # don't free @chain, because CTX_add_extra_chain_cert
3099             # did not duplicate the certificates
3100             }
3101 90 50       429 if (!$havecert) {
3102 0         0 push @err, [ PKCS12 => _errstack() ];
3103 0         0 my $err = "Failed to load certificate from file $f:";
3104 0         0 for(@err) {
3105 0         0 my ($type,@e) = @$_;
3106 0 0       0 $err .= " [format:$type] @e **" if @e;
3107             }
3108 0         0 return IO::Socket::SSL->error($err);
3109             }
3110             }
3111              
3112 302 100 100     2514 if (!$havecert || $havekey) {
    100 66        
    50          
3113             # skip SSL_key_*
3114             } elsif ( my $pkey = $arg_hash->{SSL_key} ) {
3115             # binary, e.g. EVP_PKEY*
3116 28 50       175 Net::SSLeay::CTX_use_PrivateKey($ctx, $pkey)
3117             || return IO::Socket::SSL->error("Failed to use Private Key");
3118 28         74 $havekey = 'MEM';
3119             } elsif ( my $f = $arg_hash->{SSL_key_file}
3120             || (($havecert eq 'PEM') ? $arg_hash->{SSL_cert_file}:undef) ) {
3121 91         555 for my $ft ( FILETYPE_PEM, FILETYPE_ASN1 ) {
3122 92 100       116478 if (Net::SSLeay::CTX_use_PrivateKey_file($ctx,$f,$ft)) {
3123 91 100       596 $havekey = ($ft == FILETYPE_PEM) ? 'PEM':'DER';
3124 91         311 last;
3125             }
3126             }
3127 91 50       405 $havekey or return IO::Socket::SSL->error(
3128             "Failed to load key from file (no PEM or DER)");
3129             }
3130              
3131 302 100 66     4590 Net::SSLeay::CTX_set_post_handshake_auth($ctx,1)
      100        
      66        
3132             if (!$is_server && $can_pha && $havecert && $havekey);
3133             }
3134              
3135 286 100       1405 if ($arg_hash->{SSL_server}) {
3136              
3137 100 50       650 if ( my $f = $arg_hash->{SSL_dh_file} ) {
    50          
3138 0   0     0 my $bio = Net::SSLeay::BIO_new_file( $f,'r' )
3139             || return IO::Socket::SSL->error( "Failed to open DH file $f" );
3140 0         0 my $dh = Net::SSLeay::PEM_read_bio_DHparams($bio);
3141 0         0 Net::SSLeay::BIO_free($bio);
3142 0 0       0 $dh || return IO::Socket::SSL->error( "Failed to read PEM for DH from $f - wrong format?" );
3143 0         0 my $rv;
3144 0         0 for (values (%ctx)) {
3145 0 0       0 $rv = Net::SSLeay::CTX_set_tmp_dh( $_,$dh ) or last;
3146             }
3147 0         0 Net::SSLeay::DH_free( $dh );
3148 0 0       0 $rv || return IO::Socket::SSL->error( "Failed to set DH from $f" );
3149             } elsif ( my $dh = $arg_hash->{SSL_dh} ) {
3150             # binary, e.g. DH*
3151              
3152 100         357 for( values %ctx ) {
3153 114 50       1472 Net::SSLeay::CTX_set_tmp_dh( $_,$dh ) || return
3154             IO::Socket::SSL->error( "Failed to set DH from SSL_dh" );
3155             }
3156             }
3157             }
3158              
3159 286 100       1550 if ( my $curve = $arg_hash->{SSL_ecdh_curve} ) {
3160 10 50       26 return IO::Socket::SSL->_internal_error(
3161             "ECDH curve needs Net::SSLeay>=1.56 and OpenSSL>=1.0",9)
3162             if ! $can_ecdh;
3163              
3164 10         29 for(values %ctx) {
3165 10 50 66     71 if ($arg_hash->{SSL_server} and $curve eq 'auto') {
    50          
    0          
    0          
3166 0 0       0 if ($can_ecdh eq 'can_auto') {
    0          
3167 0 0       0 Net::SSLeay::CTX_set_ecdh_auto($_,1) or
3168             return IO::Socket::SSL->error(
3169             "failed to set ECDH curve context");
3170             } elsif ($can_ecdh eq 'auto') {
3171             # automatically enabled anyway
3172             } else {
3173 0         0 return IO::Socket::SSL->error(
3174             "SSL_CTX_set_ecdh_auto not implemented");
3175             }
3176              
3177             } elsif ($set_groups_list) {
3178 10 50       156 $set_groups_list->($_,$curve) or return IO::Socket::SSL->error(
3179             "failed to set ECDH groups/curves on context");
3180             # needed for OpenSSL 1.0.2 if ($can_ecdh eq 'can_auto') {
3181 10 50       39 Net::SSLeay::CTX_set_ecdh_auto($_,1) if $can_ecdh eq 'can_auto';
3182             } elsif ($curve =~m{:}) {
3183 0         0 return IO::Socket::SSL->error(
3184             "SSL_CTX_groups_list or SSL_CTX_curves_list not implemented");
3185              
3186             } elsif ($arg_hash->{SSL_server}) {
3187 0 0       0 if ( $curve !~ /^\d+$/ ) {
3188             # name of curve, find NID
3189 0   0     0 $curve = Net::SSLeay::OBJ_txt2nid($curve)
3190             || return IO::Socket::SSL->error(
3191             "cannot find NID for curve name '$curve'");
3192             }
3193 0 0       0 my $ecdh = Net::SSLeay::EC_KEY_new_by_curve_name($curve) or
3194             return IO::Socket::SSL->error(
3195             "cannot create curve for NID $curve");
3196 0         0 for( values %ctx ) {
3197 0 0       0 Net::SSLeay::CTX_set_tmp_ecdh($_,$ecdh) or
3198             return IO::Socket::SSL->error(
3199             "failed to set ECDH curve context");
3200             }
3201 0         0 Net::SSLeay::EC_KEY_free($ecdh);
3202             }
3203             }
3204             }
3205              
3206 286         1006 my $verify_cb = $arg_hash->{SSL_verify_callback};
3207 286         680 my @accept_fp;
3208 286 100       973 if ( my $fp = $arg_hash->{SSL_fingerprint} ) {
3209 11 100       32 for( ref($fp) ? @$fp : $fp) {
3210 13 50       200 my ($algo,$pubkey,$digest) = m{^(?:([\w-]+)\$)?(pub\$)?([a-f\d:]+)$}i
3211             or return IO::Socket::SSL->_internal_error("invalid fingerprint '$_'",9);
3212 13         103 ( $digest = lc($digest) ) =~s{:}{}g;
3213 13 0 33     38 $algo ||=
    0          
    0          
3214             length($digest) == 32 ? 'md5' :
3215             length($digest) == 40 ? 'sha1' :
3216             length($digest) == 64 ? 'sha256' :
3217             return IO::Socket::SSL->_internal_error(
3218             "cannot detect hash algorithm from fingerprint '$_'",9);
3219 13         22 $algo = lc($algo);
3220 13   100     121 push @accept_fp,[ $algo, $pubkey || '', pack('H*',$digest) ]
3221             }
3222             }
3223 286   66     1381 my $verify_fingerprint = @accept_fp && do {
3224             my $fail;
3225             my $force = $arg_hash->{SSL_force_fingerprint};
3226             sub {
3227 26     26   43 my ($ok,$cert,$depth) = @_;
3228 26         49 $fail = 1 if ! $ok;
3229 26         52 return 1 if $depth>0; # to let us continue with verification
3230             # Check fingerprint only from top certificate.
3231 14         19 my %fp;
3232 14         49 for(@accept_fp) {
3233 15 100 66     196 my $fp = $fp{$_->[0],$_->[1]} ||= $_->[1]
3234             ? Net::SSLeay::X509_pubkey_digest($cert,$algo2digest->($_->[0]))
3235             : Net::SSLeay::X509_digest($cert,$algo2digest->($_->[0]));
3236 15         48 next if $fp ne $_->[2];
3237 10         32 return 1;
3238             }
3239 4 100       17 return $force ? 0 : ! $fail;
3240             }
3241             };
3242             my $verify_callback = ( $verify_cb || @accept_fp ) && sub {
3243 187     187   694 my ($ok, $ctx_store) = @_;
3244 187         371 my ($certname,$cert,$error,$depth);
3245 187         701 if ($ctx_store) {
3246 187         706 $cert = Net::SSLeay::X509_STORE_CTX_get_current_cert($ctx_store);
3247 187         569 $error = Net::SSLeay::X509_STORE_CTX_get_error($ctx_store);
3248 187         445 $depth = Net::SSLeay::X509_STORE_CTX_get_error_depth($ctx_store);
3249 187         1725 $certname =
3250             Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert)).
3251             Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert));
3252 187   66     876 $error &&= Net::SSLeay::ERR_error_string($error);
3253             }
3254 187         811 $DEBUG>=3 && DEBUG( "ok=$ok [$depth] $certname" );
3255 187         687 $ok = $verify_cb->($ok,$ctx_store,$certname,$error,$cert,$depth) if $verify_cb;
3256 187         612 $ok = $verify_fingerprint->($ok,$cert,$depth) if $verify_fingerprint && $cert;
3257 187         36644 return $ok;
3258 286   66     3151 };
3259              
3260 286 50       2362 if ( $^O eq 'darwin' ) {
3261             # explicitly set error code to disable use of apples TEA patch
3262             # https://hynek.me/articles/apple-openssl-verification-surprises/
3263 0         0 my $vcb = $verify_callback;
3264             $verify_callback = sub {
3265 0 0   0   0 my $rv = $vcb ? &$vcb : $_[0];
3266 0 0       0 if ( $rv != 1 ) {
3267             # 50 - X509_V_ERR_APPLICATION_VERIFICATION: application verification failure
3268 0         0 Net::SSLeay::X509_STORE_CTX_set_error($_[1], 50);
3269             }
3270 0         0 return $rv;
3271 0         0 };
3272             }
3273             Net::SSLeay::CTX_set_verify($_, $verify_mode, $verify_callback)
3274 286         4023 for (values %ctx);
3275              
3276 286         908 my $staple_callback = $arg_hash->{SSL_ocsp_staple_callback};
3277 286 100 66     2962 if ( !$is_server && $can_ocsp_staple && ! $verify_fingerprint) {
      100        
3278 175         1638 $self->{ocsp_cache} = $arg_hash->{SSL_ocsp_cache};
3279             my $status_cb = sub {
3280 80     80   381 my ($ssl,$resp) = @_;
3281 80 50       434 my $iossl = $SSL_OBJECT{$ssl} or
3282             die "no IO::Socket::SSL object found for SSL $ssl";
3283 80 50       401 $iossl->[1] and do {
3284             # we must return with 1 or it will be called again
3285             # and because we have no SSL object we must make the error global
3286 0         0 Carp::cluck($IO::Socket::SSL::SSL_ERROR
3287             = "OCSP callback on server side");
3288 0         0 return 1;
3289             };
3290 80         163 $iossl = $iossl->[0];
3291              
3292             # if we have a callback use this
3293             # callback must not free or copy $resp !!
3294 80 50       216 if ( $staple_callback ) {
3295 0         0 $staple_callback->($iossl,$resp);
3296 0         0 return 1;
3297             }
3298              
3299             # Default callback does verification.
3300             # _SSL_ocsp_verify is only written when a staple is received AND fully
3301             # verified (good status, valid signature, cert status retrieved).
3302             # Returning 1 here without writing _SSL_ocsp_verify means the staple
3303             # is treated the same as if no staple was provided: with
3304             # SSL_OCSP_TRY_STAPLE the connection continues; with
3305             # SSL_OCSP_MUST_STAPLE the post-handshake check will reject it.
3306 80 50       313 if ( ! $resp ) {
3307 80 50       260 $DEBUG>=3 && DEBUG("did not get stapled OCSP response");
3308 80         31469 return 1;
3309             }
3310 0 0       0 $DEBUG>=3 && DEBUG("got stapled OCSP response");
3311 0         0 my $status = Net::SSLeay::OCSP_response_status($resp);
3312 0 0       0 if ($status != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL()) {
3313             # Treat a broken staple the same as no staple (see comment above).
3314 0 0       0 $DEBUG>=3 && DEBUG("bad status of stapled OCSP response: ".
3315             Net::SSLeay::OCSP_response_status_str($status));
3316 0         0 return 1;
3317             }
3318 0 0       0 if (!eval { Net::SSLeay::OCSP_response_verify($ssl,$resp) }) {
  0         0  
3319             # Treat an unverifiable staple the same as no staple (see comment above).
3320 0 0       0 $DEBUG>=3 && DEBUG("verify of stapled OCSP response failed");
3321 0         0 return 1;
3322             }
3323 0         0 my (@results,$hard_error);
3324 0         0 my @chain = $iossl->peer_certificates;
3325 0         0 for my $cert (@chain) {
3326 0         0 my $certid = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) };
  0         0  
3327 0 0       0 if (!$certid) {
3328 0 0       0 $DEBUG>=3 && DEBUG("cannot create OCSP_CERTID: $@");
3329 0         0 push @results,[-1,$@];
3330 0         0 last;
3331             }
3332 0         0 ($status) = Net::SSLeay::OCSP_response_results($resp,$certid);
3333 0 0 0     0 if ($status && $status->[2]) {
3334 0         0 my $cache = ${*$iossl}{_SSL_ctx}{ocsp_cache};
  0         0  
3335 0 0       0 if (!$status->[1]) {
    0          
3336 0         0 push @results,[1,$status->[2]{nextUpdate}];
3337 0 0       0 $cache && $cache->put($certid,$status->[2]);
3338             } elsif ( $status->[2]{statusType} ==
3339             Net::SSLeay::V_OCSP_CERTSTATUS_GOOD()) {
3340 0         0 push @results,[1,$status->[2]{nextUpdate}];
3341             $cache && $cache->put($certid,{
3342 0 0       0 %{$status->[2]},
  0         0  
3343             expire => time()+120,
3344             soft_error => $status->[1],
3345             });
3346             } else {
3347 0         0 push @results,($hard_error = [0,$status->[1]]);
3348             $cache && $cache->put($certid,{
3349 0 0       0 %{$status->[2]},
  0         0  
3350             hard_error => $status->[1],
3351             });
3352             }
3353             }
3354             }
3355             # return result of lead certificate, this should be in chain[0] and
3356             # thus result[0], but we better check. But if we had any hard_error
3357             # return this instead
3358 0 0 0     0 if ($hard_error) {
    0          
3359 0         0 ${*$iossl}{_SSL_ocsp_verify} = $hard_error;
  0         0  
3360             } elsif (@results and $chain[0] == $iossl->peer_certificate) {
3361 0         0 ${*$iossl}{_SSL_ocsp_verify} = $results[0];
  0         0  
3362             }
3363 0         0 return 1;
3364 175         3269 };
3365 175         2150 Net::SSLeay::CTX_set_tlsext_status_cb($_,$status_cb) for (values %ctx);
3366             }
3367              
3368 286 50       1119 if ( my $cl = $arg_hash->{SSL_cipher_list} ) {
3369 286         730 for (keys %ctx) {
3370             Net::SSLeay::CTX_set_cipher_list($ctx{$_}, ref($cl)
3371             ? $cl->{$_} || $cl->{''} || $DEFAULT_SSL_ARGS{SSL_cipher_list} || next
3372 300 50 0     27539 : $cl
    50          
3373             ) || return IO::Socket::SSL->error("Failed to set SSL cipher list");
3374             }
3375             }
3376 286 50       1267 if ( my $cl = $arg_hash->{SSL_ciphersuites} ) {
3377 0 0       0 return IO::Socket::SSL->error("no support for SSL_ciphersuites in Net::SSLeay")
3378             if ! $can_ciphersuites;
3379 0         0 for (keys %ctx) {
3380             Net::SSLeay::CTX_set_ciphersuites($ctx{$_}, ref($cl)
3381             ? $cl->{$_} || $cl->{''} || $DEFAULT_SSL_ARGS{SSL_cipher_list} || next
3382 0 0 0     0 : $cl
    0          
3383             ) || return IO::Socket::SSL->error("Failed to set SSL cipher list");
3384             }
3385             }
3386              
3387             # Main context is default context or any other if no default context.
3388 286   33     951 my $ctx = $ctx{''} || (values %ctx)[0];
3389 286 100 66     2534 if (keys(%ctx) > 1 || ! exists $ctx{''}) {
3390 6 50       20 $can_server_sni or return IO::Socket::SSL->_internal_error(
3391             "Server side SNI not supported for this openssl/Net::SSLeay",9);
3392              
3393             Net::SSLeay::CTX_set_tlsext_servername_callback($ctx, sub {
3394 19     19   71 my $ssl = shift;
3395 19         82 my $host = Net::SSLeay::get_servername($ssl);
3396 19 100       74 $host = '' if ! defined $host;
3397 19 50 66     178 my $snictx = $ctx{lc($host)} || $ctx{''} or do {
3398 0 0       0 $DEBUG>1 and DEBUG(
3399             "cannot get context from servername '$host'");
3400 0         0 return 2; # SSL_TLSEXT_ERR_ALERT_FATAL
3401             };
3402 19 50       61 $DEBUG>1 and DEBUG("set context from servername $host");
3403 19 100       335 Net::SSLeay::set_SSL_CTX($ssl,$snictx) if $snictx != $ctx;
3404 19         480960 return 0; # SSL_TLSEXT_ERR_OK
3405 6         144 });
3406             }
3407              
3408 286 50       966 if ( my $cb = $arg_hash->{SSL_create_ctx_callback} ) {
3409 0         0 $cb->($_) for values (%ctx);
3410             }
3411              
3412 286         2177 $self->{context} = $ctx;
3413 286         1171 $self->{verify_mode} = $arg_hash->{SSL_verify_mode};
3414             $self->{ocsp_mode} =
3415             defined($arg_hash->{SSL_ocsp_mode}) ? $arg_hash->{SSL_ocsp_mode} :
3416 286 100       1581 $self->{verify_mode} ? IO::Socket::SSL::SSL_OCSP_TRY_STAPLE() :
    50          
3417             0;
3418 286 50       939 $DEBUG>=3 && DEBUG( "new ctx $ctx" );
3419              
3420 286 50       1402 if ( my $cache = $arg_hash->{SSL_session_cache} ) {
    100          
3421             # use predefined cache
3422 0         0 $self->{session_cache} = $cache
3423             } elsif ( my $size = $arg_hash->{SSL_session_cache_size}) {
3424 3         91 $self->{session_cache} = IO::Socket::SSL::Session_Cache->new( $size );
3425             }
3426              
3427              
3428 286 100 66     1082 if ($self->{session_cache} and %sess_cb) {
3429 3         119 Net::SSLeay::CTX_set_session_cache_mode($ctx,
3430             Net::SSLeay::SESS_CACHE_CLIENT());
3431 3         1171 my $cache = $self->{session_cache};
3432             $sess_cb{new}($ctx, sub {
3433 15     15   66 my ($ssl,$session) = @_;
3434 15   33     90 my $self = ($SSL_OBJECT{$ssl} || do {
3435             warn "callback session new: no known SSL object for $ssl";
3436             return;
3437             })->[0];
3438 15         47 my $args = ${*$self}{_SSL_arguments};
  15         80  
3439 15 50       76 my $key = $args->{SSL_session_key} or do {
3440 0         0 warn "callback session new: no known SSL_session_key for $ssl";
3441 0         0 return;
3442             };
3443 15 50       75 $DEBUG>=3 && DEBUG("callback session new <$key> $session");
3444 15         50 Net::SSLeay::SESSION_up_ref($session);
3445 15         84 $cache->add_session($key,$session);
3446 3         72 });
3447             $sess_cb{remove}($ctx, sub {
3448 12     12   37 my ($ctx,$session) = @_;
3449 12 50       33 $DEBUG>=3 && DEBUG("callback session remove $session");
3450 12         43 $cache->del_session(undef,$session);
3451 3         62 });
3452             }
3453              
3454 286         2549 return $self;
3455             }
3456              
3457              
3458             sub has_session_cache {
3459 0     0   0 return defined shift->{session_cache};
3460             }
3461              
3462              
3463 0     0   0 sub CLONE { %CTX_CREATED_IN_THIS_THREAD = (); }
3464             sub DESTROY {
3465 287     287   60160 my $self = shift;
3466 287 100       1613 if ( my $ctx = $self->{context} ) {
3467 284 50       1025 $DEBUG>=3 && DEBUG("free ctx $ctx open=".join( " ",keys %CTX_CREATED_IN_THIS_THREAD ));
3468 284 50 33     1412 if (!$use_threads or delete $CTX_CREATED_IN_THIS_THREAD{$ctx} ) {
3469             # remove any verify callback for this context
3470 284 100       1096 if ( $self->{verify_mode}) {
3471 105 50       332 $DEBUG>=3 && DEBUG("free ctx $ctx callback" );
3472 105         2247 Net::SSLeay::CTX_set_verify($ctx, 0,undef);
3473             }
3474 284 50       981 if ( $self->{ocsp_error_ref}) {
3475 0 0       0 $DEBUG>=3 && DEBUG("free ctx $ctx tlsext_status_cb" );
3476 0         0 Net::SSLeay::CTX_set_tlsext_status_cb($ctx,undef);
3477             }
3478 284 50       889 $DEBUG>=3 && DEBUG("OK free ctx $ctx" );
3479 284         271455 Net::SSLeay::CTX_free($ctx);
3480             }
3481             }
3482 287         1317 delete(@{$self}{'context','session_cache'});
  287         27332  
3483             }
3484              
3485             package IO::Socket::SSL::Session_Cache;
3486             *DEBUG = *IO::Socket::SSL::DEBUG;
3487              
3488             # The cache is consisting of one list which contains all sessions and then
3489             # for each session key another list containing all sessions for same key.
3490             # The order of the list is by use, i.e. last used are put on top.
3491             # self.ghead points to the top of the global list while
3492             # self.shead{key} to the top of the session key specific list
3493             # All lists are cyclic
3494             # Each element in the list consists of an array with slots for ...
3495             use constant {
3496 89         380332 SESSION => 0, # session object
3497             KEY => 1, # key for object
3498             GNEXT => 2, # next element in global list
3499             GPREV => 3, # previous element in global list
3500             SNEXT => 4, # next element for same session key
3501             SPREV => 5, # previous element for same session key
3502 89     89   635469 };
  89         136  
3503              
3504             sub new {
3505 3     3   11 my ($class, $size) = @_;
3506 3 50       11 $size>0 or return;
3507 3         105 return bless {
3508             room => $size, # free space regarding to max size
3509             ghead => undef, # top of global list
3510             shead => {}, # top of key specific list
3511             }, $class;
3512             }
3513              
3514             sub add_session {
3515 19     19   135 my ($self, $key, $session) = @_;
3516              
3517             # create new
3518 19         40 my $v = [];
3519 19         42 $v->[SESSION] = $session;
3520 19         32 $v->[KEY] = $key;
3521 19 50       49 $DEBUG>=3 && DEBUG("add_session($key,$session)");
3522 19         80 _add_entry($self,$v);
3523             }
3524              
3525             sub replace_session {
3526 0     0   0 my ($self, $key, $session) = @_;
3527 0         0 $self->del_session($key);
3528 0         0 $self->add_session($key, $session);
3529             }
3530              
3531             sub del_session {
3532 13     13   45 my ($self, $key, $session) = @_;
3533              
3534             # find all sessions which match given key and session and add to @del
3535             # if key is given scan only sessions for the key, else all sessions
3536             my ($head,$inext) = $key
3537 13 100       41 ? ($self->{shead}{$key},SNEXT) : ($self->{ghead},GNEXT);
3538 13         20 my $v = $head;
3539 13         17 my @del;
3540 13         50 while ($v) {
3541 18 100       50 if (!$session) {
    100          
3542 3         6 push @del,$v
3543             } elsif ($v->[SESSION] == $session) {
3544 12         20 push @del, $v;
3545 12         20 last;
3546             }
3547 6         9 $v = $v->[$inext];
3548 6 100       17 last if $v == $head;
3549             }
3550 13 0 0     30 $DEBUG>=3 && DEBUG("del_session("
    0          
    50          
3551             . ($key ? $key : "undef")
3552             . ($session ? ",$session) -> " : ") -> ")
3553             . (~~@del || 'none'));
3554 13         27 for (@del) {
3555 15         38 _del_entry($self,$_);
3556 15 100       72 Net::SSLeay::SESSION_free($_->[SESSION]) if $_->[SESSION];
3557 15         36 @$_ = ();
3558             }
3559 13         183 return ~~@del;
3560             }
3561              
3562             sub get_session {
3563 16     16   60 my ($self, $key, $session) = @_;
3564              
3565             # find first session for key
3566             # if $session is given further look for this specific one
3567 16         41 my $v = $self->{shead}{$key};
3568 16 100       43 if ($session) {
3569 3         6 my $shead = $v;
3570 3         30 while ($v) {
3571 3 50       9 $DEBUG>=3 && DEBUG("check $session - $v->[SESSION]");
3572 3 50       14 last if $v->[SESSION] == $session;
3573 0         0 $v = $v->[SNEXT];
3574 0 0       0 $v = undef if $v == $shead; # session not found
3575             }
3576             }
3577              
3578             # mark as recent by moving to top so that it gets expired last
3579 16 100       112 _touch_entry($self,$v) if $v;
3580              
3581 16 0       61 $DEBUG>=3 && DEBUG("get_session($key"
    0          
    50          
3582             . ( $session ? ",$session) -> " : ") -> ")
3583             . ($v? $v->[SESSION]:"none"));
3584 16   66     115 return $v && $v->[SESSION];
3585             }
3586              
3587             sub _add_entry {
3588 19     19   36 my ($self,$v) = @_;
3589              
3590             # If there are already sessions for same key add to this list else create
3591             # a new sublist for this key. Similar for global list.
3592 19         117 for(
3593             [ SNEXT, SPREV, \$self->{shead}{$v->[KEY]} ],
3594             [ GNEXT, GPREV, \$self->{ghead} ],
3595             ) {
3596 38         100 my ($inext,$iprev,$rhead) = @$_;
3597 38 100       68 if ($$rhead) {
3598             # add on top of list
3599 27         43 $v->[$inext] = $$rhead;
3600 27         31 $v->[$iprev] = ${$rhead}->[$iprev];
  27         53  
3601 27         41 ${$rhead}->[$iprev][$inext] = $v;
  27         42  
3602 27         36 ${$rhead}->[$iprev] = $v;
  27         37  
3603 27         50 $$rhead = $v;
3604             } else {
3605             # create a new list
3606 11         31 $$rhead = $v->[$inext] = $v->[$iprev] = $v;
3607             }
3608             }
3609              
3610 19         59 $self->{room}--;
3611              
3612             # drop old entries if necessary
3613 19 100       85104 if ($self->{room}<0) {
3614 1         2 my $l = $self->{ghead}[GPREV];
3615 1         4 _del_entry($self,$l);
3616 1 50       2 Net::SSLeay::SESSION_free($l->[SESSION]) if $l->[SESSION];
3617 1         3 @$l = ();
3618             }
3619             }
3620              
3621             sub _del_entry {
3622 16     16   32 my ($self,$v) = @_;
3623             # Remove element from both key specific list and global list
3624             # If key specific list is then empty drop it from self.shead
3625 16         65 for(
3626             [ SNEXT, SPREV, \$self->{shead}{$v->[KEY]} ],
3627             [ GNEXT, GPREV, \$self->{ghead} ],
3628             ) {
3629 32         51 my ($inext,$iprev,$rhead) = @$_;
3630 32 50       54 $$rhead or return;
3631 32         61 $v->[$inext][$iprev] = $v->[$iprev];
3632 32         43 $v->[$iprev][$inext] = $v->[$inext];
3633 32 100       86 if ($v != $$rhead) {
    100          
3634             # not removed from top of list
3635             } elsif ($v->[$inext] == $v) {
3636             # was only element on list, drop list
3637 7 100       17 if ($inext == SNEXT) {
3638 4         46 delete $self->{shead}{$v->[KEY]};
3639             } else {
3640 3         9 $$rhead = undef;
3641             }
3642             } else {
3643             # was top element, keep others
3644 20         45 $$rhead = $v->[$inext];
3645             }
3646             }
3647 16         37 $self->{room}++;
3648             }
3649              
3650             sub _touch_entry {
3651 11     11   30 my ($self,$v) = @_;
3652              
3653             # Put element on top of both global list and key specific list
3654             # so that it gets expired last when making space in the cache
3655 11         60 for(
3656             [ SNEXT, SPREV, \$self->{shead}{$v->[KEY]} ],
3657             [ GNEXT, GPREV, \$self->{ghead} ],
3658             ) {
3659 22         63 my ($inext,$iprev,$rhead) = @$_;
3660 22 50       66 $$rhead or die "entry not in list ($inext)"; # should not happen
3661 22 100       75 next if $$rhead == $v; # already at top
3662              
3663             # remove from current position - like _del_entry
3664 6         13 $v->[$inext][$iprev] = $v->[$iprev];
3665 6         30 $v->[$iprev][$inext] = $v->[$inext];
3666              
3667             # add on top - like _add_entry
3668 6         14 $v->[$inext] = $$rhead;
3669 6         7 $v->[$iprev] = ${$rhead}->[$iprev];
  6         18  
3670 6         8 ${$rhead}->[$iprev][$inext] = $v;
  6         31  
3671 6         11 ${$rhead}->[$iprev] = $v;
  6         25  
3672 6         18 $$rhead = $v;
3673             }
3674             }
3675              
3676             sub _dump {
3677 0     0   0 my $self = shift;
3678              
3679 0         0 my %v2i;
3680 0         0 my $v = $self->{ghead};
3681 0         0 while ($v) {
3682 0 0       0 exists $v2i{$v} and die;
3683 0         0 $v2i{$v} = int(keys %v2i);
3684 0         0 $v = $v->[GNEXT];
3685 0 0       0 last if $v == $self->{ghead};
3686             }
3687              
3688 0         0 my $out = "room: $self->{room}\nghead:\n";
3689 0         0 $v = $self->{ghead};
3690 0         0 while ($v) {
3691             $out .= sprintf(" - [%d] <%d,%d> '%s' <%s>\n",
3692 0         0 $v2i{$v}, $v2i{$v->[GPREV]}, $v2i{$v->[GNEXT]},
3693             $v->[KEY], $v->[SESSION]);
3694 0         0 $v = $v->[GNEXT];
3695 0 0       0 last if $v == $self->{ghead};
3696             }
3697 0         0 $out .= "shead:\n";
3698 0         0 for my $key (sort keys %{$self->{shead}}) {
  0         0  
3699 0         0 $out .= " - '$key'\n";
3700 0         0 my $shead = $self->{shead}{$key};
3701 0         0 my $v = $shead;
3702 0         0 while ($v) {
3703             $out .= sprintf(" - [%d] <%d,%d> '%s' <%s>\n",
3704 0         0 $v2i{$v}, $v2i{$v->[SPREV]}, $v2i{$v->[SNEXT]},
3705             $v->[KEY], $v->[SESSION]);
3706 0         0 $v = $v->[SNEXT];
3707 0 0       0 last if $v == $shead;
3708             }
3709             }
3710 0         0 return $out;
3711             }
3712              
3713             sub DESTROY {
3714 2     2   6 my $self = shift;
3715 2         7 delete $self->{shead};
3716 2         5 my $v = delete $self->{ghead};
3717 2         147 while ($v) {
3718 0 0       0 Net::SSLeay::SESSION_free($v->[SESSION]) if $v->[SESSION];
3719 0         0 my $next = $v->[GNEXT];
3720 0         0 @$v = ();
3721 0         0 $v = $next;
3722             }
3723             }
3724              
3725              
3726              
3727             package IO::Socket::SSL::OCSP_Cache;
3728              
3729             sub new {
3730 0     0   0 my ($class,$size) = @_;
3731 0   0     0 return bless {
3732             '' => { _lru => 0, size => $size || 100 }
3733             },$class;
3734             }
3735             sub get {
3736 0     0   0 my ($self,$id) = @_;
3737 0 0       0 my $e = $self->{$id} or return;
3738 0         0 $e->{_lru} = $self->{''}{_lru}++;
3739 0 0 0     0 if ( $e->{expire} && time()<$e->{expire}) {
3740 0         0 delete $self->{$id};
3741 0         0 return;
3742             }
3743 0 0 0     0 if ( $e->{nextUpdate} && time()<$e->{nextUpdate} ) {
3744 0         0 delete $self->{$id};
3745 0         0 return;
3746             }
3747 0         0 return $e;
3748             }
3749              
3750             sub put {
3751 0     0   0 my ($self,$id,$e) = @_;
3752 0         0 $self->{$id} = $e;
3753 0         0 $e->{_lru} = $self->{''}{_lru}++;
3754 0         0 my $del = keys(%$self) - $self->{''}{size};
3755 0 0       0 if ($del>0) {
3756 0         0 my @k = sort { $self->{$a}{_lru} <=> $self->{$b}{_lru} } keys %$self;
  0         0  
3757 0         0 delete @{$self}{ splice(@k,0,$del) };
  0         0  
3758             }
3759 0         0 return $e;
3760             }
3761              
3762             package IO::Socket::SSL::OCSP_Resolver;
3763             *DEBUG = *IO::Socket::SSL::DEBUG;
3764              
3765             # create a new resolver
3766             # $ssl - the ssl object
3767             # $cache - OCSP_Cache object (put,get)
3768             # $failhard - flag if we should fail hard on OCSP problems
3769             # $certs - list of certs to verify
3770             sub new {
3771 0     0   0 my ($class,$ssl,$cache,$failhard,$certs) = @_;
3772 0         0 my (%todo,$done,$hard_error,@soft_error);
3773 0         0 for my $cert (@$certs) {
3774             # skip entries which have no OCSP uri or where we cannot get a certid
3775             # (e.g. self-signed or where we don't have the issuer)
3776 0         0 my $subj = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert));
3777 0 0       0 my $uri = Net::SSLeay::P_X509_get_ocsp_uri($cert) or do {
3778 0 0       0 $DEBUG>2 && DEBUG("no URI for certificate $subj");
3779 0         0 push @soft_error,"no ocsp_uri for $subj";
3780 0         0 next;
3781             };
3782 0 0       0 my $certid = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) } or do {
  0         0  
3783 0 0       0 $DEBUG>2 && DEBUG("no OCSP_CERTID for certificate $subj: $@");
3784 0         0 push @soft_error,"no certid for $subj: $@";
3785 0         0 next;
3786             };
3787 0 0       0 if (!($done = $cache->get($certid))) {
    0          
    0          
3788 0         0 push @{ $todo{$uri}{ids} }, $certid;
  0         0  
3789 0         0 push @{ $todo{$uri}{subj} }, $subj;
  0         0  
3790             } elsif ( $done->{hard_error} ) {
3791             # one error is enough to fail validation
3792 0         0 $hard_error = $done->{hard_error};
3793 0         0 %todo = ();
3794 0         0 last;
3795             } elsif ( $done->{soft_error} ) {
3796 0         0 push @soft_error,$done->{soft_error};
3797             }
3798             }
3799 0         0 while ( my($uri,$v) = each %todo) {
3800 0         0 my $ids = $v->{ids};
3801 0         0 my $oreq = Net::SSLeay::OCSP_ids2req(@$ids);
3802 0         0 $v->{req} = Net::SSLeay::i2d_OCSP_REQUEST($oreq);
3803 0         0 Net::SSLeay::OCSP_REQUEST_free($oreq);
3804             }
3805 0 0 0     0 $hard_error ||= '' if ! %todo;
3806 0 0       0 return bless {
3807             ssl => $ssl,
3808             cache => $cache,
3809             failhard => $failhard,
3810             hard_error => $hard_error,
3811             soft_error => @soft_error ? join("; ",@soft_error) : undef,
3812             todo => \%todo,
3813             },$class;
3814             }
3815              
3816             # return current result, e.g. '' for no error, else error
3817             # if undef we have no final result yet
3818 0     0   0 sub hard_error { return shift->{hard_error} }
3819 0     0   0 sub soft_error { return shift->{soft_error} }
3820              
3821             # return hash with uri => ocsp_request_data for open requests
3822             sub requests {
3823 0     0   0 my $todo = shift()->{todo};
3824 0         0 return map { ($_,$todo->{$_}{req}) } keys %$todo;
  0         0  
3825             }
3826              
3827             # add new response
3828             sub add_response {
3829 0     0   0 my ($self,$uri,$resp_d) = @_;
3830 0         0 my $todo = delete $self->{todo}{$uri};
3831 0 0 0     0 return $self->{error} if ! $todo || $self->{error};
3832              
3833 0         0 my ($req,$resp,@soft_error,@hard_error);
3834              
3835             # do we have a response
3836 0 0       0 if (!$resp_d) {
    0          
    0          
    0          
    0          
3837             @soft_error = "http request for OCSP failed; subject: ".
3838 0         0 join("; ",@{$todo->{subj}});
  0         0  
3839              
3840             # is it a valid OCSP_RESPONSE
3841 0         0 } elsif ( ! eval { $resp = Net::SSLeay::d2i_OCSP_RESPONSE($resp_d) }) {
3842             @soft_error = "invalid response (no OCSP_RESPONSE); subject: ".
3843 0         0 join("; ",@{$todo->{subj}});
  0         0  
3844             # hopefully short-time error
3845             $self->{cache}->put($_,{
3846             soft_error => "@soft_error",
3847             expire => time()+10,
3848 0         0 }) for (@{$todo->{ids}});
  0         0  
3849             # is the OCSP response status success
3850             } elsif (
3851             ( my $status = Net::SSLeay::OCSP_response_status($resp))
3852             != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL()
3853             ){
3854             @soft_error = "OCSP response failed: ".
3855             Net::SSLeay::OCSP_response_status_str($status).
3856 0         0 "; subject: ".join("; ",@{$todo->{subj}});
  0         0  
3857             # hopefully short-time error
3858             $self->{cache}->put($_,{
3859             soft_error => "@soft_error",
3860             expire => time()+10,
3861 0         0 }) for (@{$todo->{ids}});
  0         0  
3862              
3863             # does nonce match the request and can the signature be verified
3864             } elsif ( ! eval {
3865 0         0 $req = Net::SSLeay::d2i_OCSP_REQUEST($todo->{req});
3866 0         0 Net::SSLeay::OCSP_response_verify($self->{ssl},$resp,$req);
3867             }) {
3868 0 0       0 if ($@) {
3869 0         0 @soft_error = $@
3870             } else {
3871 0         0 my @err;
3872 0         0 while ( my $err = Net::SSLeay::ERR_get_error()) {
3873 0         0 push @soft_error, Net::SSLeay::ERR_error_string($err);
3874             }
3875             @soft_error = 'failed to verify OCSP response; subject: '.
3876 0 0       0 join("; ",@{$todo->{subj}}) if ! @soft_error;
  0         0  
3877             }
3878             # configuration problem or we don't know the signer
3879             $self->{cache}->put($_,{
3880             soft_error => "@soft_error",
3881             expire => time()+120,
3882 0         0 }) for (@{$todo->{ids}});
  0         0  
3883              
3884             # extract results from response
3885             } elsif ( my @result =
3886 0         0 Net::SSLeay::OCSP_response_results($resp,@{$todo->{ids}})) {
3887 0         0 my (@found,@miss);
3888 0         0 for my $rv (@result) {
3889 0 0       0 if ($rv->[2]) {
3890 0         0 push @found,$rv->[0];
3891 0 0       0 if (!$rv->[1]) {
    0          
3892             # no error
3893 0         0 $self->{cache}->put($rv->[0],$rv->[2]);
3894             } elsif ( $rv->[2]{statusType} ==
3895             Net::SSLeay::V_OCSP_CERTSTATUS_GOOD()) {
3896             # soft error, like response after nextUpdate
3897             push @soft_error,$rv->[1]."; subject: ".
3898 0         0 join("; ",@{$todo->{subj}});
  0         0  
3899             $self->{cache}->put($rv->[0],{
3900 0         0 %{$rv->[2]},
  0         0  
3901             soft_error => "@soft_error",
3902             expire => time()+120,
3903             });
3904             } else {
3905             # hard error
3906 0         0 $self->{cache}->put($rv->[0],$rv->[2]);
3907             push @hard_error, $rv->[1]."; subject: ".
3908 0         0 join("; ",@{$todo->{subj}});
  0         0  
3909             }
3910             } else {
3911 0         0 push @miss,$rv->[0];
3912             }
3913             }
3914 0 0 0     0 if (@miss && @found) {
3915             # we sent multiple responses, but server answered only to one
3916             # try again
3917 0         0 $self->{todo}{$uri} = $todo;
3918 0         0 $todo->{ids} = \@miss;
3919 0         0 my $oreq = Net::SSLeay::OCSP_ids2req(@miss);
3920 0         0 $todo->{req} = Net::SSLeay::i2d_OCSP_REQUEST($oreq);
3921 0         0 Net::SSLeay::OCSP_REQUEST_free($oreq);
3922 0 0       0 $DEBUG>=2 && DEBUG("$uri just answered ".@found." of ".(@found+@miss)." requests");
3923             }
3924             } else {
3925             @soft_error = "no data in response; subject: ".
3926 0         0 join("; ",@{$todo->{subj}});
  0         0  
3927             # probably configuration problem
3928             $self->{cache}->put($_,{
3929             soft_error => "@soft_error",
3930             expire => time()+120,
3931 0         0 }) for (@{$todo->{ids}});
  0         0  
3932             }
3933              
3934 0 0       0 Net::SSLeay::OCSP_RESPONSE_free($resp) if $resp;
3935 0 0       0 Net::SSLeay::OCSP_REQUEST_free($req) if $req;
3936 0 0       0 if ($self->{failhard}) {
3937 0         0 push @hard_error,@soft_error;
3938 0         0 @soft_error = ();
3939             }
3940 0 0       0 if (@soft_error) {
3941 0 0       0 $self->{soft_error} .= "; " if $self->{soft_error};
3942 0         0 $self->{soft_error} .= "$uri: ".join('; ',@soft_error);
3943             }
3944 0 0       0 if (@hard_error) {
    0          
3945 0         0 $self->{hard_error} = "$uri: ".join('; ',@hard_error);
3946 0         0 %{$self->{todo}} = ();
  0         0  
3947 0         0 } elsif ( ! %{$self->{todo}} ) {
3948 0         0 $self->{hard_error} = ''
3949             }
3950 0         0 return $self->{hard_error};
3951             }
3952              
3953             # make all necessary requests to get OCSP responses blocking
3954             sub resolve_blocking {
3955 0     0   0 my ($self,%args) = @_;
3956 0         0 while ( my %todo = $self->requests ) {
3957 0 0       0 eval { require HTTP::Tiny } or die "need HTTP::Tiny installed";
  0         0  
3958             # OCSP responses have their own signature, so we don't need SSL verification
3959 0         0 my $ua = HTTP::Tiny->new(verify_SSL => 0,%args);
3960 0         0 while (my ($uri,$reqdata) = each %todo) {
3961 0 0       0 $DEBUG && DEBUG("sending OCSP request to $uri");
3962 0         0 my $resp = $ua->request('POST',$uri, {
3963             headers => { 'Content-type' => 'application/ocsp-request' },
3964             content => $reqdata
3965             });
3966 0 0       0 $DEBUG && DEBUG("got OCSP response from $uri code=$resp->{status}");
3967             defined ($self->add_response($uri,
3968 0 0 0     0 $resp->{success} && $resp->{content}))
3969             && last;
3970             }
3971             }
3972 0 0       0 $DEBUG>=2 && DEBUG("no more open OCSP requests");
3973 0         0 return $self->{hard_error};
3974             }
3975              
3976             package IO::Socket::SSL::Trace;
3977             *DEBUG = *IO::Socket::SSL::DEBUG;
3978              
3979             # Exhaustive list of constants we need for tracing
3980             my %trace_constants = map { $_ => eval { Net::SSLeay->$_ } || -1 } qw(
3981             SSL2_VERSION
3982             SSL3_VERSION
3983             TLS1_VERSION
3984             TLS1_1_VERSION
3985             TLS1_2_VERSION
3986             TLS1_3_VERSION
3987             DTLS1_VERSION
3988             DTLS1_2_VERSION
3989             DTLS1_BAD_VER
3990             SSL3_RT_INNER_CONTENT_TYPE
3991             SSL3_RT_CHANGE_CIPHER_SPEC
3992             SSL3_RT_ALERT
3993             SSL3_RT_HEADER
3994             SSL3_RT_HANDSHAKE
3995             SSL3_RT_APPLICATION_DATA
3996             SSL2_MT_ERROR
3997             SSL2_MT_CLIENT_HELLO
3998             SSL2_MT_CLIENT_MASTER_KEY
3999             SSL2_MT_CLIENT_FINISHED
4000             SSL2_MT_SERVER_HELLO
4001             SSL2_MT_SERVER_VERIFY
4002             SSL2_MT_SERVER_FINISHED
4003             SSL2_MT_REQUEST_CERTIFICATE
4004             SSL2_MT_CLIENT_CERTIFICATE
4005             SSL3_MT_HELLO_REQUEST
4006             SSL3_MT_CLIENT_HELLO
4007             SSL3_MT_SERVER_HELLO
4008             SSL3_MT_NEWSESSION_TICKET
4009             SSL3_MT_CERTIFICATE
4010             SSL3_MT_SERVER_KEY_EXCHANGE
4011             SSL3_MT_CLIENT_KEY_EXCHANGE
4012             SSL3_MT_CERTIFICATE_REQUEST
4013             SSL3_MT_SERVER_DONE
4014             SSL3_MT_CERTIFICATE_VERIFY
4015             SSL3_MT_FINISHED
4016             SSL3_MT_CERTIFICATE_STATUS
4017             SSL3_MT_ENCRYPTED_EXTENSIONS
4018             SSL3_MT_SUPPLEMENTAL_DATA
4019             SSL3_MT_END_OF_EARLY_DATA
4020             SSL3_MT_KEY_UPDATE
4021             SSL3_MT_NEXT_PROTO
4022             SSL3_MT_MESSAGE_HASH
4023             );
4024              
4025             #
4026             # Major versions
4027             #
4028             $trace_constants{SSL2_VERSION_MAJOR} = $trace_constants{SSL2_VERSION} >> 8;
4029             $trace_constants{SSL3_VERSION_MAJOR} = $trace_constants{SSL3_VERSION} >> 8;
4030              
4031             #
4032             # Mapping between trace constant and version string
4033             #
4034             my %tc_ver2s;
4035             for (
4036             [ SSL2_VERSION => "SSLv2" ],
4037             [ SSL2_VERSION => "SSLv2" ],
4038             [ SSL3_VERSION => "SSLv3" ],
4039             [ TLS1_VERSION => "TLSv1.0" ],
4040             [ TLS1_1_VERSION => "TLSv1.1" ],
4041             [ TLS1_2_VERSION => "TLSv1.2" ],
4042             [ TLS1_3_VERSION => "TLSv1.3" ],
4043             [ DTLS1_VERSION => "DTLSv1.0" ],
4044             [ DTLS1_2_VERSION => "DTLSv1.2" ],
4045             [ DTLS1_BAD_VER => "DTLSv1.0 (bad)" ]
4046             ) {
4047             next if $trace_constants{$_->[0]} == -1;
4048             $tc_ver2s{$trace_constants{$_->[0]}} = $_->[1];
4049             }
4050              
4051             my %tc_type2s;
4052             for (
4053             [ SSL3_RT_HEADER => "TLS header" ],
4054             [ SSL3_RT_CHANGE_CIPHER_SPEC => "TLS change cipher" ],
4055             [ SSL3_RT_ALERT => "TLS alert" ],
4056             [ SSL3_RT_HANDSHAKE => "TLS handshake" ],
4057             [ SSL3_RT_APPLICATION_DATA => "TLS app data" ]
4058             ) {
4059             next if $trace_constants{$_->[0]} == -1;
4060             $tc_type2s{$trace_constants{$_->[0]}} = $_->[1];
4061             }
4062              
4063             my %tc_msgtype2s;
4064             for(
4065             [ SSL2_MT_ERROR => "Error" ],
4066             [ SSL2_MT_CLIENT_HELLO => "Client hello" ],
4067             [ SSL2_MT_CLIENT_MASTER_KEY => "Client key" ],
4068             [ SSL2_MT_CLIENT_FINISHED => "Client finished" ],
4069             [ SSL2_MT_SERVER_HELLO => "Server hello" ],
4070             [ SSL2_MT_SERVER_VERIFY => "Server verify" ],
4071             [ SSL2_MT_SERVER_FINISHED => "Server finished" ],
4072             [ SSL2_MT_REQUEST_CERTIFICATE => "Request CERT" ],
4073             [ SSL2_MT_REQUEST_CERTIFICATE => "Client CERT" ]
4074             ) {
4075             next if $trace_constants{$_->[0]} == -1;
4076             $tc_msgtype2s{$trace_constants{SSL2_VERSION_MAJOR}, $trace_constants{$_->[0]}} = $_->[1];
4077             }
4078             for(
4079             [ SSL3_MT_HELLO_REQUEST => "Hello request" ],
4080             [ SSL3_MT_CLIENT_HELLO => "Client hello" ],
4081             [ SSL3_MT_SERVER_HELLO => "Server hello" ],
4082             [ SSL3_MT_NEWSESSION_TICKET => "Newsession Ticket" ],
4083             [ SSL3_MT_CERTIFICATE => "Certificate" ],
4084             [ SSL3_MT_SERVER_KEY_EXCHANGE => "Server key exchange" ],
4085             [ SSL3_MT_CLIENT_KEY_EXCHANGE => "Client key exchange" ],
4086             [ SSL3_MT_CERTIFICATE_REQUEST => "Request CERT" ],
4087             [ SSL3_MT_SERVER_DONE => "Server finished" ],
4088             [ SSL3_MT_CERTIFICATE_VERIFY => "CERT verify" ],
4089             [ SSL3_MT_FINISHED => "Finished" ],
4090             [ SSL3_MT_CERTIFICATE_STATUS => "Certificate Status" ],
4091             [ SSL3_MT_ENCRYPTED_EXTENSIONS => "Encrypted Extensions" ],
4092             [ SSL3_MT_SUPPLEMENTAL_DATA => "Supplemental data" ],
4093             [ SSL3_MT_END_OF_EARLY_DATA => "End of early data" ],
4094             [ SSL3_MT_KEY_UPDATE => "Key update" ],
4095             [ SSL3_MT_NEXT_PROTO => "Next protocol" ],
4096             [ SSL3_MT_MESSAGE_HASH => "Message hash" ]
4097             ) {
4098             next if $trace_constants{$_->[0]} == -1;
4099             $tc_msgtype2s{$trace_constants{SSL3_VERSION_MAJOR}, $trace_constants{$_->[0]}} = $_->[1];
4100             }
4101              
4102             #
4103             # Translation of curl ossl_trace
4104             #
4105              
4106             sub ossl_trace {
4107 0 0   0   0 $DEBUG>=2 or return;
4108 0         0 my ($direction, $ssl_ver, $content_type, $buf, $len, $ssl) = @_;
4109              
4110             # Restore original $! value on return
4111 0         0 local $!;
4112              
4113 0   0     0 my $verstr = $tc_ver2s{$ssl_ver} || "(version=$ssl_ver)";
4114              
4115             # Log progress for interesting records only (like Handshake or Alert), skip
4116             # all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0).
4117             # For TLS 1.3, skip notification of the decrypted inner Content-Type.
4118              
4119 0 0 0     0 if ($ssl_ver
      0        
4120             && ($content_type != $trace_constants{SSL3_RT_HEADER})
4121             && ($content_type != $trace_constants{SSL3_RT_INNER_CONTENT_TYPE})
4122             ) {
4123              
4124             # the info given when the version is zero is not that useful for us
4125 0         0 $ssl_ver >>= 8; # check the upper 8 bits only below */
4126              
4127             # SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
4128             # always pass-up content-type as 0. But the interesting message-type
4129             # is at 'buf[0]'.
4130              
4131             my $tls_rt_name = ($ssl_ver == $trace_constants{SSL3_VERSION_MAJOR} && $content_type)
4132 0 0 0     0 ? $tc_type2s{$content_type} || "TLS Unknown (type=$content_type)"
      0        
4133             : "";
4134              
4135 0         0 my $msg_type;
4136             my $msg_name;
4137 0 0       0 if ($content_type == $trace_constants{SSL3_RT_CHANGE_CIPHER_SPEC}) {
    0          
4138 0         0 $msg_type = unpack('c1', $buf);
4139 0         0 $msg_name = "Change cipher spec";
4140             } elsif ($content_type == $trace_constants{SSL3_RT_ALERT}) {
4141 0         0 my @c = unpack('c2', $buf);
4142 0         0 $msg_type = ($c[0] << 8) + $c[1];
4143 0   0     0 $msg_name = eval { Net::SSLeay::alert_desc_string_long($msg_type) } || "Unknown alert";
4144             } else {
4145 0         0 $msg_type = unpack('c1', $buf);
4146 0   0     0 $msg_name = $tc_msgtype2s{$ssl_ver, $msg_type} || "Unknown (ssl_ver=$ssl_ver, msg=$msg_type)";
4147             }
4148 0 0       0 DEBUG(sprintf("* %s (%s), %s, %s (%d)",
4149             $verstr, $direction ? "OUT" : "IN", $tls_rt_name, $msg_name, $msg_type));
4150             }
4151              
4152             #
4153             # Here one might want to hexdump $buf (?)
4154             #
4155             # $DEBUG>=4 && printf STDERR "%s", hexdump($buf);
4156             }
4157              
4158              
4159             1;
4160              
4161             __END__