diff options
Diffstat (limited to 'ext/openssl/ossl_ssl.c')
-rw-r--r-- | ext/openssl/ossl_ssl.c | 139 |
1 files changed, 12 insertions, 127 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index c38142bf..76db821e 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -55,19 +55,11 @@ static ID id_i_io, id_i_context, id_i_hostname; static int ossl_ssl_ex_vcb_idx; static int ossl_ssl_ex_ptr_idx; static int ossl_sslctx_ex_ptr_idx; -#if !defined(HAVE_X509_STORE_UP_REF) -static int ossl_sslctx_ex_store_p; -#endif static void ossl_sslctx_free(void *ptr) { - SSL_CTX *ctx = ptr; -#if !defined(HAVE_X509_STORE_UP_REF) - if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p)) - ctx->cert_store = NULL; -#endif - SSL_CTX_free(ctx); + SSL_CTX_free(ptr); } static const rb_data_type_t ossl_sslctx_type = { @@ -89,7 +81,7 @@ ossl_sslctx_s_alloc(VALUE klass) VALUE obj; obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0); -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) ctx = SSL_CTX_new(TLS_method()); #else ctx = SSL_CTX_new(SSLv23_method()); @@ -101,14 +93,15 @@ ossl_sslctx_s_alloc(VALUE klass) RTYPEDDATA_DATA(obj) = ctx; SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj); -#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO) +#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \ + !defined(LIBRESSL_VERSION_NUMBER) /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It * allows to specify multiple curve names and OpenSSL will select * automatically from them. In OpenSSL 1.0.2, the automatic selection has to - * be enabled explicitly. But OpenSSL 1.1.0 removed the knob and it is - * always enabled. To uniform the behavior, we enable the automatic - * selection also in 1.0.2. Users can still disable ECDH by removing ECDH - * cipher suites by SSLContext#ciphers=. */ + * be enabled explicitly. OpenSSL 1.1.0 and LibreSSL 2.6.1 removed the knob + * and it is always enabled. To uniform the behavior, we enable the + * automatic selection also in 1.0.2. Users can still disable ECDH by + * removing ECDH cipher suites by SSLContext#ciphers=. */ if (!SSL_CTX_set_ecdh_auto(ctx, 1)) ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto"); #endif @@ -363,7 +356,7 @@ ossl_call_session_get_cb(VALUE ary) } static SSL_SESSION * -#if (!defined(LIBRESSL_VERSION_NUMBER) ? OPENSSL_VERSION_NUMBER >= 0x10100000 : LIBRESSL_VERSION_NUMBER >= 0x2080000f) +#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000 ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy) #else ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy) @@ -572,8 +565,6 @@ ssl_renegotiation_cb(const SSL *ssl) rb_funcallv(cb, id_call, 1, &ssl_obj); } -#if !defined(OPENSSL_NO_NEXTPROTONEG) || \ - defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) static VALUE ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded)) { @@ -655,7 +646,6 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out, return SSL_TLSEXT_ERR_OK; } -#endif #ifndef OPENSSL_NO_NEXTPROTONEG static int @@ -684,7 +674,6 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen, } #endif -#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB static int ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) @@ -696,7 +685,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen); } -#endif /* This function may serve as the entry point to support further callbacks. */ static void @@ -781,17 +769,7 @@ ossl_sslctx_setup(VALUE self) 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); @@ -873,7 +851,6 @@ ossl_sslctx_setup(VALUE self) } #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); @@ -888,7 +865,6 @@ ossl_sslctx_setup(VALUE self) 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); @@ -1021,9 +997,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) * 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" @@ -1047,48 +1020,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg) 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; } #else @@ -1211,10 +1144,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self) * 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. */ static VALUE ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self) @@ -1253,34 +1182,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self) 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 + 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; } @@ -2381,7 +2285,6 @@ ossl_ssl_npn_protocol(VALUE self) } # endif -# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB /* * call-seq: * ssl.alpn_protocol => String | nil @@ -2404,9 +2307,7 @@ ossl_ssl_alpn_protocol(VALUE self) else return rb_str_new((const char *) out, outlen); } -# endif -# ifdef HAVE_SSL_GET_SERVER_TMP_KEY /* * call-seq: * ssl.tmp_key => PKey or nil @@ -2424,7 +2325,6 @@ ossl_ssl_tmp_key(VALUE self) return Qnil; return ossl_pkey_new(key); } -# endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */ #endif /* !defined(OPENSSL_NO_SOCK) */ void @@ -2449,11 +2349,6 @@ Init_ossl_ssl(void) ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0); if (ossl_sslctx_ex_ptr_idx < 0) ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index"); -#if !defined(HAVE_X509_STORE_UP_REF) - ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0); - if (ossl_sslctx_ex_store_p < 0) - ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index"); -#endif /* Document-module: OpenSSL::SSL * @@ -2690,7 +2585,6 @@ Init_ossl_ssl(void) rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse); #endif -#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB /* * An Enumerable of Strings. Each String represents a protocol to be * advertised as the list of supported protocols for Application-Layer @@ -2720,7 +2614,6 @@ Init_ossl_ssl(void) * end */ rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse); -#endif rb_define_alias(cSSLContext, "ssl_timeout", "timeout"); rb_define_alias(cSSLContext, "ssl_timeout=", "timeout="); @@ -2834,12 +2727,8 @@ Init_ossl_ssl(void) rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1); rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0); rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0); -# ifdef HAVE_SSL_GET_SERVER_TMP_KEY rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0); -# endif -# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0); -# endif # ifndef OPENSSL_NO_NEXTPROTONEG rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0); # endif @@ -2852,12 +2741,8 @@ Init_ossl_ssl(void) rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL)); rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT)); -#ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */ rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING)); -#endif -#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */ rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG)); -#endif #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */ rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX)); #endif |