[ruby/openssl] ssl: fix tests using TLS 1.1 or older

Commit https://github.com/ruby/openssl/commit/aa7f03e18f26 broke test_minmax_version and test_fallback_scsv
on systems using OpenSSL 1.1.1 with a system-wide configuration file
that specifies MinProtocol=TLSv1.2.

http://rubyci.s3.amazonaws.com/debian11/ruby-master/log/20250228T003003Z.fail.html.gz
http://rubyci.s3.amazonaws.com/rhel8/ruby-master/log/20250228T003003Z.fail.html.gz

These test cases were already broken before the commit, but they were
being skipped because check_supported_protocol_versions failed to detect
TLS 1.1 support. To avoid affected by the configuration file, explicitly
reset SSLContext#min_version when TLS 1.1 or older is required.

The test cases are also broken with OpenSSL 3.0 or later, but this is
not currently visible because it still fails to detect TLS 1.1 support.
This is caused by the default SSLContext#security_level value, as
OpenSSL 3.0 changed TLS 1.1 to be disabled at level 1.

https://github.com/ruby/openssl/commit/6d0ea81b5e
This commit is contained in:
Kazuki Yamaguchi 2025-02-28 12:23:27 +09:00 committed by git
parent 42c0722f83
commit a6da77c9e9

View File

@ -1248,12 +1248,16 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
supported = [] supported = []
ctx_proc = proc { |ctx| ctx_proc = proc { |ctx|
# The default security level is 1 in OpenSSL <= 3.1, 2 in OpenSSL >= 3.2
# In OpenSSL >= 3.0, TLS 1.1 or older is disabled at level 1
ctx.security_level = 0
# Explicitly reset them to avoid influenced by OPENSSL_CONF # Explicitly reset them to avoid influenced by OPENSSL_CONF
ctx.min_version = ctx.max_version = nil ctx.min_version = ctx.max_version = nil
} }
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port| start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
possible_versions.each do |ver| possible_versions.each do |ver|
ctx = OpenSSL::SSL::SSLContext.new ctx = OpenSSL::SSL::SSLContext.new
ctx.security_level = 0
ctx.min_version = ctx.max_version = ver ctx.min_version = ctx.max_version = ver
server_connect(port, ctx) { |ssl| server_connect(port, ctx) { |ssl|
ssl.puts "abc"; assert_equal "abc\n", ssl.gets ssl.puts "abc"; assert_equal "abc\n", ssl.gets
@ -1304,11 +1308,15 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# Server enables a single version # Server enables a single version
supported.each do |ver| supported.each do |ver|
ctx_proc = proc { |ctx| ctx.min_version = ctx.max_version = ver } ctx_proc = proc { |ctx|
ctx.security_level = 0
ctx.min_version = ctx.max_version = ver
}
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
supported.each do |cver| supported.each do |cver|
# Client enables a single version # Client enables a single version
ctx1 = OpenSSL::SSL::SSLContext.new ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.security_level = 0
ctx1.min_version = ctx1.max_version = cver ctx1.min_version = ctx1.max_version = cver
if ver == cver if ver == cver
server_connect(port, ctx1) { |ssl| server_connect(port, ctx1) { |ssl|
@ -1323,6 +1331,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
if cver <= OpenSSL::SSL::TLS1_2_VERSION if cver <= OpenSSL::SSL::TLS1_2_VERSION
# Client enables a single version using #ssl_version= # Client enables a single version using #ssl_version=
ctx2 = OpenSSL::SSL::SSLContext.new ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.security_level = 0
ctx2.ssl_version = vmap[cver][:method] ctx2.ssl_version = vmap[cver][:method]
if ver == cver if ver == cver
server_connect(port, ctx2) { |ssl| server_connect(port, ctx2) { |ssl|
@ -1337,6 +1346,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# Client enables all supported versions # Client enables all supported versions
ctx3 = OpenSSL::SSL::SSLContext.new ctx3 = OpenSSL::SSL::SSLContext.new
ctx3.security_level = 0
ctx3.min_version = ctx3.max_version = nil ctx3.min_version = ctx3.max_version = nil
server_connect(port, ctx3) { |ssl| server_connect(port, ctx3) { |ssl|
assert_equal vmap[ver][:name], ssl.ssl_version assert_equal vmap[ver][:name], ssl.ssl_version
@ -1351,12 +1361,17 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# Server sets min_version (earliest is disabled) # Server sets min_version (earliest is disabled)
sver = supported[1] sver = supported[1]
ctx_proc = proc { |ctx| ctx.min_version = sver } ctx_proc = proc { |ctx|
ctx.security_level = 0
ctx.min_version = sver
}
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
supported.each do |cver| supported.each do |cver|
# Client sets min_version # Client sets min_version
ctx1 = OpenSSL::SSL::SSLContext.new ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.security_level = 0
ctx1.min_version = cver ctx1.min_version = cver
ctx1.max_version = 0
server_connect(port, ctx1) { |ssl| server_connect(port, ctx1) { |ssl|
assert_equal vmap[supported.last][:name], ssl.ssl_version assert_equal vmap[supported.last][:name], ssl.ssl_version
ssl.puts "abc"; assert_equal "abc\n", ssl.gets ssl.puts "abc"; assert_equal "abc\n", ssl.gets
@ -1364,6 +1379,8 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# Client sets max_version # Client sets max_version
ctx2 = OpenSSL::SSL::SSLContext.new ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.security_level = 0
ctx2.min_version = 0
ctx2.max_version = cver ctx2.max_version = cver
if cver >= sver if cver >= sver
server_connect(port, ctx2) { |ssl| server_connect(port, ctx2) { |ssl|
@ -1378,7 +1395,11 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# Server sets max_version (latest is disabled) # Server sets max_version (latest is disabled)
sver = supported[-2] sver = supported[-2]
ctx_proc = proc { |ctx| ctx.max_version = sver } ctx_proc = proc { |ctx|
ctx.security_level = 0
ctx.min_version = 0
ctx.max_version = sver
}
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
supported.each do |cver| supported.each do |cver|
# Client sets min_version # Client sets min_version
@ -1395,6 +1416,8 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# Client sets max_version # Client sets max_version
ctx2 = OpenSSL::SSL::SSLContext.new ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.security_level = 0
ctx2.min_version = 0
ctx2.max_version = cver ctx2.max_version = cver
server_connect(port, ctx2) { |ssl| server_connect(port, ctx2) { |ssl|
if cver >= sver if cver >= sver
@ -1771,11 +1794,11 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
def test_fallback_scsv def test_fallback_scsv
supported = check_supported_protocol_versions supported = check_supported_protocol_versions
return unless supported.include?(OpenSSL::SSL::TLS1_1_VERSION) && unless supported.include?(OpenSSL::SSL::TLS1_1_VERSION)
supported.include?(OpenSSL::SSL::TLS1_2_VERSION) omit "TLS 1.1 support is required to run this test case"
end
pend "Fallback SCSV is not supported" unless \ omit "Fallback SCSV is not supported" if libressl?
OpenSSL::SSL::SSLContext.method_defined?(:enable_fallback_scsv)
start_server do |port| start_server do |port|
ctx = OpenSSL::SSL::SSLContext.new ctx = OpenSSL::SSL::SSLContext.new
@ -1786,11 +1809,15 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end end
ctx_proc = proc { |ctx| ctx_proc = proc { |ctx|
ctx.security_level = 0
ctx.min_version = 0
ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION
} }
start_server(ctx_proc: ctx_proc) do |port| start_server(ctx_proc: ctx_proc) do |port|
ctx = OpenSSL::SSL::SSLContext.new ctx = OpenSSL::SSL::SSLContext.new
ctx.enable_fallback_scsv ctx.enable_fallback_scsv
ctx.security_level = 0
ctx.min_version = 0
ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION
# Here is OK too # Here is OK too
# TLS1.2 not supported, fallback to TLS1.1 and signaling the fallback # TLS1.2 not supported, fallback to TLS1.1 and signaling the fallback
@ -1808,11 +1835,15 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# Otherwise, this test fails when using openssl 1.1.1 (or later) that supports TLS1.3. # Otherwise, this test fails when using openssl 1.1.1 (or later) that supports TLS1.3.
# TODO: We may need another test for TLS1.3 because it seems to have a different mechanism. # TODO: We may need another test for TLS1.3 because it seems to have a different mechanism.
ctx1 = OpenSSL::SSL::SSLContext.new ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.security_level = 0
ctx1.min_version = 0
ctx1.max_version = OpenSSL::SSL::TLS1_2_VERSION ctx1.max_version = OpenSSL::SSL::TLS1_2_VERSION
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1) s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
ctx2 = OpenSSL::SSL::SSLContext.new ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.enable_fallback_scsv ctx2.enable_fallback_scsv
ctx2.security_level = 0
ctx2.min_version = 0
ctx2.max_version = OpenSSL::SSL::TLS1_1_VERSION ctx2.max_version = OpenSSL::SSL::TLS1_1_VERSION
s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2) s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2)
# AWS-LC has slightly different error messages in all-caps. # AWS-LC has slightly different error messages in all-caps.