Convert CRYPTO_LOCK_EVP_PKEY to new multi-threading API
authorAlessandro Ghedini <alessandro@ghedini.me>
Fri, 26 Feb 2016 12:21:15 +0000 (12:21 +0000)
committerRich Salz <rsalz@openssl.org>
Tue, 8 Mar 2016 16:10:34 +0000 (11:10 -0500)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/asn1/x_pubkey.c
crypto/cms/cms_env.c
crypto/cms/cms_sd.c
crypto/evp/p_lib.c
crypto/evp/pmeth_fn.c
crypto/evp/pmeth_lib.c
crypto/include/internal/evp_int.h
include/openssl/crypto.h
include/openssl/x509.h

index 1d65b20ed6189dbaa4d9f2667392cb9a28f7fd6c..7c88291e8020f9297e3f6f3769e68c777d57b597 100644 (file)
 static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
                      void *exarg)
 {
+    if (operation == ASN1_OP_NEW_POST) {
+        X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+        pubkey->lock = CRYPTO_THREAD_lock_new();
+        if (pubkey->lock == NULL)
+            return 0;
+    }
     if (operation == ASN1_OP_FREE_POST) {
         X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+        CRYPTO_THREAD_lock_free(pubkey->lock);
         EVP_PKEY_free(pubkey->pkey);
     }
     return 1;
@@ -155,14 +162,14 @@ EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key)
     }
 
     /* Check to see if another thread set key->pkey first */
-    CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+    CRYPTO_THREAD_write_lock(key->lock);
     if (key->pkey) {
-        CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+        CRYPTO_THREAD_unlock(key->lock);
         EVP_PKEY_free(ret);
         ret = key->pkey;
     } else {
         key->pkey = ret;
-        CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+        CRYPTO_THREAD_unlock(key->lock);
     }
 
     return ret;
index 3b065ae250062bb5ba089da847668d888abacc5f..c54667f5df5007ed2e57918be4dd2b7c01f6b08d 100644 (file)
@@ -200,7 +200,8 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
         return 0;
 
     X509_up_ref(recip);
-    CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
+    EVP_PKEY_up_ref(pk);
+
     ktri->pkey = pk;
     ktri->recip = recip;
 
index 2757aa939245dda90b57efb422f0e20344d8bc8a..151f40f9a54f07c261cd27e52ef1ba653a4a04f3 100644 (file)
@@ -283,8 +283,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
     /* Call for side-effect of computing hash and caching extensions */
     X509_check_purpose(signer, -1, -1);
 
-    CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
     X509_up_ref(signer);
+    EVP_PKEY_up_ref(pk);
 
     si->pkey = pk;
     si->signer = signer;
index b34a268c899921664e9923f3eb5f49c57dec71e5..a7d624427e3cffb5133039dd6f5104b07931d531 100644 (file)
@@ -190,18 +190,25 @@ EVP_PKEY *EVP_PKEY_new(void)
 
     if (ret == NULL) {
         EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
-        return (NULL);
+        return NULL;
     }
     ret->type = EVP_PKEY_NONE;
     ret->save_type = EVP_PKEY_NONE;
     ret->references = 1;
     ret->save_parameters = 1;
-    return (ret);
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
 }
 
 void EVP_PKEY_up_ref(EVP_PKEY *pkey)
 {
-    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+    int i;
+    CRYPTO_atomic_add(&pkey->references, 1, &i, pkey->lock);
 }
 
 /*
@@ -416,7 +423,7 @@ void EVP_PKEY_free(EVP_PKEY *x)
     if (x == NULL)
         return;
 
-    i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
+    CRYPTO_atomic_add(&x->references, -1, &i, x->lock);
     REF_PRINT_COUNT("EVP_PKEY", x);
     if (i > 0)
         return;
@@ -437,6 +444,7 @@ static void EVP_PKEY_free_it(EVP_PKEY *x)
     ENGINE_finish(x->engine);
     x->engine = NULL;
 #endif
+    CRYPTO_THREAD_lock_free(x->lock);
 }
 
 static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
index 11c319dd41f0157292cedea4d17af937273fadc4..872947a6aa5014484d081a08a48762969bfaf1d1 100644 (file)
@@ -324,7 +324,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
         return ret;
     }
 
-    CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY);
+    EVP_PKEY_up_ref(peer);
     return 1;
 }
 
index 9ae61cf22ee840b0531692f6e618cbc454becc74..26bec9a64b7caa41fee5a88025ffca5d42b904ae 100644 (file)
@@ -175,7 +175,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
     ret->operation = EVP_PKEY_OP_UNDEFINED;
     ret->pkey = pkey;
     if (pkey)
-        CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+        EVP_PKEY_up_ref(pkey);
 
     if (pmeth->init) {
         if (pmeth->init(ret) <= 0) {
@@ -288,12 +288,12 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
 #endif
 
     if (pctx->pkey)
-        CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+        EVP_PKEY_up_ref(pctx->pkey);
 
     rctx->pkey = pctx->pkey;
 
     if (pctx->peerkey)
-        CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+        EVP_PKEY_up_ref(pctx->peerkey);
 
     rctx->peerkey = pctx->peerkey;
 
index cccc1e10feba005a2d55b02ba06b8624b18ca5b5..f5811c1d10b82653c03990ca76d9814993c44a02 100644 (file)
@@ -416,6 +416,7 @@ struct evp_pkey_st {
     } pkey;
     int save_parameters;
     STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+    CRYPTO_RWLOCK *lock;
 } /* EVP_PKEY */ ;
 
 
index a36d7175e163a0088f6571ba9a6d066cdc9f2c8e..4af6f72b0c139665d45dd50758921d736860ed32 100644 (file)
@@ -170,7 +170,6 @@ extern "C" {
 # define CRYPTO_LOCK_X509_PKEY           5
 # define CRYPTO_LOCK_X509_CRL            6
 # define CRYPTO_LOCK_X509_REQ            7
-# define CRYPTO_LOCK_EVP_PKEY            10
 # define CRYPTO_LOCK_X509_STORE          11
 # define CRYPTO_LOCK_SSL_CTX             12
 # define CRYPTO_LOCK_SSL_CERT            13
index fc77886d20e57f105f9308d59a00357b646030b3..294ab83b0ec78724687ff475c7b9345d691bffaf 100644 (file)
@@ -133,6 +133,7 @@ struct X509_pubkey_st {
     X509_ALGOR *algor;
     ASN1_BIT_STRING *public_key;
     EVP_PKEY *pkey;
+    CRYPTO_RWLOCK *lock;
 };
 
 typedef struct X509_sig_st {