Skip to content

Commit 56e7b40

Browse files
committed
Do not set SNI hostname if connecting to IP address
RFC 6066, section 3, explicitly disallows the use of an IP address as an SNI server name. So check if the connection is being made to an IP address using the resolv regexps, and do not set an SNI hostname in that case. Recent changes to LibreSSL make it more strictly follow RFC 6066, resulting an s.hostname= raising an error if passed an IP address. When such verions of LibreSSL are used, this change not only fixes the net/http tests, it also fixes tests for webrick and open-uri, which both make SSL connections to 127.0.0.1 using net/http in their tests. Note that this results in a warning in the tests, but that is due to an issue in the openssl extension. A pull request has been submitted to the openssl extension to remove that warning. Revert the previous change that modified the regexp used for checking the error message.
1 parent 6ab399d commit 56e7b40

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

lib/net/http.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
require 'net/protocol'
2424
require 'uri'
25+
require 'resolv'
2526
autoload :OpenSSL, 'openssl'
2627

2728
module Net #:nodoc:
@@ -1036,11 +1037,21 @@ def connect
10361037
OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
10371038
OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
10381039
@ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
1040+
1041+
# Server Name Indication (SNI) RFC 3546
1042+
case @address
1043+
when Resolv::IPv4::Regex, Resolv::IPv6::Regex
1044+
# don't set SNI, as IP addresses in SNI is not valid
1045+
# per RFC 6066, section 3.
1046+
else
1047+
ssl_host_address = @address
1048+
end
1049+
10391050
D "starting SSL for #{conn_addr}:#{conn_port}..."
10401051
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
10411052
s.sync_close = true
1042-
# Server Name Indication (SNI) RFC 3546
1043-
s.hostname = @address if s.respond_to? :hostname=
1053+
s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address
1054+
10441055
if @ssl_session and
10451056
Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
10461057
s.session = @ssl_session

test/net/http/test_https.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def test_identity_verify_failure
255255
ex = assert_raise(OpenSSL::SSL::SSLError){
256256
http.request_get("/") {|res| }
257257
}
258-
re_msg = /certificate verify failed|hostname \"#{HOST_IP}\" does not match|ssl3 ext invalid servername/
258+
re_msg = /certificate verify failed|hostname \"#{HOST_IP}\" does not match/
259259
assert_match(re_msg, ex.message)
260260
end
261261

0 commit comments

Comments
 (0)