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..4bde90f277 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) @@ -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; } /*- 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; - 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); } diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c index 63d8d95f3f..4bb16545ef 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,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 */ diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 843b65f022..c6717c53c8 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -479,6 +479,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) for (i = 0; i < num; i++) { int ret; + x = sk_X509_value(ctx->chain, i); if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && (x->ex_flags & EXFLAG_CRITICAL)) { @@ -519,12 +520,58 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) ret = 1; break; } - if ((x->ex_flags & EXFLAG_CA) == 0 - && x->ex_pathlen != -1 - && (ctx->param->flags & X509_V_FLAG_X509_STRICT)) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - ret = 0; + if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) != 0) { + /* Check Basic Constraints according to RFC 5280 section 4.2.1.9 */ + if (x->ex_pathlen != -1) { + if ((x->ex_flags & EXFLAG_CA) == 0) + ctx->error = X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA; + if ((x->ex_kusage & KU_KEY_CERT_SIGN) == 0) + ctx->error = X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN; + } + /* TODO check basic constrains of CA cert are marked critical */ + /* Check keyCertSign according to RFC 5280 section 4.2.1.3 */ + if ((x->ex_flags & EXFLAG_CA) == 0 + && (x->ex_kusage & KU_KEY_CERT_SIGN) != 0) + ctx->error = X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA; + /* Check issuer is non-empty acc. to RFC 5280 section 4.1.2.4 */ + if (X509_NAME_entry_count(X509_get_issuer_name(x)) == 0) + ctx->error = X509_V_ERR_ISSUER_NAME_EMPTY; + /* Check subject is non-empty acc. to RFC 5280 section 4.1.2.6 */ + if (((x->ex_flags & EXFLAG_CA) != 0 + || (x->ex_kusage & KU_CRL_SIGN) != 0 + || x->altname == NULL + ) && X509_NAME_entry_count(X509_get_subject_name(x)) == 0) + ctx->error = X509_V_ERR_SUBJECT_NAME_EMPTY; + /* + * TODO check: If subject naming information is present only in + * the subjectAltName extension, + * then the subject name MUST be an empty sequence + * and the subjectAltName extension MUST be critical. + */ + /* Check SAN is non-empty according to RFC 5280 section 4.2.1.6 */ + if (x->altname != NULL && sk_GENERAL_NAME_num(x->altname) <= 0) + ctx->error = X509_V_ERR_EMPTY_SUBJECT_ALT_NAME; + /* TODO add more checks on SAN entries */ + /* Check sig alg consistency acc. to RFC 5280 section 4.1.1.2 */ + if (X509_ALGOR_cmp(&x->sig_alg, &x->cert_info.signature) != 0) + ctx->error = X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY; + if (X509_get_version(x) >= 2) { /* at least X.509v3 */ + /* Check AKID presence acc. to RFC 5280 section 4.2.1.1 */ + if (i + 1 < num /* + * this means not last cert in chain, + * taken as "generated by conforming CAs" + */ + && (x->akid == NULL || x->akid->keyid == NULL)) + ctx->error = X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER; + /* TODO check that AKID extension is not critical */ + /* Check SKID presence acc. to RFC 5280 section 4.2.1.2 */ + if ((x->ex_flags & EXFLAG_CA) != 0 && x->skid == NULL) + ctx->error = X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER; + /* TODO check that SKID extension is not be critical */ + } } + if (ctx->error != X509_V_OK) + ret = 0; if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK)) return 0; /* check_purpose() makes the callback as needed */ diff --git a/doc/internal/man3/x509v3_cache_extensions.pod b/doc/internal/man3/x509v3_cache_extensions.pod new file mode 100644 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 + + 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 +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 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. + +=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..ec2021357b 100644 --- a/include/openssl/x509_vfy.h +++ b/include/openssl/x509_vfy.h @@ -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 */ 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/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-----