lib/openssl/ssl.rb in rubysl-openssl-2.10 vs lib/openssl/ssl.rb in rubysl-openssl-2.11
- old
+ new
@@ -14,72 +14,64 @@
require "io/nonblock"
module OpenSSL
module SSL
class SSLContext
- DEFAULT_PARAMS = {
+ DEFAULT_PARAMS = { # :nodoc:
:ssl_version => "SSLv23",
:verify_mode => OpenSSL::SSL::VERIFY_PEER,
- :ciphers => %w{
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384
- DHE-RSA-AES128-GCM-SHA256
- DHE-DSS-AES128-GCM-SHA256
- DHE-RSA-AES256-GCM-SHA384
- DHE-DSS-AES256-GCM-SHA384
- ECDHE-ECDSA-AES128-SHA256
- ECDHE-RSA-AES128-SHA256
- ECDHE-ECDSA-AES128-SHA
- ECDHE-RSA-AES128-SHA
- ECDHE-ECDSA-AES256-SHA384
- ECDHE-RSA-AES256-SHA384
- ECDHE-ECDSA-AES256-SHA
- ECDHE-RSA-AES256-SHA
- DHE-RSA-AES128-SHA256
- DHE-RSA-AES256-SHA256
- DHE-RSA-AES128-SHA
- DHE-RSA-AES256-SHA
- DHE-DSS-AES128-SHA256
- DHE-DSS-AES256-SHA256
- DHE-DSS-AES128-SHA
- DHE-DSS-AES256-SHA
- AES128-GCM-SHA256
- AES256-GCM-SHA384
- AES128-SHA256
- AES256-SHA256
- AES128-SHA
- AES256-SHA
- ECDHE-ECDSA-RC4-SHA
- ECDHE-RSA-RC4-SHA
- RC4-SHA
- }.join(":"),
+ :verify_hostname => true,
:options => -> {
opts = OpenSSL::SSL::OP_ALL
- opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
+ opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
- opts |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2)
- opts |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3)
+ opts |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
opts
}.call
}
- DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
- DEFAULT_CERT_STORE.set_default_paths
- if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
- DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
+ if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") &&
+ OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000)
+ DEFAULT_PARAMS.merge!(
+ ciphers: %w{
+ ECDHE-ECDSA-AES128-GCM-SHA256
+ ECDHE-RSA-AES128-GCM-SHA256
+ ECDHE-ECDSA-AES256-GCM-SHA384
+ ECDHE-RSA-AES256-GCM-SHA384
+ DHE-RSA-AES128-GCM-SHA256
+ DHE-DSS-AES128-GCM-SHA256
+ DHE-RSA-AES256-GCM-SHA384
+ DHE-DSS-AES256-GCM-SHA384
+ ECDHE-ECDSA-AES128-SHA256
+ ECDHE-RSA-AES128-SHA256
+ ECDHE-ECDSA-AES128-SHA
+ ECDHE-RSA-AES128-SHA
+ ECDHE-ECDSA-AES256-SHA384
+ ECDHE-RSA-AES256-SHA384
+ ECDHE-ECDSA-AES256-SHA
+ ECDHE-RSA-AES256-SHA
+ DHE-RSA-AES128-SHA256
+ DHE-RSA-AES256-SHA256
+ DHE-RSA-AES128-SHA
+ DHE-RSA-AES256-SHA
+ DHE-DSS-AES128-SHA256
+ DHE-DSS-AES256-SHA256
+ DHE-DSS-AES128-SHA
+ DHE-DSS-AES256-SHA
+ AES128-GCM-SHA256
+ AES256-GCM-SHA384
+ AES128-SHA256
+ AES256-SHA256
+ AES128-SHA
+ AES256-SHA
+ }.join(":"),
+ )
end
- INIT_VARS = ["cert", "key", "client_ca", "ca_file", "ca_path",
- "timeout", "verify_mode", "verify_depth", "renegotiation_cb",
- "verify_callback", "cert_store", "extra_chain_cert",
- "client_cert_cb", "session_id_context", "tmp_dh_callback",
- "session_get_cb", "session_new_cb", "session_remove_cb",
- "tmp_ecdh_callback", "servername_cb", "npn_protocols",
- "alpn_protocols", "alpn_select_cb",
- "npn_select_cb"].map { |x| "@#{x}" }
+ DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc:
+ DEFAULT_CERT_STORE.set_default_paths
+ DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
# A callback invoked when DH parameters are required.
#
# The callback is invoked with the Session for the key exchange, an
# flag indicating the use of an export cipher and the keylength
@@ -88,40 +80,40 @@
# The callback must return an OpenSSL::PKey::DH instance of the correct
# key length.
attr_accessor :tmp_dh_callback
- if ExtConfig::HAVE_TLSEXT_HOST_NAME
- # A callback invoked at connect time to distinguish between multiple
- # server names.
- #
- # The callback is invoked with an SSLSocket and a server name. The
- # callback must return an SSLContext for the server name or nil.
- attr_accessor :servername_cb
- end
+ # A callback invoked at connect time to distinguish between multiple
+ # server names.
+ #
+ # The callback is invoked with an SSLSocket and a server name. The
+ # callback must return an SSLContext for the server name or nil.
+ attr_accessor :servername_cb if ExtConfig::HAVE_TLSEXT_HOST_NAME
# call-seq:
# SSLContext.new => ctx
# SSLContext.new(:TLSv1) => ctx
# SSLContext.new("SSLv23_client") => ctx
#
# You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
def initialize(version = nil)
- INIT_VARS.each { |v| instance_variable_set v, nil }
- self.options = self.options | OpenSSL::SSL::OP_ALL
- return unless version
- self.ssl_version = version
+ self.options |= OpenSSL::SSL::OP_ALL
+ self.ssl_version = version if version
end
##
- # Sets the parameters for this SSL context to the values in +params+.
+ # call-seq:
+ # ctx.set_params(params = {}) -> params
+ #
+ # Sets saner defaults optimized for the use with HTTP-like protocols.
+ #
+ # If a Hash +params+ is given, the parameters are overridden with it.
# The keys in +params+ must be assignment methods on SSLContext.
#
# If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
# cert_store are not set then the system default certificate store is
# used.
-
def set_params(params={})
params = DEFAULT_PARAMS.merge(params)
params.each{|name, value| self.__send__("#{name}=", value) }
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
unless self.ca_file or self.ca_path or self.cert_store
@@ -250,48 +242,24 @@
class SSLSocket
include Buffering
include SocketForwarder
- if ExtConfig::OPENSSL_NO_SOCK
- def initialize(io, ctx = nil); raise NotImplementedError; end
- else
- if ExtConfig::HAVE_TLSEXT_HOST_NAME
- attr_accessor :hostname
- end
+ if ExtConfig::HAVE_TLSEXT_HOST_NAME
+ attr_reader :hostname
+ end
- attr_reader :io, :context
- attr_accessor :sync_close
- alias :to_io :io
+ # The underlying IO object.
+ attr_reader :io
+ alias :to_io :io
- # call-seq:
- # SSLSocket.new(io) => aSSLSocket
- # SSLSocket.new(io, ctx) => aSSLSocket
- #
- # Creates a new SSL socket from +io+ which must be a real ruby object (not an
- # IO-like object that responds to read/write).
- #
- # If +ctx+ is provided the SSL Sockets initial params will be taken from
- # the context.
- #
- # The OpenSSL::Buffering module provides additional IO methods.
- #
- # This method will freeze the SSLContext if one is provided;
- # however, session management is still allowed in the frozen SSLContext.
+ # The SSLContext object used in this connection.
+ attr_reader :context
- def initialize(io, context = OpenSSL::SSL::SSLContext.new)
- @io = io
- @context = context
- @sync_close = false
- @hostname = nil
- @io.nonblock = true if @io.respond_to?(:nonblock=)
- Rubinius.synchronize(SSL) do
- context.setup
- end
- super()
- end
- end
+ # Whether to close the underlying socket as well, when the SSL/TLS
+ # connection is shut down. This defaults to +false+.
+ attr_accessor :sync_close
# call-seq:
# ssl.sysclose => nil
#
# Sends "close notify" to the peer and tries to shut down the SSL
@@ -302,29 +270,37 @@
return if closed?
stop
io.close if sync_close
end
- ##
- # Perform hostname verification after an SSL connection is established
+ # call-seq:
+ # ssl.post_connection_check(hostname) -> true
#
+ # Perform hostname verification following RFC 6125.
+ #
# This method MUST be called after calling #connect to ensure that the
# hostname of a remote peer has been verified.
def post_connection_check(hostname)
if peer_cert.nil?
msg = "Peer verification enabled, but no certificate received."
if using_anon_cipher?
- msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification."
+ msg += " Anonymous cipher suite #{cipher[0]} was negotiated. " \
+ "Anonymous suites must be disabled to use peer verification."
end
raise SSLError, msg
end
unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
end
return true
end
+ # call-seq:
+ # ssl.session -> aSession
+ #
+ # Returns the SSLSession object currently used, or nil if the session is
+ # not established.
def session
SSL::Session.new(self)
rescue SSL::Session::SessionError
nil
end