summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2025-02-27 22:56:33 +0900
committergit <svn-admin@ruby-lang.org>2025-02-27 17:18:02 +0000
commitd4b8da66ca9533782d2fed9762783c3e560f2998 (patch)
treeca86dcdf784f400be5178bdbad4e16bba0effc27
parentc0f3dcf7958b07e7d2cf008770594bd9c656fb51 (diff)
[ruby/openssl] ssl: refactor check_supported_protocol_versions
As reported in <https://github.com/ruby/ruby/pull/12823>, check_supported_protocol_versions is unstable and occasionally fails with Errno::ECONNABORTED during SSLSocket#connect on Windows. When the server-side SSLContext specifies an unsupported SSL/TLS protocol version, start_server accepts a TCP connection but closes it without reading ClientHello, as SSLSocket#accept immediately raises an exception. With Winsock, this can cause the client-side SSLSocket#connect to raise Errno::ECONNABORTED. While the simplest fix is to add rescue Errno::ECONNABORTED, this method can be simplified. Instead, let's set up a server that accepts all protocol versions and test client connections with different settings. https://github.com/ruby/openssl/commit/aa7f03e18f
-rw-r--r--test/openssl/test_ssl.rb40
1 files changed, 18 insertions, 22 deletions
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index c0ac7b0052..5fc5665135 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -1244,32 +1244,28 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
OpenSSL::SSL::TLS1_1_VERSION,
OpenSSL::SSL::TLS1_2_VERSION,
OpenSSL::SSL::TLS1_3_VERSION,
- ].compact
+ ]
- # Prepare for testing & do sanity check
supported = []
- possible_versions.each do |ver|
- catch(:unsupported) {
- ctx_proc = proc { |ctx|
- begin
- ctx.min_version = ctx.max_version = ver
- rescue ArgumentError, OpenSSL::SSL::SSLError
- throw :unsupported
- end
+ ctx_proc = proc { |ctx|
+ # Explicitly reset them to avoid influenced by OPENSSL_CONF
+ ctx.min_version = ctx.max_version = nil
+ }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
+ possible_versions.each do |ver|
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.min_version = ctx.max_version = ver
+ server_connect(port, ctx) { |ssl|
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
- begin
- server_connect(port) { |ssl|
- ssl.puts "abc"; assert_equal "abc\n", ssl.gets
- }
- rescue OpenSSL::SSL::SSLError, Errno::ECONNRESET
- else
- supported << ver
- end
- end
- }
+ supported << ver
+ rescue OpenSSL::SSL::SSLError, Errno::ECONNRESET
+ end
end
- assert_not_empty supported
+
+ # Sanity check: in our test suite we assume these are always supported
+ assert_include(supported, OpenSSL::SSL::TLS1_2_VERSION)
+ assert_include(supported, OpenSSL::SSL::TLS1_3_VERSION)
supported
end