Fix TLS 1.3 issues.
This commit is contained in:
parent
ab0834da77
commit
91a9a89fab
203
ruby-2.6.0-fix-test-failure-with-TLS-1.3.patch
Normal file
203
ruby-2.6.0-fix-test-failure-with-TLS-1.3.patch
Normal file
@ -0,0 +1,203 @@
|
||||
From 6fcc6c0efc42d1c6325cf4bb0ca16e2a448cdbed Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Mon, 6 Aug 2018 20:51:42 +0900
|
||||
Subject: [PATCH] test/test_ssl: fix test failure with TLS 1.3
|
||||
|
||||
SSL_connect() on the client side may return before SSL_accept() on
|
||||
server side returns. This will fix test failures with OpenSSL's current
|
||||
master.
|
||||
---
|
||||
test/openssl/test_ssl.rb | 45 ++++++++++++++++++++++++++--------------
|
||||
test/openssl/test_ssl_session.rb | 1 +
|
||||
2 files changed, 31 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
|
||||
index 7bb32adf..408c7d82 100644
|
||||
--- a/test/openssl/test_ssl.rb
|
||||
+++ b/test/openssl/test_ssl.rb
|
||||
@@ -47,6 +47,8 @@ def test_ssl_with_server_cert
|
||||
assert_equal 2, ssl.peer_cert_chain.size
|
||||
assert_equal @svr_cert.to_der, ssl.peer_cert_chain[0].to_der
|
||||
assert_equal @ca_cert.to_der, ssl.peer_cert_chain[1].to_der
|
||||
+
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
ensure
|
||||
ssl&.close
|
||||
sock&.close
|
||||
@@ -157,6 +159,7 @@ def test_sync_close
|
||||
sock = TCPSocket.new("127.0.0.1", port)
|
||||
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
||||
ssl.connect
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
ssl.close
|
||||
assert_not_predicate sock, :closed?
|
||||
ensure
|
||||
@@ -168,6 +171,7 @@ def test_sync_close
|
||||
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
||||
ssl.sync_close = true # !!
|
||||
ssl.connect
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
ssl.close
|
||||
assert_predicate sock, :closed?
|
||||
ensure
|
||||
@@ -259,7 +263,10 @@ def test_client_ca
|
||||
client_ca_from_server = sslconn.client_ca
|
||||
[@cli_cert, @cli_key]
|
||||
end
|
||||
- server_connect(port, ctx) { |ssl| assert_equal([@ca], client_ca_from_server) }
|
||||
+ server_connect(port, ctx) { |ssl|
|
||||
+ assert_equal([@ca], client_ca_from_server)
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
+ }
|
||||
}
|
||||
end
|
||||
|
||||
@@ -356,21 +363,16 @@ def test_verify_result
|
||||
}
|
||||
|
||||
start_server { |port|
|
||||
- sock = TCPSocket.new("127.0.0.1", port)
|
||||
ctx = OpenSSL::SSL::SSLContext.new
|
||||
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||
ctx.verify_callback = Proc.new do |preverify_ok, store_ctx|
|
||||
store_ctx.error = OpenSSL::X509::V_OK
|
||||
true
|
||||
end
|
||||
- ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
||||
- ssl.sync_close = true
|
||||
- begin
|
||||
- ssl.connect
|
||||
+ server_connect(port, ctx) { |ssl|
|
||||
assert_equal(OpenSSL::X509::V_OK, ssl.verify_result)
|
||||
- ensure
|
||||
- ssl.close
|
||||
- end
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
+ }
|
||||
}
|
||||
|
||||
start_server(ignore_listener_error: true) { |port|
|
||||
@@ -455,6 +457,8 @@ def test_post_connection_check
|
||||
|
||||
start_server { |port|
|
||||
server_connect(port) { |ssl|
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
+
|
||||
assert_raise(sslerr){ssl.post_connection_check("localhost.localdomain")}
|
||||
assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")}
|
||||
assert(ssl.post_connection_check("localhost"))
|
||||
@@ -476,6 +482,8 @@ def test_post_connection_check
|
||||
@svr_cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
|
||||
start_server { |port|
|
||||
server_connect(port) { |ssl|
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
+
|
||||
assert(ssl.post_connection_check("localhost.localdomain"))
|
||||
assert(ssl.post_connection_check("127.0.0.1"))
|
||||
assert_raise(sslerr){ssl.post_connection_check("localhost")}
|
||||
@@ -496,6 +502,8 @@ def test_post_connection_check
|
||||
@svr_cert = issue_cert(@svr, @svr_key, 5, exts, @ca_cert, @ca_key)
|
||||
start_server { |port|
|
||||
server_connect(port) { |ssl|
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
+
|
||||
assert(ssl.post_connection_check("localhost.localdomain"))
|
||||
assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")}
|
||||
assert_raise(sslerr){ssl.post_connection_check("localhost")}
|
||||
@@ -722,6 +730,8 @@ def test_tlsext_hostname
|
||||
ssl.connect
|
||||
assert_equal @cli_cert.serial, ssl.peer_cert.serial
|
||||
assert_predicate fooctx, :frozen?
|
||||
+
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
ensure
|
||||
ssl&.close
|
||||
sock.close
|
||||
@@ -733,6 +743,8 @@ def test_tlsext_hostname
|
||||
ssl.hostname = "bar.example.com"
|
||||
ssl.connect
|
||||
assert_equal @svr_cert.serial, ssl.peer_cert.serial
|
||||
+
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
ensure
|
||||
ssl&.close
|
||||
sock.close
|
||||
@@ -805,7 +817,8 @@ def test_verify_hostname_on_connect
|
||||
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
||||
ssl.hostname = name
|
||||
if expected_ok
|
||||
- assert_nothing_raised { ssl.connect }
|
||||
+ ssl.connect
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
else
|
||||
assert_handshake_error { ssl.connect }
|
||||
end
|
||||
@@ -1086,6 +1099,7 @@ def test_renegotiation_cb
|
||||
start_server_version(:SSLv23, ctx_proc) { |port|
|
||||
server_connect(port) { |ssl|
|
||||
assert_equal(1, num_handshakes)
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
}
|
||||
}
|
||||
end
|
||||
@@ -1104,6 +1118,7 @@ def test_alpn_protocol_selection_ary
|
||||
ctx.alpn_protocols = advertised
|
||||
server_connect(port, ctx) { |ssl|
|
||||
assert_equal(advertised.first, ssl.alpn_protocol)
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
}
|
||||
}
|
||||
end
|
||||
@@ -1226,14 +1241,11 @@ def test_npn_selected_protocol_too_long
|
||||
end
|
||||
|
||||
def test_close_after_socket_close
|
||||
- server_proc = proc { |ctx, ssl|
|
||||
- # Do nothing
|
||||
- }
|
||||
- start_server(server_proc: server_proc) { |port|
|
||||
+ start_server { |port|
|
||||
sock = TCPSocket.new("127.0.0.1", port)
|
||||
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
||||
- ssl.sync_close = true
|
||||
ssl.connect
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
sock.close
|
||||
assert_nothing_raised do
|
||||
ssl.close
|
||||
@@ -1298,6 +1310,7 @@ def test_get_ephemeral_key
|
||||
ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
|
||||
server_connect(port, ctx) { |ssl|
|
||||
assert_instance_of OpenSSL::PKey::EC, ssl.tmp_key
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -1440,6 +1453,7 @@ def test_ecdh_curves
|
||||
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
|
||||
end
|
||||
end
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
}
|
||||
|
||||
if openssl?(1, 0, 2) || libressl?(2, 5, 1)
|
||||
@@ -1455,6 +1469,7 @@ def test_ecdh_curves
|
||||
|
||||
server_connect(port, ctx) { |ssl|
|
||||
assert_equal "secp521r1", ssl.tmp_key.group.curve_name
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
}
|
||||
end
|
||||
end
|
||||
diff --git a/test/openssl/test_ssl_session.rb b/test/openssl/test_ssl_session.rb
|
||||
index 6db0c2d1..78b160ed 100644
|
||||
--- a/test/openssl/test_ssl_session.rb
|
||||
+++ b/test/openssl/test_ssl_session.rb
|
||||
@@ -113,6 +113,7 @@ def test_resumption
|
||||
non_resumable = nil
|
||||
start_server { |port|
|
||||
server_connect_with_session(port, nil, nil) { |ssl|
|
||||
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||
non_resumable = ssl.session
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
From 1dfc377ae3b174b043d3f0ed36de57b0296b34d0 Mon Sep 17 00:00:00 2001
|
||||
From: rhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
|
||||
Date: Wed, 8 Aug 2018 14:13:55 +0000
|
||||
Subject: [PATCH] net/http, net/ftp: fix session resumption with TLS 1.3
|
||||
|
||||
When TLS 1.3 is in use, the session ticket may not have been sent yet
|
||||
even though a handshake has finished. Also, the ticket could change if
|
||||
multiple session ticket messages are sent by the server. Use
|
||||
SSLContext#session_new_cb instead of calling SSLSocket#session
|
||||
immediately after a handshake. This way also works with earlier protocol
|
||||
versions.
|
||||
|
||||
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64234 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
||||
---
|
||||
lib/net/ftp.rb | 5 ++++-
|
||||
lib/net/http.rb | 7 +++++--
|
||||
test/net/http/test_https.rb | 35 ++++++++++-------------------------
|
||||
3 files changed, 19 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
|
||||
index c3ee47ef4d36..9902f9dc657a 100644
|
||||
--- a/lib/net/ftp.rb
|
||||
+++ b/lib/net/ftp.rb
|
||||
@@ -230,6 +230,10 @@ def initialize(host = nil, user_or_options = {}, passwd = nil, acct = nil)
|
||||
if defined?(VerifyCallbackProc)
|
||||
@ssl_context.verify_callback = VerifyCallbackProc
|
||||
end
|
||||
+ @ssl_context.session_cache_mode =
|
||||
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
|
||||
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
|
||||
+ @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
|
||||
@ssl_session = nil
|
||||
if options[:private_data_connection].nil?
|
||||
@private_data_connection = true
|
||||
@@ -349,7 +353,6 @@ def start_tls_session(sock)
|
||||
if @ssl_context.verify_mode != VERIFY_NONE
|
||||
ssl_sock.post_connection_check(@host)
|
||||
end
|
||||
- @ssl_session = ssl_sock.session
|
||||
return ssl_sock
|
||||
end
|
||||
private :start_tls_session
|
||||
diff --git a/lib/net/http.rb b/lib/net/http.rb
|
||||
index 281b15cedff0..683a884f5dbe 100644
|
||||
--- a/lib/net/http.rb
|
||||
+++ b/lib/net/http.rb
|
||||
@@ -983,6 +983,10 @@ def connect
|
||||
end
|
||||
@ssl_context = OpenSSL::SSL::SSLContext.new
|
||||
@ssl_context.set_params(ssl_parameters)
|
||||
+ @ssl_context.session_cache_mode =
|
||||
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
|
||||
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
|
||||
+ @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
|
||||
D "starting SSL for #{conn_address}:#{conn_port}..."
|
||||
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
|
||||
s.sync_close = true
|
||||
@@ -990,13 +994,12 @@ def connect
|
||||
s.hostname = @address if s.respond_to? :hostname=
|
||||
if @ssl_session and
|
||||
Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
|
||||
- s.session = @ssl_session if @ssl_session
|
||||
+ s.session = @ssl_session
|
||||
end
|
||||
ssl_socket_connect(s, @open_timeout)
|
||||
if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
|
||||
s.post_connection_check(@address)
|
||||
end
|
||||
- @ssl_session = s.session
|
||||
D "SSL established"
|
||||
end
|
||||
@socket = BufferedIO.new(s, read_timeout: @read_timeout,
|
||||
diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb
|
||||
index 8004d5c5f29f..a5182a1fe9db 100644
|
||||
--- a/test/net/http/test_https.rb
|
||||
+++ b/test/net/http/test_https.rb
|
||||
@@ -71,20 +71,11 @@ def test_session_reuse
|
||||
http.get("/")
|
||||
http.finish
|
||||
|
||||
- http.start
|
||||
- http.get("/")
|
||||
- http.finish # three times due to possible bug in OpenSSL 0.9.8
|
||||
-
|
||||
- sid = http.instance_variable_get(:@ssl_session).id
|
||||
-
|
||||
http.start
|
||||
http.get("/")
|
||||
|
||||
socket = http.instance_variable_get(:@socket).io
|
||||
-
|
||||
- assert socket.session_reused?
|
||||
-
|
||||
- assert_equal sid, http.instance_variable_get(:@ssl_session).id
|
||||
+ assert_equal true, socket.session_reused?
|
||||
|
||||
http.finish
|
||||
rescue SystemCallError
|
||||
@@ -101,16 +92,12 @@ def test_session_reuse_but_expire
|
||||
http.get("/")
|
||||
http.finish
|
||||
|
||||
- sid = http.instance_variable_get(:@ssl_session).id
|
||||
-
|
||||
http.start
|
||||
http.get("/")
|
||||
|
||||
socket = http.instance_variable_get(:@socket).io
|
||||
assert_equal false, socket.session_reused?
|
||||
|
||||
- assert_not_equal sid, http.instance_variable_get(:@ssl_session).id
|
||||
-
|
||||
http.finish
|
||||
rescue SystemCallError
|
||||
skip $!
|
||||
@@ -160,15 +147,16 @@ def test_certificate_verify_failure
|
||||
end
|
||||
|
||||
def test_identity_verify_failure
|
||||
+ # the certificate's subject has CN=localhost
|
||||
http = Net::HTTP.new("127.0.0.1", config("port"))
|
||||
http.use_ssl = true
|
||||
- http.verify_callback = Proc.new do |preverify_ok, store_ctx|
|
||||
- true
|
||||
- end
|
||||
+ http.cert_store = TEST_STORE
|
||||
+ @log_tester = lambda {|_| }
|
||||
ex = assert_raise(OpenSSL::SSL::SSLError){
|
||||
http.request_get("/") {|res| }
|
||||
}
|
||||
- assert_match(/hostname \"127.0.0.1\" does not match/, ex.message)
|
||||
+ re_msg = /certificate verify failed|hostname \"127.0.0.1\" does not match/
|
||||
+ assert_match(re_msg, ex.message)
|
||||
end
|
||||
|
||||
def test_timeout_during_SSL_handshake
|
||||
@@ -193,16 +181,13 @@ def test_timeout_during_SSL_handshake
|
||||
end
|
||||
|
||||
def test_min_version
|
||||
- http = Net::HTTP.new("127.0.0.1", config("port"))
|
||||
+ http = Net::HTTP.new("localhost", config("port"))
|
||||
http.use_ssl = true
|
||||
http.min_version = :TLS1
|
||||
- http.verify_callback = Proc.new do |preverify_ok, store_ctx|
|
||||
- true
|
||||
- end
|
||||
- ex = assert_raise(OpenSSL::SSL::SSLError){
|
||||
- http.request_get("/") {|res| }
|
||||
+ http.cert_store = TEST_STORE
|
||||
+ http.request_get("/") {|res|
|
||||
+ assert_equal($test_net_http_data, res.body)
|
||||
}
|
||||
- assert_match(/hostname \"127.0.0.1\" does not match/, ex.message)
|
||||
end
|
||||
|
||||
def test_max_version
|
17
ruby.spec
17
ruby.spec
@ -21,7 +21,7 @@
|
||||
%endif
|
||||
|
||||
|
||||
%global release 96
|
||||
%global release 97
|
||||
%{!?release_string:%global release_string %{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
|
||||
|
||||
# The RubyGems library has to stay out of Ruby directory three, since the
|
||||
@ -148,6 +148,10 @@ Patch16: ruby-2.5.1-Avoid-need-of-C++-compiler-to-pass-the-test-suite.patch
|
||||
# Fix some OpenSSL 1.1.1 test failures.
|
||||
# https://github.com/ruby/openssl/pull/202
|
||||
Patch17: ruby-2.5.1-Test-fixes-for-OpenSSL-1.1.1.patch
|
||||
# https://github.com/ruby/openssl/pull/209
|
||||
Patch18: ruby-2.6.0-fix-test-failure-with-TLS-1.3.patch
|
||||
# https://github.com/ruby/ruby/commit/1dfc377ae3b174b043d3f0ed36de57b0296b34d0
|
||||
Patch19: ruby-2.6.0-net-http-net-ftp-fix-session-resumption-with-TLS-1.3.patch
|
||||
|
||||
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
|
||||
Suggests: rubypick
|
||||
@ -534,6 +538,8 @@ rm -rf ext/fiddle/libffi*
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
|
||||
# Provide an example of usage of the tapset:
|
||||
cp -a %{SOURCE3} .
|
||||
@ -759,10 +765,10 @@ sed -i '/def test_mdns_each_address$/,/^ end$/ s/^/#/' test/resolv/test_mdns.rb
|
||||
|
||||
# For now, disable some OpenSSL tests incompatible with OpenSSL 1.1.1:
|
||||
# https://github.com/ruby/openssl/issues/207
|
||||
mv test/openssl/test_ssl.rb{,.disabled}
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/test_resumption/"
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/test_\(identity_verify_failure\|min_version\|session_reuse\)/"
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/test_\(add_certificate\|minmax_version\|options_disable_versions\|set_params_min_version\)/"
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/test_do_not_allow_invalid_client_cert_auth_connection/"
|
||||
# https://github.com/ruby/openssl/issues/208
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/^test_constants$/"
|
||||
|
||||
make check TESTS="-v $DISABLE_TESTS"
|
||||
|
||||
@ -1083,6 +1089,9 @@ make check TESTS="-v $DISABLE_TESTS"
|
||||
%{gem_dir}/specifications/xmlrpc-%{xmlrpc_version}.gemspec
|
||||
|
||||
%changelog
|
||||
* Mon Aug 13 2018 Vít Ondruch <vondruch@redhat.com> - 2.5.1-97
|
||||
- Fix TLS 1.3 issues.
|
||||
|
||||
* Tue Jul 31 2018 Florian Weimer <fweimer@redhat.com> - 2.5.1-96
|
||||
- Rebuild with fixed binutils
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user