Skip to content

Commit

Permalink
ssl: fix conflict of options in SSLContext#set_params
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
rhenium committed Oct 22, 2017
1 parent d1018a1 commit 62af044
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/openssl/ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def initialize(version = nil)
# used.
def set_params(params={})
params = DEFAULT_PARAMS.merge(params)
self.options = params.delete(:options) # set before min_version/max_version
params.each{|name, value| self.__send__("#{name}=", value) }
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
unless self.ca_file or self.ca_path or self.cert_store
Expand Down
18 changes: 18 additions & 0 deletions test/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,24 @@ def check_supported_protocol_versions
supported
end

def test_set_params_min_version
supported = check_supported_protocol_versions
store = OpenSSL::X509::Store.new
store.add_cert(@ca_cert)

if supported.include?(OpenSSL::SSL::SSL3_VERSION)
# SSLContext#set_params properly disables SSL 3.0 by default
ctx_proc = proc { |ctx|
ctx.min_version = ctx.max_version = OpenSSL::SSL::SSL3_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) { } }
}
end
end

def test_minmax_version
supported = check_supported_protocol_versions

Expand Down

0 comments on commit 62af044

Please sign in to comment.