mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
openssl: support OpenSSL 1.1.0's new multi-threading API
* ext/openssl/extconf.rb: Check absence of CRYPTO_lock() to see if the OpenSSL has the new threading API. In OpenSSL <= 1.0.2, an application had to set locking callbacks to use OpenSSL in a multi-threaded environment. OpenSSL 1.1.0 now finds pthreads or Windows threads so we don't need to do something special. [ruby-core:75225] [Feature #12324] Also check existence of *_up_ref(). Some structures in OpenSSL have a reference counter. We used to increment it with CRYPTO_add() which is a part of the old API. * ext/openssl/openssl_missing.h: Implement *_up_ref() if missing. * ext/openssl/ossl.c: Don't set locking callbacks if unneeded. * ext/openssl/ossl_pkey.c, ext/openssl/ossl_ssl.c, ext/openssl/ossl_x509cert.c, ext/openssl/ossl_x509crl.c, ext/openssl/ossl_x509store.c: Use *_up_ref() instead of CRYPTO_add(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55283 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9199bec9e8
commit
e478bb7d79
9 changed files with 73 additions and 12 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
Sun Jun 5 21:42:24 2016 Kazuki Yamaguchi <k@rhe.jp>
|
||||||
|
|
||||||
|
* ext/openssl/extconf.rb: Check absence of CRYPTO_lock() to see if the
|
||||||
|
OpenSSL has the new threading API. In OpenSSL <= 1.0.2, an application
|
||||||
|
had to set locking callbacks to use OpenSSL in a multi-threaded
|
||||||
|
environment. OpenSSL 1.1.0 now finds pthreads or Windows threads so we
|
||||||
|
don't need to do something special.
|
||||||
|
[ruby-core:75225] [Feature #12324]
|
||||||
|
|
||||||
|
Also check existence of *_up_ref(). Some structures in OpenSSL have
|
||||||
|
a reference counter. We used to increment it with CRYPTO_add() which
|
||||||
|
is a part of the old API.
|
||||||
|
|
||||||
|
* ext/openssl/openssl_missing.h: Implement *_up_ref() if missing.
|
||||||
|
|
||||||
|
* ext/openssl/ossl.c: Don't set locking callbacks if unneeded.
|
||||||
|
|
||||||
|
* ext/openssl/ossl_pkey.c, ext/openssl/ossl_ssl.c,
|
||||||
|
ext/openssl/ossl_x509cert.c, ext/openssl/ossl_x509crl.c,
|
||||||
|
ext/openssl/ossl_x509store.c: Use *_up_ref() instead of CRYPTO_add().
|
||||||
|
|
||||||
Sun Jun 5 21:38:13 2016 Kazuki Yamaguchi <k@rhe.jp>
|
Sun Jun 5 21:38:13 2016 Kazuki Yamaguchi <k@rhe.jp>
|
||||||
|
|
||||||
* ext/openssl/extconf.rb: Check if RAND_pseudo_bytes() is usable. It is
|
* ext/openssl/extconf.rb: Check if RAND_pseudo_bytes() is usable. It is
|
||||||
|
|
|
@ -107,9 +107,15 @@ OpenSSL.check_func_or_macro("SSL_CTX_set_ecdh_auto", "openssl/ssl.h")
|
||||||
OpenSSL.check_func_or_macro("SSL_get_server_tmp_key", "openssl/ssl.h")
|
OpenSSL.check_func_or_macro("SSL_get_server_tmp_key", "openssl/ssl.h")
|
||||||
|
|
||||||
# added in 1.1.0
|
# added in 1.1.0
|
||||||
|
have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API")
|
||||||
OpenSSL.check_func("RAND_pseudo_bytes", "openssl/rand.h") # deprecated
|
OpenSSL.check_func("RAND_pseudo_bytes", "openssl/rand.h") # deprecated
|
||||||
have_func("X509_STORE_get_ex_data")
|
have_func("X509_STORE_get_ex_data")
|
||||||
have_func("X509_STORE_set_ex_data")
|
have_func("X509_STORE_set_ex_data")
|
||||||
|
have_func("X509_up_ref")
|
||||||
|
have_func("X509_CRL_up_ref")
|
||||||
|
have_func("X509_STORE_up_ref")
|
||||||
|
have_func("SSL_SESSION_up_ref")
|
||||||
|
have_func("EVP_PKEY_up_ref")
|
||||||
OpenSSL.check_func_or_macro("SSL_CTX_set_tmp_ecdh_callback", "openssl/ssl.h") # removed
|
OpenSSL.check_func_or_macro("SSL_CTX_set_tmp_ecdh_callback", "openssl/ssl.h") # removed
|
||||||
|
|
||||||
Logging::message "=== Checking done. ===\n"
|
Logging::message "=== Checking done. ===\n"
|
||||||
|
|
|
@ -45,4 +45,29 @@ int EC_curve_nist2nid(const char *);
|
||||||
(newf), (dupf), (freef))
|
(newf), (dupf), (freef))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_X509_UP_REF)
|
||||||
|
# define X509_up_ref(x) \
|
||||||
|
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_X509_CRL_UP_REF)
|
||||||
|
# define X509_CRL_up_ref(x) \
|
||||||
|
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_CRL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_X509_STORE_UP_REF)
|
||||||
|
# define X509_STORE_up_ref(x) \
|
||||||
|
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_STORE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_SSL_SESSION_UP_REF)
|
||||||
|
# define SSL_SESSION_up_ref(x) \
|
||||||
|
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_SSL_SESSION);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_EVP_PKEY_UP_REF)
|
||||||
|
# define EVP_PKEY_up_ref(x) \
|
||||||
|
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _OSSL_OPENSSL_MISSING_H_ */
|
#endif /* _OSSL_OPENSSL_MISSING_H_ */
|
||||||
|
|
|
@ -508,6 +508,7 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(HAVE_OPENSSL_110_THREADING_API)
|
||||||
/**
|
/**
|
||||||
* Stores locks needed for OpenSSL thread safety
|
* Stores locks needed for OpenSSL thread safety
|
||||||
*/
|
*/
|
||||||
|
@ -595,6 +596,7 @@ static void Init_ossl_locks(void)
|
||||||
CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback);
|
CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback);
|
||||||
CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback);
|
CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback);
|
||||||
}
|
}
|
||||||
|
#endif /* !HAVE_OPENSSL_110_THREADING_API */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
|
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
|
||||||
|
@ -1195,7 +1197,9 @@ Init_openssl(void)
|
||||||
*/
|
*/
|
||||||
ossl_s_to_der = rb_intern("to_der");
|
ossl_s_to_der = rb_intern("to_der");
|
||||||
|
|
||||||
|
#if !defined(HAVE_OPENSSL_110_THREADING_API)
|
||||||
Init_ossl_locks();
|
Init_ossl_locks();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init components
|
* Init components
|
||||||
|
|
|
@ -191,7 +191,7 @@ DupPKeyPtr(VALUE obj)
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
|
|
||||||
SafeGetPKey(obj, pkey);
|
SafeGetPKey(obj, pkey);
|
||||||
CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
EVP_PKEY_up_ref(pkey);
|
||||||
|
|
||||||
return pkey;
|
return pkey;
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ DupPrivPKeyPtr(VALUE obj)
|
||||||
ossl_raise(rb_eArgError, "Private key is needed.");
|
ossl_raise(rb_eArgError, "Private key is needed.");
|
||||||
}
|
}
|
||||||
SafeGetPKey(obj, pkey);
|
SafeGetPKey(obj, pkey);
|
||||||
CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
EVP_PKEY_up_ref(pkey);
|
||||||
|
|
||||||
return pkey;
|
return pkey;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,8 +128,10 @@ static void
|
||||||
ossl_sslctx_free(void *ptr)
|
ossl_sslctx_free(void *ptr)
|
||||||
{
|
{
|
||||||
SSL_CTX *ctx = ptr;
|
SSL_CTX *ctx = ptr;
|
||||||
|
#if !defined(HAVE_X509_STORE_UP_REF)
|
||||||
if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1)
|
if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1)
|
||||||
ctx->cert_store = NULL;
|
ctx->cert_store = NULL;
|
||||||
|
#endif
|
||||||
SSL_CTX_free(ctx);
|
SSL_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +399,7 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
|
||||||
return 1;
|
return 1;
|
||||||
ssl_obj = (VALUE)ptr;
|
ssl_obj = (VALUE)ptr;
|
||||||
sess_obj = rb_obj_alloc(cSSLSession);
|
sess_obj = rb_obj_alloc(cSSLSession);
|
||||||
CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION);
|
SSL_SESSION_up_ref(sess);
|
||||||
DATA_PTR(sess_obj) = sess;
|
DATA_PTR(sess_obj) = sess;
|
||||||
|
|
||||||
ary = rb_ary_new2(2);
|
ary = rb_ary_new2(2);
|
||||||
|
@ -446,7 +448,7 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
|
||||||
return;
|
return;
|
||||||
sslctx_obj = (VALUE)ptr;
|
sslctx_obj = (VALUE)ptr;
|
||||||
sess_obj = rb_obj_alloc(cSSLSession);
|
sess_obj = rb_obj_alloc(cSSLSession);
|
||||||
CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION);
|
SSL_SESSION_up_ref(sess);
|
||||||
DATA_PTR(sess_obj) = sess;
|
DATA_PTR(sess_obj) = sess;
|
||||||
|
|
||||||
ary = rb_ary_new2(2);
|
ary = rb_ary_new2(2);
|
||||||
|
@ -708,7 +710,6 @@ ossl_sslctx_setup(VALUE self)
|
||||||
{
|
{
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
X509 *cert = NULL, *client_ca = NULL;
|
X509 *cert = NULL, *client_ca = NULL;
|
||||||
X509_STORE *store;
|
|
||||||
EVP_PKEY *key = NULL;
|
EVP_PKEY *key = NULL;
|
||||||
char *ca_path = NULL, *ca_file = NULL;
|
char *ca_path = NULL, *ca_file = NULL;
|
||||||
int verify_mode;
|
int verify_mode;
|
||||||
|
@ -743,16 +744,20 @@ ossl_sslctx_setup(VALUE self)
|
||||||
#endif /* OPENSSL_NO_EC */
|
#endif /* OPENSSL_NO_EC */
|
||||||
|
|
||||||
val = ossl_sslctx_get_cert_store(self);
|
val = ossl_sslctx_get_cert_store(self);
|
||||||
if(!NIL_P(val)){
|
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:
|
* WORKAROUND:
|
||||||
* X509_STORE can count references, but
|
* X509_STORE can count references, but
|
||||||
* X509_STORE_free() doesn't care it.
|
* X509_STORE_free() doesn't care it.
|
||||||
* So we won't increment it but mark it by ex_data.
|
* So we won't increment it but mark it by ex_data.
|
||||||
*/
|
*/
|
||||||
store = GetX509StorePtr(val); /* NO NEED TO DUP */
|
SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void *)1);
|
||||||
SSL_CTX_set_cert_store(ctx, store);
|
#else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
|
||||||
SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
|
X509_STORE_up_ref(store);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
val = ossl_sslctx_get_extra_cert(self);
|
val = ossl_sslctx_get_extra_cert(self);
|
||||||
|
|
|
@ -122,7 +122,7 @@ DupX509CertPtr(VALUE obj)
|
||||||
|
|
||||||
SafeGetX509(obj, x509);
|
SafeGetX509(obj, x509);
|
||||||
|
|
||||||
CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
|
X509_up_ref(x509);
|
||||||
|
|
||||||
return x509;
|
return x509;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ DupX509CRLPtr(VALUE obj)
|
||||||
X509_CRL *crl;
|
X509_CRL *crl;
|
||||||
|
|
||||||
SafeGetX509CRL(obj, crl);
|
SafeGetX509CRL(obj, crl);
|
||||||
CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
|
X509_CRL_up_ref(crl);
|
||||||
|
|
||||||
return crl;
|
return crl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ DupX509StorePtr(VALUE obj)
|
||||||
X509_STORE *store;
|
X509_STORE *store;
|
||||||
|
|
||||||
SafeGetX509Store(obj, store);
|
SafeGetX509Store(obj, store);
|
||||||
CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
|
X509_STORE_up_ref(store);
|
||||||
|
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue