From d2ec189fdd6d734c21d4067340cc96a0c4ce0595 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 23 Mar 2016 21:04:49 +0000 Subject: [PATCH] Remove X509_PUBKEY lock. Cache the decoded public key when an X509_PUBKEY structure is initially parsed so no locking is required. Ignore any decode errors. When an application calls X509_PUBKEY_get0() subsequently it will either get the cached key or the decode operation will be repeated which will return an appropriate error. Reviewed-by: Rich Salz --- crypto/x509/x_pubkey.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index 55d5594b03..b9079b58d1 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -69,23 +69,26 @@ struct X509_pubkey_st { X509_ALGOR *algor; ASN1_BIT_STRING *public_key; EVP_PKEY *pkey; - CRYPTO_RWLOCK *lock; }; /* Minor tweak to operation: free up EVP_PKEY */ 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); + } else if (operation == ASN1_OP_D2I_POST) { + /* Attempt to decode public key and cache in pubkey structure. */ + X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; + EVP_PKEY_free(pubkey->pkey); + /* + * Remove any errors from the queue: subsequent decode attempts will + * return an appropriate error. + */ + ERR_set_mark(); + pubkey->pkey = X509_PUBKEY_get0(pubkey); + ERR_pop_to_mark(); } return 1; } @@ -165,17 +168,6 @@ EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key) goto error; } - /* Check to see if another thread set key->pkey first */ - CRYPTO_THREAD_write_lock(key->lock); - if (key->pkey) { - CRYPTO_THREAD_unlock(key->lock); - EVP_PKEY_free(ret); - ret = key->pkey; - } else { - key->pkey = ret; - CRYPTO_THREAD_unlock(key->lock); - } - return ret; error: -- 2.25.1