Skip to content

Commit

Permalink
Merge pull request #853 from rhenium/ky/ssl-test-cleanup-20250206
Browse files Browse the repository at this point in the history
Cleanups in SSL tests
  • Loading branch information
rhenium authored Feb 9, 2025
2 parents f09f920 + 4987688 commit 41e07af
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 65 deletions.
101 changes: 43 additions & 58 deletions test/openssl/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -348,27 +348,27 @@ def test_verify_mode_server_cert
empty_store = OpenSSL::X509::Store.new

# Valid certificate, SSL_VERIFY_PEER
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
ctx.cert_store = populated_store
assert_nothing_raised {
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
ctx.cert_store = populated_store
server_connect(port, ctx) { |ssl| ssl.puts("abc"); ssl.gets }
}

# Invalid certificate, SSL_VERIFY_NONE
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
ctx.cert_store = empty_store
assert_nothing_raised {
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
ctx.cert_store = empty_store
server_connect(port, ctx) { |ssl| ssl.puts("abc"); ssl.gets }
}

# Invalid certificate, SSL_VERIFY_PEER
assert_handshake_error {
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
ctx.cert_store = empty_store
server_connect(port, ctx) { |ssl| ssl.puts("abc"); ssl.gets }
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
ctx.cert_store = empty_store
assert_raise(OpenSSL::SSL::SSLError) {
server_connect(port, ctx)
}
}
end
Expand Down Expand Up @@ -645,15 +645,15 @@ def test_sslctx_set_params

def test_post_connect_check_with_anon_ciphers
ctx_proc = -> ctx {
ctx.ssl_version = :TLSv1_2
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "aNULL"
ctx.tmp_dh = Fixtures.pkey("dh-1")
ctx.security_level = 0
}

start_server(ctx_proc: ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.ssl_version = :TLSv1_2
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "aNULL"
ctx.security_level = 0
server_connect(port, ctx) { |ssl|
Expand Down Expand Up @@ -1111,7 +1111,7 @@ def test_verify_hostname_on_connect
ssl.connect
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
else
assert_handshake_error { ssl.connect }
assert_raise(OpenSSL::SSL::SSLError) { ssl.connect }
end
ensure
ssl.close if ssl
Expand Down Expand Up @@ -1149,7 +1149,7 @@ def test_verify_hostname_failure_error_code
sock = TCPSocket.new("127.0.0.1", port)
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
ssl.hostname = "b.example.com"
assert_handshake_error { ssl.connect }
assert_raise(OpenSSL::SSL::SSLError) { ssl.connect }
assert_equal false, verify_callback_ok
assert_equal OpenSSL::X509::V_ERR_HOSTNAME_MISMATCH, verify_callback_err
ensure
Expand Down Expand Up @@ -1250,7 +1250,7 @@ def test_set_params_min_version
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.set_params(cert_store: store, verify_hostname: false)
assert_handshake_error { server_connect(port, ctx) { } }
assert_raise(OpenSSL::SSL::SSLError) { server_connect(port, ctx) }
}
end
end
Expand Down Expand Up @@ -1283,7 +1283,7 @@ def test_minmax_version
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
else
assert_handshake_error { server_connect(port, ctx1) { } }
assert_raise(OpenSSL::SSL::SSLError) { server_connect(port, ctx1) }
end

# There is no version-specific SSL methods for TLS 1.3
Expand All @@ -1297,7 +1297,7 @@ def test_minmax_version
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
else
assert_handshake_error { server_connect(port, ctx2) { } }
assert_raise(OpenSSL::SSL::SSLError) { server_connect(port, ctx2) }
end
end
end
Expand Down Expand Up @@ -1338,7 +1338,7 @@ def test_minmax_version
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
else
assert_handshake_error { server_connect(port, ctx2) { } }
assert_raise(OpenSSL::SSL::SSLError) { server_connect(port, ctx2) }
end
end
}
Expand All @@ -1357,7 +1357,7 @@ def test_minmax_version
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
else
assert_handshake_error { server_connect(port, ctx1) { } }
assert_raise(OpenSSL::SSL::SSLError) { server_connect(port, ctx1) }
end

# Client sets max_version
Expand Down Expand Up @@ -1489,7 +1489,7 @@ def test_options_disable_versions
# Client only supports TLS 1.2
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_2_VERSION
assert_handshake_error { server_connect(port, ctx1) { } }
assert_raise(OpenSSL::SSL::SSLError) { server_connect(port, ctx1) }

# Client only supports TLS 1.3
ctx2 = OpenSSL::SSL::SSLContext.new
Expand All @@ -1505,7 +1505,7 @@ def test_options_disable_versions
# Client doesn't support TLS 1.2
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_2
assert_handshake_error { server_connect(port, ctx1) { } }
assert_raise(OpenSSL::SSL::SSLError) { server_connect(port, ctx1) }

# Client supports TLS 1.2 by default
ctx2 = OpenSSL::SSL::SSLContext.new
Expand All @@ -1529,7 +1529,7 @@ def test_renegotiation_cb
num_handshakes = 0
renegotiation_cb = Proc.new { |ssl| num_handshakes += 1 }
ctx_proc = Proc.new { |ctx| ctx.renegotiation_cb = renegotiation_cb }
start_server_version(:SSLv23, ctx_proc) { |port|
start_server(ctx_proc: ctx_proc) { |port|
server_connect(port) { |ssl|
assert_equal(1, num_handshakes)
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
Expand All @@ -1545,7 +1545,7 @@ def test_alpn_protocol_selection_ary
}
ctx.alpn_protocols = advertised
}
start_server_version(:SSLv23, ctx_proc) { |port|
start_server(ctx_proc: ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.alpn_protocols = advertised
server_connect(port, ctx) { |ssl|
Expand Down Expand Up @@ -1587,9 +1587,10 @@ def test_npn_protocol_selection_ary

advertised = ["http/1.1", "spdy/2"]
ctx_proc = proc { |ctx| ctx.npn_protocols = advertised }
start_server_version(:TLSv1_2, ctx_proc) { |port|
start_server(ctx_proc: ctx_proc) { |port|
selector = lambda { |which|
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = :TLS1_2
ctx.npn_select_cb = -> (protocols) { protocols.send(which) }
server_connect(port, ctx) { |ssl|
assert_equal(advertised.send(which), ssl.npn_protocol)
Expand All @@ -1609,9 +1610,10 @@ def advertised.each
yield "spdy/2"
end
ctx_proc = Proc.new { |ctx| ctx.npn_protocols = advertised }
start_server_version(:TLSv1_2, ctx_proc) { |port|
start_server(ctx_proc: ctx_proc) { |port|
selector = lambda { |selected, which|
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = :TLS1_2
ctx.npn_select_cb = -> (protocols) { protocols.to_a.send(which) }
server_connect(port, ctx) { |ssl|
assert_equal(selected, ssl.npn_protocol)
Expand All @@ -1626,8 +1628,9 @@ def test_npn_protocol_selection_cancel
return unless OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)

ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["http/1.1"] }
start_server_version(:TLSv1_2, ctx_proc) { |port|
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = :TLS1_2
ctx.npn_select_cb = -> (protocols) { raise RuntimeError.new }
assert_raise(RuntimeError) { server_connect(port, ctx) }
}
Expand All @@ -1636,22 +1639,22 @@ def test_npn_protocol_selection_cancel
def test_npn_advertised_protocol_too_long
return unless OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)

ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["a" * 256] }
start_server_version(:TLSv1_2, ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.npn_select_cb = -> (protocols) { protocols.first }
assert_handshake_error { server_connect(port, ctx) }
}
ctx = OpenSSL::SSL::SSLContext.new
assert_raise(OpenSSL::SSL::SSLError) do
ctx.npn_protocols = ["a" * 256]
ctx.setup
end
end

def test_npn_selected_protocol_too_long
return unless OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)

ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["http/1.1"] }
start_server_version(:TLSv1_2, ctx_proc) { |port|
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = :TLS1_2
ctx.npn_select_cb = -> (protocols) { "a" * 256 }
assert_handshake_error { server_connect(port, ctx) }
assert_raise(OpenSSL::SSL::SSLError) { server_connect(port, ctx) }
}
end

Expand Down Expand Up @@ -1685,12 +1688,12 @@ def test_sync_close_without_connect
def test_get_ephemeral_key
# kRSA
ctx_proc1 = proc { |ctx|
ctx.ssl_version = :TLSv1_2
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "kRSA"
}
start_server(ctx_proc: ctx_proc1, ignore_listener_error: true) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.ssl_version = :TLSv1_2
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "kRSA"
begin
server_connect(port, ctx) { |ssl| assert_nil ssl.tmp_key }
Expand All @@ -1701,15 +1704,15 @@ def test_get_ephemeral_key
end

# DHE
# TODO: How to test this with TLS 1.3?
# TODO: SSL_CTX_set1_groups() is required for testing this with TLS 1.3
ctx_proc2 = proc { |ctx|
ctx.ssl_version = :TLSv1_2
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "EDH"
ctx.tmp_dh = Fixtures.pkey("dh-1")
}
start_server(ctx_proc: ctx_proc2) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.ssl_version = :TLSv1_2
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "EDH"
server_connect(port, ctx) { |ssl|
assert_instance_of OpenSSL::PKey::DH, ssl.tmp_key
Expand Down Expand Up @@ -1881,10 +1884,6 @@ def test_ciphers_method_frozen_object
end

def test_ciphers_method_bogus_csuite
omit "Old #{OpenSSL::OPENSSL_LIBRARY_VERSION}" if
year = OpenSSL::OPENSSL_LIBRARY_VERSION[/\A OpenSSL\s+[01]\..*\s\K\d+\z/x] and
year.to_i <= 2018

ssl_ctx = OpenSSL::SSL::SSLContext.new

assert_raise_with_message(
Expand Down Expand Up @@ -2057,20 +2056,6 @@ def test_export_keying_material

private

def start_server_version(version, ctx_proc = nil,
server_proc = method(:readwrite_loop), &blk)
ctx_wrap = Proc.new { |ctx|
ctx.ssl_version = version
ctx_proc.call(ctx) if ctx_proc
}
start_server(
ctx_proc: ctx_wrap,
server_proc: server_proc,
ignore_listener_error: true,
&blk
)
end

def server_connect(port, ctx = nil)
sock = TCPSocket.new("127.0.0.1", port)
ssl = ctx ? OpenSSL::SSL::SSLSocket.new(sock, ctx) : OpenSSL::SSL::SSLSocket.new(sock)
Expand Down
12 changes: 7 additions & 5 deletions test/openssl/test_ssl_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

class OpenSSL::TestSSLSession < OpenSSL::SSLTestCase
def test_session
ctx_proc = proc { |ctx| ctx.ssl_version = :TLSv1_2 }
ctx_proc = proc { |ctx|
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
}
start_server(ctx_proc: ctx_proc) do |port|
server_connect_with_session(port, nil, nil) { |ssl|
session = ssl.session
Expand Down Expand Up @@ -143,7 +145,7 @@ def test_resumption

def test_server_session_cache
ctx_proc = Proc.new do |ctx|
ctx.ssl_version = :TLSv1_2
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.options |= OpenSSL::SSL::OP_NO_TICKET
end

Expand Down Expand Up @@ -197,7 +199,7 @@ def test_server_session_cache
10.times do |i|
connections = i
cctx = OpenSSL::SSL::SSLContext.new
cctx.ssl_version = :TLSv1_2
cctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
server_connect_with_session(port, cctx, first_session) { |ssl|
ssl.puts("abc"); assert_equal "abc\n", ssl.gets
first_session ||= ssl.session
Expand Down Expand Up @@ -299,11 +301,11 @@ def test_ctx_server_session_cb
connections = nil
called = {}
cctx = OpenSSL::SSL::SSLContext.new
cctx.ssl_version = :TLSv1_2
cctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
sctx = nil
ctx_proc = Proc.new { |ctx|
sctx = ctx
ctx.ssl_version = :TLSv1_2
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.options |= OpenSSL::SSL::OP_NO_TICKET

# get_cb is called whenever a client proposed to resume a session but
Expand Down
3 changes: 1 addition & 2 deletions test/openssl/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def readwrite_loop(ctx, ssl)
end
end

def start_server(verify_mode: OpenSSL::SSL::VERIFY_NONE, start_immediately: true,
def start_server(verify_mode: OpenSSL::SSL::VERIFY_NONE,
ctx_proc: nil, server_proc: method(:readwrite_loop),
accept_proc: proc{},
ignore_listener_error: false, &block)
Expand All @@ -212,7 +212,6 @@ def start_server(verify_mode: OpenSSL::SSL::VERIFY_NONE, start_immediately: true
port = tcps.connect_address.ip_port

ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
ssls.start_immediately = start_immediately

threads = []
begin
Expand Down

0 comments on commit 41e07af

Please sign in to comment.