File Coverage

blib/lib/IO/Socket/SSL.pm
Criterion Covered Total %
statement 1493 1991 74.9
branch 782 1404 55.7
condition 366 677 54.0
subroutine 151 202 74.7
pod 56 86 65.1
total 2848 4360 65.3


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