File Coverage

blib/lib/IO/Socket/SSL.pm
Criterion Covered Total %
statement 1374 1760 78.0
branch 711 1228 57.9
condition 307 575 53.3
subroutine 147 188 78.1
pod 54 82 65.8
total 2593 3833 67.6


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