From 1dfc377ae3b174b043d3f0ed36de57b0296b34d0 Mon Sep 17 00:00:00 2001 From: rhe Date: Wed, 8 Aug 2018 14:13:55 +0000 Subject: 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 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'lib/net') diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb index c3ee47ef4d..9902f9dc65 100644 --- a/lib/net/ftp.rb +++ b/lib/net/ftp.rb @@ -230,6 +230,10 @@ module Net 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 @@ module Net 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 281b15cedf..683a884f5d 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -983,6 +983,10 @@ module Net #:nodoc: 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 @@ module Net #:nodoc: 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, -- cgit v1.2.3