[前][次][番号順一覧][スレッド一覧]

ruby-changes:43209

From: rhe <ko1@a...>
Date: Sun, 5 Jun 2016 21:46:11 +0900 (JST)
Subject: [ruby-changes:43209] rhe:r55283 (trunk): openssl: support OpenSSL 1.1.0's new multi-threading API

rhe	2016-06-05 21:46:05 +0900 (Sun, 05 Jun 2016)

  New Revision: 55283

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55283

  Log:
    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().

  Modified files:
    trunk/ChangeLog
    trunk/ext/openssl/extconf.rb
    trunk/ext/openssl/openssl_missing.h
    trunk/ext/openssl/ossl.c
    trunk/ext/openssl/ossl_pkey.c
    trunk/ext/openssl/ossl_ssl.c
    trunk/ext/openssl/ossl_x509cert.c
    trunk/ext/openssl/ossl_x509crl.c
    trunk/ext/openssl/ossl_x509store.c
Index: ext/openssl/ossl_x509crl.c
===================================================================
--- ext/openssl/ossl_x509crl.c	(revision 55282)
+++ ext/openssl/ossl_x509crl.c	(revision 55283)
@@ -67,7 +67,7 @@ DupX509CRLPtr(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_x509crl.c#L67
     X509_CRL *crl;
 
     SafeGetX509CRL(obj, crl);
-    CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
+    X509_CRL_up_ref(crl);
 
     return crl;
 }
Index: ext/openssl/extconf.rb
===================================================================
--- ext/openssl/extconf.rb	(revision 55282)
+++ ext/openssl/extconf.rb	(revision 55283)
@@ -107,9 +107,15 @@ OpenSSL.check_func_or_macro("SSL_CTX_set https://github.com/ruby/ruby/blob/trunk/ext/openssl/extconf.rb#L107
 OpenSSL.check_func_or_macro("SSL_get_server_tmp_key", "openssl/ssl.h")
 
 # 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
 have_func("X509_STORE_get_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
 
 Logging::message "=== Checking done. ===\n"
Index: ext/openssl/ossl_ssl.c
===================================================================
--- ext/openssl/ossl_ssl.c	(revision 55282)
+++ ext/openssl/ossl_ssl.c	(revision 55283)
@@ -128,8 +128,10 @@ static void https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L128
 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_ssl_ex_store_p)== (void*)1)
 	ctx->cert_store = NULL;
+#endif
     SSL_CTX_free(ctx);
 }
 
@@ -397,7 +399,7 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L399
     	return 1;
     ssl_obj = (VALUE)ptr;
     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;
 
     ary = rb_ary_new2(2);
@@ -446,7 +448,7 @@ ossl_sslctx_session_remove_cb(SSL_CTX *c https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L448
     	return;
     sslctx_obj = (VALUE)ptr;
     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;
 
     ary = rb_ary_new2(2);
@@ -708,7 +710,6 @@ ossl_sslctx_setup(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L710
 {
     SSL_CTX *ctx;
     X509 *cert = NULL, *client_ca = NULL;
-    X509_STORE *store;
     EVP_PKEY *key = NULL;
     char *ca_path = NULL, *ca_file = NULL;
     int verify_mode;
@@ -743,16 +744,20 @@ ossl_sslctx_setup(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L744
 #endif /* OPENSSL_NO_EC */
 
     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:
 	 *   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.
 	 */
-        store = GetX509StorePtr(val); /* NO NEED TO DUP */
-        SSL_CTX_set_cert_store(ctx, store);
-        SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
+        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 = ossl_sslctx_get_extra_cert(self);
Index: ext/openssl/ossl_pkey.c
===================================================================
--- ext/openssl/ossl_pkey.c	(revision 55282)
+++ ext/openssl/ossl_pkey.c	(revision 55283)
@@ -191,7 +191,7 @@ DupPKeyPtr(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey.c#L191
     EVP_PKEY *pkey;
 
     SafeGetPKey(obj, pkey);
-    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+    EVP_PKEY_up_ref(pkey);
 
     return pkey;
 }
@@ -205,7 +205,7 @@ DupPrivPKeyPtr(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey.c#L205
 	ossl_raise(rb_eArgError, "Private key is needed.");
     }
     SafeGetPKey(obj, pkey);
-    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+    EVP_PKEY_up_ref(pkey);
 
     return pkey;
 }
Index: ext/openssl/ossl.c
===================================================================
--- ext/openssl/ossl.c	(revision 55282)
+++ ext/openssl/ossl.c	(revision 55283)
@@ -508,6 +508,7 @@ ossl_fips_mode_set(VALUE self, VALUE ena https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L508
 #endif
 }
 
+#if !defined(HAVE_OPENSSL_110_THREADING_API)
 /**
  * Stores locks needed for OpenSSL thread safety
  */
@@ -595,6 +596,7 @@ static void Init_ossl_locks(void) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L596
     CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_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
@@ -1195,7 +1197,9 @@ Init_openssl(void) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L1197
      */
     ossl_s_to_der = rb_intern("to_der");
 
+#if !defined(HAVE_OPENSSL_110_THREADING_API)
     Init_ossl_locks();
+#endif
 
     /*
      * Init components
Index: ext/openssl/openssl_missing.h
===================================================================
--- ext/openssl/openssl_missing.h	(revision 55282)
+++ ext/openssl/openssl_missing.h	(revision 55283)
@@ -45,4 +45,29 @@ int EC_curve_nist2nid(const char *); https://github.com/ruby/ruby/blob/trunk/ext/openssl/openssl_missing.h#L45
 				(newf), (dupf), (freef))
 #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_ */
Index: ext/openssl/ossl_x509store.c
===================================================================
--- ext/openssl/ossl_x509store.c	(revision 55282)
+++ ext/openssl/ossl_x509store.c	(revision 55283)
@@ -98,7 +98,7 @@ DupX509StorePtr(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_x509store.c#L98
     X509_STORE *store;
 
     SafeGetX509Store(obj, store);
-    CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
+    X509_STORE_up_ref(store);
 
     return store;
 }
Index: ext/openssl/ossl_x509cert.c
===================================================================
--- ext/openssl/ossl_x509cert.c	(revision 55282)
+++ ext/openssl/ossl_x509cert.c	(revision 55283)
@@ -122,7 +122,7 @@ DupX509CertPtr(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_x509cert.c#L122
 
     SafeGetX509(obj, x509);
 
-    CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
+    X509_up_ref(x509);
 
     return x509;
 }
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55282)
+++ ChangeLog	(revision 55283)
@@ -1,3 +1,24 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Jun  5 21:42:24 2016  Kazuki Yamaguchi  <k@r...>
+
+	* 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@r...>
 
 	* ext/openssl/extconf.rb: Check if RAND_pseudo_bytes() is usable. It is

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]