Make X509_PUBKEY opaque
[openssl.git] / crypto / x509v3 / v3_purp.c
index ed634cb2f5571a9e1d6f0be8eafeb4cd27d9eba0..ae82fd181cd0245ac7dd2c60b79ef87e6034ab6d 100644 (file)
@@ -1,4 +1,3 @@
-/* v3_purp.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 2001.
  */
 
 #include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
 #include <openssl/x509v3.h>
 #include <openssl/x509_vfy.h>
+#include "internal/x509_int.h"
 
 static void x509v3_cache_extensions(X509 *x);
 
@@ -127,10 +128,11 @@ int X509_check_purpose(X509 *x, int id, int ca)
     int idx;
     const X509_PURPOSE *pt;
     if (!(x->ex_flags & EXFLAG_SET)) {
-        CRYPTO_w_lock(CRYPTO_LOCK_X509);
+        CRYPTO_THREAD_write_lock(x->lock);
         x509v3_cache_extensions(x);
-        CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+        CRYPTO_THREAD_unlock(x->lock);
     }
+    /* Return if side-effect only call */
     if (id == -1)
         return 1;
     idx = X509_PURPOSE_get_by_id(id);
@@ -172,7 +174,7 @@ int X509_PURPOSE_get_by_sname(char *sname)
     X509_PURPOSE *xptmp;
     for (i = 0; i < X509_PURPOSE_get_count(); i++) {
         xptmp = X509_PURPOSE_get0(i);
-        if (!strcmp(xptmp->sname, sname))
+        if (strcmp(xptmp->sname, sname) == 0)
             return i;
     }
     return -1;
@@ -209,7 +211,7 @@ int X509_PURPOSE_add(int id, int trust, int flags,
     idx = X509_PURPOSE_get_by_id(id);
     /* Need a new entry */
     if (idx == -1) {
-        if (!(ptmp = OPENSSL_malloc(sizeof(*ptmp)))) {
+        if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) {
             X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
             return 0;
         }
@@ -223,8 +225,8 @@ int X509_PURPOSE_add(int id, int trust, int flags,
         OPENSSL_free(ptmp->sname);
     }
     /* dup supplied name */
-    ptmp->name = BUF_strdup(name);
-    ptmp->sname = BUF_strdup(sname);
+    ptmp->name = OPENSSL_strdup(name);
+    ptmp->sname = OPENSSL_strdup(sname);
     if (!ptmp->name || !ptmp->sname) {
         X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
         return 0;
@@ -241,7 +243,8 @@ int X509_PURPOSE_add(int id, int trust, int flags,
 
     /* If its a new entry manage the dynamic table */
     if (idx == -1) {
-        if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
+        if (xptable == NULL
+            && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) {
             X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
             return 0;
         }
@@ -320,8 +323,10 @@ int X509_supported_extension(X509_EXTENSION *ex)
         NID_basic_constraints,  /* 87 */
         NID_certificate_policies, /* 89 */
         NID_ext_key_usage,      /* 126 */
+#ifndef OPENSSL_NO_RFC3779
         NID_sbgp_ipAddrBlock,   /* 290 */
         NID_sbgp_autonomousSysNum, /* 291 */
+#endif
         NID_policy_constraints, /* 401 */
         NID_proxyCertInfo,      /* 663 */
         NID_name_constraints,   /* 666 */
@@ -375,6 +380,14 @@ static void setup_crldp(X509 *x)
         setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
 }
 
+#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
+#define ku_reject(x, usage) \
+        (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+#define xku_reject(x, usage) \
+        (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+#define ns_reject(x, usage) \
+        (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
+
 static void x509v3_cache_extensions(X509 *x)
 {
     BASIC_CONSTRAINTS *bs;
@@ -492,7 +505,8 @@ static void x509v3_cache_extensions(X509 *x)
     if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
         x->ex_flags |= EXFLAG_SI;
         /* If SKID matches AKID also indicate self signed */
-        if (X509_check_akid(x, x->akid) == X509_V_OK)
+        if (X509_check_akid(x, x->akid) == X509_V_OK &&
+            !ku_reject(x, KU_KEY_CERT_SIGN))
             x->ex_flags |= EXFLAG_SS;
     }
     x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
@@ -501,9 +515,11 @@ static void x509v3_cache_extensions(X509 *x)
         x->ex_flags |= EXFLAG_INVALID;
     setup_crldp(x);
 
+#ifndef OPENSSL_NO_RFC3779
     x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
     x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
                                        NULL, NULL);
+#endif
     for (i = 0; i < X509_get_ext_count(x); i++) {
         ex = X509_get_ext(x, i);
         if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
@@ -529,14 +545,6 @@ static void x509v3_cache_extensions(X509 *x)
  * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
  */
 
-#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
-#define ku_reject(x, usage) \
-        (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
-#define xku_reject(x, usage) \
-        (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
-#define ns_reject(x, usage) \
-        (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
-
 static int check_ca(const X509 *x)
 {
     /* keyUsage if present should allow cert signing */
@@ -568,9 +576,9 @@ static int check_ca(const X509 *x)
 int X509_check_ca(X509 *x)
 {
     if (!(x->ex_flags & EXFLAG_SET)) {
-        CRYPTO_w_lock(CRYPTO_LOCK_X509);
+        CRYPTO_THREAD_write_lock(x->lock);
         x509v3_cache_extensions(x);
-        CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+        CRYPTO_THREAD_unlock(x->lock);
     }
 
     return check_ca(x);
@@ -840,3 +848,35 @@ int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
     }
     return X509_V_OK;
 }
+
+uint32_t X509_get_extension_flags(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    return x->ex_flags;
+}
+
+uint32_t X509_get_key_usage(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    if (x->ex_flags & EXFLAG_KUSAGE)
+        return x->ex_kusage;
+    return UINT32_MAX;
+}
+
+uint32_t X509_get_extended_key_usage(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    if (x->ex_flags & EXFLAG_XKUSAGE)
+        return x->ex_xkusage;
+    return UINT32_MAX;
+}
+
+const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    return x->skid;
+}