Class: OpenSSL::SSL::SSLContext
| Relationships & Source Files | |
| Inherits: | Object | 
| Defined in: | ext/openssl/ossl_ssl.c, ext/openssl/lib/openssl/ssl.rb | 
Overview
Constant Summary
- 
    DEFAULT_2048 =
    private
    
 # File 'ext/openssl/lib/openssl/ssl.rb', line 34OpenSSL::PKey::DH.new <<-_end_of_pem_ -----BEGIN DH PARAMETERS----- MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY JbrYeNV3kUIKhPxWHhObHKpD1R84UpLs2b55iMd6GmL7OYmNIT/FccKhTcveab VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6 YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 1bNveX5wInh5GDx1FGhKBZs1HaedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD 7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg== -----END DH PARAMETERS----- _end_of_pem_ 
- 
    DEFAULT_CERT_STORE =
    Internal use only
    
 # File 'ext/openssl/lib/openssl/ssl.rb', line 90OpenSSL::X509::Store.new 
- 
    DEFAULT_PARAMS =
    Internal use only
    
 # File 'ext/openssl/lib/openssl/ssl.rb', line 21{ # :nodoc: :min_version => OpenSSL::SSL::TLS1_VERSION, :verify_mode => OpenSSL::SSL::VERIFY_PEER, :verify_hostname => true, : => -> { opts = OpenSSL::SSL::OP_ALL opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS opts |= OpenSSL::SSL::OP_NO_COMPRESSION opts }.call }
- 
    DEFAULT_TMP_DH_CALLBACK =
    Internal use only
    
 # File 'ext/openssl/lib/openssl/ssl.rb', line 46lambda { |ctx, is_export, keylen| # :nodoc: warn "using default DH parameters." if $VERBOSE DEFAULT_2048 } 
- 
    METHODS =
    # File 'ext/openssl/lib/openssl/ssl.rb', line 228The list of available SSL/TLS methods. This constant is only provided for backwards compatibility. METHODS_MAP.flat_map { |name,| [name, :"#{name}_client", :"#{name}_server"] }.freeze 
- 
    METHODS_MAP =
    private
    
 # File 'ext/openssl/lib/openssl/ssl.rb', line 216{ SSLv23: 0, SSLv2: OpenSSL::SSL::SSL2_VERSION, SSLv3: OpenSSL::SSL::SSL3_VERSION, TLSv1: OpenSSL::SSL::TLS1_VERSION, TLSv1_1: OpenSSL::SSL::TLS1_1_VERSION, TLSv1_2: OpenSSL::SSL::TLS1_2_VERSION, }.freeze
- 
    SESSION_CACHE_BOTH =
    # File 'ext/openssl/ossl_ssl.c', line 2850no different than CACHE_SERVER in 0.9.8e LONG2NUM(SSL_SESS_CACHE_BOTH) 
- 
    SESSION_CACHE_CLIENT =
    # File 'ext/openssl/ossl_ssl.c', line 2840doesn’t actually do anything in 0.9.8e LONG2NUM(SSL_SESS_CACHE_CLIENT) 
- 
    SESSION_CACHE_NO_AUTO_CLEAR =
    # File 'ext/openssl/ossl_ssl.c', line 2858Normally the session cache is checked for expired sessions every 255 connections. Since this may lead to a delay that cannot be controlled, the automatic flushing may be disabled and #flush_sessions can be called explicitly. LONG2NUM(SSL_SESS_CACHE_NO_AUTO_CLEAR) 
- 
    SESSION_CACHE_NO_INTERNAL =
    # File 'ext/openssl/ossl_ssl.c', line 2877Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and SESSION_CACHE_NO_INTERNAL_STORE. LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL) 
- 
    SESSION_CACHE_NO_INTERNAL_LOOKUP =
    # File 'ext/openssl/ossl_ssl.c', line 2866Always perform external lookups of sessions even if they are in the internal cache. This flag has no effect on clients LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) 
- 
    SESSION_CACHE_NO_INTERNAL_STORE =
    # File 'ext/openssl/ossl_ssl.c', line 2871Never automatically store sessions in the internal store. LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_STORE) 
- 
    SESSION_CACHE_OFF =
    # File 'ext/openssl/ossl_ssl.c', line 2835No session caching for client or server LONG2NUM(SSL_SESS_CACHE_OFF) 
- 
    SESSION_CACHE_SERVER =
    # File 'ext/openssl/ossl_ssl.c', line 2845Server sessions are added to the session cache LONG2NUM(SSL_SESS_CACHE_SERVER) 
Class Method Summary
- 
    
      .new  ⇒ ctx 
    
    constructor
    Creates a new ::OpenSSL::SSLcontext.
Instance Attribute Summary
- 
    
      #alpn_protocols  
    
    rw
    An Enumerable of Strings. 
- 
    
      #alpn_select_cb  
    
    rw
    A callback invoked on the server side when the server needs to select a protocol from the list sent by the client. 
- 
    
      #ca_file  
    
    rw
    The path to a file containing a PEM-format CA certificate. 
- 
    
      #ca_path  
    
    rw
    The path to a directory containing CA certificates in PEM format. 
- 
    
      #cert  
    
    rw
    Context certificate. 
- 
    
      #cert_store  
    
    rw
    An ::OpenSSL::X509::Storeused for certificate verification.
- 
    
      #ciphers  ⇒ Array, ... 
    
    rw
    The list of cipher suites configured for this context. 
- 
    
      #ciphers=("cipher1:cipher2:...")  
    
    rw
    Sets the list of available cipher suites for this context. 
- 
    
      #client_ca  
    
    rw
    A certificate or Array of certificates that will be sent to the client. 
- 
    
      #client_cert_cb  
    
    rw
    A callback invoked when a client certificate is requested by a server and no certificate has been set. 
- 
    
      #ecdh_curves=(curve_list)  ⇒ curve_list 
    
    writeonly
    Sets the list of “supported elliptic curves” for this context. 
- 
    
      #extra_chain_cert  
    
    rw
    An Array of extra ::OpenSSL::X509certificates to be added to the certificate chain.
- 
    
      #key  
    
    rw
    Context private key. 
- 
    
      #max_version=(OpenSSL::SSL::TLS1_2_VERSION)  
    
    writeonly
    Sets the upper bound of the supported SSL/TLS protocol version. 
- 
    
      #min_version=(OpenSSL::SSL::TLS1_2_VERSION)  
    
    writeonly
    Sets the lower bound on the supported SSL/TLS protocol version. 
- 
    
      #npn_protocols  
    
    rw
    An Enumerable of Strings. 
- 
    
      #npn_select_cb  
    
    rw
    A callback invoked on the client side when the client needs to select a protocol from the list sent by the server. 
- 
    
      #options  
    
    rw
    Gets various ::OpenSSLoptions.
- 
    
      #options=(options)  
    
    rw
    Sets various ::OpenSSLoptions.
- 
    
      #renegotiation_cb  
    
    rw
    A callback invoked whenever a new handshake is initiated on an established connection. 
- 
    
      #security_level  ⇒ Integer 
    
    rw
    Returns the security level for the context. 
- 
    
      #security_level=(integer)  
    
    rw
    Sets the security level for the context. 
- 
    
      #servername_cb  
    
    rw
    A callback invoked at connect time to distinguish between multiple server names. 
- 
    
      #session_cache_mode  ⇒ Integer 
    
    rw
    The current session cache mode. 
- 
    
      #session_cache_mode=(integer)  ⇒ Integer 
    
    rw
    Sets the ::OpenSSL::SSLsession cache mode.
- 
    
      #session_cache_size  ⇒ Integer 
    
    rw
    Returns the current session cache size. 
- 
    
      #session_cache_size=(integer)  ⇒ Integer 
    
    rw
    Sets the session cache size. 
- 
    
      #session_get_cb  
    
    rw
    A callback invoked on a server when a session is proposed by the client but the session could not be found in the server’s internal cache. 
- 
    
      #session_id_context  
    
    rw
    Sets the context in which a session can be reused. 
- 
    
      #session_new_cb  
    
    rw
    A callback invoked when a new session was negotiated. 
- 
    
      #session_remove_cb  
    
    rw
    A callback invoked when a session is removed from the internal cache. 
- 
    
      #ssl_timeout  
    
    rw
    Alias for #timeout. 
- 
    
      #ssl_version=(:TLSv1)  
    
    writeonly
    Sets the SSL/TLS protocol version for the context. 
- 
    
      #timeout  
      (also: #ssl_timeout)
    
    rw
    Maximum session lifetime in seconds. 
- 
    
      #tmp_dh_callback  
    
    rw
    A callback invoked when DH parameters are required. 
- 
    
      #tmp_ecdh_callback  
    
    rw
    A callback invoked when ECDH parameters are required. 
- 
    
      #verify_callback  
    
    rw
    A callback for additional certificate verification. 
- 
    
      #verify_depth  
    
    rw
    Number of CA certificates to walk when verifying a certificate chain. 
- 
    
      #verify_hostname  
    
    rw
    Whether to check the server certificate is valid for the hostname. 
- 
    
      #verify_mode  
    
    rw
    Sessionverification mode.
Instance Method Summary
- 
    
      #add_certificate(certiticate, pkey [, extra_certs])  ⇒ self 
    
    Adds a certificate to the context. 
- 
    
      #enable_fallback_scsv  ⇒ nil 
    
    Activate TLS_FALLBACK_SCSV for this context. 
- 
    
      #flush_sessions(time)  ⇒ self 
    
    Removes sessions in the internal cache that have expired at time. 
- 
    
      #setup  ⇒ Qtrue #firstt time 
    
    Alias for #setup. 
- 
    
      #session_add(session)  ⇒ Boolean 
    
    Adds session to the session cache. 
- 
    
      #session_cache_stats  ⇒ Hash 
    
    Returns a Hash containing the following keys: 
- 
    
      #session_remove(session)  ⇒ Boolean 
    
    Removes session from the session cache. 
- 
    
      #set_params(params = {})  ⇒ params 
    
    Sets saner defaults optimized for the use with HTTP-like protocols. 
- 
    
      #setup  ⇒ Qtrue #firstt time 
      (also: #freeze)
    
    This method is called automatically when a new SSLSocketis created.
- 
    
      #set_minmax_proto_version(min, max)  ⇒ nil 
    
    private
    Sets the minimum and maximum supported protocol versions. 
Constructor Details
    
      .new  ⇒ ctx 
      .new(:TLSv1)  ⇒ ctx 
      .new("SSLv23")  ⇒ ctx 
    
  
ctx 
      .new(:TLSv1)  ⇒ ctx 
      .new("SSLv23")  ⇒ ctx 
    Creates a new ::OpenSSL::SSL context.
If an argument is given, #ssl_version= is called with the value. Note that this form is deprecated. New applications should use #min_version= and #max_version= as necessary.
Instance Attribute Details
#alpn_protocols (rw)
An Enumerable of Strings. Each String represents a protocol to be advertised as the list of supported protocols for Application-Layer Protocol Negotiation. Supported in ::OpenSSL 1.0.2 and higher. Has no effect on the server side. If not set explicitly, the ALPN extension will not be included in the handshake.
Example
ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]#alpn_select_cb (rw)
A callback invoked on the server side when the server needs to select a protocol from the list sent by the client. Supported in ::OpenSSL 1.0.2 and higher. The callback must return a protocol of those advertised by the client. If none is acceptable, raising an error in the callback will cause the handshake to fail. Not setting this callback explicitly means not supporting the ALPN extension on the server - any protocols advertised by the client will be ignored.
Example
ctx.alpn_select_cb = lambda do |protocols|
  # inspect the protocols and select one
  protocols.first
end#ca_file (rw)
The path to a file containing a PEM-format CA certificate
#ca_path (rw)
The path to a directory containing CA certificates in PEM format.
Files are looked up by subject’s ::OpenSSL::X509 name’s hash value.
#cert (rw)
Context certificate
The cert, key, and extra_chain_cert attributes are deprecated. It is recommended to use #add_certificate instead.
#cert_store (rw)
An ::OpenSSL::X509::Store used for certificate verification.
    #ciphers  ⇒ Array, ...  (rw)  
The list of cipher suites configured for this context.
# File 'ext/openssl/ossl_ssl.c', line 1005
static VALUE
ossl_sslctx_get_ciphers(VALUE self)
{
    SSL_CTX *ctx;
    STACK_OF(SSL_CIPHER) *ciphers;
    const SSL_CIPHER *cipher;
    VALUE ary;
    int i, num;
    GetSSLCTX(self, ctx);
    ciphers = SSL_CTX_get_ciphers(ctx);
    if (!ciphers)
        return rb_ary_new();
    num = sk_SSL_CIPHER_num(ciphers);
    ary = rb_ary_new2(num);
    for(i = 0; i < num; i++){
        cipher = sk_SSL_CIPHER_value(ciphers, i);
        rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));
    }
    return ary;
}
  
    
      #ciphers=("cipher1:cipher2:...")   (rw)
      #ciphers=([name, ...])  
      #ciphers=([[name, version, bits, alg_bits], ...])  
    
  
Sets the list of available cipher suites for this context. Note in a server context some ciphers require the appropriate certificates. For example, an RSA cipher suite can only be chosen when an RSA certificate is available.
# File 'ext/openssl/ossl_ssl.c', line 1038
static VALUE
ossl_sslctx_set_ciphers(VALUE self, VALUE v)
{
    SSL_CTX *ctx;
    VALUE str, elem;
    int i;
    rb_check_frozen(self);
    if (NIL_P(v))
	return v;
    else if (RB_TYPE_P(v, T_ARRAY)) {
        str = rb_str_new(0, 0);
        for (i = 0; i < RARRAY_LEN(v); i++) {
            elem = rb_ary_entry(v, i);
            if (RB_TYPE_P(elem, T_ARRAY)) elem = rb_ary_entry(elem, 0);
            elem = rb_String(elem);
            rb_str_append(str, elem);
            if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, ":");
        }
    } else {
        str = v;
        StringValue(str);
    }
    GetSSLCTX(self, ctx);
    if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
        ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
    }
    return v;
}
  #client_ca (rw)
A certificate or Array of certificates that will be sent to the client.
#client_cert_cb (rw)
A callback invoked when a client certificate is requested by a server and no certificate has been set.
The callback is invoked with a Session and must return an Array containing an ::OpenSSL::X509::Certificate and an ::OpenSSL::PKey.  If any other value is returned the handshake is suspended.
    #ecdh_curves=(curve_list)  ⇒ curve_list  (writeonly)  
Sets the list of “supported elliptic curves” for this context.
For a TLS client, the list is directly used in the Supported Elliptic Curves Extension. For a server, the list is used by ::OpenSSL to determine the set of shared curves. ::OpenSSL will pick the most appropriate one from it.
Note that this works differently with old ::OpenSSL (<= 1.0.1). Only one curve can be set, and this has no effect for TLS clients.
Example
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ecdh_curves = "X25519:P-256:P-224"
svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1)
Thread.new { svr.accept }
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ecdh_curves = "P-256"
cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2)
cli.connect
p cli.tmp_key.group.curve_name
# => "prime256v1" (is an alias for NIST P-256)# File 'ext/openssl/ossl_ssl.c', line 1098
static VALUE
ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    rb_check_frozen(self);
    GetSSLCTX(self, ctx);
    StringValueCStr(arg);
#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
    if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
	ossl_raise(eSSLError, NULL);
#else
    /* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
     * SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
    {
	VALUE curve, splitted;
	EC_KEY *ec;
	int nid;
	splitted = rb_str_split(arg, ":");
	if (!RARRAY_LEN(splitted))
	    ossl_raise(eSSLError, "invalid input format");
	curve = RARRAY_AREF(splitted, 0);
	StringValueCStr(curve);
	/* SSL_CTX_set1_curves_list() accepts NIST names */
	nid = EC_curve_nist2nid(RSTRING_PTR(curve));
	if (nid == NID_undef)
	    nid = OBJ_txt2nid(RSTRING_PTR(curve));
	if (nid == NID_undef)
	    ossl_raise(eSSLError, "unknown curve name");
	ec = EC_KEY_new_by_curve_name(nid);
	if (!ec)
	    ossl_raise(eSSLError, NULL);
	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
	if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
	    EC_KEY_free(ec);
	    ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
	}
	EC_KEY_free(ec);
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
	/* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
	 * is enabled. So disable ecdh_auto. */
	if (!SSL_CTX_set_ecdh_auto(ctx, 0))
	    ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
# endif
    }
#endif
    return arg;
}
  #extra_chain_cert (rw)
An Array of extra ::OpenSSL::X509 certificates to be added to the certificate chain.
The cert, key, and extra_chain_cert attributes are deprecated. It is recommended to use #add_certificate instead.
#key (rw)
Context private key
The cert, key, and extra_chain_cert attributes are deprecated. It is recommended to use #add_certificate instead.
    
      #max_version=(OpenSSL::SSL::TLS1_2_VERSION)   (writeonly)
      #max_version=(:TLS1_2)  
      #max_version=(nil)  
    
  
Sets the upper bound of the supported SSL/TLS protocol version. See #min_version= for the possible values.
# File 'ext/openssl/lib/openssl/ssl.rb', line 183
def max_version=(version) set_minmax_proto_version(@min_proto_version ||= nil, version) @max_proto_version = version end
    
      #min_version=(OpenSSL::SSL::TLS1_2_VERSION)   (writeonly)
      #min_version=(:TLS1_2)  
      #min_version=(nil)  
    
  
Sets the lower bound on the supported SSL/TLS protocol version. The version may be specified by an integer constant named OpenSSL::SSL::*_VERSION, a Symbol, or nil which means “any version”.
Be careful that you don’t overwrite OpenSSL::SSL::OP_NO_SSL,TLSv* options by #options= once you have called #min_version= or #max_version=.
Example
ctx = OpenSSL::SSL::SSLContext.new
ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx)
sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2# File 'ext/openssl/lib/openssl/ssl.rb', line 171
def min_version=(version) set_minmax_proto_version(version, @max_proto_version ||= nil) @min_proto_version = version end
#npn_protocols (rw)
An Enumerable of Strings. Each String represents a protocol to be advertised as the list of supported protocols for Next Protocol Negotiation. Supported in ::OpenSSL 1.0.1 and higher. Has no effect on the client side. If not set explicitly, the NPN extension will not be sent by the server in the handshake.
Example
ctx.npn_protocols = ["http/1.1", "spdy/2"]#npn_select_cb (rw)
A callback invoked on the client side when the client needs to select a protocol from the list sent by the server. Supported in ::OpenSSL 1.0.1 and higher. The client MUST select a protocol of those advertised by the server. If none is acceptable, raising an error in the callback will cause the handshake to fail. Not setting this callback explicitly means not supporting the NPN extension on the client - any protocols advertised by the server will be ignored.
Example
ctx.npn_select_cb = lambda do |protocols|
  # inspect the protocols and select one
  protocols.first
end#options (rw)
Gets various ::OpenSSL options.
# File 'ext/openssl/ossl_ssl.c', line 752
static VALUE
ossl_sslctx_get_options(VALUE self)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
    /*
     * Do explicit cast because SSL_CTX_get_options() returned (signed) long in
     * OpenSSL before 1.1.0.
     */
    return ULONG2NUM((unsigned long)SSL_CTX_get_options(ctx));
}
  #options=(options) (rw)
Sets various ::OpenSSL options.
# File 'ext/openssl/ossl_ssl.c', line 767
static VALUE
ossl_sslctx_set_options(VALUE self, VALUE options)
{
    SSL_CTX *ctx;
    rb_check_frozen(self);
    GetSSLCTX(self, ctx);
    SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));
    if (NIL_P(options)) {
	SSL_CTX_set_options(ctx, SSL_OP_ALL);
    } else {
	SSL_CTX_set_options(ctx, NUM2ULONG(options));
    }
    return self;
}
  #renegotiation_cb (rw)
A callback invoked whenever a new handshake is initiated on an established connection. May be used to disable renegotiation entirely.
The callback is invoked with the active SSLSocket. The callback’s return value is ignored. A normal return indicates “approval” of the renegotiation and will continue the process. To forbid renegotiation and to cancel the process, raise an exception within the callback.
Disable client renegotiation
When running a server, it is often desirable to disable client renegotiation entirely. You may use a callback as follows to implement this feature:
ctx.renegotiation_cb = lambda do |ssl|
  raise RuntimeError, "Client renegotiation disabled"
end#security_level ⇒ Integer (rw)
Returns the security level for the context.
See also #security_level=.
# File 'ext/openssl/ossl_ssl.c', line 1163
static VALUE
ossl_sslctx_get_security_level(VALUE self)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
    return INT2NUM(SSL_CTX_get_security_level(ctx));
#else
    (void)ctx;
    return INT2FIX(0);
#endif
}
  #security_level=(integer) (rw)
Sets the security level for the context. ::OpenSSL limits parameters according to the level. The “parameters” include: ciphersuites, curves, key sizes, certificate signature algorithms, protocol version and so on. For example, level 1 rejects parameters offering below 80 bits of security, such as ciphersuites using MD5 for the MAC or RSA keys shorter than 1024 bits.
Note that attempts to set such parameters with insufficient security are also blocked. You need to lower the level first.
This feature is not supported in ::OpenSSL < 1.1.0, and setting the level to other than 0 will raise NotImplementedError. Level 0 means everything is permitted, the same behavior as previous versions of ::OpenSSL.
See the manpage of SSL_CTX_set_security_level(3) for details.
# File 'ext/openssl/ossl_ssl.c', line 1197
static VALUE
ossl_sslctx_set_security_level(VALUE self, VALUE value)
{
    SSL_CTX *ctx;
    rb_check_frozen(self);
    GetSSLCTX(self, ctx);
#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
    SSL_CTX_set_security_level(ctx, NUM2INT(value));
#else
    (void)ctx;
    if (NUM2INT(value) != 0)
	ossl_raise(rb_eNotImpError, "setting security level to other than 0 is "
		   "not supported in this version of OpenSSL");
#endif
    return value;
}
  #servername_cb (rw)
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.
# File 'ext/openssl/lib/openssl/ssl.rb', line 110
attr_accessor :servername_cb
#session_cache_mode ⇒ Integer (rw)
The current session cache mode.
# File 'ext/openssl/ossl_ssl.c', line 1387
static VALUE
ossl_sslctx_get_session_cache_mode(VALUE self)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
    return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
}
  #session_cache_mode=(integer) ⇒ Integer (rw)
Sets the ::OpenSSL::SSL session cache mode.  Bitwise-or together the desired SESSION_CACHE_* constants to set.  See SSL_CTX_set_session_cache_mode(3) for details.
# File 'ext/openssl/ossl_ssl.c', line 1405
static VALUE
ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
    SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg));
    return arg;
}
  #session_cache_size ⇒ Integer (rw)
Returns the current session cache size. Zero is used to represent an unlimited cache size.
# File 'ext/openssl/ossl_ssl.c', line 1424
static VALUE
ossl_sslctx_get_session_cache_size(VALUE self)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
    return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
}
  #session_cache_size=(integer) ⇒ Integer (rw)
Sets the session cache size. Returns the previously valid session cache size. Zero is used to represent an unlimited session cache size.
# File 'ext/openssl/ossl_ssl.c', line 1441
static VALUE
ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
    SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg));
    return arg;
}
  #session_get_cb (rw)
#session_id_context (rw)
Sets the context in which a session can be reused. This allows sessions for multiple applications to be distinguished, for example, by name.
#session_new_cb (rw)
A callback invoked when a new session was negotiated.
The callback is invoked with an SSLSocket.  If false is returned the session will be removed from the internal cache.
#session_remove_cb (rw)
A callback invoked when a session is removed from the internal cache.
The callback is invoked with an SSLContext and a Session.
IMPORTANT NOTE: It is currently not possible to use this safely in a multi-threaded application. The callback is called inside a global lock and it can randomly cause deadlock on Ruby thread switching.
#ssl_timeout (rw)
Alias for #timeout.
    
      #ssl_version=(:TLSv1)   (writeonly)
      #ssl_version=("SSLv23")  
    
  
Sets the SSL/TLS protocol version for the context. This forces connections to use only the specified protocol version. This is deprecated and only provided for backwards compatibility. Use #min_version= and #max_version= instead.
History
As the name hints, this used to call the SSL_CTX_set_ssl_version() function which sets the ::OpenSSL::SSL method used for connections created from the context. As of Ruby/OpenSSL 2.1, this accessor method is implemented to call #min_version= and #max_version= instead.
# File 'ext/openssl/lib/openssl/ssl.rb', line 202
def ssl_version=(meth) meth = meth.to_s if meth.is_a?(Symbol) if /(?<type>_client|_server)\z/ =~ meth meth = $` if $VERBOSE warn "#{caller(1, 1)[0]}: method type #{type.inspect} is ignored" end end version = METHODS_MAP[meth.intern] or raise ArgumentError, "unknown SSL method `%s'" % meth set_minmax_proto_version(version, version) @min_proto_version = @max_proto_version = version end
#timeout (rw) Also known as: #ssl_timeout
Maximum session lifetime in seconds.
#tmp_dh_callback (rw)
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 required.
The callback must return an ::OpenSSL::PKey::DH instance of the correct key length.
# File 'ext/openssl/lib/openssl/ssl.rb', line 103
attr_accessor :tmp_dh_callback
#tmp_ecdh_callback (rw)
A callback invoked when ECDH 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 required.
The callback is deprecated. This does not work with recent versions of ::OpenSSL. Use #ecdh_curves= instead.
#verify_callback (rw)
A callback for additional certificate verification. The callback is invoked for each certificate in the chain.
The callback is invoked with two values.  preverify_ok indicates indicates if the verification was passed (true) or not (false). store_context is an ::OpenSSL::X509::StoreContext containing the context used for certificate verification.
If the callback returns false, the chain verification is immediately stopped and a bad_certificate alert is then sent.
#verify_depth (rw)
Number of CA certificates to walk when verifying a certificate chain.
#verify_hostname (rw)
Whether to check the server certificate is valid for the hostname.
In order to make this work, verify_mode must be set to VERIFY_PEER and the server hostname must be given by SSLSocket#hostname=.
#verify_mode (rw)
Session verification mode.
Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE, VERIFY_FAIL_IF_NO_PEER_CERT and defined on ::OpenSSL::SSL
The default mode is VERIFY_NONE, which does not perform any verification at all.
See SSL_CTX_set_verify(3) for details.
Instance Method Details
    #add_certificate(certiticate, pkey [, extra_certs])  ⇒ self   
Adds a certificate to the context. pkey must be a corresponding private key with certificate.
Multiple certificates with different public key type can be added by repeated calls of this method, and ::OpenSSL will choose the most appropriate certificate during the handshake.
#cert=, #key=, and #extra_chain_cert= are old accessor methods for setting certificate and internally call this method.
Parameters
- certificate
- 
A certificate. An instance of OpenSSL::X509::Certificate. 
- pkey
- 
The private key for certificate. An instance of OpenSSL::PKey::PKey. 
- extra_certs
- 
Optional. An array of OpenSSL::X509::Certificate. When sending a certificate chain, the certificates specified by this are sent following certificate, in the order in the array. 
Example
rsa_cert = OpenSSL::X509::Certificate.new(...)
rsa_pkey = OpenSSL::PKey.read(...)
ca_intermediate_cert = OpenSSL::X509::Certificate.new(...)
ctx.add_certificate(rsa_cert, rsa_pkey, [ca_intermediate_cert])
ecdsa_cert = ...
ecdsa_pkey = ...
another_ca_cert = ...
ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])Note
::OpenSSL before the version 1.0.2 could handle only one extra chain across all key types. Calling this method discards the chain set previously.
# File 'ext/openssl/ossl_ssl.c', line 1276
static VALUE
ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
{
    VALUE cert, key, extra_chain_ary;
    SSL_CTX *ctx;
    X509 *x509;
    STACK_OF(X509) *extra_chain = NULL;
    EVP_PKEY *pkey, *pub_pkey;
    GetSSLCTX(self, ctx);
    rb_scan_args(argc, argv, "21", &cert, &key, &extra_chain_ary);
    rb_check_frozen(self);
    x509 = GetX509CertPtr(cert);
    pkey = GetPrivPKeyPtr(key);
    /*
     * The reference counter is bumped, and decremented immediately.
     * X509_get0_pubkey() is only available in OpenSSL >= 1.1.0.
     */
    pub_pkey = X509_get_pubkey(x509);
    EVP_PKEY_free(pub_pkey);
    if (!pub_pkey)
	rb_raise(rb_eArgError, "certificate does not contain public key");
    if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
	rb_raise(rb_eArgError, "public key mismatch");
    if (argc >= 3)
	extra_chain = ossl_x509_ary2sk(extra_chain_ary);
    if (!SSL_CTX_use_certificate(ctx, x509)) {
	sk_X509_pop_free(extra_chain, X509_free);
	ossl_raise(eSSLError, "SSL_CTX_use_certificate");
    }
    if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
	sk_X509_pop_free(extra_chain, X509_free);
	ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
    }
    if (extra_chain) {
#if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
	if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
	    sk_X509_pop_free(extra_chain, X509_free);
	    ossl_raise(eSSLError, "SSL_CTX_set0_chain");
	}
#else
	STACK_OF(X509) *orig_extra_chain;
	X509 *x509_tmp;
	/* First, clear the existing chain */
	SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
	if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
	    rb_warning("SSL_CTX_set0_chain() is not available; " \
		       "clearing previously set certificate chain");
	    SSL_CTX_clear_extra_chain_certs(ctx);
	}
	while ((x509_tmp = sk_X509_shift(extra_chain))) {
	    /* Transfers ownership */
	    if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
		X509_free(x509_tmp);
		sk_X509_pop_free(extra_chain, X509_free);
		ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
	    }
	}
	sk_X509_free(extra_chain);
#endif
    }
    return self;
}
  
    #enable_fallback_scsv  ⇒ nil   
Activate TLS_FALLBACK_SCSV for this context. See RFC 7507.
# File 'ext/openssl/ossl_ssl.c', line 1225
static VALUE
ossl_sslctx_enable_fallback_scsv(VALUE self)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
    SSL_CTX_set_mode(ctx, SSL_MODE_SEND_FALLBACK_SCSV);
    return Qnil;
}
  
    #flush_sessions(time)  ⇒ self   
Removes sessions in the internal cache that have expired at time.
# File 'ext/openssl/ossl_ssl.c', line 1507
static VALUE
ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
{
    VALUE arg1;
    SSL_CTX *ctx;
    time_t tm = 0;
    rb_scan_args(argc, argv, "01", &arg1);
    GetSSLCTX(self, ctx);
    if (NIL_P(arg1)) {
        tm = time(0);
    } else if (rb_obj_is_instance_of(arg1, rb_cTime)) {
        tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0));
    } else {
        ossl_raise(rb_eArgError, "arg must be Time or nil");
    }
    SSL_CTX_flush_sessions(ctx, (long)tm);
    return self;
}
  
    
      #setup  ⇒ Qtrue #firstt time 
      #setup  ⇒ nil #thereafterr 
    
  
Qtrue #firstt time 
      #setup  ⇒ nil #thereafterr 
    Alias for #setup.
    #session_add(session)  ⇒ Boolean   
Adds session to the session cache.
# File 'ext/openssl/ossl_ssl.c', line 1351
static VALUE
ossl_sslctx_session_add(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    SSL_SESSION *sess;
    GetSSLCTX(self, ctx);
    GetSSLSession(arg, sess);
    return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}
  
    #session_cache_stats  ⇒ Hash   
Returns a Hash containing the following keys:
- :accept
- 
Number of started SSL/TLS handshakes in server mode 
- :accept_good
- 
Number of established SSL/TLS sessions in server mode 
- :accept_renegotiate
- 
Number of start renegotiations in server mode 
- :cache_full
- 
Number of sessions that were removed due to cache overflow 
- :cache_hits
- 
Number of successfully reused connections 
- :cache_misses
- 
Number of sessions proposed by clients that were not found in the cache 
- :cache_num
- 
Number of sessions in the internal session cache 
- :cb_hits
- 
Number of sessions retrieved from the external cache in server mode 
- :connect
- 
Number of started SSL/TLS handshakes in client mode 
- :connect_good
- 
Number of established SSL/TLS sessions in client mode 
- :connect_renegotiate
- 
Number of start renegotiations in client mode 
- :timeouts
- 
Number of sessions proposed by clients that were found in the cache but had expired due to timeouts 
# File 'ext/openssl/ossl_ssl.c', line 1475
static VALUE
ossl_sslctx_get_session_cache_stats(VALUE self)
{
    SSL_CTX *ctx;
    VALUE hash;
    GetSSLCTX(self, ctx);
    hash = rb_hash_new();
    rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx)));
    return hash;
}
  
    #session_remove(session)  ⇒ Boolean   
Removes session from the session cache.
# File 'ext/openssl/ossl_ssl.c', line 1369
static VALUE
ossl_sslctx_session_remove(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    SSL_SESSION *sess;
    GetSSLCTX(self, ctx);
    GetSSLSession(arg, sess);
    return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}
  
    #set_minmax_proto_version(min, max)  ⇒ nil  (private)  
Sets the minimum and maximum supported protocol versions. See #min_version= and #max_version=.
# File 'ext/openssl/ossl_ssl.c', line 165
static VALUE
ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
{
    SSL_CTX *ctx;
    int min, max;
    GetSSLCTX(self, ctx);
    min = parse_proto_version(min_v);
    max = parse_proto_version(max_v);
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
    if (!SSL_CTX_set_min_proto_version(ctx, min))
	ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
    if (!SSL_CTX_set_max_proto_version(ctx, max))
	ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
#else
    {
	unsigned long sum = 0, opts = 0;
	int i;
	static const struct {
	    int ver;
	    unsigned long opts;
	} options_map[] = {
	    { SSL2_VERSION, SSL_OP_NO_SSLv2 },
	    { SSL3_VERSION, SSL_OP_NO_SSLv3 },
	    { TLS1_VERSION, SSL_OP_NO_TLSv1 },
	    { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
	    { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
# if defined(TLS1_3_VERSION)
	    { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
# endif
	};
	for (i = 0; i < numberof(options_map); i++) {
	    sum |= options_map[i].opts;
            if ((min && min > options_map[i].ver) ||
                (max && max < options_map[i].ver)) {
		opts |= options_map[i].opts;
            }
	}
	SSL_CTX_clear_options(ctx, sum);
	SSL_CTX_set_options(ctx, opts);
    }
#endif
    return Qnil;
}
  
    #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.
# File 'ext/openssl/lib/openssl/ssl.rb', line 139
def set_params(params={}) params = DEFAULT_PARAMS.merge(params) self. = params.delete(:) # set before min_version/max_version 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 self.cert_store = DEFAULT_CERT_STORE end end return params end
    
      #setup  ⇒ Qtrue #firstt time 
      #setup  ⇒ nil #thereafterr 
    
    Also known as: #freeze
  
Qtrue #firstt time 
      #setup  ⇒ nil #thereafterr 
    # File 'ext/openssl/ossl_ssl.c', line 795
static VALUE
ossl_sslctx_setup(VALUE self)
{
    SSL_CTX *ctx;
    X509 *cert = NULL, *client_ca = NULL;
    EVP_PKEY *key = NULL;
    char *ca_path = NULL, *ca_file = NULL;
    int verify_mode;
    long i;
    VALUE val;
    if(OBJ_FROZEN(self)) return Qnil;
    GetSSLCTX(self, ctx);
#if !defined(OPENSSL_NO_DH)
    SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
#endif
#if !defined(OPENSSL_NO_EC)
    /* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
     * but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
    if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) {
# if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
	rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
	SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
#  if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
	/* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
	 * tmp_ecdh_callback. So disable ecdh_auto. */
	if (!SSL_CTX_set_ecdh_auto(ctx, 0))
	    ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
#  endif
# else
	ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
		   "use #ecdh_curves= instead");
# endif
    }
#endif /* OPENSSL_NO_EC */
#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
    SSL_CTX_set_post_handshake_auth(ctx, 1);
#endif
    val = rb_attr_get(self, id_i_cert_store);
    if (!NIL_P(val)) {
	X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
	SSL_CTX_set_cert_store(ctx, store);
#if !defined(HAVE_X509_STORE_UP_REF)
	/*
         * WORKAROUND:
	 *   X509_STORE can count references, but
	 *   X509_STORE_free() doesn't care it.
	 *   So we won't increment it but mark it by ex_data.
	 */
        SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
#else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
	X509_STORE_up_ref(store);
#endif
    }
    val = rb_attr_get(self, id_i_extra_chain_cert);
    if(!NIL_P(val)){
	rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
    }
    /* private key may be bundled in certificate file. */
    val = rb_attr_get(self, id_i_cert);
    cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
    val = rb_attr_get(self, id_i_key);
    key = NIL_P(val) ? NULL : GetPrivPKeyPtr(val); /* NO DUP NEEDED */
    if (cert && key) {
        if (!SSL_CTX_use_certificate(ctx, cert)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_certificate");
        }
        if (!SSL_CTX_use_PrivateKey(ctx, key)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
        }
        if (!SSL_CTX_check_private_key(ctx)) {
            ossl_raise(eSSLError, "SSL_CTX_check_private_key");
        }
    }
    val = rb_attr_get(self, id_i_client_ca);
    if(!NIL_P(val)){
	if (RB_TYPE_P(val, T_ARRAY)) {
	    for(i = 0; i < RARRAY_LEN(val); i++){
		client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
        	if (!SSL_CTX_add_client_CA(ctx, client_ca)){
		    /* Copies X509_NAME => FREE it. */
        	    ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
        	}
	    }
        }
	else{
	    client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
            if (!SSL_CTX_add_client_CA(ctx, client_ca)){
		/* Copies X509_NAME => FREE it. */
        	ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
            }
	}
    }
    val = rb_attr_get(self, id_i_ca_file);
    ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
    val = rb_attr_get(self, id_i_ca_path);
    ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
    if(ca_file || ca_path){
	if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
	    rb_warning("can't set verify locations");
    }
    val = rb_attr_get(self, id_i_verify_mode);
    verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
    SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
    if (RTEST(rb_attr_get(self, id_i_client_cert_cb)))
	SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
    val = rb_attr_get(self, id_i_timeout);
    if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
    val = rb_attr_get(self, id_i_verify_depth);
    if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
#ifndef OPENSSL_NO_NEXTPROTONEG
    val = rb_attr_get(self, id_i_npn_protocols);
    if (!NIL_P(val)) {
	VALUE encoded = ssl_encode_npn_protocols(val);
	rb_ivar_set(self, id_npn_protocols_encoded, encoded);
	SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
	OSSL_Debug("SSL NPN advertise callback added");
    }
    if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
	SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
	OSSL_Debug("SSL NPN select callback added");
    }
#endif
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
    val = rb_attr_get(self, id_i_alpn_protocols);
    if (!NIL_P(val)) {
	VALUE rprotos = ssl_encode_npn_protocols(val);
	/* returns 0 on success */
	if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos),
				    RSTRING_LENINT(rprotos)))
	    ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos");
	OSSL_Debug("SSL ALPN values added");
    }
    if (RTEST(rb_attr_get(self, id_i_alpn_select_cb))) {
	SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
	OSSL_Debug("SSL ALPN select callback added");
    }
#endif
    rb_obj_freeze(self);
    val = rb_attr_get(self, id_i_session_id_context);
    if (!NIL_P(val)){
	StringValue(val);
	if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
					    RSTRING_LENINT(val))){
	    ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
	}
    }
    if (RTEST(rb_attr_get(self, id_i_session_get_cb))) {
	SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
	OSSL_Debug("SSL SESSION get callback added");
    }
    if (RTEST(rb_attr_get(self, id_i_session_new_cb))) {
	SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
	OSSL_Debug("SSL SESSION new callback added");
    }
    if (RTEST(rb_attr_get(self, id_i_session_remove_cb))) {
	SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
	OSSL_Debug("SSL SESSION remove callback added");
    }
    val = rb_attr_get(self, id_i_servername_cb);
    if (!NIL_P(val)) {
        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
	OSSL_Debug("SSL TLSEXT servername callback added");
    }
    return Qtrue;
}