diff --git a/IO-Socket-SSL-2.059-Adapt-to-OpenSSL-1.1.1.patch b/IO-Socket-SSL-2.059-Adapt-to-OpenSSL-1.1.1.patch new file mode 100644 index 0000000..e260fcf --- /dev/null +++ b/IO-Socket-SSL-2.059-Adapt-to-OpenSSL-1.1.1.patch @@ -0,0 +1,142 @@ +From d432295468a1efa18e56c1fbb34e3a23bb07d1e8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Thu, 16 Aug 2018 14:56:23 +0200 +Subject: [PATCH] Adapt to OpenSSL 1.1.1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It needs patched Net-SSLeay (CPAN RT#125218). + +This patch introduces some TLSv1.3 identifiers but does not document +them. This is to let the IO-Socket-SSL maintainer to define the API. + +This is not a final patch. We need to fix failures in: + +t/npn.t +t/session_ticket.t +t/sni_verify.t + +Signed-off-by: Petr Písař +--- + lib/IO/Socket/SSL.pm | 17 +++++++++++++++-- + t/ecdhe.t | 16 +++++++++++----- + t/protocol_version.t | 4 ++-- + t/session_ticket.t | 2 ++ + 4 files changed, 30 insertions(+), 9 deletions(-) + +diff --git a/lib/IO/Socket/SSL.pm b/lib/IO/Socket/SSL.pm +index 9c81ffc..5b43467 100644 +--- a/lib/IO/Socket/SSL.pm ++++ b/lib/IO/Socket/SSL.pm +@@ -211,7 +211,8 @@ BEGIN{ + # get constants for SSL_OP_NO_* now, instead calling the related functions + # every time we setup a connection + my %SSL_OP_NO; +-for(qw( SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv11:TLSv1_1 TLSv1_2 TLSv12:TLSv1_2 )) { ++for(qw( SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv11:TLSv1_1 TLSv1_2 TLSv12:TLSv1_2 ++ TLSv1_3 TLSv13:TLSv1_3 )) { + my ($k,$op) = m{:} ? split(m{:},$_,2) : ($_,$_); + my $sub = "Net::SSLeay::OP_NO_$op"; + local $SIG{__DIE__}; +@@ -1836,6 +1837,7 @@ sub get_sslversion { + my $ssl = shift()->_get_ssl_object || return; + my $version = Net::SSLeay::version($ssl) or return; + return ++ $version == 0x0304 ? 'TLSv1_3' : + $version == 0x0303 ? 'TLSv1_2' : + $version == 0x0302 ? 'TLSv1_1' : + $version == 0x0301 ? 'TLSv1' : +@@ -2281,7 +2283,7 @@ sub new { + + my $ver = ''; + for (split(/\s*:\s*/,$arg_hash->{SSL_version})) { +- m{^(!?)(?:(SSL(?:v2|v3|v23|v2/3))|(TLSv1(?:_?[12])?))$}i ++ m{^(!?)(?:(SSL(?:v2|v3|v23|v2/3))|(TLSv1(?:_?[123])?))$}i + or croak("invalid SSL_version specified"); + my $not = $1; + ( my $v = lc($2||$3) ) =~s{^(...)}{\U$1}; +@@ -2329,6 +2331,17 @@ sub new { + IO::Socket::SSL->error("SSL Context init failed"); + $CTX_CREATED_IN_THIS_THREAD{$ctx} = 1 if $use_threads; + ++ # There is no CTX_tlsv1_3_new(). Create TLSv1.3 only context using ++ # a flexible method. ++ if ($ver eq 'TLSv1_3') { ++ if (!Net::SSLeay::CTX_set_min_proto_version($ctx, ++ Net::SSLeay::TLS1_3_VERSION()) or ++ !Net::SSLeay::CTX_set_max_proto_version($ctx, ++ Net::SSLeay::TLS1_3_VERSION())) { ++ IO::Socket::SSL->error("TLSv1_3 context init failed"); ++ } ++ } ++ + # SSL_OP_CIPHER_SERVER_PREFERENCE + $ssl_op |= 0x00400000 if $arg_hash->{SSL_honor_cipher_order}; + +diff --git a/t/ecdhe.t b/t/ecdhe.t +index 638d82b..1b229c5 100644 +--- a/t/ecdhe.t ++++ b/t/ecdhe.t +@@ -53,12 +53,18 @@ if ( !defined $pid ) { + }; + ok( "client connected" ); + +- my $cipher = $to_server->get_cipher(); +- if ( $cipher !~m/^ECDHE-/ ) { +- notok("bad key exchange: $cipher"); +- exit; ++ my $protocol = $to_server->get_sslversion; ++ if ($protocol eq 'TLSv1_3') { ++ # ++ ok("# SKIP TLSv1.3 doesn't advertize key exchange in a chipher name"); ++ } else { ++ my $cipher = $to_server->get_cipher(); ++ if ( $cipher !~m/^ECDHE-/ ) { ++ notok("bad key exchange: $cipher"); ++ exit; ++ } ++ ok("ecdh key exchange: $cipher"); + } +- ok("ecdh key exchange: $cipher"); + + } else { ###### Server + +diff --git a/t/protocol_version.t b/t/protocol_version.t +index e3853d8..3577720 100644 +--- a/t/protocol_version.t ++++ b/t/protocol_version.t +@@ -13,7 +13,7 @@ plan skip_all => "Test::More has no done_testing" + $|=1; + + my $XDEBUG = 0; +-my @versions = qw(SSLv3 TLSv1 TLSv1_1 TLSv1_2); ++my @versions = qw(SSLv3 TLSv1 TLSv1_1 TLSv1_2 TLSv1_3); + + my $server = IO::Socket::SSL->new( + LocalAddr => '127.0.0.1', +@@ -82,7 +82,7 @@ if ($pid == 0) { + die "best protocol version server supports is $ver" if $supported{foo}; + + # Check if the OpenSSL was compiled without support for specific protocols +- for(qw(SSLv3 TLSv1 TLSv1_1)) { ++ for(qw(SSLv3 TLSv1 TLSv1_1 TLSv1_2 TLSv1_3)) { + if ( ! $check->($_,'')) { + diag("looks like OpenSSL was compiled without $_ support"); + delete $supported{$_}; +diff --git a/t/session_ticket.t b/t/session_ticket.t +index d3c15d9..bff6a86 100644 +--- a/t/session_ticket.t ++++ b/t/session_ticket.t +@@ -73,6 +73,8 @@ my $client = sub { + }; + + ++# FIXME: TLSv1.3 requires to use SSL_CTX_sess_set_new_cb() by clients instead ++# of SSL_get1_session(). Missing from Net::SSLeay. + $client->(0,0,"no initial session -> no reuse"); + $client->(0,1,"reuse with the next session and secret[0]"); + $client->(1,1,"reuse even though server changed, since they share ticket secret"); +-- +2.14.4 + diff --git a/IO-Socket-SSL-2.059-Do-two-way-shutdown-in-t-sni.t.patch b/IO-Socket-SSL-2.059-Do-two-way-shutdown-in-t-sni.t.patch new file mode 100644 index 0000000..2e2b54d --- /dev/null +++ b/IO-Socket-SSL-2.059-Do-two-way-shutdown-in-t-sni.t.patch @@ -0,0 +1,65 @@ +From 1d19a7d01960fd8dc00bb3929a1ffaee186470fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Tue, 21 Aug 2018 16:02:19 +0200 +Subject: [PATCH] Do two-way shutdown in t/sni.t +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +TLSv1.3 performs more reading and writing in SSL_accept(). If a client +disconnects after the handshake but before the server finishes +SSL_accept(), the t/sni.t test would fail because accept() could fail with +ECONNRESET. This happened randomly. + +Failed accept() lead to undef->get_servername() call that triggered +a run-time exception and that caused a client being stucked and the +test script never exited. + +This fixes both these issues. + +Signed-off-by: Petr Písař +--- + t/sni.t | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/t/sni.t b/t/sni.t +index de0f06e..91206de 100644 +--- a/t/sni.t ++++ b/t/sni.t +@@ -68,15 +68,31 @@ if ( $pid == 0 ) { + + $client->verify_hostname($host,'http') or print "not "; + print "ok # client verify hostname in cert $host\n"; ++ # Shutdown TLS properly. Otherwise TLSv1.3 $server->accept() fails with ++ # ECONNRESET when a client disconnects too early. ++ $client->close('SSL_fast_shutdown' => 0); + } + exit; + } + ++# If the server dies, a client can get stuck in read(2) while Perl interpreter ++# is collecting children status in the die handler using wait4(2). ++$SIG{__DIE__} = sub { ++ STDERR->print("Server died. Killing client with $pid PID.\n"); ++ kill(9, $pid); ++}; + for my $host (@tests) { +- my $csock = $server->accept or print "not "; +- print "ok # server accept\n"; ++ my $csock = $server->accept; ++ if (!$csock) { ++ print "not ok # server accept SSL_ERROR='$SSL_ERROR', errno='$!'"; ++ } else { ++ print "ok # server accept\n"; ++ } + my $name = $csock->get_servername; + print "not " if ! $name or $name ne $host; + print "ok # server got SNI name $host\n"; ++ # Shutdown TLS properly. Otherwise TLSv1.3 $server->accept() fails with ++ # ECONNRESET when a client disconnects too early. ++ $csock->close('SSL_fast_shutdown' => 0); + } + wait; +-- +2.14.4 + diff --git a/IO-Socket-SSL-2.059-Do-two-way-shutdown-in-t-sni_verify.t.patch b/IO-Socket-SSL-2.059-Do-two-way-shutdown-in-t-sni_verify.t.patch new file mode 100644 index 0000000..ad3d2df --- /dev/null +++ b/IO-Socket-SSL-2.059-Do-two-way-shutdown-in-t-sni_verify.t.patch @@ -0,0 +1,47 @@ +From 84a3bc6c273977bcd4b709e0d9a3d9fcdd58e36d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Fri, 17 Aug 2018 14:46:33 +0200 +Subject: [PATCH] Do two-way shutdown in t/sni_verify.t +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +OpenSSL 1.1.1-pre7 sigipipes TLSv1.3 server if client does not +shutdown TLS properly. + + +Signed-off-by: Petr Písař +--- + t/sni_verify.t | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/t/sni_verify.t b/t/sni_verify.t +index b3b299b..b5ac4bd 100644 +--- a/t/sni_verify.t ++++ b/t/sni_verify.t +@@ -71,6 +71,13 @@ if ( $pid == 0 ) { + + $client->verify_hostname($host,'http') or print "not "; + print "ok # client verify hostname in cert $host\n"; ++ ++ if ($client) { ++ # Shutdown TLS properly. Otherwise TLSv1.3 server will receive SIGPIPE ++ # in SSL_accept() and dies. ++ # . ++ $client->close('SSL_fast_shutdown' => 0); ++ } + } + exit; + } +@@ -81,5 +88,8 @@ for my $host (@tests) { + my $name = $csock->get_servername; + print "not " if ! $name or $name ne $host; + print "ok # server got SNI name $host\n"; ++ if ($csock) { ++ $csock->close('SSL_fast_shutdown' => 0); ++ } + } + wait; +-- +2.14.4 + diff --git a/IO-Socket-SSL-2.059-Exclude-TLSv1.3-from-t-session_ticket.t.patch b/IO-Socket-SSL-2.059-Exclude-TLSv1.3-from-t-session_ticket.t.patch new file mode 100644 index 0000000..8b13a63 --- /dev/null +++ b/IO-Socket-SSL-2.059-Exclude-TLSv1.3-from-t-session_ticket.t.patch @@ -0,0 +1,59 @@ +From c332d19048735e32e2754685fa3c8654ca068b78 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Tue, 21 Aug 2018 12:32:39 +0200 +Subject: [PATCH] Exclude TLSv1.3 from t/session_ticket.t +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The test fails with OpenSSL 1.1.1 because SSL_get1_session() is not +reliable with TLSv1.3. A proper resumption support would need +migration to SSL_CTX_sess_set_new_cb() API. + +This patch also performs full SSL_shutdown in the test becasue +SSL_get1_session() manual documents that a connection must be properly +SSL_shutdowned, otherwise the session will be removed from the +(internal) session cache. + +Signed-off-by: Petr Písař +--- + t/session_ticket.t | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/t/session_ticket.t b/t/session_ticket.t +index bff6a86..69cbc96 100644 +--- a/t/session_ticket.t ++++ b/t/session_ticket.t +@@ -69,7 +69,7 @@ my $client = sub { + diag("connect to $i: ". + ($cl ? "success reuse=$reuse" : "error: $!,$SSL_ERROR")); + is($reuse,$expect_reuse,$desc); +- close($cl); ++ $cl->close('SSL_fast_shutdown' => 0); + }; + + +@@ -123,6 +123,11 @@ sub _server { + SSL_verify_mode => SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + SSL_ticket_keycb => $get_ticket_key, + SSL_session_id_context => 'foobar', ++ SSL_version => 'SSLv23:!TLSv1_3', # TLSv1.3 sends session tickes after ++ # a handshake, this SSL_get1_session() is not reliable anymore. ++ # Exclude TLSv1.3 from tests. Proper TLSv1.3 session resumption ++ # will need SSL_CTX_sess_set_new_cb(). ++ # + ) or die "failed to create SSL context: $SSL_ERROR"; + } + +@@ -158,7 +163,7 @@ sub _server { + print "rotate secrets\n"; + push @secrets, shift(@secrets); + } +- close($cl); ++ $cl->close('SSL_fast_shutdown' => 0); + alarm(0); + last; + } +-- +2.14.4 + diff --git a/IO-Socket-SSL-2.059-Fix-building-on-systems-without-TLSv1.3-support.patch b/IO-Socket-SSL-2.059-Fix-building-on-systems-without-TLSv1.3-support.patch new file mode 100644 index 0000000..4613520 --- /dev/null +++ b/IO-Socket-SSL-2.059-Fix-building-on-systems-without-TLSv1.3-support.patch @@ -0,0 +1,41 @@ +From 12ff43c81b10446bd74cc719f0a6913040598c58 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Tue, 21 Aug 2018 16:34:39 +0200 +Subject: [PATCH] Fix building on systems without TLSv1.3 support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If OpenSSL does not support TLSv1.3, Net::SSLeay does not have +TLS1_3_VERSION() and t/protocol_version.t fails with: + + # Failed test 'Your vendor has not defined SSLeay macro TLS1_3_VERSION at /home/test/fedora/perl-IO-Socket-SSL/IO-Socket-SSL-2.059/blib/lib/IO/Socket/SSL.pm line 2337. + # ' + # at ./t/testlib.pl line 39. + +This patch fixes creating IO::Socket:SSL context for TLSv1.3 by +checking whether it's supported by Net::SSLeay. + +Signed-off-by: Petr Písař +--- + lib/IO/Socket/SSL.pm | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/IO/Socket/SSL.pm b/lib/IO/Socket/SSL.pm +index 5b43467..7138ab0 100644 +--- a/lib/IO/Socket/SSL.pm ++++ b/lib/IO/Socket/SSL.pm +@@ -2334,6 +2334,10 @@ sub new { + # There is no CTX_tlsv1_3_new(). Create TLSv1.3 only context using + # a flexible method. + if ($ver eq 'TLSv1_3') { ++ if (!eval {Net::SSLeay::TLS1_3_VERSION()}) { ++ return IO::Socket::SSL->_internal_error( ++ "SSL Version $ver not supported",9); ++ } + if (!Net::SSLeay::CTX_set_min_proto_version($ctx, + Net::SSLeay::TLS1_3_VERSION()) or + !Net::SSLeay::CTX_set_max_proto_version($ctx, +-- +2.14.4 + diff --git a/IO-Socket-SSL-2.059-NPN-is-unavailable-in-TLSv1.3.patch b/IO-Socket-SSL-2.059-NPN-is-unavailable-in-TLSv1.3.patch new file mode 100644 index 0000000..6b93df3 --- /dev/null +++ b/IO-Socket-SSL-2.059-NPN-is-unavailable-in-TLSv1.3.patch @@ -0,0 +1,49 @@ +From 94b0b52f05911bd8cfe579406248c8afe36004d7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Fri, 17 Aug 2018 15:14:40 +0200 +Subject: [PATCH] NPN is unavailable in TLSv1.3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +TLSv1.3 does not support NPN. Application can use ALPN. This caused +t/npn.t failures when TLSv1.3 was negotiated. This patch disables +TLSv1.3 in the test. + + + +Signed-off-by: Petr Písař +--- + lib/IO/Socket/SSL.pod | 2 +- + t/npn.t | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/IO/Socket/SSL.pod b/lib/IO/Socket/SSL.pod +index 95401aa..363901b 100644 +--- a/lib/IO/Socket/SSL.pod ++++ b/lib/IO/Socket/SSL.pod +@@ -1336,7 +1336,7 @@ as an array ref. + See also method C. + + Next Protocol Negotiation (NPN) is available with Net::SSLeay 1.46+ and +-openssl-1.0.1+. ++openssl-1.0.1+. NPN is unavailable in TLSv1.3 protocol. + To check support you might call C<< IO::Socket::SSL->can_npn() >>. + If you use this option with an unsupported Net::SSLeay/OpenSSL it will + throw an error. +diff --git a/t/npn.t b/t/npn.t +index 8992a77..6ee6ca6 100644 +--- a/t/npn.t ++++ b/t/npn.t +@@ -25,6 +25,8 @@ my $addr = '127.0.0.1'; + my $server = IO::Socket::SSL->new( + LocalAddr => $addr, + Listen => 2, ++ SSL_version => 'SSLv23:!TLSv1_3', # NPN does not exist in TLSv1.3 ++ # https://github.com/openssl/openssl/issues/3665 + SSL_cert_file => 'certs/server-cert.pem', + SSL_key_file => 'certs/server-key.pem', + SSL_npn_protocols => [qw(one two)], +-- +2.14.4 + diff --git a/perl-IO-Socket-SSL.spec b/perl-IO-Socket-SSL.spec index f9d3c99..fdee340 100644 --- a/perl-IO-Socket-SSL.spec +++ b/perl-IO-Socket-SSL.spec @@ -1,12 +1,30 @@ Name: perl-IO-Socket-SSL Version: 2.059 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Perl library for transparent SSL License: GPL+ or Artistic URL: https://metacpan.org/release/IO-Socket-SSL Source0: https://cpan.metacpan.org/modules/by-module/IO/IO-Socket-SSL-%{version}.tar.gz Patch0: IO-Socket-SSL-2.054-use-system-default-cipher-list.patch Patch1: IO-Socket-SSL-2.059-use-system-default-SSL-version.patch +# Adapt to OpenSSL 1.1.1, it requires patched Net-SSLeay, bug #1616198, +# CPAN RT#126899 +Patch2: IO-Socket-SSL-2.059-Adapt-to-OpenSSL-1.1.1.patch +# Adapt to OpenSSL 1.1.1, it requires patched Net-SSLeay, bug #1616198, +# CPAN RT#126899 +Patch3: IO-Socket-SSL-2.059-Do-two-way-shutdown-in-t-sni_verify.t.patch +# Adapt to OpenSSL 1.1.1, it requires patched Net-SSLeay, bug #1616198, +# CPAN RT#126899 +Patch4: IO-Socket-SSL-2.059-NPN-is-unavailable-in-TLSv1.3.patch +# Adapt to OpenSSL 1.1.1, it requires patched Net-SSLeay, bug #1616198, +# CPAN RT#126899 +Patch5: IO-Socket-SSL-2.059-Exclude-TLSv1.3-from-t-session_ticket.t.patch +# Adapt to OpenSSL 1.1.1, it requires patched Net-SSLeay, bug #1616198, +# CPAN RT#126899 +Patch6: IO-Socket-SSL-2.059-Do-two-way-shutdown-in-t-sni.t.patch +# Adapt to OpenSSL 1.1.1, it requires patched Net-SSLeay, bug #1616198, +# CPAN RT#126899 +Patch7: IO-Socket-SSL-2.059-Fix-building-on-systems-without-TLSv1.3-support.patch BuildArch: noarch # Module Build BuildRequires: coreutils @@ -86,6 +104,14 @@ mod_perl. # Use system-default SSL version too %patch1 +# OpensSSL 1.1.1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 + %build NO_NETWORK_TESTING=1 perl Makefile.PL INSTALLDIRS=vendor make %{?_smp_mflags} @@ -111,6 +137,9 @@ make test %{_mandir}/man3/IO::Socket::SSL::Utils.3* %changelog +* Tue Aug 21 2018 Petr Pisar - 2.059-2 +- Adapt to OpenSSL 1.1.1, it requires patched Net-SSLeay (bug #1616198) + * Thu Aug 16 2018 Paul Howarth - 2.059-1 - Update to 2.059 - Fix memory leak when CRLs are used (CPAN RT#125867)