Skip to content

Commit 62af044

Browse files
committed
ssl: fix conflict of options in SSLContext#set_params
Make SSLContext#set_params call #options= first. SSLContext#set_params by default disables SSL 2.0 and SSL 3.0 by calling SSLContext#min_version=. After that, it sets the SSL option flags by calling SSLContext#options=. This is problematic when built with OpenSSL before 1.1.0 because SSLContext#min_version= achieves its goal using the SSL_OP_NO_{SSL,TLS}* options. Since the subsequent SSLContext#options= call replaces the flags rather than OR together, this results in effectively disabling min_version setting in SSLContext::DEFAULT_PARAMS. The issue was first fixed in Ruby trunk tree, as part of r60310 ("fix OpenSSL::SSL::SSLContext#min_version doesn't work", 2017-10-21).
1 parent d1018a1 commit 62af044

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

lib/openssl/ssl.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def initialize(version = nil)
136136
# used.
137137
def set_params(params={})
138138
params = DEFAULT_PARAMS.merge(params)
139+
self.options = params.delete(:options) # set before min_version/max_version
139140
params.each{|name, value| self.__send__("#{name}=", value) }
140141
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
141142
unless self.ca_file or self.ca_path or self.cert_store

test/test_ssl.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,24 @@ def check_supported_protocol_versions
811811
supported
812812
end
813813

814+
def test_set_params_min_version
815+
supported = check_supported_protocol_versions
816+
store = OpenSSL::X509::Store.new
817+
store.add_cert(@ca_cert)
818+
819+
if supported.include?(OpenSSL::SSL::SSL3_VERSION)
820+
# SSLContext#set_params properly disables SSL 3.0 by default
821+
ctx_proc = proc { |ctx|
822+
ctx.min_version = ctx.max_version = OpenSSL::SSL::SSL3_VERSION
823+
}
824+
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
825+
ctx = OpenSSL::SSL::SSLContext.new
826+
ctx.set_params(cert_store: store, verify_hostname: false)
827+
assert_handshake_error { server_connect(port, ctx) { } }
828+
}
829+
end
830+
end
831+
814832
def test_minmax_version
815833
supported = check_supported_protocol_versions
816834

0 commit comments

Comments
 (0)