From 62af0446569ae842de67b636b0bd0bb84ec2c8be Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sun, 22 Oct 2017 05:24:05 +0900 Subject: 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). --- lib/openssl/ssl.rb | 1 + test/test_ssl.rb | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/openssl/ssl.rb b/lib/openssl/ssl.rb index fb143c94..6a6f2b94 100644 --- a/lib/openssl/ssl.rb +++ b/lib/openssl/ssl.rb @@ -136,6 +136,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 # 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 diff --git a/test/test_ssl.rb b/test/test_ssl.rb index 3f17ab0d..011b2af4 100644 --- a/test/test_ssl.rb +++ b/test/test_ssl.rb @@ -811,6 +811,24 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase 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 -- cgit v1.2.3