Skip to content

Commit 001b93a

Browse files
mrpasquiniMatt Pasquini
authored andcommitted
SSL min_version/max_version support
1 parent 4658227 commit 001b93a

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
@@ -95,8 +95,17 @@ def attr_config(symbol)
9595
# String name of OpenSSL's SSL version method name: TLSv1_2, TLSv1_1, TLSv1,
9696
# SSLv2, SSLv23, SSLv3 or :auto (and nil) to allow version negotiation (default).
9797
# See {OpenSSL::SSL::SSLContext::METHODS} for a list of available versions
98-
# in your specific Ruby environment.
98+
# in your specific Ruby environment. This is
99+
# deprecated and only provided for backwards compatibility. Use
100+
# #min_version= and #max_version= instead.
99101
attr_config :ssl_version
102+
# Sets the upper bound on the supported SSL/TLS protocol version.
103+
# See min_version for possible values.
104+
attr_config :max_version
105+
# Sets the lower bound on the supported SSL/TLS protocol version.
106+
# The version may be specified by an integer constant named
107+
# OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
108+
attr_config :min_version
100109
# OpenSSL::X509::Certificate:: certificate for SSL client authentication.
101110
# nil by default. (no client authentication)
102111
attr_config :client_cert
@@ -125,7 +134,7 @@ def attr_config(symbol)
125134
# A number of OpenSSL's SSL options. Default value is
126135
# OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv2
127136
# CAUTION: this is OpenSSL specific option and ignored on JRuby.
128-
# Use ssl_version to specify the TLS version you want to use.
137+
# Use min_version and max_version to specify the TLS versions you want to use.
129138
attr_config :options
130139
# A String of OpenSSL's cipher configuration. Default value is
131140
# ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH
@@ -158,6 +167,8 @@ def initialize(client)
158167
@dest = nil
159168
@timeout = nil
160169
@ssl_version = :auto
170+
@max_version = nil
171+
@min_version = nil
161172
# Follow ruby-ossl's definition
162173
@options = OpenSSL::SSL::OP_ALL
163174
@options &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
@@ -309,6 +320,8 @@ def set_context(ctx) # :nodoc:
309320
ctx.options = @options
310321
ctx.ciphers = @ciphers
311322
ctx.ssl_version = @ssl_version unless @ssl_version == :auto
323+
ctx.min_version = @min_version if @min_version
324+
ctx.max_version = @max_version if @max_version
312325
end
313326

314327
# 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
@@ -251,7 +251,7 @@ def test_no_sslv3
251251
omit('TODO: SSLv3 is not supported in many environments. re-enable when disable TLSv1')
252252
teardown_server
253253
setup_server_with_ssl_version(:SSLv3)
254-
assert_raise(OpenSSL::SSL::SSLError) do
254+
assert_raise(NotImplementedError) do
255255
@client.ssl_config.verify_mode = nil
256256
@client.get("https://localhost:#{serverport}/hello")
257257
end
@@ -266,6 +266,22 @@ def test_allow_tlsv1
266266
end
267267
end
268268

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

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

0 commit comments

Comments
 (0)