-/* crypto/asn1/x_pubkey.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
#ifndef OPENSSL_NO_RSA
# include <openssl/rsa.h>
#endif
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;
return 0;
}
-EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
+EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key)
{
EVP_PKEY *ret = NULL;
if (key == NULL)
goto error;
- if (key->pkey != NULL) {
- CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ if (key->pkey != NULL)
return key->pkey;
- }
if (key->public_key == NULL)
goto error;
if ((ret = EVP_PKEY_new()) == NULL) {
- X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
+ X509err(X509_F_X509_PUBKEY_GET0, ERR_R_MALLOC_FAILURE);
goto error;
}
if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) {
- X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM);
+ X509err(X509_F_X509_PUBKEY_GET0, X509_R_UNSUPPORTED_ALGORITHM);
goto error;
}
if (ret->ameth->pub_decode) {
if (!ret->ameth->pub_decode(ret, key)) {
- X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ X509err(X509_F_X509_PUBKEY_GET0, X509_R_PUBLIC_KEY_DECODE_ERROR);
goto error;
}
} else {
- X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
+ X509err(X509_F_X509_PUBKEY_GET0, X509_R_METHOD_NOT_SUPPORTED);
goto error;
}
/* 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);
}
- CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
return ret;
return (NULL);
}
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
+{
+ EVP_PKEY *ret = X509_PUBKEY_get0(key);
+ if (ret != NULL)
+ EVP_PKEY_up_ref(ret);
+ return ret;
+}
+
/*
* Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
* decode as X509_PUBKEY
{
X509_PUBKEY *xpk;
EVP_PKEY *pktmp;
- xpk = d2i_X509_PUBKEY(NULL, pp, length);
+ const unsigned char *q;
+ q = *pp;
+ xpk = d2i_X509_PUBKEY(NULL, &q, length);
if (!xpk)
return NULL;
pktmp = X509_PUBKEY_get(xpk);
X509_PUBKEY_free(xpk);
if (!pktmp)
return NULL;
+ *pp = q;
if (a) {
EVP_PKEY_free(*a);
*a = pktmp;
if (!a)
return 0;
pktmp = EVP_PKEY_new();
- if (!pktmp) {
+ if (pktmp == NULL) {
ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!a)
return 0;
pktmp = EVP_PKEY_new();
- if (!pktmp) {
+ if (pktmp == NULL) {
ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
return 0;
}