Skip to content

Commit

Permalink
Fix error handling in x509v3_cache_extensions and related functions
Browse files Browse the repository at this point in the history
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@fedoraproject.org>
(Merged from #10756)
  • Loading branch information
bernd-edlinger committed Mar 22, 2020
1 parent 673692b commit ba4356a
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 69 deletions.
14 changes: 11 additions & 3 deletions apps/rehash.c
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 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@gmail.com>
*
* Licensed under the OpenSSL license (the "License"). You may not use
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions 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 OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -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) {
Expand Down
5 changes: 3 additions & 2 deletions crypto/ts/ts_rsp_sign.c
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -771,7 +771,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;

Expand Down
10 changes: 6 additions & 4 deletions crypto/ts/ts_rsp_verify.c
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -289,11 +289,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);
Expand Down Expand Up @@ -326,7 +327,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;

Expand Down
9 changes: 6 additions & 3 deletions crypto/x509/x509_cmp.c
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -134,9 +134,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)
Expand Down
7 changes: 4 additions & 3 deletions 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 OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 3 additions & 7 deletions crypto/x509/x509_vfy.c
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions 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 OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -362,7 +362,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);
Expand All @@ -376,7 +377,8 @@ int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
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);
Expand Down
37 changes: 25 additions & 12 deletions crypto/x509/x_crl.c
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand All @@ -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),
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) = {
Expand Down

0 comments on commit ba4356a

Please sign in to comment.