An SSLContext
is used to set various options regarding certificates, algorithms, verification, session caching, etc. The SSLContext
is used to create an SSLSocket
.
All attributes must be set before creating an SSLSocket
as the SSLContext
will be frozen afterward.
- A
- C
- E
- F
- M
- N
- O
- S
- T
Constants
DH_ffdhe2048 | = | OpenSSL::PKey::DH.new <<-_end_of_pem_ |
METHODS | = | METHODS_MAP.flat_map { |name,| [name, :"#{name}_client", :"#{name}_server"] }.freeze |
The list of available SSL/TLS methods. This constant is only provided for backwards compatibility. |
||
SESSION_CACHE_BOTH | = | LONG2NUM(SSL_SESS_CACHE_BOTH) |
Both client and server sessions are added to the session cache |
||
SESSION_CACHE_CLIENT | = | LONG2NUM(SSL_SESS_CACHE_CLIENT) |
Client sessions are added to the session cache |
||
SESSION_CACHE_NO_AUTO_CLEAR | = | LONG2NUM(SSL_SESS_CACHE_NO_AUTO_CLEAR) |
Normally 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 |
||
SESSION_CACHE_NO_INTERNAL | = | LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL) |
Enables both |
||
SESSION_CACHE_NO_INTERNAL_LOOKUP | = | LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) |
Always perform external lookups of sessions even if they are in the internal cache. This flag has no effect on clients |
||
SESSION_CACHE_NO_INTERNAL_STORE | = | LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_STORE) |
Never automatically store sessions in the internal store. |
||
SESSION_CACHE_OFF | = | LONG2NUM(SSL_SESS_CACHE_OFF) |
No session caching for client or server |
||
SESSION_CACHE_SERVER | = | LONG2NUM(SSL_SESS_CACHE_SERVER) |
Server sessions are added to the session cache |
Attributes
[RW] | alpn_protocols | An Example
|
[RW] | alpn_select_cb | A callback invoked on the server side when the server needs to select a protocol from the list sent by the client. Supported in Example
|
[RW] | ca_file | The path to a file containing a PEM-format CA certificate |
[RW] | ca_path | The path to a directory containing CA certificates in PEM format. Files are looked up by subject’s |
[RW] | cert | Context certificate The cert, key, and extra_chain_cert attributes are deprecated. It is recommended to use |
[RW] | cert_store | An |
[RW] | client_ca | A certificate or |
[RW] | client_cert_cb | A callback invoked when a client certificate is requested by a server and no certificate has been set. The callback is invoked with a |
[RW] | extra_chain_cert | An The cert, key, and extra_chain_cert attributes are deprecated. It is recommended to use |
[RW] | key | Context private key The cert, key, and extra_chain_cert attributes are deprecated. It is recommended to use |
[RW] | keylog_cb | A callback invoked when TLS key material is generated or received, in order to allow applications to store this keying material for debugging purposes. The callback is invoked with an It is only compatible with Example
|
[RW] | npn_protocols | An Example
|
[RW] | npn_select_cb | A callback invoked on the client side when the client needs to select a protocol from the list sent by the server. Supported in Example
|
[RW] | renegotiation_cb | 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 Disable client renegotiationWhen running a server, it is often desirable to disable client renegotiation entirely. You may use a callback as follows to implement this feature:
|
[RW] | servername_cb | A callback invoked at connect time to distinguish between multiple server names. The callback is invoked with an |
[RW] | session_get_cb | 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. The callback is invoked with the |
[RW] | session_id_context | Sets the context in which a session can be reused. This allows sessions for multiple applications to be distinguished, for example, by name. |
[RW] | session_new_cb | A callback invoked when a new session was negotiated. The callback is invoked with an |
[RW] | session_remove_cb | A callback invoked when a session is removed from the internal cache. The callback is invoked with an 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. |
[RW] | ssl_timeout | Maximum session lifetime in seconds. |
[RW] | timeout | Maximum session lifetime in seconds. |
[RW] | tmp_dh_callback | A callback invoked when DH parameters are required for ephemeral DH key exchange. The callback is invoked with the The callback must return an Deprecated in version 3.0. Use |
[RW] | verify_callback | 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 ( If the callback returns |
[RW] | verify_depth | Number of CA certificates to walk when verifying a certificate chain. |
[RW] | verify_hostname | Whether to check the server certificate is valid for the hostname. In order to make this work, |
[RW] | verify_mode |
Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE, VERIFY_FAIL_IF_NO_PEER_CERT and defined on The default mode is VERIFY_NONE, which does not perform any verification at all. See SSL_CTX_set_verify(3) for details. |
Class Public methods
SSLContext.new → ctx
SSLContext.new(:TLSv1) → ctx
SSLContext.new("SSLv23") → ctx
Link
Creates a new 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 Public methods
ctx.add_certificate(certificate, pkey [, extra_certs]) → self Link
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])
Source: show
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_eq(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 && !SSL_CTX_set0_chain(ctx, extra_chain)) { sk_X509_pop_free(extra_chain, X509_free); ossl_raise(eSSLError, "SSL_CTX_set0_chain"); } return self; }
ctx.ciphers => [[name, version, bits, alg_bits], ...] Link
The list of cipher suites configured for this context.
Source: show
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; }
ctx.ciphers = "cipher1:cipher2:..."
ctx.ciphers = [name, ...]
ctx.ciphers = [[name, version, bits, alg_bits], ...]
Link
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.
Source: show
static VALUE ossl_sslctx_set_ciphers(VALUE self, VALUE v) { SSL_CTX *ctx; VALUE str; rb_check_frozen(self); if (NIL_P(v)) return v; str = build_cipher_string(v); GetSSLCTX(self, ctx); if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) ossl_raise(eSSLError, "SSL_CTX_set_cipher_list"); return v; }
ctx.ciphersuites = "cipher1:cipher2:..."
ctx.ciphersuites = [name, ...]
ctx.ciphersuites = [[name, version, bits, alg_bits], ...]
Link
Sets the list of available TLSv1.3 cipher suites for this context.
Source: show
static VALUE ossl_sslctx_set_ciphersuites(VALUE self, VALUE v) { SSL_CTX *ctx; VALUE str; rb_check_frozen(self); if (NIL_P(v)) return v; str = build_cipher_string(v); GetSSLCTX(self, ctx); if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str))) ossl_raise(eSSLError, "SSL_CTX_set_ciphersuites"); return v; }
ctx.ecdh_curves = curve_list → curve_list Link
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.
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)
Source: show
static VALUE ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg) { SSL_CTX *ctx; rb_check_frozen(self); GetSSLCTX(self, ctx); StringValueCStr(arg); if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg))) ossl_raise(eSSLError, NULL); return arg; }
ctx.enable_fallback_scsv() => nil Link
Activate TLS_FALLBACK_SCSV for this context. See RFC 7507.
Source: show
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; }
ctx.flush_sessions(time) → self Link
Removes sessions in the internal cache that have expired at time.
Source: show
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; }
freeze() Link
This method is called automatically when a new SSLSocket
is created. However, it is not thread-safe and must be called before creating SSLSocket
objects in a multi-threaded program.
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.max_version = :TLS1_2
ctx.max_version = nil
Link
Sets the upper bound of the supported SSL/TLS protocol version. See min_version=
for the possible values.
ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.min_version = :TLS1_2
ctx.min_version = nil
Link
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,TLS}v* 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
options() Link
Gets various OpenSSL
options.
Source: show
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=(p1) Link
Sets various OpenSSL
options.
Source: show
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; }
ctx.security_level → Integer Link
Returns the security level for the context.
See also OpenSSL::SSL::SSLContext#security_level=
.
Source: show
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 }
ctx.security_level = integer Link
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.
Source: show
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; }
ctx.session_add(session) → true | false Link
Adds session to the session cache.
Source: show
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; }
ctx.session_cache_mode → Integer Link
The current session cache mode.
Source: show
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)); }
ctx.session_cache_mode=(integer) → Integer Link
Sets the SSL
session cache mode. Bitwise-or together the desired SESSION_CACHE_* constants to set. See SSL_CTX_set_session_cache_mode(3) for details.
Source: show
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; }
ctx.session_cache_size → Integer Link
Returns the current session cache size. Zero is used to represent an unlimited cache size.
Source: show
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)); }
ctx.session_cache_size=(integer) → Integer Link
Sets the session cache size. Returns the previously valid session cache size. Zero is used to represent an unlimited session cache size.
Source: show
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; }
ctx.session_cache_stats → Hash Link
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
Source: show
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; }
ctx.session_remove(session) → true | false Link
Removes session from the session cache.
Source: show
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; }
ctx.set_params(params = {}) → params Link
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 ruby/ext/openssl/lib/openssl/ssl.rb, line 146 def set_params(params={}) params = DEFAULT_PARAMS.merge(params) self.options = params.delete(:options) # 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
ctx.setup => Qtrue # first time
ctx.setup => nil # thereafter
Link
This method is called automatically when a new SSLSocket
is created. However, it is not thread-safe and must be called before creating SSLSocket
objects in a multi-threaded program.
Source: show
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 #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); X509_STORE_up_ref(store); } 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); #ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file)) ossl_raise(eSSLError, "SSL_CTX_load_verify_file"); if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path)) ossl_raise(eSSLError, "SSL_CTX_load_verify_dir"); #else if (ca_file || ca_path) { if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) ossl_raise(eSSLError, "SSL_CTX_load_verify_locations"); } #endif 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)); #ifdef OSSL_USE_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 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"); } 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"); } #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) /* * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6). */ if (RTEST(rb_attr_get(self, id_i_keylog_cb))) { SSL_CTX_set_keylog_callback(ctx, ossl_sslctx_keylog_cb); OSSL_Debug("SSL keylog callback added"); } #endif return Qtrue; }
ctx.ssl_version = :TLSv1
ctx.ssl_version = "SSLv23"
Link
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 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 ruby/ext/openssl/lib/openssl/ssl.rb, line 209 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
ctx.tmp_dh = pkey Link
Sets DH parameters used for ephemeral DH key exchange. This is relevant for servers only.
pkey
is an instance of OpenSSL::PKey::DH
. Note that key components contained in the key object, if any, are ignored. The server will always generate a new key pair for each handshake.
Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3).
Example:
ctx = OpenSSL::SSL::SSLContext.new
ctx.tmp_dh = OpenSSL::DH.generate(2048)
svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx)
Thread.new { svr.accept }
Source: show
static VALUE ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg) { SSL_CTX *ctx; EVP_PKEY *pkey; rb_check_frozen(self); GetSSLCTX(self, ctx); pkey = GetPKeyPtr(arg); if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) rb_raise(eSSLError, "invalid pkey type %s (expected DH)", OBJ_nid2sn(EVP_PKEY_base_id(pkey))); #ifdef HAVE_SSL_SET0_TMP_DH_PKEY if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey)) ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey"); EVP_PKEY_up_ref(pkey); #else if (!SSL_CTX_set_tmp_dh(ctx, EVP_PKEY_get0_DH(pkey))) ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh"); #endif return arg; }