mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
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@roeckx.be> Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/12478)
This commit is contained in:
parent
b0a4cbead3
commit
1e41dadfa7
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*-
|
||||
|
@ -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),
|
||||
|
@ -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"},
|
||||
|
@ -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;
|
||||
siginf->pknid = pknid;
|
||||
if (mdnid == 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);
|
||||
if (ameth == NULL || ameth->siginf_set == NULL
|
||||
|| ameth->siginf_set(siginf, alg, sig) == 0)
|
||||
return;
|
||||
siginf->flags |= X509_SIG_INFO_VALID;
|
||||
return;
|
||||
|| pknid == NID_undef) {
|
||||
X509err(0, X509_R_UNKNOWN_SIGID_ALGS);
|
||||
return 0;
|
||||
}
|
||||
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)
|
||||
siginf->secbits = 63;
|
||||
else if (mdnid == NID_md5)
|
||||
siginf->secbits = 39;
|
||||
siginf->pknid = pknid;
|
||||
|
||||
switch (mdnid) {
|
||||
case NID_sha1:
|
||||
case NID_sha256:
|
||||
case NID_sha384:
|
||||
case NID_sha512:
|
||||
case NID_undef:
|
||||
/* If we have one, use a custom handler for this algorithm */
|
||||
ameth = EVP_PKEY_asn1_find(NULL, pknid);
|
||||
if (ameth == NULL || ameth->siginf_set == NULL
|
||||
|| !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;
|
||||
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:
|
||||
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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
40
doc/internal/man3/x509v3_cache_extensions.pod
Normal file
40
doc/internal/man3/x509v3_cache_extensions.pod
Normal file
@ -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
|
@ -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>
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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_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_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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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-----
|
||||
|
Loading…
Reference in New Issue
Block a user