diff options
Diffstat (limited to 'src/crypto/x509/x_pubkey.c')
-rw-r--r-- | src/crypto/x509/x_pubkey.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/crypto/x509/x_pubkey.c b/src/crypto/x509/x_pubkey.c index d6512ae..c2e0863 100644 --- a/src/crypto/x509/x_pubkey.c +++ b/src/crypto/x509/x_pubkey.c @@ -64,6 +64,7 @@ #include <openssl/x509.h> #include "../evp/internal.h" +#include "../internal.h" /* Minor tweak to operation: free up EVP_PKEY */ @@ -126,16 +127,25 @@ error: return 0; } +/* g_pubkey_lock is used to protect the initialisation of the |pkey| member of + * |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t| + * inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is + * not. */ +static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT; + EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) { EVP_PKEY *ret=NULL; if (key == NULL) goto error; + CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock); if (key->pkey != NULL) { + CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock); return EVP_PKEY_up_ref(key->pkey); } + CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock); if (key->public_key == NULL) goto error; @@ -166,17 +176,17 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) } /* Check to see if another thread set key->pkey first */ - CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); + CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock); if (key->pkey) { - CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock); EVP_PKEY_free(ret); ret = key->pkey; } else { key->pkey = ret; - CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock); } return EVP_PKEY_up_ref(ret); |