非常教程

Ruby 2.4参考手册

OpenSSL

OpenSSL::SSL::SSLContext

Parent:Object

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.

Constants

METHODS

The list of available SSL/TLS methods

SESSION_CACHE_BOTH

Both client and server sessions are added to the session cache

SESSION_CACHE_CLIENT

Client sessions are added to the session cache

SESSION_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 flush_sessions can be called explicitly.

SESSION_CACHE_NO_INTERNAL

Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and SESSION_CACHE_NO_INTERNAL_STORE.

SESSION_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

Never automatically store sessions in the internal store.

SESSION_CACHE_OFF

No session caching for client or server

SESSION_CACHE_SERVER

Server sessions are added to the session cache

Attributes

alpn_protocolsRW

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_cbRW

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_fileRW

The path to a file containing a PEM-format CA certificate

ca_pathRW

The path to a directory containing CA certificates in PEM format.

Files are looked up by subject's X509 name's hash value.

certRW

Context certificate

cert_storeRW

An OpenSSL::X509::Store used for certificate verification.

client_caRW

A certificate or Array of certificates that will be sent to the client.

client_cert_cbRW

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.

extra_chain_certRW

An Array of extra X509 certificates to be added to the certificate chain.

keyRW

Context private key

npn_protocolsRW

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_cbRW

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

renegotiation_cbRW

A callback invoked whenever a new handshake is initiated. May be used to disable renegotiation entirely.

The callback is invoked with the active SSLSocket. The callback's return value is irrelevant, normal return indicates “approval” of the renegotiation and will continue the process. To forbid renegotiation and to cancel the process, an Error may be raised 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:

num_handshakes = 0
ctx.renegotiation_cb = lambda do |ssl|
  num_handshakes += 1
  raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
end

servername_cbRW

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.

session_get_cbRW

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 SSLSocket and session id. The callback may return a Session from an external cache.

session_id_contextRW

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_cbRW

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_cbRW

A callback invoked when a session is removed from the internal cache.

The callback is invoked with an SSLContext and a Session.

ssl_timeoutRW

Maximum session lifetime in seconds.

timeoutRW

Maximum session lifetime in seconds.

tmp_dh_callbackRW

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.

tmp_ecdh_callbackRW

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_callbackRW

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_depthRW

Number of CA certificates to walk when verifying a certificate chain.

verify_hostnameRW

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 OpenSSL::SSL::SSLSocket#hostname=.

verify_modeRW

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.

Public Class Methods

new → ctx Show source

new(:TLSv1) → ctx

new("SSLv23_client") → ctx

You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS

# File ext/openssl/lib/openssl/ssl.rb, line 97
def initialize(version = nil)
  self.options |= OpenSSL::SSL::OP_ALL
  self.ssl_version = version if version
end

Public Instance Methods

ciphers → [name, version, bits, alg_bits], ...()

The list of cipher suites configured for this context.

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);
    if(!ctx){
        rb_warning("SSL_CTX is not initialized.");
        return Qnil;
    }
    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:..." Show source

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.

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(!ctx){
        ossl_raise(eSSLError, "SSL_CTX is not initialized.");
        return Qnil;
    }
    if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
        ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
    }

    return v;
}

ecdh_curves = curve_list → curve_list Show source

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)
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;
}

flush_sessions(time | nil) → self Show source

Removes sessions in the internal cache that have expired at time.

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()

Alias for: setup

options() Show source

Gets various OpenSSL options.

static VALUE
ossl_sslctx_get_options(VALUE self)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
    return LONG2NUM(SSL_CTX_get_options(ctx));
}

options=(p1) Show source

Sets various OpenSSL options.

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, NUM2LONG(options));
    }

    return self;
}

security_level → Integer Show source

Returns the security level for the context.

See also #security_level=.

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 Show source

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.

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;
}

session_add(session) → true | false Show source

Adds session to the session cache.

static VALUE
ossl_sslctx_session_add(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    SSL_SESSION *sess;

    GetSSLCTX(self, ctx);
    SafeGetSSLSession(arg, sess);

    return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}

session_cache_mode → Integer Show source

The current session cache mode.

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 Show source

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.

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 Show source

Returns the current session cache size. Zero is used to represent an unlimited cache size.

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 Show source

Sets the session cache size. Returns the previously valid session cache size. Zero is used to represent an unlimited session cache size.

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_cache_stats → Hash Show source

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

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) → true | false Show source

Removes session from the session cache.

static VALUE
ossl_sslctx_session_remove(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    SSL_SESSION *sess;

    GetSSLCTX(self, ctx);
    SafeGetSSLSession(arg, sess);

    return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}

set_params(params = {}) → params Show source

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 114
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
      self.cert_store = DEFAULT_CERT_STORE
    end
  end
  return params
end

setup → Qtrue # first time Show source

setup → nil # thereafter

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.

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 */

    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_ssl_ex_store_p, (void *)1);
#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));

#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
    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 *)encoded);
        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");
    }

#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
    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");
    }
#endif

    return Qtrue;
}

Also aliased as: freeze

ssl_version = :TLSv1 Show source

ssl_version = "SSLv23_client"

Sets the SSL/TLS protocol version for the context. This forces connections to use only the specified protocol version.

You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS

static VALUE
ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
{
    SSL_CTX *ctx;
    const char *s;
    VALUE m = ssl_method;
    int i;

    GetSSLCTX(self, ctx);
    if (RB_TYPE_P(ssl_method, T_SYMBOL))
        m = rb_sym2str(ssl_method);
    s = StringValueCStr(m);
    for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
        if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
            int version = ossl_ssl_method_tab[i].version;
#endif
            SSL_METHOD *method = ossl_ssl_method_tab[i].func();

            if (SSL_CTX_set_ssl_version(ctx, method) != 1)
                ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");

#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
            if (!SSL_CTX_set_min_proto_version(ctx, version))
                ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
            if (!SSL_CTX_set_max_proto_version(ctx, version))
                ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
#endif
            return ssl_method;
        }
    }

    ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
}
 Ruby Core © 1993–2017 Yukihiro Matsumoto

Licensed under the Ruby License.

Ruby Standard Library © contributors

Licensed under their own licenses.

OpenSSL相关

1.OpenSSL::ASN1
2.OpenSSL::ASN1::ASN1Data
3.OpenSSL::ASN1::ASN1Error
4.OpenSSL::ASN1::Constructive
5.OpenSSL::ASN1::ObjectId
6.OpenSSL::ASN1::Primitive
7.OpenSSL::BN
8.OpenSSL::BNError
9.OpenSSL::Buffering
10.OpenSSL::Cipher
11.OpenSSL::Cipher::Cipher
12.OpenSSL::Config
13.OpenSSL::ConfigError
14.OpenSSL::Digest
15.OpenSSL::Digest::DigestError
16.OpenSSL::Engine
17.OpenSSL::Engine::EngineError
18.OpenSSL::ExtConfig
19.OpenSSL::HMAC
20.OpenSSL::HMACError
21.OpenSSL::Netscape
22.OpenSSL::Netscape::SPKI
23.OpenSSL::Netscape::SPKIError
24.OpenSSL::OCSP
25.OpenSSL::OCSP::BasicResponse
26.OpenSSL::OCSP::CertificateId
27.OpenSSL::OCSP::OCSPError
28.OpenSSL::OCSP::Request
29.OpenSSL::OCSP::Response
30.OpenSSL::OCSP::SingleResponse
31.OpenSSL::OpenSSLError
32.OpenSSL::PKCS12
33.OpenSSL::PKCS5
34.OpenSSL::PKCS5::PKCS5Error
35.OpenSSL::PKCS7
36.OpenSSL::PKCS7::RecipientInfo
37.OpenSSL::PKCS7::SignerInfo
38.OpenSSL::PKey
39.OpenSSL::PKey::DH
40.OpenSSL::PKey::DHError
41.OpenSSL::PKey::DSA
42.OpenSSL::PKey::DSAError
43.OpenSSL::PKey::EC
44.OpenSSL::PKey::EC::Group
45.OpenSSL::PKey::EC::Point
46.OpenSSL::PKey::PKey
47.OpenSSL::PKey::PKeyError
48.OpenSSL::PKey::RSA
49.OpenSSL::PKey::RSAError
50.OpenSSL::Random
51.OpenSSL::SSL
52.OpenSSL::SSL::Session
53.OpenSSL::SSL::SocketForwarder
54.OpenSSL::SSL::SSLError
55.OpenSSL::SSL::SSLServer
56.OpenSSL::SSL::SSLSocket
57.OpenSSL::X509::Attribute
58.OpenSSL::X509::Certificate
59.OpenSSL::X509::CRL
60.OpenSSL::X509::Extension
61.OpenSSL::X509::ExtensionFactory
62.OpenSSL::X509::Name
63.OpenSSL::X509::Name::RFC2253DN
64.OpenSSL::X509::Request
65.OpenSSL::X509::Revoked
66.OpenSSL::X509::Store
67.OpenSSL::X509::StoreContext
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct