提交 ba4356ae 编写于 作者: B Bernd Edlinger

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: NTomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/10756)
上级 673692b8
/* /*
* 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> * Copyright (c) 2013-2014 Timo Teräs <timo.teras@gmail.com>
* *
* Licensed under the OpenSSL license (the "License"). You may not use * Licensed under the OpenSSL license (the "License"). You may not use
...@@ -274,11 +274,19 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h) ...@@ -274,11 +274,19 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h)
if (x->x509 != NULL) { if (x->x509 != NULL) {
type = TYPE_CERT; type = TYPE_CERT;
name = X509_get_subject_name(x->x509); 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) { } else if (x->crl != NULL) {
type = TYPE_CRL; type = TYPE_CRL;
name = X509_CRL_get_issuer(x->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 { } else {
++errs; ++errs;
goto end; goto end;
......
/* /*
* 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * 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 * ...@@ -62,7 +62,8 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *
if (pkey && cert) { if (pkey && cert) {
if (!X509_check_private_key(cert, pkey)) if (!X509_check_private_key(cert, pkey))
return NULL; return NULL;
X509_digest(cert, EVP_sha1(), keyid, &keyidlen); if (!X509_digest(cert, EVP_sha1(), keyid, &keyidlen))
return NULL;
} }
if (cert) { if (cert) {
......
/* /*
* 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
...@@ -771,7 +771,8 @@ static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed) ...@@ -771,7 +771,8 @@ static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed)
X509_check_purpose(cert, -1, 0); X509_check_purpose(cert, -1, 0);
if ((cid = ESS_CERT_ID_new()) == NULL) if ((cid = ESS_CERT_ID_new()) == NULL)
goto err; 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)) if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
goto err; goto err;
......
/* /*
* 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
...@@ -289,11 +289,12 @@ static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) ...@@ -289,11 +289,12 @@ static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
if (!cert_ids || !cert) if (!cert_ids || !cert)
return -1; return -1;
X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
/* Recompute SHA1 hash of certificate if necessary (side effect). */ /* Recompute SHA1 hash of certificate if necessary (side effect). */
X509_check_purpose(cert, -1, 0); 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. */ /* Look for cert in the cert_ids vector. */
for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {
ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
...@@ -326,7 +327,8 @@ static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert) ...@@ -326,7 +327,8 @@ static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert)
else else
md = EVP_sha256(); 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) if (cid->hash->length != (int)len)
return -1; return -1;
......
/* /*
* 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
...@@ -134,9 +134,12 @@ unsigned long X509_subject_name_hash_old(X509 *x) ...@@ -134,9 +134,12 @@ unsigned long X509_subject_name_hash_old(X509 *x)
int X509_cmp(const X509 *a, const X509 *b) int X509_cmp(const X509 *a, const X509 *b)
{ {
int rv; int rv;
/* ensure hash is valid */ /* ensure hash is valid */
X509_check_purpose((X509 *)a, -1, 0); if (X509_check_purpose((X509 *)a, -1, 0) != 1)
X509_check_purpose((X509 *)b, -1, 0); return -2;
if (X509_check_purpose((X509 *)b, -1, 0) != 1)
return -2;
rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
if (rv) if (rv)
......
/* /*
* 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * 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) ...@@ -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) static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
{ {
/* Call for side-effect of computing hash and caching extensions */ /* Call for side-effect of computing hash and caching extensions */
X509_check_purpose(x, -1, 0); if (X509_check_purpose(x, -1, 0) != 1)
if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && x->ex_flags & EXFLAG_SS) return X509_TRUST_UNTRUSTED;
if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && (x->ex_flags & EXFLAG_SS))
return X509_TRUST_TRUSTED; return X509_TRUST_TRUSTED;
else else
return X509_TRUST_UNTRUSTED; return X509_TRUST_UNTRUSTED;
......
/* /*
* 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * 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) ...@@ -107,12 +107,8 @@ static int null_callback(int ok, X509_STORE_CTX *e)
/* Return 1 is a certificate is self signed */ /* Return 1 is a certificate is self signed */
static int cert_self_signed(X509 *x) static int cert_self_signed(X509 *x)
{ {
/* if (X509_check_purpose(x, -1, 0) != 1)
* FIXME: x509v3_cache_extensions() needs to detect more failures and not return 0;
* set EXFLAG_SET when that happens. Especially, if the failures are
* parse errors, rather than memory pressure!
*/
X509_check_purpose(x, -1, 0);
if (x->ex_flags & EXFLAG_SS) if (x->ex_flags & EXFLAG_SS)
return 1; return 1;
else else
......
/* /*
* 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
...@@ -362,7 +362,8 @@ int X509_pubkey_digest(const X509 *data, const EVP_MD *type, ...@@ -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, int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
unsigned int *len) 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. */ /* Asking for SHA1 and we already computed it. */
if (len != NULL) if (len != NULL)
*len = sizeof(data->sha1_hash); *len = sizeof(data->sha1_hash);
...@@ -376,7 +377,8 @@ int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, ...@@ -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, int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
unsigned char *md, unsigned int *len) 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. */ /* Asking for SHA1; always computed in CRL d2i. */
if (len != NULL) if (len != NULL)
*len = sizeof(data->sha1_hash); *len = sizeof(data->sha1_hash);
......
/* /*
* 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
static int X509_REVOKED_cmp(const X509_REVOKED *const *a, static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
const X509_REVOKED *const *b); 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_SEQUENCE(X509_REVOKED) = {
ASN1_EMBED(X509_REVOKED,serialNumber, ASN1_INTEGER), ASN1_EMBED(X509_REVOKED,serialNumber, ASN1_INTEGER),
...@@ -155,7 +155,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ...@@ -155,7 +155,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
X509_CRL *crl = (X509_CRL *)*pval; X509_CRL *crl = (X509_CRL *)*pval;
STACK_OF(X509_EXTENSION) *exts; STACK_OF(X509_EXTENSION) *exts;
X509_EXTENSION *ext; X509_EXTENSION *ext;
int idx; int idx, i;
switch (operation) { switch (operation) {
case ASN1_OP_D2I_PRE: case ASN1_OP_D2I_PRE:
...@@ -184,23 +184,35 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ...@@ -184,23 +184,35 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
break; break;
case ASN1_OP_D2I_POST: 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, crl->idp = X509_CRL_get_ext_d2i(crl,
NID_issuing_distribution_point, NULL, NID_issuing_distribution_point, &i,
NULL); NULL);
if (crl->idp) if (crl->idp != NULL) {
setup_idp(crl, crl->idp); 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, crl->akid = X509_CRL_get_ext_d2i(crl,
NID_authority_key_identifier, NULL, NID_authority_key_identifier, &i,
NULL); NULL);
if (crl->akid == NULL && i != -1)
crl->flags |= EXFLAG_INVALID;
crl->crl_number = X509_CRL_get_ext_d2i(crl, 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, crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
NID_delta_crl, NULL, NID_delta_crl, &i,
NULL); NULL);
if (crl->base_crl_number == NULL && i != -1)
crl->flags |= EXFLAG_INVALID;
/* Delta CRLs must have CRL number */ /* Delta CRLs must have CRL number */
if (crl->base_crl_number && !crl->crl_number) if (crl->base_crl_number && !crl->crl_number)
crl->flags |= EXFLAG_INVALID; crl->flags |= EXFLAG_INVALID;
...@@ -259,9 +271,10 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ...@@ -259,9 +271,10 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
/* Convert IDP into a more convenient form */ /* 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; int idp_only = 0;
/* Set various flags according to IDP */ /* Set various flags according to IDP */
crl->idp_flags |= IDP_PRESENT; crl->idp_flags |= IDP_PRESENT;
if (idp->onlyuser > 0) { if (idp->onlyuser > 0) {
...@@ -292,7 +305,7 @@ static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) ...@@ -292,7 +305,7 @@ static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
crl->idp_reasons &= CRLDP_ALL_REASONS; 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) = { ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
......
/* /*
* Copyright 1999-2019 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * 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) ...@@ -81,6 +81,8 @@ int X509_check_purpose(X509 *x, int id, int ca)
const X509_PURPOSE *pt; const X509_PURPOSE *pt;
x509v3_cache_extensions(x); x509v3_cache_extensions(x);
if (x->ex_flags & EXFLAG_INVALID)
return -1;
/* Return if side-effect only call */ /* Return if side-effect only call */
if (id == -1) if (id == -1)
...@@ -300,10 +302,11 @@ int X509_supported_extension(X509_EXTENSION *ex) ...@@ -300,10 +302,11 @@ int X509_supported_extension(X509_EXTENSION *ex)
return 0; return 0;
} }
static void setup_dp(X509 *x, DIST_POINT *dp) static int setup_dp(X509 *x, DIST_POINT *dp)
{ {
X509_NAME *iname = NULL; X509_NAME *iname = NULL;
int i; int i;
if (dp->reasons) { if (dp->reasons) {
if (dp->reasons->length > 0) if (dp->reasons->length > 0)
dp->dp_reasons = dp->reasons->data[0]; dp->dp_reasons = dp->reasons->data[0];
...@@ -313,7 +316,7 @@ static void setup_dp(X509 *x, DIST_POINT *dp) ...@@ -313,7 +316,7 @@ static void setup_dp(X509 *x, DIST_POINT *dp)
} else } else
dp->dp_reasons = CRLDP_ALL_REASONS; dp->dp_reasons = CRLDP_ALL_REASONS;
if (!dp->distpoint || (dp->distpoint->type != 1)) if (!dp->distpoint || (dp->distpoint->type != 1))
return; return 1;
for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
if (gen->type == GEN_DIRNAME) { if (gen->type == GEN_DIRNAME) {
...@@ -324,16 +327,21 @@ static void setup_dp(X509 *x, DIST_POINT *dp) ...@@ -324,16 +327,21 @@ static void setup_dp(X509 *x, DIST_POINT *dp)
if (!iname) if (!iname)
iname = X509_get_issuer_name(x); 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; 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++) x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL);
setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); 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) #define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
...@@ -366,12 +374,13 @@ static void x509v3_cache_extensions(X509 *x) ...@@ -366,12 +374,13 @@ static void x509v3_cache_extensions(X509 *x)
return; 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 ... */ /* V1 should mean no extensions ... */
if (!X509_get_version(x)) if (!X509_get_version(x))
x->ex_flags |= EXFLAG_V1; x->ex_flags |= EXFLAG_V1;
/* Handle basic constraints */ /* 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) if (bs->ca)
x->ex_flags |= EXFLAG_CA; x->ex_flags |= EXFLAG_CA;
if (bs->pathlen) { if (bs->pathlen) {
...@@ -385,9 +394,11 @@ static void x509v3_cache_extensions(X509 *x) ...@@ -385,9 +394,11 @@ static void x509v3_cache_extensions(X509 *x)
x->ex_pathlen = -1; x->ex_pathlen = -1;
BASIC_CONSTRAINTS_free(bs); BASIC_CONSTRAINTS_free(bs);
x->ex_flags |= EXFLAG_BCONS; x->ex_flags |= EXFLAG_BCONS;
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
} }
/* Handle proxy certificates */ /* 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 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_subject_alt_name, -1) >= 0
|| X509_get_ext_by_NID(x, NID_issuer_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) ...@@ -399,9 +410,11 @@ static void x509v3_cache_extensions(X509 *x)
x->ex_pcpathlen = -1; x->ex_pcpathlen = -1;
PROXY_CERT_INFO_EXTENSION_free(pci); PROXY_CERT_INFO_EXTENSION_free(pci);
x->ex_flags |= EXFLAG_PROXY; x->ex_flags |= EXFLAG_PROXY;
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
} }
/* Handle key usage */ /* 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) { if (usage->length > 0) {
x->ex_kusage = usage->data[0]; x->ex_kusage = usage->data[0];
if (usage->length > 1) if (usage->length > 1)
...@@ -410,9 +423,11 @@ static void x509v3_cache_extensions(X509 *x) ...@@ -410,9 +423,11 @@ static void x509v3_cache_extensions(X509 *x)
x->ex_kusage = 0; x->ex_kusage = 0;
x->ex_flags |= EXFLAG_KUSAGE; x->ex_flags |= EXFLAG_KUSAGE;
ASN1_BIT_STRING_free(usage); ASN1_BIT_STRING_free(usage);
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
} }
x->ex_xkusage = 0; 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; x->ex_flags |= EXFLAG_XKUSAGE;
for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
...@@ -455,18 +470,26 @@ static void x509v3_cache_extensions(X509 *x) ...@@ -455,18 +470,26 @@ static void x509v3_cache_extensions(X509 *x)
} }
} }
sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); 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) if (ns->length > 0)
x->ex_nscert = ns->data[0]; x->ex_nscert = ns->data[0];
else else
x->ex_nscert = 0; x->ex_nscert = 0;
x->ex_flags |= EXFLAG_NSCERT; x->ex_flags |= EXFLAG_NSCERT;
ASN1_BIT_STRING_free(ns); 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->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &i, NULL);
x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, 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 ? */ /* Does subject name match issuer ? */
if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
x->ex_flags |= EXFLAG_SI; x->ex_flags |= EXFLAG_SI;
...@@ -475,16 +498,22 @@ static void x509v3_cache_extensions(X509 *x) ...@@ -475,16 +498,22 @@ static void x509v3_cache_extensions(X509 *x)
!ku_reject(x, KU_KEY_CERT_SIGN)) !ku_reject(x, KU_KEY_CERT_SIGN))
x->ex_flags |= EXFLAG_SS; 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); 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; x->ex_flags |= EXFLAG_INVALID;
setup_crldp(x);
#ifndef OPENSSL_NO_RFC3779 #ifndef OPENSSL_NO_RFC3779
x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL);
x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, if (x->rfc3779_addr == NULL && i != -1)
NULL, NULL); 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 #endif
for (i = 0; i < X509_get_ext_count(x); i++) { for (i = 0; i < X509_get_ext_count(x); i++) {
ex = X509_get_ext(x, i); ex = X509_get_ext(x, i);
...@@ -777,7 +806,11 @@ int X509_check_issued(X509 *issuer, X509 *subject) ...@@ -777,7 +806,11 @@ int X509_check_issued(X509 *issuer, X509 *subject)
return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
x509v3_cache_extensions(issuer); x509v3_cache_extensions(issuer);
if (issuer->ex_flags & EXFLAG_INVALID)
return X509_V_ERR_UNSPECIFIED;
x509v3_cache_extensions(subject); x509v3_cache_extensions(subject);
if (subject->ex_flags & EXFLAG_INVALID)
return X509_V_ERR_UNSPECIFIED;
if (subject->akid) { if (subject->akid) {
int ret = X509_check_akid(issuer, subject->akid); int ret = X509_check_akid(issuer, subject->akid);
...@@ -842,7 +875,8 @@ uint32_t X509_get_extension_flags(X509 *x) ...@@ -842,7 +875,8 @@ uint32_t X509_get_extension_flags(X509 *x)
uint32_t X509_get_key_usage(X509 *x) uint32_t X509_get_key_usage(X509 *x)
{ {
/* Call for side-effect of computing hash and caching extensions */ /* 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) if (x->ex_flags & EXFLAG_KUSAGE)
return x->ex_kusage; return x->ex_kusage;
return UINT32_MAX; return UINT32_MAX;
...@@ -851,7 +885,8 @@ uint32_t X509_get_key_usage(X509 *x) ...@@ -851,7 +885,8 @@ uint32_t X509_get_key_usage(X509 *x)
uint32_t X509_get_extended_key_usage(X509 *x) uint32_t X509_get_extended_key_usage(X509 *x)
{ {
/* Call for side-effect of computing hash and caching extensions */ /* 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) if (x->ex_flags & EXFLAG_XKUSAGE)
return x->ex_xkusage; return x->ex_xkusage;
return UINT32_MAX; return UINT32_MAX;
...@@ -860,28 +895,32 @@ uint32_t X509_get_extended_key_usage(X509 *x) ...@@ -860,28 +895,32 @@ uint32_t X509_get_extended_key_usage(X509 *x)
const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x) const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x)
{ {
/* Call for side-effect of computing hash and caching extensions */ /* 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; return x->skid;
} }
const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x) const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x)
{ {
/* Call for side-effect of computing hash and caching extensions */ /* 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); return (x->akid != NULL ? x->akid->keyid : NULL);
} }
const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x) const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x)
{ {
/* Call for side-effect of computing hash and caching extensions */ /* 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); return (x->akid != NULL ? x->akid->issuer : NULL);
} }
const ASN1_INTEGER *X509_get0_authority_serial(X509 *x) const ASN1_INTEGER *X509_get0_authority_serial(X509 *x)
{ {
/* Call for side-effect of computing hash and caching extensions */ /* 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); return (x->akid != NULL ? x->akid->serial : NULL);
} }
......
...@@ -80,6 +80,17 @@ The certificate contains an unhandled critical extension. ...@@ -80,6 +80,17 @@ The certificate contains an unhandled critical extension.
Some certificate extension values are invalid or inconsistent. The Some certificate extension values are invalid or inconsistent. The
certificate should be rejected. 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> =item B<EXFLAG_KUSAGE>
...@@ -183,7 +194,7 @@ X509_get_proxy_pathlen() were added in OpenSSL 1.1.0. ...@@ -183,7 +194,7 @@ X509_get_proxy_pathlen() were added in OpenSSL 1.1.0.
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved. Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy this file except in compliance with the License. You can obtain a copy
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册