Blob Blame History Raw
From d432295468a1efa18e56c1fbb34e3a23bb07d1e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
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ř <ppisar@redhat.com>
---
 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') {
+        # <https://www.openssl.org/blog/blog/2017/05/04/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