File Coverage

blib/lib/IO/Socket/SSL.pm
Criterion Covered Total %
statement 1371 1740 78.7
branch 710 1212 58.5
condition 306 561 54.5
subroutine 147 186 79.0
pod 53 81 65.4
total 2587 3780 68.4


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