#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
+#include "asn1_locl.h"
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
{
X509_PUBKEY *pk=NULL;
- const EVP_PKEY_ASN1_METHOD *meth;
if (x == NULL) return(0);
if ((pk=X509_PUBKEY_new()) == NULL) goto error;
- meth = EVP_PKEY_ASN1_find(pkey->type);
-
- if (meth)
+ if (pkey->ameth)
{
- if (meth->pub_encode)
+ if (pkey->ameth->pub_encode)
{
- if (!meth->pub_encode(pk, pkey))
+ if (!pkey->ameth->pub_encode(pk, pkey))
{
X509err(X509_F_X509_PUBKEY_SET,
X509_R_PUBLIC_KEY_ENCODE_ERROR);
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
{
EVP_PKEY *ret=NULL;
- const EVP_PKEY_ASN1_METHOD *meth;
if (key == NULL) goto error;
goto error;
}
- meth = EVP_PKEY_ASN1_find(OBJ_obj2nid(key->algor->algorithm));
+ if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
+ {
+ X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
+ goto error;
+ }
- if (meth)
+ if (ret->ameth->pub_decode)
{
- if (meth->pub_decode)
- {
- if (!meth->pub_decode(ret, key))
- {
- X509err(X509_F_X509_PUBKEY_GET,
- X509_R_PUBLIC_KEY_DECODE_ERROR);
- goto error;
- }
- }
- else
+ if (!ret->ameth->pub_decode(ret, key))
{
X509err(X509_F_X509_PUBKEY_GET,
- X509_R_METHOD_NOT_SUPPORTED);
+ X509_R_PUBLIC_KEY_DECODE_ERROR);
goto error;
}
}
else
{
- X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
+ X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
goto error;
}
- key->pkey = ret;
+ /* Check to see if another thread set key->pkey first */
+ CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+ if (key->pkey)
+ {
+ EVP_PKEY_free(ret);
+ ret = key->pkey;
+ }
+ else
+ key->pkey = ret;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
return ret;