[openssl] master update
dev at ddvo.net
dev at ddvo.net
Fri Sep 11 05:47:04 UTC 2020
The branch master has been updated
via 82bdd6419361136e7be533d31a990ba0476fced3 (commit)
via e41a2c4c609a8f64dfab2d832e975b0b37ff286d (commit)
via d72c8b457b77c31a20cf66e9c92aa19a4b7b5884 (commit)
via bb377c8d6c61920d889b961bd5c862eaac8b28e4 (commit)
via da6c691d6d417ad413fdc1e7a7a183d005e7fefd (commit)
via 89f13ca4342be5b541b0885e3058617e5cce0de8 (commit)
via 8a639b9d7234ed490f85ea46e4e8c74620452acd (commit)
via 1e41dadfa7b9f792ed0f4714a3d3d36f070cf30e (commit)
from b0a4cbead384e2ac8dbb697795ace242e1b07c18 (commit)
- Log -----------------------------------------------------------------
commit 82bdd6419361136e7be533d31a990ba0476fced3
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Tue Sep 8 09:39:33 2020 +0200
check_chain_extensions(): Require X.509 v3 if extensions are present
Reviewed-by: Kurt Roeckx <kurt at roeckx.be>
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
commit e41a2c4c609a8f64dfab2d832e975b0b37ff286d
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Mon Sep 7 22:38:46 2020 +0200
check_chain_extensions(): Change exclusion condition w.r.t. RFC 6818 section 2
Reviewed-by: Kurt Roeckx <kurt at roeckx.be>
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
commit d72c8b457b77c31a20cf66e9c92aa19a4b7b5884
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Wed Aug 26 09:45:11 2020 +0200
x509_vfy.c: Make sure that strict checks are not done for self-issued EE certs
Reviewed-by: Kurt Roeckx <kurt at roeckx.be>
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
commit bb377c8d6c61920d889b961bd5c862eaac8b28e4
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Tue Aug 25 16:58:36 2020 +0200
check_chain_extensions(): Add check that CA cert includes key usage extension
Reviewed-by: Kurt Roeckx <kurt at roeckx.be>
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
commit da6c691d6d417ad413fdc1e7a7a183d005e7fefd
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Tue Aug 25 16:46:18 2020 +0200
check_chain_extensions(): Add check that on empty Subject the SAN must be marked critical
Reviewed-by: Kurt Roeckx <kurt at roeckx.be>
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
commit 89f13ca4342be5b541b0885e3058617e5cce0de8
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Tue Aug 25 16:13:40 2020 +0200
check_chain_extensions(): Add check that AKID and SKID are not marked critical
Reviewed-by: Kurt Roeckx <kurt at roeckx.be>
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
commit 8a639b9d7234ed490f85ea46e4e8c74620452acd
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Tue Aug 25 15:37:46 2020 +0200
check_chain_extensions(): Add check that Basic Constraints of CA cert are marked critical
Reviewed-by: Kurt Roeckx <kurt at roeckx.be>
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
commit 1e41dadfa7b9f792ed0f4714a3d3d36f070cf30e
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Sat Jun 27 16:16:12 2020 +0200
Extend X509 cert checks and error reporting in v3_{purp,crld}.c and x509_{set,vfy}.c
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 at roeckx.be>
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
-----------------------------------------------------------------------
Summary of changes:
crypto/err/openssl.txt | 7 +
crypto/x509/v3_crld.c | 27 ++--
crypto/x509/v3_purp.c | 118 +++++++++++++----
crypto/x509/v3err.c | 5 +
crypto/x509/x509_err.c | 7 +
crypto/x509/x509_set.c | 97 ++++++++------
crypto/x509/x509_txt.c | 42 +++++-
crypto/x509/x509_vfy.c | 78 ++++++++++-
doc/internal/man3/x509v3_cache_extensions.pod | 40 ++++++
doc/man1/openssl.pod | 1 +
include/crypto/x509.h | 6 +-
include/openssl/x509_vfy.h | 179 ++++++++++++++------------
include/openssl/x509err.h | 4 +
include/openssl/x509v3.h | 11 +-
include/openssl/x509v3err.h | 3 +
test/recipes/25-test_verify.t | 7 +-
test/testx509.pem | 16 +--
17 files changed, 463 insertions(+), 185 deletions(-)
create mode 100644 doc/internal/man3/x509v3_cache_extensions.pod
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index df8a7af26c..d0ba9c47be 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -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
diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c
index b54346d036..8b4e100714 100644
--- a/crypto/x509/v3_crld.c
+++ b/crypto/x509/v3_crld.c
@@ -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;
}
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c
index d7d0aae3b3..2d4098b629 100644
--- a/crypto/x509/v3_purp.c
+++ b/crypto/x509/v3_purp.c
@@ -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)
@@ -382,8 +401,8 @@ int x509v3_cache_extensions(X509 *x)
ASN1_BIT_STRING *usage;
ASN1_BIT_STRING *ns;
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 +417,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 +459,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 +469,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 +479,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 +523,7 @@ int x509v3_cache_extensions(X509 *x)
x->ex_xkusage |= XKU_ANYEKU;
break;
default:
+ /* ignore unknown extended key usage */
break;
}
}
@@ -517,6 +548,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 +570,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);
@@ -550,9 +587,10 @@ int x509v3_cache_extensions(X509 *x)
x->ex_flags |= EXFLAG_INVALID;
#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)
+ X509_EXTENSION *ex = X509_get_ext(x, i);
+ int nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
+
+ if (nid == NID_freshest_crl)
x->ex_flags |= EXFLAG_FRESHEST;
if (!X509_EXTENSION_get_critical(ex))
continue;
@@ -560,9 +598,26 @@ int x509v3_cache_extensions(X509 *x)
x->ex_flags |= EXFLAG_CRITICAL;
break;
}
+ switch (nid) {
+ case NID_basic_constraints:
+ x->ex_flags |= EXFLAG_BCONS_CRITICAL;
+ break;
+ case NID_authority_key_identifier:
+ x->ex_flags |= EXFLAG_AKID_CRITICAL;
+ break;
+ case NID_subject_key_identifier:
+ x->ex_flags |= EXFLAG_SKID_CRITICAL;
+ break;
+ case NID_subject_alt_name:
+ x->ex_flags |= EXFLAG_SAN_CRITICAL;
+ break;
+ default:
+ break;
+ }
}
- 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 +629,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;
}
/*-
diff --git a/crypto/x509/v3err.c b/crypto/x509/v3err.c
index 4c62e59db9..5124908089 100644
--- a/crypto/x509/v3err.c
+++ b/crypto/x509/v3err.c
@@ -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),
diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c
index 450f2a7930..330fed3406 100644
--- a/crypto/x509/x509_err.c
+++ b/crypto/x509/x509_err.c
@@ -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"},
diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c
index 46cabc4b42..79e4c03ca3 100644
--- a/crypto/x509/x509_set.c
+++ b/crypto/x509/x509_set.c
@@ -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);
}
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index 63d8d95f3f..53b19e46df 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -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,42 @@ 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";
+ case X509_V_ERR_CA_BCONS_NOT_CRITICAL:
+ return "Basic Constraints of CA cert not marked critical";
+ case X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL:
+ return "Subject empty and Subject Alt Name extension not critical";
+ case X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL:
+ return "Authority Key Identifier marked critical";
+ case X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL:
+ return "Subject Key Identifier marked critical";
+ case X509_V_ERR_CA_CERT_MISSING_KEY_USAGE:
+ return "CA cert does not include key usage extension";
+ case X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3:
+ return "Using cert extension requires at least X509v3";
default:
/* Printing an error number into a static buffer is not thread-safe */
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 843b65f022..4a067e5ff4 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -26,6 +26,7 @@
#include "x509_local.h"
DEFINE_STACK_OF(X509)
+DEFINE_STACK_OF(X509_EXTENSION)
DEFINE_STACK_OF(X509_REVOKED)
DEFINE_STACK_OF(GENERAL_NAME)
DEFINE_STACK_OF(X509_CRL)
@@ -479,6 +480,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 +521,78 @@ 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;
+ /*
+ * Do the following set of checks only if strict checking is requrested
+ * and not for self-issued (including self-signed) EE (non-CA) certs
+ * because RFC 5280 does not apply to them according RFC 6818 section 2.
+ */
+ if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) != 0
+ && num > 1) { /*
+ * this should imply
+ * !(i == 0 && (x->ex_flags & EXFLAG_CA) == 0
+ * && (x->ex_flags & EXFLAG_SI) != 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;
+ }
+ if ((x->ex_flags & EXFLAG_CA) != 0
+ && (x->ex_flags & EXFLAG_BCONS) != 0
+ && (x->ex_flags & EXFLAG_BCONS_CRITICAL) == 0)
+ ctx->error = X509_V_ERR_CA_BCONS_NOT_CRITICAL;
+ /* Check Key Usage according to RFC 5280 section 4.2.1.3 */
+ if ((x->ex_flags & EXFLAG_CA) != 0) {
+ if ((x->ex_flags & EXFLAG_KUSAGE) == 0)
+ ctx->error = X509_V_ERR_CA_CERT_MISSING_KEY_USAGE;
+ } else {
+ if ((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;
+ if (X509_NAME_entry_count(X509_get_subject_name(x)) == 0
+ && x->altname != NULL
+ && (x->ex_flags & EXFLAG_SAN_CRITICAL) == 0)
+ ctx->error = X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_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 (x->akid != NULL && (x->ex_flags & EXFLAG_AKID_CRITICAL) != 0)
+ ctx->error = X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL;
+ if (x->skid != NULL && (x->ex_flags & EXFLAG_SKID_CRITICAL) != 0)
+ ctx->error = X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL;
+ 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;
+ /* 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;
+ } else {
+ if (sk_X509_EXTENSION_num(X509_get0_extensions(x)) > 0)
+ ctx->error = X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3;
+ }
}
+ 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
index 0000000000..3fb7609daa
--- /dev/null
+++ b/doc/internal/man3/x509v3_cache_extensions.pod
@@ -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
diff --git a/doc/man1/openssl.pod b/doc/man1/openssl.pod
index 1f344217a2..3ae273b5bf 100644
--- a/doc/man1/openssl.pod
+++ b/doc/man1/openssl.pod
@@ -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>
diff --git a/include/crypto/x509.h b/include/crypto/x509.h
index bd8f9ba52d..8c9a288cbc 100644
--- a/include/crypto/x509.h
+++ b/include/crypto/x509.h
@@ -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,
diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h
index 2d3bd70ae2..d43a442fc7 100644
--- a/include/openssl/x509_vfy.h
+++ b/include/openssl/x509_vfy.h
@@ -124,103 +124,118 @@ 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
+# define X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL 88
+# define X509_V_ERR_CA_BCONS_NOT_CRITICAL 89
+# define X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL 90
+# define X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL 91
+# define X509_V_ERR_CA_CERT_MISSING_KEY_USAGE 92
+# define X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 93
/* Certificate verify flags */
-
# ifndef OPENSSL_NO_DEPRECATED_1_1_0
# define X509_V_FLAG_CB_ISSUER_CHECK 0x0 /* Deprecated */
# endif
diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h
index 19743b5987..94c5c5b75e 100644
--- a/include/openssl/x509err.h
+++ b/include/openssl/x509err.h
@@ -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
diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h
index 24f5a361d0..a3ef7ced3a 100644
--- a/include/openssl/x509v3.h
+++ b/include/openssl/x509v3.h
@@ -364,8 +364,7 @@ struct ISSUING_DIST_POINT_st {
# define EXFLAG_NSCERT 0x8
# define EXFLAG_CA 0x10
-/* Really self issued not necessarily self signed */
-# define EXFLAG_SI 0x20
+# define EXFLAG_SI 0x20 /* self-issued, maybe not self-signed */
# define EXFLAG_V1 0x40
# define EXFLAG_INVALID 0x80
/* EXFLAG_SET is set to indicate that some values have been precomputed */
@@ -375,8 +374,12 @@ struct ISSUING_DIST_POINT_st {
# define EXFLAG_INVALID_POLICY 0x800
# define EXFLAG_FRESHEST 0x1000
-/* Self signed */
-# define EXFLAG_SS 0x2000
+# define EXFLAG_SS 0x2000 /* cert is apparently self-signed */
+
+# define EXFLAG_BCONS_CRITICAL 0x10000
+# define EXFLAG_AKID_CRITICAL 0x20000
+# define EXFLAG_SKID_CRITICAL 0x40000
+# define EXFLAG_SAN_CRITICAL 0x80000
# define KU_DIGITAL_SIGNATURE 0x0080
# define KU_NON_REPUDIATION 0x0040
diff --git a/include/openssl/x509v3err.h b/include/openssl/x509v3err.h
index d7aa5da6ac..b245a63902 100644
--- a/include/openssl/x509v3err.h
+++ b/include/openssl/x509v3err.h
@@ -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
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index 42d44dcdce..aaa7fa3d90 100644
--- a/test/recipes/25-test_verify.t
+++ b/test/recipes/25-test_verify.t
@@ -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");
diff --git a/test/testx509.pem b/test/testx509.pem
index 8a85d14964..e0c7a1f9af 100644
--- a/test/testx509.pem
+++ b/test/testx509.pem
@@ -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-----
More information about the openssl-commits
mailing list