From d14580de7d53e6c9e8f64e58e979f8d959902ad3 Mon Sep 17 00:00:00 2001 From: tobhe <> Date: Sat, 13 Mar 2021 23:01:49 +0000 Subject: Use EXFLAG_INVALID to handle out of memory and parse errors in x509v3_cache_extensions(). ok tb@ --- src/lib/libcrypto/x509/x509_purp.c | 50 ++++++++++++++++++++++++++++-------- src/lib/libcrypto/x509/x509_verify.c | 6 ++++- 2 files changed, 45 insertions(+), 11 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libcrypto/x509/x509_purp.c b/src/lib/libcrypto/x509/x509_purp.c index f2d46658f6..3b8bd6b81c 100644 --- a/src/lib/libcrypto/x509/x509_purp.c +++ b/src/lib/libcrypto/x509/x509_purp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_purp.c,v 1.2 2020/09/13 15:06:17 beck Exp $ */ +/* $OpenBSD: x509_purp.c,v 1.3 2021/03/13 23:01:49 tobhe Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2001. */ @@ -132,6 +132,8 @@ X509_check_purpose(X509 *x, int id, int ca) CRYPTO_w_lock(CRYPTO_LOCK_X509); x509v3_cache_extensions(x); CRYPTO_w_unlock(CRYPTO_LOCK_X509); + if (x->ex_flags & EXFLAG_INVALID) + return X509_V_ERR_UNSPECIFIED; } if (id == -1) return 1; @@ -421,7 +423,12 @@ setup_crldp(X509 *x) { int i; - x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL); + if (x->crldp == NULL && i != -1) { + x->ex_flags |= EXFLAG_INVALID; + return; + } + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); } @@ -449,7 +456,7 @@ x509v3_cache_extensions(X509 *x) x->ex_flags |= EXFLAG_V1; /* Handle basic constraints */ - if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { + if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL))) { if (bs->ca) x->ex_flags |= EXFLAG_CA; if (bs->pathlen) { @@ -463,10 +470,12 @@ x509v3_cache_extensions(X509 *x) x->ex_pathlen = -1; BASIC_CONSTRAINTS_free(bs); x->ex_flags |= EXFLAG_BCONS; + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; } /* Handle proxy certificates */ - if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { + if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &i, NULL))) { if (x->ex_flags & EXFLAG_CA || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { @@ -485,10 +494,12 @@ x509v3_cache_extensions(X509 *x) x->ex_pcpathlen = -1; PROXY_CERT_INFO_EXTENSION_free(pci); x->ex_flags |= EXFLAG_PROXY; + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; } /* Handle key usage */ - if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { + if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL))) { if (usage->length > 0) { x->ex_kusage = usage->data[0]; if (usage->length > 1) @@ -497,9 +508,12 @@ x509v3_cache_extensions(X509 *x) x->ex_kusage = 0; x->ex_flags |= EXFLAG_KUSAGE; ASN1_BIT_STRING_free(usage); + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; } + x->ex_xkusage = 0; - if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { + if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL))) { x->ex_flags |= EXFLAG_XKUSAGE; for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { @@ -538,19 +552,27 @@ x509v3_cache_extensions(X509 *x) } } sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; } - if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { + if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &i, NULL))) { if (ns->length > 0) x->ex_nscert = ns->data[0]; else x->ex_nscert = 0; x->ex_flags |= EXFLAG_NSCERT; ASN1_BIT_STRING_free(ns); + } else if (i != -1) { + x->ex_flags |= EXFLAG_INVALID; } - x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); - x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); + 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->skid == NULL && i != -1) + x->ex_flags |= EXFLAG_INVALID; /* Does subject name match issuer? */ if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { @@ -561,7 +583,9 @@ x509v3_cache_extensions(X509 *x) x->ex_flags |= EXFLAG_SS; } - x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &i, NULL); + if (x->altname == NULL && i != -1) + x->ex_flags |= EXFLAG_INVALID; x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); if (!x->nc && (i != -1)) x->ex_flags |= EXFLAG_INVALID; @@ -626,6 +650,8 @@ X509_check_ca(X509 *x) CRYPTO_w_lock(CRYPTO_LOCK_X509); x509v3_cache_extensions(x); CRYPTO_w_unlock(CRYPTO_LOCK_X509); + if (x->ex_flags & EXFLAG_INVALID) + return X509_V_ERR_UNSPECIFIED; } return check_ca(x); @@ -837,7 +863,11 @@ X509_check_issued(X509 *issuer, X509 *subject) X509_get_issuer_name(subject))) return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; x509v3_cache_extensions(issuer); + if (issuer->ex_flags & EXFLAG_INVALID) + return X509_V_ERR_UNSPECIFIED; x509v3_cache_extensions(subject); + if (subject->ex_flags & EXFLAG_INVALID) + return X509_V_ERR_UNSPECIFIED; if (subject->akid) { int ret = X509_check_akid(issuer, subject->akid); diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c index 3c8369f1f9..9c34e31ee3 100644 --- a/src/lib/libcrypto/x509/x509_verify.c +++ b/src/lib/libcrypto/x509/x509_verify.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_verify.c,v 1.35 2021/03/12 15:53:38 tb Exp $ */ +/* $OpenBSD: x509_verify.c,v 1.36 2021/03/13 23:01:49 tobhe Exp $ */ /* * Copyright (c) 2020-2021 Bob Beck * @@ -756,6 +756,10 @@ x509_verify_cert_extensions(struct x509_verify_ctx *ctx, X509 *cert, int need_ca CRYPTO_w_lock(CRYPTO_LOCK_X509); x509v3_cache_extensions(cert); CRYPTO_w_unlock(CRYPTO_LOCK_X509); + if (cert->ex_flags & EXFLAG_INVALID) { + ctx->error = X509_V_ERR_UNSPECIFIED; + return 0; + } } if (ctx->xsc != NULL) -- cgit v1.2.3-55-g6feb