Skip to content

Commit

Permalink
SSL min_version/max_version support
Browse files Browse the repository at this point in the history
  • Loading branch information
mrpasquini committed Jul 17, 2020
1 parent 4d60d8b commit 7fca465
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lib/httpclient/jruby_ssl_socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@ def initialize(socket, dest, config, opts = {})
@ssl_socket = create_ssl_socket(socket, dest, config, opts)
ssl_version = java_ssl_version(config)
@ssl_socket.setEnabledProtocols([ssl_version].to_java(java.lang.String)) if ssl_version != DEFAULT_SSL_PROTOCOL
@ssl_socket.setEnabledProtocols([min_version].to_java(java.lang.String)) if min_version
@ssl_socket.setEnabledProtocols([max_version].to_java(java.lang.String)) if max_version
if config.ciphers != SSLConfig::CIPHERS_DEFAULT
@ssl_socket.setEnabledCipherSuites(config.ciphers.to_java(java.lang.String))
end
Expand Down
17 changes: 15 additions & 2 deletions lib/httpclient/ssl_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,17 @@ def attr_config(symbol)
# String name of OpenSSL's SSL version method name: TLSv1_2, TLSv1_1, TLSv1,
# SSLv2, SSLv23, SSLv3 or :auto (and nil) to allow version negotiation (default).
# See {OpenSSL::SSL::SSLContext::METHODS} for a list of available versions
# in your specific Ruby environment.
# in your specific Ruby environment. This is
# deprecated and only provided for backwards compatibility. Use
# #min_version= and #max_version= instead.
attr_config :ssl_version
# Sets the upper bound on the supported SSL/TLS protocol version.
# See min_version for possible values.
attr_config :max_version
# Sets the lower bound on the supported SSL/TLS protocol version.
# The version may be specified by an integer constant named
# OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
attr_config :min_version
# OpenSSL::X509::Certificate:: certificate for SSL client authentication.
# nil by default. (no client authentication)
attr_config :client_cert
Expand Down Expand Up @@ -123,7 +132,7 @@ def attr_config(symbol)
# A number of OpenSSL's SSL options. Default value is
# OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv2
# CAUTION: this is OpenSSL specific option and ignored on JRuby.
# Use ssl_version to specify the TLS version you want to use.
# Use min_version and max_version to specify the TLS versions you want to use.
attr_config :options
# A String of OpenSSL's cipher configuration. Default value is
# ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH
Expand Down Expand Up @@ -154,6 +163,8 @@ def initialize(client)
@dest = nil
@timeout = nil
@ssl_version = :auto
@max_version = nil
@min_version = nil
# Follow ruby-ossl's definition
@options = OpenSSL::SSL::OP_ALL
@options &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
Expand Down Expand Up @@ -303,6 +314,8 @@ def set_context(ctx) # :nodoc:
ctx.options = @options
ctx.ciphers = @ciphers
ctx.ssl_version = @ssl_version unless @ssl_version == :auto
ctx.min_version = @min_version if @min_version
ctx.max_version = @max_version if @max_version
end

# post connection check proc for ruby < 1.8.5.
Expand Down
36 changes: 36 additions & 0 deletions test/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,15 @@ def test_allow_tlsv1
end
end

def test_allow_with_min_max
teardown_server
setup_server_with_min_and_max_version(:TLS1_2)
assert_nothing_raised do
@client.ssl_config.verify_mode = nil
@client.get("https://localhost:#{serverport}/hello")
end
end

def test_use_higher_TLS
omit('TODO: it does not pass with Java 7 or old openssl ')
teardown_server
Expand Down Expand Up @@ -499,6 +508,33 @@ def setup_server_with_ssl_version(ssl_version)
@server_thread = start_server_thread(@server)
end

def setup_server_with_min_and_max_version(version)
logger = Logger.new(STDERR)
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
@server = WEBrick::HTTPServer.new(
:BindAddress => "localhost",
:Logger => logger,
:Port => 0,
:AccessLog => [],
:DocumentRoot => DIR,
:SSLEnable => true,
:SSLCACertificateFile => File.join(DIR, 'ca.cert'),
:SSLCertificate => cert('server.cert'),
:SSLPrivateKey => key('server.key')
)
@server.ssl_context.min_version = version
@server.ssl_context.max_version = version

@serverport = @server.config[:Port]
[:hello].each do |sym|
@server.mount(
"/#{sym}",
WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
)
end
@server_thread = start_server_thread(@server)
end

def setup_server_with_server_cert(ca_cert, server_cert, server_key)
logger = Logger.new(STDERR)
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
Expand Down

0 comments on commit 7fca465

Please sign in to comment.