mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-11-27 00:03:01 -05:00
fixing cerfificate hostname validation callback
This commit is contained in:
parent
0b7dbb8cfa
commit
2ecfde95d8
@ -18,6 +18,8 @@ AllCops:
|
||||
- 'vendor/**/*'
|
||||
- 'www/**/*'
|
||||
- 'lib/httpx/extensions.rb'
|
||||
# Do not lint ffi block, for openssl parity
|
||||
- 'lib/httpx/io/tls/*.rb'
|
||||
|
||||
Metrics/ClassLength:
|
||||
Max: 400
|
||||
|
||||
@ -36,4 +36,3 @@ Style/Documentation:
|
||||
|
||||
Naming/AccessorMethodName:
|
||||
Enabled: false
|
||||
|
||||
@ -100,7 +100,7 @@ module HTTPX
|
||||
# signals TLS invalid status / shutdown.
|
||||
def close_cb(msg = nil)
|
||||
log { "TLS Error: #{msg}, closing" }
|
||||
raise TLSError, msg || "TLS Error"
|
||||
raise TLSError, "TLSError: certificate verify failed (#{msg})"
|
||||
end
|
||||
|
||||
# TLS callback.
|
||||
|
||||
@ -15,19 +15,28 @@ module HTTPX
|
||||
|
||||
bio_out = SSL.BIO_new(SSL.BIO_s_mem)
|
||||
ret = SSL.PEM_write_bio_X509(bio_out, x509)
|
||||
unless ret
|
||||
if ret
|
||||
len = SSL.BIO_pending(bio_out)
|
||||
buffer = FFI::MemoryPointer.new(:char, len, false)
|
||||
size = SSL.BIO_read(bio_out, buffer, len)
|
||||
|
||||
# THis is the callback into the ruby class
|
||||
cert = buffer.read_string(size)
|
||||
SSL.BIO_free(bio_out)
|
||||
raise "Error reading certificate"
|
||||
# InstanceLookup[ssl.address].verify(cert) || preverify_ok.zero? ? 1 : 0
|
||||
box = InstanceLookup[ssl.address]
|
||||
hostname_verify = box.verify(cert)
|
||||
if hostname_verify
|
||||
1
|
||||
else
|
||||
SSL.X509_STORE_CTX_set_error(x509_store, SSL::X509_V_ERR_HOSTNAME_MISMATCH)
|
||||
0
|
||||
end
|
||||
else
|
||||
SSL.BIO_free(bio_out)
|
||||
SSL.X509_STORE_CTX_set_error(x509_store, SSL::X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)
|
||||
0
|
||||
end
|
||||
|
||||
len = SSL.BIO_pending(bio_out)
|
||||
buffer = FFI::MemoryPointer.new(:char, len, false)
|
||||
size = SSL.BIO_read(bio_out, buffer, len)
|
||||
|
||||
# THis is the callback into the ruby class
|
||||
cert = buffer.read_string(size)
|
||||
SSL.BIO_free(bio_out)
|
||||
InstanceLookup[ssl.address].verify(cert) || preverify_ok.zero? ? 1 : 0
|
||||
end
|
||||
|
||||
attr_reader :is_server, :context, :handshake_completed, :hosts, :ssl_version, :cipher, :verify_peer
|
||||
|
||||
@ -60,9 +60,9 @@ module HTTPX
|
||||
set_alpn_negotiation(options[:protocols])
|
||||
end
|
||||
|
||||
|
||||
def cleanup
|
||||
return unless @ssl_ctx
|
||||
|
||||
SSL.SSL_CTX_free(@ssl_ctx)
|
||||
@ssl_ctx = nil
|
||||
end
|
||||
@ -101,9 +101,9 @@ module HTTPX
|
||||
|
||||
def set_min_version(version)
|
||||
return unless version
|
||||
|
||||
num = SSL.const_get("#{version}_VERSION")
|
||||
SSL.SSL_CTX_set_min_proto_version(@ssl_ctx, num) == 1
|
||||
puts "version done"
|
||||
rescue NameError
|
||||
raise Error, "#{version} is unsupported"
|
||||
end
|
||||
@ -124,7 +124,6 @@ module HTTPX
|
||||
else
|
||||
protocols = Context.build_alpn_string(protocols)
|
||||
@alpn_set = SSL.SSL_CTX_set_alpn_protos(@ssl_ctx, protocols, protocols.length) == 0
|
||||
puts "alpn protocols: #{protocols}"
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
@ -148,16 +148,21 @@ module HTTPX
|
||||
attach_function :SSL_set_ex_data, %i[ssl int string], :int
|
||||
callback :verify_callback, %i[int x509], :int
|
||||
attach_function :SSL_set_verify, %i[ssl int verify_callback], :void
|
||||
attach_function :SSL_CTX_set_verify, %i[ssl int verify_callback], :void
|
||||
attach_function :SSL_get_verify_result, %i[ssl], :long
|
||||
attach_function :SSL_connect, [:ssl], :int
|
||||
|
||||
# Verify callback
|
||||
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2
|
||||
X509_V_ERR_HOSTNAME_MISMATCH = 62
|
||||
X509_V_ERR_CERT_REJECTED = 28
|
||||
attach_function :X509_STORE_CTX_get_current_cert, [:pointer], :x509
|
||||
attach_function :SSL_get_ex_data_X509_STORE_CTX_idx, [], :int
|
||||
attach_function :X509_STORE_CTX_get_ex_data, %i[pointer int], :ssl
|
||||
attach_function :X509_STORE_CTX_get_error_depth, %i[x509], :int
|
||||
attach_function :PEM_write_bio_X509, %i[bio x509], :bool
|
||||
attach_function :X509_verify_cert_error_string, %i[long], :string
|
||||
attach_function :X509_STORE_CTX_set_error, %i[ssl_ctx long], :void
|
||||
|
||||
# SSL Context Class
|
||||
# OpenSSL before 1.1.0 do not have these methods
|
||||
@ -230,7 +235,7 @@ module HTTPX
|
||||
|
||||
def self.SSL_set_tlsext_host_name(ssl, host_name)
|
||||
name_ptr = FFI::MemoryPointer.from_string(host_name)
|
||||
raise Error, "error setting SNI hostname" if SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, name_ptr) == 0
|
||||
raise Error, "error setting SNI hostname" if SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, name_ptr).zero?
|
||||
end
|
||||
|
||||
# Server Name Indication (SNI) Support
|
||||
@ -286,7 +291,7 @@ module HTTPX
|
||||
# Deconstructor
|
||||
attach_function :SSL_CTX_free, [:ssl_ctx], :void
|
||||
|
||||
PrivateMaterials = <<~keystr
|
||||
PrivateMaterials = <<~KEYSTR
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQDCYYhcw6cGRbhBVShKmbWm7UVsEoBnUf0cCh8AX+MKhMxwVDWV
|
||||
Igdskntn3cSJjRtmgVJHIK0lpb/FYHQB93Ohpd9/Z18pDmovfFF9nDbFF0t39hJ/
|
||||
@ -325,7 +330,7 @@ module HTTPX
|
||||
Df6hTAs7H3MWww62ddvR8l07AWfSzSP5L6mDsbvq7EmQsmPODwb6C+i2aF3EDL8j
|
||||
uw73m4YIGI0Zw2XdBpiOGkx2H56Kya6mJJe/5XORZedh1wpI7zki01tHYbcy
|
||||
-----END CERTIFICATE-----
|
||||
keystr
|
||||
KEYSTR
|
||||
|
||||
BuiltinPasswdCB = FFI::Function.new(:int, %i[pointer int int pointer]) do |buffer, _len, _flag, _data|
|
||||
buffer.write_string("kittycat")
|
||||
|
||||
@ -112,7 +112,8 @@ class HTTPSTest < Minitest::Test
|
||||
uri = build_uri("/get")
|
||||
response = HTTPX.with(ssl: { hostname: "great-gatsby.com" }).get(uri)
|
||||
assert response.is_a?(HTTPX::ErrorResponse), "response should contain errors"
|
||||
assert response.error.message.include?("certificate verify failed")
|
||||
assert response.error.message.include?("certificate verify failed"),
|
||||
"unexpected error: #{response.error.message}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user