[openssl] master update

bernd.edlinger at hotmail.de bernd.edlinger at hotmail.de
Sat Mar 21 18:08:20 UTC 2020


The branch master has been updated
       via  7e06a6758bef584deabc9cb4b0d21b3e664b25c9 (commit)
      from  d3b2f8760a56da3e70c30e5614181f3798e4ad54 (commit)


- Log -----------------------------------------------------------------
commit 7e06a6758bef584deabc9cb4b0d21b3e664b25c9
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date:   Sat Jan 4 15:54:53 2020 +0100

    Fix error handling in x509v3_cache_extensions and related functions
    
    Basically we use EXFLAG_INVALID for all kinds of out of memory and
    all kinds of parse errors in x509v3_cache_extensions.
    
    [extended tests]
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/10755)

-----------------------------------------------------------------------

Summary of changes:
 apps/rehash.c                         | 14 +++--
 crypto/ess/ess_lib.c                  |  5 +-
 crypto/pkcs12/p12_crt.c               |  5 +-
 crypto/ts/ts_rsp_verify.c             | 10 ++--
 crypto/x509/v3_purp.c                 | 97 ++++++++++++++++++++++++-----------
 crypto/x509/x509_cmp.c                |  9 ++--
 crypto/x509/x509_trs.c                |  7 +--
 crypto/x509/x509_vfy.c                | 10 ++--
 crypto/x509/x_all.c                   |  8 +--
 crypto/x509/x_crl.c                   | 37 ++++++++-----
 doc/man3/X509_get_extension_flags.pod | 13 ++++-
 11 files changed, 146 insertions(+), 69 deletions(-)

diff --git a/apps/rehash.c b/apps/rehash.c
index de54064244..e67b27fd15 100644
--- a/apps/rehash.c
+++ b/apps/rehash.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2013-2014 Timo Teräs <timo.teras at gmail.com>
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -274,11 +274,19 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h)
     if (x->x509 != NULL) {
         type = TYPE_CERT;
         name = X509_get_subject_name(x->x509);
-        X509_digest(x->x509, evpmd, digest, NULL);
+        if (!X509_digest(x->x509, evpmd, digest, NULL)) {
+            BIO_printf(bio_err, "out of memory\n");
+            ++errs;
+            goto end;
+        }
     } else if (x->crl != NULL) {
         type = TYPE_CRL;
         name = X509_CRL_get_issuer(x->crl);
-        X509_CRL_digest(x->crl, evpmd, digest, NULL);
+        if (!X509_CRL_digest(x->crl, evpmd, digest, NULL)) {
+            BIO_printf(bio_err, "out of memory\n");
+            ++errs;
+            goto end;
+        }
     } else {
         ++errs;
         goto end;
diff --git a/crypto/ess/ess_lib.c b/crypto/ess/ess_lib.c
index 17c0ea56c6..a2d6bfe7a9 100644
--- a/crypto/ess/ess_lib.c
+++ b/crypto/ess/ess_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-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
@@ -59,7 +59,8 @@ static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
     X509_check_purpose(cert, -1, 0);
     if ((cid = ESS_CERT_ID_new()) == NULL)
         goto err;
-    X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
+    if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL))
+        goto err;
     if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
         goto err;
 
diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c
index 94bd3e1636..0e8b419d0f 100644
--- a/crypto/pkcs12/p12_crt.c
+++ b/crypto/pkcs12/p12_crt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-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
@@ -62,7 +62,8 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *
     if (pkey && cert) {
         if (!X509_check_private_key(cert, pkey))
             return NULL;
-        X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
+        if (!X509_digest(cert, EVP_sha1(), keyid, &keyidlen))
+            return NULL;
     }
 
     if (cert) {
diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c
index dfb068c8b6..1f20fb9c0e 100644
--- a/crypto/ts/ts_rsp_verify.c
+++ b/crypto/ts/ts_rsp_verify.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-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
@@ -265,11 +265,12 @@ static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
     if (!cert_ids || !cert)
         return -1;
 
-    X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
-
     /* Recompute SHA1 hash of certificate if necessary (side effect). */
     X509_check_purpose(cert, -1, 0);
 
+    if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL))
+        return -1;
+
     /* Look for cert in the cert_ids vector. */
     for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {
         ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
@@ -302,7 +303,8 @@ static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert)
         else
             md = EVP_sha256();
 
-        X509_digest(cert, md, cert_digest, &len);
+        if (!X509_digest(cert, md, cert_digest, &len))
+            return -1;
         if (cid->hash->length != (int)len)
             return -1;
 
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c
index 10fd0f73f3..3c39c8fda7 100644
--- a/crypto/x509/v3_purp.c
+++ b/crypto/x509/v3_purp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-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
@@ -81,6 +81,8 @@ int X509_check_purpose(X509 *x, int id, int ca)
     const X509_PURPOSE *pt;
 
     x509v3_cache_extensions(x);
+    if (x->ex_flags & EXFLAG_INVALID)
+        return -1;
 
     /* Return if side-effect only call */
     if (id == -1)
@@ -300,10 +302,11 @@ int X509_supported_extension(X509_EXTENSION *ex)
     return 0;
 }
 
-static void setup_dp(X509 *x, DIST_POINT *dp)
+static int setup_dp(X509 *x, DIST_POINT *dp)
 {
     X509_NAME *iname = NULL;
     int i;
+
     if (dp->reasons) {
         if (dp->reasons->length > 0)
             dp->dp_reasons = dp->reasons->data[0];
@@ -313,7 +316,7 @@ static void setup_dp(X509 *x, DIST_POINT *dp)
     } else
         dp->dp_reasons = CRLDP_ALL_REASONS;
     if (!dp->distpoint || (dp->distpoint->type != 1))
-        return;
+        return 1;
     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) {
@@ -324,16 +327,21 @@ static void setup_dp(X509 *x, DIST_POINT *dp)
     if (!iname)
         iname = X509_get_issuer_name(x);
 
-    DIST_POINT_set_dpname(dp->distpoint, iname);
-
+    return DIST_POINT_set_dpname(dp->distpoint, iname);
 }
 
-static void setup_crldp(X509 *x)
+static int setup_crldp(X509 *x)
 {
     int i;
-    x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
-    for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
-        setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
+
+    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;
+    }
+    return 1;
 }
 
 #define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
@@ -366,12 +374,13 @@ static void x509v3_cache_extensions(X509 *x)
         return;
     }
 
-    X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
+    if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL))
+        x->ex_flags |= EXFLAG_INVALID;
     /* V1 should mean no extensions ... */
     if (!X509_get_version(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) {
@@ -385,9 +394,11 @@ static void 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) {
@@ -399,9 +410,11 @@ static void 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)
@@ -410,9 +423,11 @@ static void 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))) {
@@ -455,18 +470,26 @@ static void 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->akid == 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))) {
         x->ex_flags |= EXFLAG_SI;
@@ -475,16 +498,22 @@ static void x509v3_cache_extensions(X509 *x)
             !ku_reject(x, KU_KEY_CERT_SIGN))
             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))
+    if (x->nc == NULL && i != -1)
+        x->ex_flags |= EXFLAG_INVALID;
+    if (!setup_crldp(x))
         x->ex_flags |= EXFLAG_INVALID;
-    setup_crldp(x);
 
 #ifndef OPENSSL_NO_RFC3779
-    x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
-    x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
-                                       NULL, NULL);
+    x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL);
+    if (x->rfc3779_addr == NULL && i != -1)
+        x->ex_flags |= EXFLAG_INVALID;
+    x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, &i, NULL);
+    if (x->rfc3779_asid == NULL && i != -1)
+        x->ex_flags |= EXFLAG_INVALID;
 #endif
     for (i = 0; i < X509_get_ext_count(x); i++) {
         ex = X509_get_ext(x, i);
@@ -778,7 +807,11 @@ int X509_check_issued(X509 *issuer, X509 *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);
@@ -861,7 +894,8 @@ uint32_t X509_get_extension_flags(X509 *x)
 uint32_t X509_get_key_usage(X509 *x)
 {
     /* Call for side-effect of computing hash and caching extensions */
-    X509_check_purpose(x, -1, -1);
+    if (X509_check_purpose(x, -1, -1) != 1)
+        return 0;
     if (x->ex_flags & EXFLAG_KUSAGE)
         return x->ex_kusage;
     return UINT32_MAX;
@@ -870,7 +904,8 @@ uint32_t X509_get_key_usage(X509 *x)
 uint32_t X509_get_extended_key_usage(X509 *x)
 {
     /* Call for side-effect of computing hash and caching extensions */
-    X509_check_purpose(x, -1, -1);
+    if (X509_check_purpose(x, -1, -1) != 1)
+        return 0;
     if (x->ex_flags & EXFLAG_XKUSAGE)
         return x->ex_xkusage;
     return UINT32_MAX;
@@ -879,28 +914,32 @@ uint32_t X509_get_extended_key_usage(X509 *x)
 const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x)
 {
     /* Call for side-effect of computing hash and caching extensions */
-    X509_check_purpose(x, -1, -1);
+    if (X509_check_purpose(x, -1, -1) != 1)
+        return NULL;
     return x->skid;
 }
 
 const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x)
 {
     /* Call for side-effect of computing hash and caching extensions */
-    X509_check_purpose(x, -1, -1);
+    if (X509_check_purpose(x, -1, -1) != 1)
+        return NULL;
     return (x->akid != NULL ? x->akid->keyid : NULL);
 }
 
 const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x)
 {
     /* Call for side-effect of computing hash and caching extensions */
-    X509_check_purpose(x, -1, -1);
+    if (X509_check_purpose(x, -1, -1) != 1)
+        return NULL;
     return (x->akid != NULL ? x->akid->issuer : NULL);
 }
 
 const ASN1_INTEGER *X509_get0_authority_serial(X509 *x)
 {
     /* Call for side-effect of computing hash and caching extensions */
-    X509_check_purpose(x, -1, -1);
+    if (X509_check_purpose(x, -1, -1) != 1)
+        return NULL;
     return (x->akid != NULL ? x->akid->serial : NULL);
 }
 
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index b8a61ffe2a..9092c20f39 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -135,9 +135,12 @@ unsigned long X509_subject_name_hash_old(X509 *x)
 int X509_cmp(const X509 *a, const X509 *b)
 {
     int rv;
+
     /* ensure hash is valid */
-    X509_check_purpose((X509 *)a, -1, 0);
-    X509_check_purpose((X509 *)b, -1, 0);
+    if (X509_check_purpose((X509 *)a, -1, 0) != 1)
+        return -2;
+    if (X509_check_purpose((X509 *)b, -1, 0) != 1)
+        return -2;
 
     rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
     if (rv)
diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c
index b077ba584f..10718c347d 100644
--- a/crypto/x509/x509_trs.c
+++ b/crypto/x509/x509_trs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-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
@@ -240,8 +240,9 @@ static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
 static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
 {
     /* Call for side-effect of computing hash and caching extensions */
-    X509_check_purpose(x, -1, 0);
-    if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && x->ex_flags & EXFLAG_SS)
+    if (X509_check_purpose(x, -1, 0) != 1)
+        return X509_TRUST_UNTRUSTED;
+    if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && (x->ex_flags & EXFLAG_SS))
         return X509_TRUST_TRUSTED;
     else
         return X509_TRUST_UNTRUSTED;
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index c8d1258803..07ca7ae31e 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -107,12 +107,8 @@ static int null_callback(int ok, X509_STORE_CTX *e)
 /* Return 1 is a certificate is self signed */
 static int cert_self_signed(X509 *x)
 {
-    /*
-     * FIXME: x509v3_cache_extensions() needs to detect more failures and not
-     * set EXFLAG_SET when that happens.  Especially, if the failures are
-     * parse errors, rather than memory pressure!
-     */
-    X509_check_purpose(x, -1, 0);
+    if (X509_check_purpose(x, -1, 0) != 1)
+        return 0;
     if (x->ex_flags & EXFLAG_SS)
         return 1;
     else
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index ca9d3dbc98..00b45ffdd8 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -433,7 +433,8 @@ int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
 int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
                 unsigned int *len)
 {
-    if (type == EVP_sha1() && (data->ex_flags & EXFLAG_SET) != 0) {
+    if (type == EVP_sha1() && (data->ex_flags & EXFLAG_SET) != 0
+            && (data->ex_flags & EXFLAG_INVALID) == 0) {
         /* Asking for SHA1 and we already computed it. */
         if (len != NULL)
             *len = sizeof(data->sha1_hash);
@@ -476,7 +477,8 @@ ASN1_OCTET_STRING *X509_digest_sig(const X509 *cert)
 int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
                     unsigned char *md, unsigned int *len)
 {
-    if (type == EVP_sha1() && (data->flags & EXFLAG_SET) != 0) {
+    if (type == EVP_sha1() && (data->flags & EXFLAG_SET) != 0
+            && (data->flags & EXFLAG_INVALID) == 0) {
         /* Asking for SHA1; always computed in CRL d2i. */
         if (len != NULL)
             *len = sizeof(data->sha1_hash);
diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c
index fdc059123f..fb1d01f402 100644
--- a/crypto/x509/x_crl.c
+++ b/crypto/x509/x_crl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -17,7 +17,7 @@
 
 static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
                             const X509_REVOKED *const *b);
-static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
+static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
 
 ASN1_SEQUENCE(X509_REVOKED) = {
         ASN1_EMBED(X509_REVOKED,serialNumber, ASN1_INTEGER),
@@ -155,7 +155,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
     X509_CRL *crl = (X509_CRL *)*pval;
     STACK_OF(X509_EXTENSION) *exts;
     X509_EXTENSION *ext;
-    int idx;
+    int idx, i;
 
     switch (operation) {
     case ASN1_OP_D2I_PRE:
@@ -184,23 +184,35 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
         break;
 
     case ASN1_OP_D2I_POST:
-        X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+        if (!X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL))
+            crl->flags |= EXFLAG_INVALID;
         crl->idp = X509_CRL_get_ext_d2i(crl,
-                                        NID_issuing_distribution_point, NULL,
+                                        NID_issuing_distribution_point, &i,
                                         NULL);
-        if (crl->idp)
-            setup_idp(crl, crl->idp);
+        if (crl->idp != NULL) {
+            if (!setup_idp(crl, crl->idp))
+                crl->flags |= EXFLAG_INVALID;
+        }
+        else if (i != -1) {
+            crl->flags |= EXFLAG_INVALID;
+        }
 
         crl->akid = X509_CRL_get_ext_d2i(crl,
-                                         NID_authority_key_identifier, NULL,
+                                         NID_authority_key_identifier, &i,
                                          NULL);
+        if (crl->akid == NULL && i != -1)
+            crl->flags |= EXFLAG_INVALID;
 
         crl->crl_number = X509_CRL_get_ext_d2i(crl,
-                                               NID_crl_number, NULL, NULL);
+                                               NID_crl_number, &i, NULL);
+        if (crl->crl_number == NULL && i != -1)
+            crl->flags |= EXFLAG_INVALID;
 
         crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
-                                                    NID_delta_crl, NULL,
+                                                    NID_delta_crl, &i,
                                                     NULL);
+        if (crl->base_crl_number == NULL && i != -1)
+            crl->flags |= EXFLAG_INVALID;
         /* Delta CRLs must have CRL number */
         if (crl->base_crl_number && !crl->crl_number)
             crl->flags |= EXFLAG_INVALID;
@@ -259,9 +271,10 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 
 /* Convert IDP into a more convenient form */
 
-static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
+static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
 {
     int idp_only = 0;
+
     /* Set various flags according to IDP */
     crl->idp_flags |= IDP_PRESENT;
     if (idp->onlyuser > 0) {
@@ -292,7 +305,7 @@ static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
         crl->idp_reasons &= CRLDP_ALL_REASONS;
     }
 
-    DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+    return DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
 }
 
 ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
diff --git a/doc/man3/X509_get_extension_flags.pod b/doc/man3/X509_get_extension_flags.pod
index 34f811c7dc..3f09939e52 100644
--- a/doc/man3/X509_get_extension_flags.pod
+++ b/doc/man3/X509_get_extension_flags.pod
@@ -80,6 +80,17 @@ The certificate contains an unhandled critical extension.
 
 Some certificate extension values are invalid or inconsistent. The
 certificate should be rejected.
+This bit may also be raised after an out-of-memory error while
+processing the X509 object, so it may not be related to the processed
+ASN1 object itself.
+
+=item B<EXFLAG_INVALID_POLICY>
+
+The NID_certificate_policies certificate extension is invalid or
+inconsistent. The certificate should be rejected.
+This bit may also be raised after an out-of-memory error while
+processing the X509 object, so it may not be related to the processed
+ASN1 object itself.
 
 =item B<EXFLAG_KUSAGE>
 
@@ -183,7 +194,7 @@ X509_get_proxy_pathlen() were added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2015-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


More information about the openssl-commits mailing list