Extend X509 cert checks and error reporting in v3_{purp,crld}.c and x509_{set,vfy}.c
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Sat, 27 Jun 2020 14:16:12 +0000 (16:16 +0200)
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>
Fri, 11 Sep 2020 05:42:22 +0000 (07:42 +0200)
add various checks for malformedness to static check_chain_extensions() in x509_vfc.c
improve error reporting of X509v3_cache_extensions() in v3_purp.c
add error reporting to x509_init_sig_info() in x509_set.c
improve static setup_dp() and related functions in v3_purp.c and v3_crld.c
add test case for non-conforming cert from https://tools.ietf.org/html/rfc8410#section-10.2

Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)

16 files changed:
crypto/err/openssl.txt
crypto/x509/v3_crld.c
crypto/x509/v3_purp.c
crypto/x509/v3err.c
crypto/x509/x509_err.c
crypto/x509/x509_set.c
crypto/x509/x509_txt.c
crypto/x509/x509_vfy.c
doc/internal/man3/x509v3_cache_extensions.pod [new file with mode: 0644]
doc/man1/openssl.pod
include/crypto/x509.h
include/openssl/x509_vfy.h
include/openssl/x509err.h
include/openssl/x509v3err.h
test/recipes/25-test_verify.t
test/testx509.pem

index df8a7af26c94a40f0a4ccaa5cec68927ad92c3b6..d0ba9c47be57460366e314cd575662dff78e06cd 100644 (file)
@@ -3487,6 +3487,7 @@ X509V3_R_BN_TO_ASN1_INTEGER_ERROR:101:bn to asn1 integer error
 X509V3_R_DIRNAME_ERROR:149:dirname error
 X509V3_R_DISTPOINT_ALREADY_SET:160:distpoint already set
 X509V3_R_DUPLICATE_ZONE_ID:133:duplicate zone id
+X509V3_R_EMPTY_KEY_USAGE:169:empty key usage
 X509V3_R_ERROR_CONVERTING_ZONE:131:error converting zone
 X509V3_R_ERROR_CREATING_EXTENSION:144:error creating extension
 X509V3_R_ERROR_IN_EXTENSION:128:error in extension
@@ -3501,6 +3502,7 @@ X509V3_R_INCORRECT_POLICY_SYNTAX_TAG:152:incorrect policy syntax tag
 X509V3_R_INVALID_ASNUMBER:162:invalid asnumber
 X509V3_R_INVALID_ASRANGE:163:invalid asrange
 X509V3_R_INVALID_BOOLEAN_STRING:104:invalid boolean string
+X509V3_R_INVALID_CERTIFICATE:158:invalid certificate
 X509V3_R_INVALID_EMPTY_NAME:108:invalid empty name
 X509V3_R_INVALID_EXTENSION_STRING:105:invalid extension string
 X509V3_R_INVALID_INHERITANCE:165:invalid inheritance
@@ -3522,6 +3524,7 @@ X509V3_R_INVALID_SYNTAX:143:invalid syntax
 X509V3_R_ISSUER_DECODE_ERROR:126:issuer decode error
 X509V3_R_MISSING_VALUE:124:missing value
 X509V3_R_NEED_ORGANIZATION_AND_NUMBERS:142:need organization and numbers
+X509V3_R_NEGATIVE_PATHLEN:168:negative pathlen
 X509V3_R_NO_CONFIG_DATABASE:136:no config database
 X509V3_R_NO_ISSUER_CERTIFICATE:121:no issuer certificate
 X509V3_R_NO_ISSUER_DETAILS:127:no issuer details
@@ -3557,9 +3560,12 @@ X509_R_CERTIFICATE_VERIFICATION_FAILED:139:certificate verification failed
 X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table
 X509_R_CRL_ALREADY_DELTA:127:crl already delta
 X509_R_CRL_VERIFY_FAILURE:131:crl verify failure
+X509_R_ERROR_GETTING_MD_BY_NID:141:error getting md by nid
+X509_R_ERROR_USING_SIGINF_SET:142:error using siginf set
 X509_R_IDP_MISMATCH:128:idp mismatch
 X509_R_INVALID_ATTRIBUTES:138:invalid attributes
 X509_R_INVALID_DIRECTORY:113:invalid directory
+X509_R_INVALID_DISTPOINT:143:invalid distpoint
 X509_R_INVALID_FIELD_NAME:119:invalid field name
 X509_R_INVALID_TRUST:123:invalid trust
 X509_R_ISSUER_MISMATCH:129:issuer mismatch
@@ -3583,6 +3589,7 @@ X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY:108:unable to get certs public key
 X509_R_UNKNOWN_KEY_TYPE:117:unknown key type
 X509_R_UNKNOWN_NID:109:unknown nid
 X509_R_UNKNOWN_PURPOSE_ID:121:unknown purpose id
+X509_R_UNKNOWN_SIGID_ALGS:144:unknown sigid algs
 X509_R_UNKNOWN_TRUST_ID:120:unknown trust id
 X509_R_UNSUPPORTED_ALGORITHM:111:unsupported algorithm
 X509_R_WRONG_LOOKUP_TYPE:112:wrong lookup type
index b54346d036393802fd12652aeacb204ccd3f79fe..8b4e100714a2d7887c652672e7a8e16a07c4e77c 100644 (file)
@@ -485,30 +485,31 @@ static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
     return 1;
 }
 
+/* Append any nameRelativeToCRLIssuer in dpn to iname, set in dpn->dpname */
 int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname)
 {
     int i;
     STACK_OF(X509_NAME_ENTRY) *frag;
     X509_NAME_ENTRY *ne;
-    if (!dpn || (dpn->type != 1))
+
+    if (dpn == NULL || dpn->type != 1)
         return 1;
     frag = dpn->name.relativename;
+    X509_NAME_free(dpn->dpname); /* just in case it was already set */
     dpn->dpname = X509_NAME_dup(iname);
-    if (!dpn->dpname)
+    if (dpn->dpname == NULL)
         return 0;
     for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
         ne = sk_X509_NAME_ENTRY_value(frag, i);
-        if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
-            X509_NAME_free(dpn->dpname);
-            dpn->dpname = NULL;
-            return 0;
-        }
+        if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
+            goto err;
     }
     /* generate cached encoding of name */
-    if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
-        X509_NAME_free(dpn->dpname);
-        dpn->dpname = NULL;
-        return 0;
-    }
-    return 1;
+    if (i2d_X509_NAME(dpn->dpname, NULL) >= 0)
+        return 1;
+
+ err:
+    X509_NAME_free(dpn->dpname);
+    dpn->dpname = NULL;
+    return 0;
 }
index d7d0aae3b34714396ee606b0ad0ee9bf826baf38..4bde90f277db440002dca72a66e7bdc6d2ccdcc7 100644 (file)
@@ -305,34 +305,49 @@ int X509_supported_extension(X509_EXTENSION *ex)
     return 0;
 }
 
-static int setup_dp(X509 *x, DIST_POINT *dp)
+/* return 1 on success, 0 if x is invalid, -1 on (internal) error */
+static int setup_dp(const X509 *x, DIST_POINT *dp)
 {
     const X509_NAME *iname = NULL;
     int i;
 
-    if (dp->reasons) {
+    if (dp->distpoint == NULL && sk_GENERAL_NAME_num(dp->CRLissuer) <= 0) {
+        X509err(0, X509_R_INVALID_DISTPOINT);
+        return 0;
+    }
+    if (dp->reasons != NULL) {
         if (dp->reasons->length > 0)
             dp->dp_reasons = dp->reasons->data[0];
         if (dp->reasons->length > 1)
             dp->dp_reasons |= (dp->reasons->data[1] << 8);
         dp->dp_reasons &= CRLDP_ALL_REASONS;
-    } else
+    } else {
         dp->dp_reasons = CRLDP_ALL_REASONS;
-    if (!dp->distpoint || (dp->distpoint->type != 1))
+    }
+    if (dp->distpoint == NULL || dp->distpoint->type != 1)
         return 1;
+
+    /* handle name fragment given by nameRelativeToCRLIssuer */
+    /*
+     * Note that the below way of determining iname is not really compliant
+     * with https://tools.ietf.org/html/rfc5280#section-4.2.1.13
+     * According to it, sk_GENERAL_NAME_num(dp->CRLissuer) MUST be <= 1
+     * and any CRLissuer could be of type different to GEN_DIRNAME.
+     */
     for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
         GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+
         if (gen->type == GEN_DIRNAME) {
             iname = gen->d.directoryName;
             break;
         }
     }
-    if (!iname)
+    if (iname == NULL)
         iname = X509_get_issuer_name(x);
-
-    return DIST_POINT_set_dpname(dp->distpoint, iname);
+    return DIST_POINT_set_dpname(dp->distpoint, iname) ? 1 : -1;
 }
 
+/* return 1 on success, 0 if x is invalid, -1 on (internal) error */
 static int setup_crldp(X509 *x)
 {
     int i;
@@ -340,9 +355,12 @@ static int setup_crldp(X509 *x)
     x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL);
     if (x->crldp == NULL && i != -1)
         return 0;
+
     for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
-        if (!setup_dp(x, sk_DIST_POINT_value(x->crldp, i)))
-            return 0;
+        int res = setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
+
+        if (res < 1)
+            return res;
     }
     return 1;
 }
@@ -373,6 +391,7 @@ static int check_sig_alg_match(const EVP_PKEY *pkey, const X509 *subject)
 /*
  * Cache info on various X.509v3 extensions and further derived information,
  * e.g., if cert 'x' is self-issued, in x->ex_flags and other internal fields.
+ * X509_SIG_INFO_VALID is set in x->flags if x->siginf was filled successfully.
  * Set EXFLAG_INVALID and return 0 in case the certificate is invalid.
  */
 int x509v3_cache_extensions(X509 *x)
@@ -384,6 +403,7 @@ int x509v3_cache_extensions(X509 *x)
     EXTENDED_KEY_USAGE *extusage;
     X509_EXTENSION *ex;
     int i;
+    int res;
 
 #ifdef tsan_ld_acq
     /* fast lock-free check, see end of the function for details. */
@@ -398,30 +418,34 @@ int x509v3_cache_extensions(X509 *x)
     }
     ERR_set_mark();
 
+    /* Cache the SHA1 digest of the cert */
     if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL))
-            x->ex_flags |= EXFLAG_INVALID;
+        /*
+         * Note that the cert is marked invalid also on internal malloc failure
+         * or on failure of EVP_MD_fetch(), potentially called by X509_digest().
+         */
+        x->ex_flags |= EXFLAG_INVALID;
 
     /* V1 should mean no extensions ... */
     if (X509_get_version(x) == 0)
         x->ex_flags |= EXFLAG_V1;
 
     /* Handle basic constraints */
+    x->ex_pathlen = -1;
     if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL)) != NULL) {
         if (bs->ca)
             x->ex_flags |= EXFLAG_CA;
         if (bs->pathlen != NULL) {
+            /*
+             * the error case !bs->ca is checked by check_chain_extensions()
+             * in case ctx->param->flags & X509_V_FLAG_X509_STRICT
+             */
             if (bs->pathlen->type == V_ASN1_NEG_INTEGER) {
+                X509err(0, X509V3_R_NEGATIVE_PATHLEN);
                 x->ex_flags |= EXFLAG_INVALID;
-                x->ex_pathlen = 0;
             } else {
                 x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
-                if (!bs->ca && x->ex_pathlen != 0) {
-                    x->ex_flags |= EXFLAG_INVALID;
-                    x->ex_pathlen = 0;
-                }
             }
-        } else {
-            x->ex_pathlen = -1;
         }
         BASIC_CONSTRAINTS_free(bs);
         x->ex_flags |= EXFLAG_BCONS;
@@ -436,9 +460,9 @@ int x509v3_cache_extensions(X509 *x)
             || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
             x->ex_flags |= EXFLAG_INVALID;
         }
-        if (pci->pcPathLengthConstraint) {
+        if (pci->pcPathLengthConstraint != NULL)
             x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
-        else
+        else
             x->ex_pcpathlen = -1;
         PROXY_CERT_INFO_EXTENSION_free(pci);
         x->ex_flags |= EXFLAG_PROXY;
@@ -446,7 +470,7 @@ int x509v3_cache_extensions(X509 *x)
         x->ex_flags |= EXFLAG_INVALID;
     }
 
-    /* Handle (basic and extended) key usage */
+    /* Handle basic key usage */
     if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL)) != NULL) {
         x->ex_kusage = 0;
         if (usage->length > 0) {
@@ -456,9 +480,16 @@ int x509v3_cache_extensions(X509 *x)
         }
         x->ex_flags |= EXFLAG_KUSAGE;
         ASN1_BIT_STRING_free(usage);
+        /* Check for empty key usage according to RFC 5280 section 4.2.1.3 */
+        if (x->ex_kusage == 0) {
+            X509err(0, X509V3_R_EMPTY_KEY_USAGE);
+            x->ex_flags |= EXFLAG_INVALID;
+        }
     } else if (i != -1) {
         x->ex_flags |= EXFLAG_INVALID;
     }
+
+    /* Handle extended key usage */
     x->ex_xkusage = 0;
     if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL)) != NULL) {
         x->ex_flags |= EXFLAG_XKUSAGE;
@@ -493,6 +524,7 @@ int x509v3_cache_extensions(X509 *x)
                 x->ex_xkusage |= XKU_ANYEKU;
                 break;
             default:
+                /* ignore unknown extended key usage */
                 break;
             }
         }
@@ -517,6 +549,7 @@ int x509v3_cache_extensions(X509 *x)
     x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &i, NULL);
     if (x->skid == NULL && i != -1)
         x->ex_flags |= EXFLAG_INVALID;
+
     x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &i, NULL);
     if (x->akid == NULL && i != -1)
         x->ex_flags |= EXFLAG_INVALID;
@@ -538,8 +571,13 @@ int x509v3_cache_extensions(X509 *x)
     x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
     if (x->nc == NULL && i != -1)
         x->ex_flags |= EXFLAG_INVALID;
-    if (!setup_crldp(x))
+
+    /* Handle CRL distribution point entries */
+    res = setup_crldp(x);
+    if (res == 0)
         x->ex_flags |= EXFLAG_INVALID;
+    else if (res < 0)
+        goto err;
 
 #ifndef OPENSSL_NO_RFC3779
     x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL);
@@ -551,8 +589,7 @@ int x509v3_cache_extensions(X509 *x)
 #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))
-            == NID_freshest_crl)
+        if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_freshest_crl)
             x->ex_flags |= EXFLAG_FRESHEST;
         if (!X509_EXTENSION_get_critical(ex))
             continue;
@@ -562,7 +599,8 @@ int x509v3_cache_extensions(X509 *x)
         }
     }
 
-    x509_init_sig_info(x);
+    /* Set x->siginf, ignoring errors due to unsupported algos */
+    (void)x509_init_sig_info(x);
 
     x->ex_flags |= EXFLAG_SET; /* indicate that cert has been processed */
 #ifdef tsan_st_rel
@@ -574,9 +612,16 @@ int x509v3_cache_extensions(X509 *x)
      */
 #endif
     ERR_pop_to_mark();
-    CRYPTO_THREAD_unlock(x->lock);
+    if ((x->ex_flags & EXFLAG_INVALID) == 0) {
+        CRYPTO_THREAD_unlock(x->lock);
+        return 1;
+    }
+    X509err(0, X509V3_R_INVALID_CERTIFICATE);
 
-    return (x->ex_flags & EXFLAG_INVALID) == 0;
+ err:
+    x->ex_flags |= EXFLAG_SET; /* indicate that cert has been processed */
+    CRYPTO_THREAD_unlock(x->lock);
+    return 0;
 }
 
 /*-
index 4c62e59db996305214c2ea5cdfff041d3530b115..512490808950a7dc0c1630f1cb391b6fdafac8d5 100644 (file)
@@ -24,6 +24,7 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = {
     "distpoint already set"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_DUPLICATE_ZONE_ID),
     "duplicate zone id"},
+    {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EMPTY_KEY_USAGE), "empty key usage"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CONVERTING_ZONE),
     "error converting zone"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CREATING_EXTENSION),
@@ -51,6 +52,8 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = {
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_ASRANGE), "invalid asrange"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_BOOLEAN_STRING),
     "invalid boolean string"},
+    {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_CERTIFICATE),
+    "invalid certificate"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_EXTENSION_STRING),
     "invalid extension string"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_INHERITANCE),
@@ -84,6 +87,8 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = {
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_MISSING_VALUE), "missing value"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS),
     "need organization and numbers"},
+    {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEGATIVE_PATHLEN),
+    "negative pathlen"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_CONFIG_DATABASE),
     "no config database"},
     {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_ISSUER_CERTIFICATE),
index 450f2a79309a1c5df3ecbffac9bf2007bc94fd96..330fed34064398951be7eac0321e7ccfe868811d 100644 (file)
@@ -27,10 +27,15 @@ static const ERR_STRING_DATA X509_str_reasons[] = {
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE),
     "crl verify failure"},
+    {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_GETTING_MD_BY_NID),
+    "error getting md by nid"},
+    {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_USING_SIGINF_SET),
+    "error using siginf set"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_IDP_MISMATCH), "idp mismatch"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_ATTRIBUTES),
     "invalid attributes"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DIRECTORY), "invalid directory"},
+    {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DISTPOINT), "invalid distpoint"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_FIELD_NAME),
     "invalid field name"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_TRUST), "invalid trust"},
@@ -66,6 +71,8 @@ static const ERR_STRING_DATA X509_str_reasons[] = {
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_NID), "unknown nid"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_PURPOSE_ID),
     "unknown purpose id"},
+    {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_SIGID_ALGS),
+    "unknown sigid algs"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_TRUST_ID), "unknown trust id"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNSUPPORTED_ALGORITHM),
     "unsupported algorithm"},
index 46cabc4b42516276005af58a2b85acca61fb9d0b..79e4c03ca399b53a1b87396833b484c8760da3ed 100644 (file)
@@ -192,60 +192,85 @@ int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
     return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags);
 }
 
-static void x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
-                               const ASN1_STRING *sig)
+/* Modify *siginf according to alg and sig. Return 1 on success, else 0. */
+static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
+                              const ASN1_STRING *sig)
 {
     int pknid, mdnid;
     const EVP_MD *md;
+    const EVP_PKEY_ASN1_METHOD *ameth;
 
     siginf->mdnid = NID_undef;
     siginf->pknid = NID_undef;
     siginf->secbits = -1;
     siginf->flags = 0;
     if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)
-            || pknid == NID_undef)
-        return;
+            || pknid == NID_undef) {
+        X509err(0, X509_R_UNKNOWN_SIGID_ALGS);
+        return 0;
+    }
+    siginf->mdnid = mdnid;
     siginf->pknid = pknid;
-    if (mdnid == NID_undef) {
+
+    switch (mdnid) {
+    case NID_undef:
         /* If we have one, use a custom handler for this algorithm */
-        const EVP_PKEY_ASN1_METHOD *ameth = EVP_PKEY_asn1_find(NULL, pknid);
+        ameth = EVP_PKEY_asn1_find(NULL, pknid);
         if (ameth == NULL || ameth->siginf_set == NULL
-                || ameth->siginf_set(siginf, alg, sig) == 0)
-            return;
-        siginf->flags |= X509_SIG_INFO_VALID;
-        return;
-    }
-    siginf->flags |= X509_SIG_INFO_VALID;
-    siginf->mdnid = mdnid;
-    md = EVP_get_digestbynid(mdnid);
-    if (md == NULL)
-        return;
-    /* Security bits: half number of bits in digest */
-    siginf->secbits = EVP_MD_size(md) * 4;
-    /*
-     * SHA1 and MD5 are known to be broken. Reduce security bits so that
-     * they're no longer accepted at security level 1. The real values don't
-     * really matter as long as they're lower than 80, which is our security
-     * level 1.
-     * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for SHA1 at
-     * 2^63.4
-     * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf
-     * puts a chosen-prefix attack for MD5 at 2^39.
-     */
-    if (mdnid == NID_sha1)
+                || !ameth->siginf_set(siginf, alg, sig)) {
+            X509err(0, X509_R_ERROR_USING_SIGINF_SET);
+            return 0;
+        }
+        break;
+        /*
+         * SHA1 and MD5 are known to be broken. Reduce security bits so that
+         * they're no longer accepted at security level 1.
+         * The real values don't really matter as long as they're lower than 80,
+         * which is our security level 1.
+         */
+    case NID_sha1:
+        /*
+         * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack
+         * for SHA1 at2^63.4
+         */
         siginf->secbits = 63;
-    else if (mdnid == NID_md5)
+        break;
+    case NID_md5:
+        /*
+         * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf
+         * puts a chosen-prefix attack for MD5 at 2^39.
+         */
         siginf->secbits = 39;
+        break;
+    case NID_id_GostR3411_94:
+        /*
+         * There is a collision attack on GOST R 34.11-94 at 2^105, see
+         * https://link.springer.com/chapter/10.1007%2F978-3-540-85174-5_10
+         */
+        siginf->secbits = 105;
+        break;
+    default:
+        /* Security bits: half number of bits in digest */
+        if ((md = EVP_get_digestbynid(mdnid)) == NULL) {
+            X509err(0, X509_R_ERROR_GETTING_MD_BY_NID);
+            return 0;
+        }
+        siginf->secbits = EVP_MD_size(md) * 4;
+        break;
+    }
     switch (mdnid) {
-        case NID_sha1:
-        case NID_sha256:
-        case NID_sha384:
-        case NID_sha512:
+    case NID_sha1:
+    case NID_sha256:
+    case NID_sha384:
+    case NID_sha512:
         siginf->flags |= X509_SIG_INFO_TLS;
     }
+    siginf->flags |= X509_SIG_INFO_VALID;
+    return 1;
 }
 
-void x509_init_sig_info(X509 *x)
+/* Returns 1 on success, 0 on failure */
+int x509_init_sig_info(X509 *x)
 {
-    x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
+    return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
 }
index 63d8d95f3f554340356a96c658a9678dd0f4eac3..4bb16545ef9a12d9656055bb83ab42a454536b88 100644 (file)
@@ -69,8 +69,8 @@ const char *X509_verify_cert_error_string(long n)
         return "certificate chain too long";
     case X509_V_ERR_CERT_REVOKED:
         return "certificate revoked";
-    case X509_V_ERR_INVALID_CA:
-        return "invalid CA certificate";
+    case X509_V_ERR_NO_ISSUER_PUBLIC_KEY:
+        return "issuer certificate doesn't have a public key";
     case X509_V_ERR_PATH_LENGTH_EXCEEDED:
         return "path length constraint exceeded";
     case X509_V_ERR_INVALID_PURPOSE:
@@ -174,12 +174,30 @@ const char *X509_verify_cert_error_string(long n)
         return "OCSP verification failed";
     case X509_V_ERR_OCSP_CERT_UNKNOWN:
         return "OCSP unknown cert";
-    case X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH:
-        return "subject signature algorithm and issuer public key algorithm mismatch";
-    case X509_V_ERR_NO_ISSUER_PUBLIC_KEY:
-        return "issuer certificate doesn't have a public key";
     case X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM:
         return "Cannot find certificate signature algorithm";
+    case X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH:
+        return "subject signature algorithm and issuer public key algorithm mismatch";
+    case X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY:
+        return "cert info siganature and signature algorithm mismatch";
+    case X509_V_ERR_INVALID_CA:
+        return "invalid CA certificate";
+    case X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA:
+        return "Path length invalid for non-CA cert";
+    case X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN:
+        return "Path length given without key usage keyCertSign";
+    case X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA:
+        return "Key usage keyCertSign invalid for non-CA cert";
+    case X509_V_ERR_ISSUER_NAME_EMPTY:
+        return "Issuer name empty";
+    case X509_V_ERR_SUBJECT_NAME_EMPTY:
+        return "Subject name empty";
+    case X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER:
+        return "Missing Authority Key Identifier";
+    case X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER:
+        return "Missing Subject Key Identifier";
+    case X509_V_ERR_EMPTY_SUBJECT_ALT_NAME:
+        return "Empty Subject Alternative Name extension";
 
     default:
         /* Printing an error number into a static buffer is not thread-safe */
index 843b65f022fbb86dcfcbca47f43ad1881fc965ae..c6717c53c84bf8a4b50d814908d579889eb1106f 100644 (file)
@@ -479,6 +479,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
 
     for (i = 0; i < num; i++) {
         int ret;
+
         x = sk_X509_value(ctx->chain, i);
         if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
             && (x->ex_flags & EXFLAG_CRITICAL)) {
@@ -519,12 +520,58 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                 ret = 1;
             break;
         }
-        if ((x->ex_flags & EXFLAG_CA) == 0
-            && x->ex_pathlen != -1
-            && (ctx->param->flags & X509_V_FLAG_X509_STRICT)) {
-            ctx->error = X509_V_ERR_INVALID_EXTENSION;
-            ret = 0;
+        if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) != 0) {
+            /* Check Basic Constraints according to RFC 5280 section 4.2.1.9 */
+            if (x->ex_pathlen != -1) {
+                if ((x->ex_flags & EXFLAG_CA) == 0)
+                    ctx->error = X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA;
+                if ((x->ex_kusage & KU_KEY_CERT_SIGN) == 0)
+                    ctx->error = X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN;
+            }
+            /* TODO check basic constrains of CA cert are marked critical */
+            /* Check keyCertSign according to RFC 5280 section 4.2.1.3 */
+            if ((x->ex_flags & EXFLAG_CA) == 0
+                    && (x->ex_kusage & KU_KEY_CERT_SIGN) != 0)
+                ctx->error = X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA;
+            /* Check issuer is non-empty acc. to RFC 5280 section 4.1.2.4 */
+            if (X509_NAME_entry_count(X509_get_issuer_name(x)) == 0)
+                ctx->error = X509_V_ERR_ISSUER_NAME_EMPTY;
+            /* Check subject is non-empty acc. to RFC 5280 section 4.1.2.6 */
+            if (((x->ex_flags & EXFLAG_CA) != 0
+                 || (x->ex_kusage & KU_CRL_SIGN) != 0
+                 || x->altname == NULL
+                 ) && X509_NAME_entry_count(X509_get_subject_name(x)) == 0)
+                ctx->error = X509_V_ERR_SUBJECT_NAME_EMPTY;
+                /*
+                 * TODO check: If subject naming information is present only in
+                 * the subjectAltName extension,
+                 * then the subject name MUST be an empty sequence
+                 * and the subjectAltName extension MUST be critical.
+                 */
+            /* Check SAN is non-empty according to RFC 5280 section 4.2.1.6 */
+            if (x->altname != NULL && sk_GENERAL_NAME_num(x->altname) <= 0)
+                ctx->error = X509_V_ERR_EMPTY_SUBJECT_ALT_NAME;
+            /* TODO add more checks on SAN entries */
+            /* Check sig alg consistency acc. to RFC 5280 section 4.1.1.2 */
+            if (X509_ALGOR_cmp(&x->sig_alg, &x->cert_info.signature) != 0)
+                ctx->error = X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY;
+            if (X509_get_version(x) >= 2) { /* at least X.509v3 */
+                /* Check AKID presence acc. to RFC 5280 section 4.2.1.1 */
+                if (i + 1 < num /*
+                                 * this means not last cert in chain,
+                                 * taken as "generated by conforming CAs"
+                                 */
+                        && (x->akid == NULL || x->akid->keyid == NULL))
+                    ctx->error = X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER;
+                /* TODO check that AKID extension is not critical */
+                /* Check SKID presence acc. to RFC 5280 section 4.2.1.2 */
+                if ((x->ex_flags & EXFLAG_CA) != 0 && x->skid == NULL)
+                    ctx->error = X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER;
+                /* TODO check that SKID extension is not be critical */
+            }
         }
+        if (ctx->error != X509_V_OK)
+            ret = 0;
         if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK))
             return 0;
         /* check_purpose() makes the callback as needed */
diff --git a/doc/internal/man3/x509v3_cache_extensions.pod b/doc/internal/man3/x509v3_cache_extensions.pod
new file mode 100644 (file)
index 0000000..3fb7609
--- /dev/null
@@ -0,0 +1,40 @@
+=pod
+
+=head1 NAME
+
+x509v3_cache_extensions
+- cache info on various X.509v3 extensions and further derived certificate data
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509v3.h>
+
+ int x509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq);
+
+=head1 DESCRIPTION
+
+This function processes any X509v3 extensions present in an X509 object I<x>
+and caches the result of that processing as well as further derived info,
+for instance whether the certificate is self-issued or has version X.509v1.
+It computes the SHA1 digest of the certificate using the default library context
+and property query string and stores the result in x->sha1_hash.
+It sets B<X509_SIG_INFO_VALID> in x->flags if x->siginf was filled successfully,
+which may not be possible if a referenced algorithm is unknown or not available.
+Many OpenSSL functions that use an X509 object call this function implicitly.
+
+=head1 RETURN VALUES
+
+This function returns 0 if the extensions or other portions of the certificate
+are invalid or an error occurred.
+Otherwise it returns 1.
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index 1f344217a2fa879e0efb234061655dd490e47d5f..3ae273b5bf7ae453c293d27f2c84abb0362f298b 100644 (file)
@@ -906,6 +906,7 @@ a verification time, the check is not suppressed.
 =item B<-x509_strict>
 
 This disables non-compliant workarounds for broken certificates.
+Thus errors are thrown on certificates not compliant with RFC 5280.
 
 =item B<-ignore_critical>
 
index bd8f9ba52d17c862f1e421e180db487e8dfe18b4..8c9a288cbc12244968cf5abeb3e0cdff72e4d2ef 100644 (file)
@@ -304,9 +304,13 @@ int a2i_ipadd(unsigned char *ipout, const char *ipasc);
 int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm);
 int x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags);
 int x509v3_cache_extensions(X509 *x);
+int x509_init_sig_info(X509 *x);
+int x509_check_issued_int(X509 *issuer, X509 *subject, OPENSSL_CTX *libctx,
+                          const char *propq);
+
 int x509_set0_libctx(X509 *x, OPENSSL_CTX *libctx, const char *propq);
 int x509_crl_set0_libctx(X509_CRL *x, OPENSSL_CTX *libctx, const char *propq);
-void x509_init_sig_info(X509 *x);
+int x509_init_sig_info(X509 *x);
 int asn1_item_digest_with_libctx(const ASN1_ITEM *it, const EVP_MD *type,
                                  void *data, unsigned char *md,
                                  unsigned int *len, OPENSSL_CTX *libctx,
index 2d3bd70ae27d6fa996d6672d9ec5a3d0a2cc7ca6..ec2021357b39d5e970e948b5b8988aaa623a6485 100644 (file)
@@ -124,100 +124,110 @@ X509_LOOKUP_ctrl_with_libctx((x), X509_L_LOAD_STORE, (name), 0, NULL,          \
 X509_LOOKUP_ctrl_with_libctx((x), X509_L_ADD_STORE, (name), 0, NULL,           \
                              (libctx), (propq))
 
+# define X509_V_OK                                       0
+# define X509_V_ERR_UNSPECIFIED                          1
+# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2
+# define X509_V_ERR_UNABLE_TO_GET_CRL                    3
+# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4
+# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5
+# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
+# define X509_V_ERR_CERT_SIGNATURE_FAILURE               7
+# define X509_V_ERR_CRL_SIGNATURE_FAILURE                8
+# define X509_V_ERR_CERT_NOT_YET_VALID                   9
+# define X509_V_ERR_CERT_HAS_EXPIRED                     10
+# define X509_V_ERR_CRL_NOT_YET_VALID                    11
+# define X509_V_ERR_CRL_HAS_EXPIRED                      12
+# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13
+# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14
+# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15
+# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16
+# define X509_V_ERR_OUT_OF_MEM                           17
+# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18
+# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19
+# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20
+# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21
+# define X509_V_ERR_CERT_CHAIN_TOO_LONG                  22
+# define X509_V_ERR_CERT_REVOKED                         23
+# define X509_V_ERR_NO_ISSUER_PUBLIC_KEY                 24
+# define X509_V_ERR_PATH_LENGTH_EXCEEDED                 25
+# define X509_V_ERR_INVALID_PURPOSE                      26
+# define X509_V_ERR_CERT_UNTRUSTED                       27
+# define X509_V_ERR_CERT_REJECTED                        28
 
-# define         X509_V_OK                                       0
-# define         X509_V_ERR_UNSPECIFIED                          1
-# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2
-# define         X509_V_ERR_UNABLE_TO_GET_CRL                    3
-# define         X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4
-# define         X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5
-# define         X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
-# define         X509_V_ERR_CERT_SIGNATURE_FAILURE               7
-# define         X509_V_ERR_CRL_SIGNATURE_FAILURE                8
-# define         X509_V_ERR_CERT_NOT_YET_VALID                   9
-# define         X509_V_ERR_CERT_HAS_EXPIRED                     10
-# define         X509_V_ERR_CRL_NOT_YET_VALID                    11
-# define         X509_V_ERR_CRL_HAS_EXPIRED                      12
-# define         X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13
-# define         X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14
-# define         X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15
-# define         X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16
-# define         X509_V_ERR_OUT_OF_MEM                           17
-# define         X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18
-# define         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19
-# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20
-# define         X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21
-# define         X509_V_ERR_CERT_CHAIN_TOO_LONG                  22
-# define         X509_V_ERR_CERT_REVOKED                         23
-# define         X509_V_ERR_INVALID_CA                           24
-# define         X509_V_ERR_PATH_LENGTH_EXCEEDED                 25
-# define         X509_V_ERR_INVALID_PURPOSE                      26
-# define         X509_V_ERR_CERT_UNTRUSTED                       27
-# define         X509_V_ERR_CERT_REJECTED                        28
 /* These are 'informational' when looking for issuer cert */
-# define         X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29
-# define         X509_V_ERR_AKID_SKID_MISMATCH                   30
-# define         X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31
-# define         X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32
-# define         X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33
-# define         X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34
-# define         X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
-# define         X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
-# define         X509_V_ERR_INVALID_NON_CA                       37
-# define         X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
-# define         X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
-# define         X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40
-# define         X509_V_ERR_INVALID_EXTENSION                    41
-# define         X509_V_ERR_INVALID_POLICY_EXTENSION             42
-# define         X509_V_ERR_NO_EXPLICIT_POLICY                   43
-# define         X509_V_ERR_DIFFERENT_CRL_SCOPE                  44
-# define         X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45
-# define         X509_V_ERR_UNNESTED_RESOURCE                    46
-# define         X509_V_ERR_PERMITTED_VIOLATION                  47
-# define         X509_V_ERR_EXCLUDED_VIOLATION                   48
-# define         X509_V_ERR_SUBTREE_MINMAX                       49
+# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29
+# define X509_V_ERR_AKID_SKID_MISMATCH                   30
+# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31
+# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32
+# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33
+# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34
+# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
+# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
+# define X509_V_ERR_INVALID_NON_CA                       37
+# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
+# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
+# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40
+# define X509_V_ERR_INVALID_EXTENSION                    41
+# define X509_V_ERR_INVALID_POLICY_EXTENSION             42
+# define X509_V_ERR_NO_EXPLICIT_POLICY                   43
+# define X509_V_ERR_DIFFERENT_CRL_SCOPE                  44
+# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45
+# define X509_V_ERR_UNNESTED_RESOURCE                    46
+# define X509_V_ERR_PERMITTED_VIOLATION                  47
+# define X509_V_ERR_EXCLUDED_VIOLATION                   48
+# define X509_V_ERR_SUBTREE_MINMAX                       49
 /* The application is not happy */
-# define         X509_V_ERR_APPLICATION_VERIFICATION             50
-# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51
-# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52
-# define         X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53
-# define         X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54
+# define X509_V_ERR_APPLICATION_VERIFICATION             50
+# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51
+# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52
+# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53
+# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54
 /* Another issuer check debug option */
-# define         X509_V_ERR_PATH_LOOP                            55
+# define X509_V_ERR_PATH_LOOP                            55
 /* Suite B mode algorithm violation */
-# define         X509_V_ERR_SUITE_B_INVALID_VERSION              56
-# define         X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57
-# define         X509_V_ERR_SUITE_B_INVALID_CURVE                58
-# define         X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59
-# define         X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60
-# define         X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+# define X509_V_ERR_SUITE_B_INVALID_VERSION              56
+# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57
+# define X509_V_ERR_SUITE_B_INVALID_CURVE                58
+# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59
+# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60
+# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
 /* Host, email and IP check errors */
-# define         X509_V_ERR_HOSTNAME_MISMATCH                    62
-# define         X509_V_ERR_EMAIL_MISMATCH                       63
-# define         X509_V_ERR_IP_ADDRESS_MISMATCH                  64
+# define X509_V_ERR_HOSTNAME_MISMATCH                    62
+# define X509_V_ERR_EMAIL_MISMATCH                       63
+# define X509_V_ERR_IP_ADDRESS_MISMATCH                  64
 /* DANE TLSA errors */
-# define         X509_V_ERR_DANE_NO_MATCH                        65
+# define X509_V_ERR_DANE_NO_MATCH                        65
 /* security level errors */
-# define         X509_V_ERR_EE_KEY_TOO_SMALL                     66
-# define         X509_V_ERR_CA_KEY_TOO_SMALL                     67
-# define         X509_V_ERR_CA_MD_TOO_WEAK                       68
+# define X509_V_ERR_EE_KEY_TOO_SMALL                     66
+# define X509_V_ERR_CA_KEY_TOO_SMALL                     67
+# define X509_V_ERR_CA_MD_TOO_WEAK                       68
 /* Caller error */
-# define         X509_V_ERR_INVALID_CALL                         69
+# define X509_V_ERR_INVALID_CALL                         69
 /* Issuer lookup error */
-# define         X509_V_ERR_STORE_LOOKUP                         70
+# define X509_V_ERR_STORE_LOOKUP                         70
 /* Certificate transparency */
-# define         X509_V_ERR_NO_VALID_SCTS                        71
+# define X509_V_ERR_NO_VALID_SCTS                        71
 
-# define         X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION         72
+# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION         72
 /* OCSP status errors */
-# define         X509_V_ERR_OCSP_VERIFY_NEEDED                   73  /* Need OCSP verification */
-# define         X509_V_ERR_OCSP_VERIFY_FAILED                   74  /* Couldn't verify cert through OCSP */
-# define         X509_V_ERR_OCSP_CERT_UNKNOWN                    75  /* Certificate wasn't recognized by the OCSP responder */
-
-# define         X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH         76
-# define         X509_V_ERR_NO_ISSUER_PUBLIC_KEY                 77
-# define         X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM      78
-
+# define X509_V_ERR_OCSP_VERIFY_NEEDED                   73  /* Need OCSP verification */
+# define X509_V_ERR_OCSP_VERIFY_FAILED                   74  /* Couldn't verify cert through OCSP */
+# define X509_V_ERR_OCSP_CERT_UNKNOWN                    75  /* Certificate wasn't recognized by the OCSP responder */
+
+# define X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM      76
+# define X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH         77
+
+/* Errors in case a check in X509_V_FLAG_X509_STRICT mode fails */
+# define X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY    78
+# define X509_V_ERR_INVALID_CA                           79
+# define X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA           80
+# define X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN     81
+# define X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA  82
+# define X509_V_ERR_ISSUER_NAME_EMPTY                    83
+# define X509_V_ERR_SUBJECT_NAME_EMPTY                   84
+# define X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER     85
+# define X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER       86
+# define X509_V_ERR_EMPTY_SUBJECT_ALT_NAME               87
 
 /* Certificate verify flags */
 
index 19743b5987c464d9ab5002e4282774b1a0abb03b..94c5c5b75e3d78eefeda244e48f75e35dadaf051 100644 (file)
@@ -107,9 +107,12 @@ int ERR_load_X509_strings(void);
 # define X509_R_CERT_ALREADY_IN_HASH_TABLE                101
 # define X509_R_CRL_ALREADY_DELTA                         127
 # define X509_R_CRL_VERIFY_FAILURE                        131
+# define X509_R_ERROR_GETTING_MD_BY_NID                   141
+# define X509_R_ERROR_USING_SIGINF_SET                    142
 # define X509_R_IDP_MISMATCH                              128
 # define X509_R_INVALID_ATTRIBUTES                        138
 # define X509_R_INVALID_DIRECTORY                         113
+# define X509_R_INVALID_DISTPOINT                         143
 # define X509_R_INVALID_FIELD_NAME                        119
 # define X509_R_INVALID_TRUST                             123
 # define X509_R_ISSUER_MISMATCH                           129
@@ -133,6 +136,7 @@ int ERR_load_X509_strings(void);
 # define X509_R_UNKNOWN_KEY_TYPE                          117
 # define X509_R_UNKNOWN_NID                               109
 # define X509_R_UNKNOWN_PURPOSE_ID                        121
+# define X509_R_UNKNOWN_SIGID_ALGS                        144
 # define X509_R_UNKNOWN_TRUST_ID                          120
 # define X509_R_UNSUPPORTED_ALGORITHM                     111
 # define X509_R_WRONG_LOOKUP_TYPE                         112
index d7aa5da6acd02e5a2a9fc487345552bc3f8b3fbc..b245a639023f49d95e8ce90faa1e707092b72c0b 100644 (file)
@@ -107,6 +107,7 @@ int ERR_load_X509V3_strings(void);
 # define X509V3_R_DIRNAME_ERROR                           149
 # define X509V3_R_DISTPOINT_ALREADY_SET                   160
 # define X509V3_R_DUPLICATE_ZONE_ID                       133
+# define X509V3_R_EMPTY_KEY_USAGE                         169
 # define X509V3_R_ERROR_CONVERTING_ZONE                   131
 # define X509V3_R_ERROR_CREATING_EXTENSION                144
 # define X509V3_R_ERROR_IN_EXTENSION                      128
@@ -121,6 +122,7 @@ int ERR_load_X509V3_strings(void);
 # define X509V3_R_INVALID_ASNUMBER                        162
 # define X509V3_R_INVALID_ASRANGE                         163
 # define X509V3_R_INVALID_BOOLEAN_STRING                  104
+# define X509V3_R_INVALID_CERTIFICATE                     158
 # define X509V3_R_INVALID_EXTENSION_STRING                105
 # define X509V3_R_INVALID_INHERITANCE                     165
 # define X509V3_R_INVALID_IPADDRESS                       166
@@ -142,6 +144,7 @@ int ERR_load_X509V3_strings(void);
 # define X509V3_R_ISSUER_DECODE_ERROR                     126
 # define X509V3_R_MISSING_VALUE                           124
 # define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS           142
+# define X509V3_R_NEGATIVE_PATHLEN                        168
 # define X509V3_R_NO_CONFIG_DATABASE                      136
 # define X509V3_R_NO_ISSUER_CERTIFICATE                   121
 # define X509V3_R_NO_ISSUER_DETAILS                       127
index 42d44dcdcec8f0264d12dfc08749a32cfdeeed03..aaa7fa3d9002d631168e58346c6fb85429331316 100644 (file)
@@ -27,7 +27,7 @@ sub verify {
     run(app([@args]));
 }
 
-plan tests => 144;
+plan tests => 145;
 
 # Canonical success
 ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
@@ -372,13 +372,16 @@ ok(verify("root-cert-rsa2", "sslserver", ["root-cert-rsa2"], [], "-check_ss_sig"
        "accept trusted self-signed EE cert excluding key usage keyCertSign");
 
 SKIP: {
-    skip "Ed25519 is not supported by this OpenSSL build", 5
+    skip "Ed25519 is not supported by this OpenSSL build", 6
              if disabled("ec");
 
     # ED25519 certificate from draft-ietf-curdle-pkix-04
     ok(verify("ee-ed25519", "sslserver", ["root-ed25519"], []),
        "accept X25519 EE cert issued by trusted Ed25519 self-signed CA cert");
 
+    ok(!verify("ee-ed25519", "sslserver", ["root-ed25519"], [], "-x509_strict"),
+       "reject X25519 EE cert in strict mode since AKID is missing");
+
     ok(!verify("root-ed25519", "sslserver", ["ee-ed25519"], []),
        "fail Ed25519 CA and EE certs swapped");
 
index 8a85d14964f8392cc46b5e9fee8446754136187f..e0c7a1f9afea9b85983cada9b546de4621ff8b5c 100644 (file)
@@ -1,10 +1,10 @@
 -----BEGIN CERTIFICATE-----
-MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
-BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz
-MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
-RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF
-AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO
-/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE
-Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ
-zl9HYIMxATFyqSiD9jsx
+MIIBczCCAR0CFEqkMs9xq0qfdNflIpoqdDaOU/ThMA0GCSqGSIb3DQEBBAUAMDox
+CzAJBgNVBAYTAkFVMQwwCgYDVQQIDANRTEQxHTAbBgNVBAMMFFNTTGVheSByc2Eg
+dGVzdCBjZXJ0MCAXDTIwMDczMTE3MTM0NVoYDzIxMjAwNzA3MTcxMzQ1WjA6MQsw
+CQYDVQQGEwJBVTEMMAoGA1UECAwDUUxEMR0wGwYDVQQDDBRTU0xlYXkgcnNhIHRl
+c3QgY2VydDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDUZKgYSMuJdiw2aIQIG4LD
+vm9HbUnyJyj6WgPkpw98dVKTj0jo3F6n/e3anYzvSpOiPkTuvw209yslzJs40Sf7
+AgMBAAEwDQYJKoZIhvcNAQEEBQADQQBV1bQAvyLvJQrNt7WEKmo/inigwjsvQYwd
+nxmV6zWhqpQZmo86/ixumUa6zTlq+y4+wiiFngMZ7Bt0O769Nlzx
 -----END CERTIFICATE-----