Add X509_CHECK_FLAG_NEVER_CHECK_SUBJECT flag
[openssl.git] / crypto / asn1 / x_pubkey.c
index d20afb982eeb1774459a7ce6c3f7c6649afae729..7c88291e8020f9297e3f6f3769e68c777d57b597 100644 (file)
@@ -1,4 +1,3 @@
-/* crypto/asn1/x_pubkey.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -61,6 +60,7 @@
 #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;
@@ -121,52 +128,49 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
     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;
 
@@ -175,6 +179,14 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
     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
@@ -184,13 +196,16 @@ EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
 {
     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;
@@ -243,7 +258,7 @@ int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
     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;
     }
@@ -283,7 +298,7 @@ int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
     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;
     }