class HTTPClient::SSLConfig
Represents SSL configuration for HTTPClient
instance. The implementation depends on OpenSSL
.
Trust Anchor Control¶ ↑
SSLConfig
loads ‘httpclient/cacert.pem’ as a trust anchor (trusted certificate(s)) with add_trust_ca
in initialization time. This means that HTTPClient
instance trusts some CA certificates by default, like Web browsers. ‘httpclient/cacert.pem’ is downloaded from curl web site by the author and included in released package.
On JRuby, HTTPClient
uses Java runtime’s trusted CA certificates, not cacert.pem by default. You can load cacert.pem by calling SSLConfig#load_trust_ca
manually like:
HTTPClient.new { self.ssl_config.load_trust_ca }.get("https://...")
You may want to change trust anchor by yourself. Call clear_cert_store
then add_trust_ca
for that purpose.
Constants
- CIPHERS_DEFAULT
Attributes
OpenSSL::X509::X509::Store used for verification. You can reset the store with clear_cert_store
and set the new store with cert_store
=.
Public Class Methods
Source
# File lib/httpclient/ssl_config.rb, line 149 def initialize(client) return unless SSLEnabled @client = client @cert_store = X509::Store.new @cert_store_crl_items = [] @client_cert = @client_key = @client_key_pass = @client_ca = nil @verify_mode = SSL::VERIFY_PEER | SSL::VERIFY_FAIL_IF_NO_PEER_CERT @verify_depth = nil @verify_callback = nil @dest = nil @timeout = nil @ssl_version = :auto # 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) @options |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION) @options |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2) @options |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3) # OpenSSL 0.9.8 default: "ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH" @ciphers = CIPHERS_DEFAULT @cacerts_loaded = false end
Creates a SSLConfig
.
Private Class Methods
Source
# File lib/httpclient/ssl_config.rb, line 73 def attr_config(symbol) name = symbol.to_s ivar_name = "@#{name}" define_method(name) { instance_variable_get(ivar_name) } define_method("#{name}=") { |rhs| if instance_variable_get(ivar_name) != rhs instance_variable_set(ivar_name, rhs) change_notify end } symbol end
Public Instance Methods
Source
# File lib/httpclient/ssl_config.rb, line 274 def add_crl(crl) unless crl.is_a?(X509::CRL) crl = X509::CRL.new(File.open(crl) { |f| f.read }) end @cert_store.add_crl(crl) @cert_store_crl_items << crl @cert_store.flags = X509::V_FLAG_CRL_CHECK | X509::V_FLAG_CRL_CHECK_ALL change_notify end
Adds CRL for verification.
- crl
-
a OpenSSL::X509::CRL or a filename of a PEM/DER formatted OpenSSL::X509::CRL.
On JRuby, instead of setting CRL by yourself you can set following options to let HTTPClient
to perform revocation check with CRL and OCSP: -J-Dcom.sun.security.enableCRLDP=true -J-Dcom.sun.net.ssl.checkRevocation=true ex. jruby -J-Dcom.sun.security.enableCRLDP=true -J-Dcom.sun.net.ssl.checkRevocation=true app.rb
Revoked cert example: test-sspev.verisign.com:2443/test-SSPEV-revoked-verisign.html
Calling this method resets all existing sessions.
Source
# File lib/httpclient/ssl_config.rb, line 237 def add_trust_ca(trust_ca_file_or_hashed_dir) unless File.exist?(trust_ca_file_or_hashed_dir) trust_ca_file_or_hashed_dir = File.join(File.dirname(__FILE__), trust_ca_file_or_hashed_dir) end @cacerts_loaded = true # avoid lazy override add_trust_ca_to_store(@cert_store, trust_ca_file_or_hashed_dir) change_notify end
Sets trust anchor certificate(s) for verification.
- trust_ca_file_or_hashed_dir
-
a filename of a PEM/DER formatted
OpenSSL::X509::Certificate
or a ‘c-rehash’eddirectory name which stores trusted certificate files.
Calling this method resets all existing sessions.
Source
# File lib/httpclient/ssl_config.rb, line 247 def add_trust_ca_to_store(cert_store, trust_ca_file_or_hashed_dir) if FileTest.directory?(trust_ca_file_or_hashed_dir) cert_store.add_path(trust_ca_file_or_hashed_dir) else cert_store.add_file(trust_ca_file_or_hashed_dir) end end
Source
# File lib/httpclient/ssl_config.rb, line 221 def cert_store=(cert_store) # This is object equality check, since OpenSSL::X509::Store doesn't overload == if !@cacerts_loaded || (@cert_store != cert_store) @cacerts_loaded = true # avoid lazy override @cert_store = cert_store change_notify end end
Sets new certificate store (OpenSSL::X509::Store
). don’t use if you don’t know what it is.
Calling this method resets all existing sessions.
Source
# File lib/httpclient/ssl_config.rb, line 144 def cert_store_items; @cert_store._httpclient_cert_store_items; end
Source
# File lib/httpclient/ssl_config.rb, line 208 def clear_cert_store @cacerts_loaded = true # avoid lazy override @cert_store = X509::Store.new if defined? JRUBY_VERSION @cert_store._httpclient_cert_store_items.clear end change_notify end
Drops current certificate store (OpenSSL::X509::Store
) for SSL and create new one for the next session.
Calling this method resets all existing sessions.
Source
# File lib/httpclient/ssl_config.rb, line 344 def default_verify_callback(is_ok, ctx) if $DEBUG if is_ok warn("ok: #{ctx.current_cert.subject.to_s.dump}") else warn("ng: #{ctx.current_cert.subject.to_s.dump} at depth #{ctx.error_depth} - #{ctx.error}: #{ctx.error_string} in #{ctx.chain.inspect}") end warn(ctx.current_cert.to_text) warn(ctx.current_cert.to_pem) end if !is_ok depth = ctx.error_depth code = ctx.error msg = ctx.error_string warn("at depth #{depth} - #{code}: #{msg}") if $DEBUG end is_ok end
Default callback for verification: only dumps error.
Source
# File lib/httpclient/ssl_config.rb, line 257 def load_trust_ca load_cacerts(@cert_store) change_notify end
Loads default trust anchors. Calling this method resets all existing sessions.
Source
# File lib/httpclient/ssl_config.rb, line 364 def sample_verify_callback(is_ok, ctx) unless is_ok depth = ctx.error_depth code = ctx.error msg = ctx.error_string warn("at depth #{depth} - #{code}: #{msg}") if $DEBUG return false end cert = ctx.current_cert self_signed = false ca = false pathlen = nil server_auth = true self_signed = (cert.subject.cmp(cert.issuer) == 0) # Check extensions whatever its criticality is. (sample) cert.extensions.each do |ex| case ex.oid when 'basicConstraints' /CA:(TRUE|FALSE), pathlen:(\d+)/ =~ ex.value ca = ($1 == 'TRUE') pathlen = $2.to_i when 'keyUsage' usage = ex.value.split(/\s*,\s*/) ca = usage.include?('Certificate Sign') server_auth = usage.include?('Key Encipherment') when 'extendedKeyUsage' usage = ex.value.split(/\s*,\s*/) server_auth = usage.include?('Netscape Server Gated Crypto') when 'nsCertType' usage = ex.value.split(/\s*,\s*/) ca = usage.include?('SSL CA') server_auth = usage.include?('SSL Server') end end if self_signed warn('self signing CA') if $DEBUG return true elsif ca warn('middle level CA') if $DEBUG return true elsif server_auth warn('for server authentication') if $DEBUG return true end if pathlen > 2 warn('pathlen > 2') if $DEBUG end return false end
Sample callback method: CAUTION: does not check CRL/ARL.
Source
# File lib/httpclient/ssl_config.rb, line 179 def set_client_cert_file(cert_file, key_file, pass = nil) if (@client_cert != cert_file) || (@client_key != key_file) || (@client_key_pass != pass) @client_cert, @client_key, @client_key_pass = cert_file, key_file, pass change_notify end end
Sets certificate and private key for SSL client authentication.
- cert_file
-
must be a filename of PEM/DER formatted file.
- key_file
-
must be a filename of PEM/DER formatted file. Key must be an RSA key. If you want to use other PKey algorithm, use client_key=.
Calling this method resets all existing sessions if value is changed.
Source
# File lib/httpclient/ssl_config.rb, line 197 def set_default_paths @cacerts_loaded = true # avoid lazy override @cert_store = X509::Store.new @cert_store.set_default_paths change_notify end
Sets OpenSSL’s default trusted CA certificates. Generally, OpenSSL
is configured to use OS’s trusted CA certificates located at /etc/pki/certs or /etc/ssl/certs. Unfortunately OpenSSL’s Windows build does not work with Windows Certificate Storage.
On Windows or when you build OpenSSL
manually, you can set the CA certificates directory by SSL_CERT_DIR env variable at runtime.
SSL_CERT_DIR=/etc/ssl/certs ruby -rhttpclient -e "..."
Calling this method resets all existing sessions.
Source
# File lib/httpclient/ssl_config.rb, line 285 def verify? @verify_mode && (@verify_mode & OpenSSL::SSL::VERIFY_PEER != 0) end
Private Instance Methods
Source
# File lib/httpclient/ssl_config.rb, line 420 def change_notify @client.reset_all nil end
Source
# File lib/httpclient/ssl_config.rb, line 426 def load_cacerts(cert_store) file = File.join(File.dirname(__FILE__), 'cacert.pem') add_trust_ca_to_store(cert_store, file) end
Use 2048 bit certs trust anchor