Skip to content

Commit c74299f

Browse files
committed
SSL min_version/max_version support
1 parent 4d60d8b commit c74299f

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

lib/httpclient/jruby_ssl_socket.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ def self.create_socket(session)
485485
DEFAULT_SSL_PROTOCOL = (java.lang.System.getProperty('java.specification.version') == '1.7') ? 'TLSv1.2' : 'TLS'
486486
def initialize(socket, dest, config, opts = {})
487487
@config = config
488+
raise NotImplementedError.new('SSL min_version is not yet supported by jruby') if config.min_version
489+
raise NotImplementedError.new('SSL max_version is not yet supported by jruby') if config.max_version
490+
488491
begin
489492
@ssl_socket = create_ssl_socket(socket, dest, config, opts)
490493
ssl_version = java_ssl_version(config)

lib/httpclient/ssl_config.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,17 @@ def attr_config(symbol)
9393
# String name of OpenSSL's SSL version method name: TLSv1_2, TLSv1_1, TLSv1,
9494
# SSLv2, SSLv23, SSLv3 or :auto (and nil) to allow version negotiation (default).
9595
# See {OpenSSL::SSL::SSLContext::METHODS} for a list of available versions
96-
# in your specific Ruby environment.
96+
# in your specific Ruby environment. This is
97+
# deprecated and only provided for backwards compatibility. Use
98+
# #min_version= and #max_version= instead.
9799
attr_config :ssl_version
100+
# Sets the upper bound on the supported SSL/TLS protocol version.
101+
# See min_version for possible values.
102+
attr_config :max_version
103+
# Sets the lower bound on the supported SSL/TLS protocol version.
104+
# The version may be specified by an integer constant named
105+
# OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
106+
attr_config :min_version
98107
# OpenSSL::X509::Certificate:: certificate for SSL client authentication.
99108
# nil by default. (no client authentication)
100109
attr_config :client_cert
@@ -123,7 +132,7 @@ def attr_config(symbol)
123132
# A number of OpenSSL's SSL options. Default value is
124133
# OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv2
125134
# CAUTION: this is OpenSSL specific option and ignored on JRuby.
126-
# Use ssl_version to specify the TLS version you want to use.
135+
# Use min_version and max_version to specify the TLS versions you want to use.
127136
attr_config :options
128137
# A String of OpenSSL's cipher configuration. Default value is
129138
# ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH
@@ -154,6 +163,8 @@ def initialize(client)
154163
@dest = nil
155164
@timeout = nil
156165
@ssl_version = :auto
166+
@max_version = nil
167+
@min_version = nil
157168
# Follow ruby-ossl's definition
158169
@options = OpenSSL::SSL::OP_ALL
159170
@options &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
@@ -303,6 +314,8 @@ def set_context(ctx) # :nodoc:
303314
ctx.options = @options
304315
ctx.ciphers = @ciphers
305316
ctx.ssl_version = @ssl_version unless @ssl_version == :auto
317+
ctx.min_version = @min_version if @min_version
318+
ctx.max_version = @max_version if @max_version
306319
end
307320

308321
# post connection check proc for ruby < 1.8.5.

test/test_ssl.rb

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def test_set_default_paths
250250
def test_no_sslv3
251251
teardown_server
252252
setup_server_with_ssl_version(:SSLv3)
253-
assert_raise(OpenSSL::SSL::SSLError) do
253+
assert_raise(NotImplementedError) do
254254
@client.ssl_config.verify_mode = nil
255255
@client.get("https://localhost:#{serverport}/hello")
256256
end
@@ -265,6 +265,22 @@ def test_allow_tlsv1
265265
end
266266
end
267267

268+
def test_allow_with_min_max
269+
teardown_server
270+
setup_server_with_min_and_max_version(:TLS1_2)
271+
if RUBY_ENGINE == 'jruby'
272+
assert_raise(OpenSSL::SSL::SSLError) do
273+
@client.ssl_config.verify_mode = nil
274+
@client.get("https://localhost:#{serverport}/hello")
275+
end
276+
else
277+
assert_nothing_raised do
278+
@client.ssl_config.verify_mode = nil
279+
@client.get("https://localhost:#{serverport}/hello")
280+
end
281+
end
282+
end
283+
268284
def test_use_higher_TLS
269285
omit('TODO: it does not pass with Java 7 or old openssl ')
270286
teardown_server
@@ -499,6 +515,33 @@ def setup_server_with_ssl_version(ssl_version)
499515
@server_thread = start_server_thread(@server)
500516
end
501517

518+
def setup_server_with_min_and_max_version(version)
519+
logger = Logger.new(STDERR)
520+
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
521+
@server = WEBrick::HTTPServer.new(
522+
:BindAddress => "localhost",
523+
:Logger => logger,
524+
:Port => 0,
525+
:AccessLog => [],
526+
:DocumentRoot => DIR,
527+
:SSLEnable => true,
528+
:SSLCACertificateFile => File.join(DIR, 'ca.cert'),
529+
:SSLCertificate => cert('server.cert'),
530+
:SSLPrivateKey => key('server.key')
531+
)
532+
@server.ssl_context.min_version = version
533+
@server.ssl_context.max_version = version
534+
535+
@serverport = @server.config[:Port]
536+
[:hello].each do |sym|
537+
@server.mount(
538+
"/#{sym}",
539+
WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
540+
)
541+
end
542+
@server_thread = start_server_thread(@server)
543+
end
544+
502545
def setup_server_with_server_cert(ca_cert, server_cert, server_key)
503546
logger = Logger.new(STDERR)
504547
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)

0 commit comments

Comments
 (0)