Latest update.

This commit is contained in:
2020-04-15 18:45:34 +09:00
parent be29e7bcc6
commit 2015c00c43
573 changed files with 22943 additions and 6714 deletions
+91 -44
View File
@@ -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
@@ -15,8 +15,6 @@
#include "crypto/x509.h"
#include "internal/tsan_assist.h"
static void x509v3_cache_extensions(X509 *x);
static int check_ssl_ca(const X509 *x);
static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
int ca);
@@ -80,7 +78,8 @@ int X509_check_purpose(X509 *x, int id, int ca)
int idx;
const X509_PURPOSE *pt;
x509v3_cache_extensions(x);
if (!X509v3_cache_extensions(x, NULL, NULL))
return -1;
/* Return if side-effect only call */
if (id == -1)
@@ -300,10 +299,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;
const X509_NAME *iname = NULL;
int i;
if (dp->reasons) {
if (dp->reasons->length > 0)
dp->dp_reasons = dp->reasons->data[0];
@@ -313,7 +313,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 +324,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)
@@ -344,7 +349,7 @@ static void setup_crldp(X509 *x)
#define ns_reject(x, usage) \
(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
static void x509v3_cache_extensions(X509 *x)
int X509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq)
{
BASIC_CONSTRAINTS *bs;
PROXY_CERT_INFO_EXTENSION *pci;
@@ -353,41 +358,52 @@ static void x509v3_cache_extensions(X509 *x)
EXTENDED_KEY_USAGE *extusage;
X509_EXTENSION *ex;
int i;
EVP_MD *sha1;
#ifdef tsan_ld_acq
/* fast lock-free check, see end of the function for details. */
if (tsan_ld_acq((TSAN_QUALIFIER int *)&x->ex_cached))
return;
return (x->ex_flags & EXFLAG_INVALID) == 0;
#endif
CRYPTO_THREAD_write_lock(x->lock);
if (x->ex_flags & EXFLAG_SET) {
CRYPTO_THREAD_unlock(x->lock);
return;
return (x->ex_flags & EXFLAG_INVALID) == 0;
}
X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
sha1 = EVP_MD_fetch(libctx, "SHA1", propq);
if (sha1 == NULL || !X509_digest(x, sha1, x->sha1_hash, NULL))
x->ex_flags |= EXFLAG_INVALID;
EVP_MD_free(sha1);
/* 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) {
if ((bs->pathlen->type == V_ASN1_NEG_INTEGER)
|| !bs->ca) {
if (bs->pathlen->type == V_ASN1_NEG_INTEGER) {
x->ex_flags |= EXFLAG_INVALID;
x->ex_pathlen = 0;
} else
} 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;
} 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 +415,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 +428,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 +475,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 +503,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->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
if (!x->nc && (i != -1))
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 == 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);
@@ -509,6 +543,8 @@ static void x509v3_cache_extensions(X509 *x)
*/
#endif
CRYPTO_THREAD_unlock(x->lock);
return (x->ex_flags & EXFLAG_INVALID) == 0;
}
/*-
@@ -516,9 +552,11 @@ static void x509v3_cache_extensions(X509 *x)
* return codes:
* 0 not a CA
* 1 is a CA
* 2 basicConstraints absent so "maybe" a CA
* 2 Only possible in older versions of openSSL when basicConstraints are absent
* new versions will not return this value. May be a CA
* 3 basicConstraints absent but self signed V1.
* 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
* 5 Netscape specific CA Flags present
*/
static int check_ca(const X509 *x)
@@ -561,7 +599,9 @@ void X509_set_proxy_pathlen(X509 *x, long l)
int X509_check_ca(X509 *x)
{
x509v3_cache_extensions(x);
/* Note 0 normally means "not a CA" - but in this case means error. */
if (!X509v3_cache_extensions(x, NULL, NULL))
return 0;
return check_ca(x);
}
@@ -777,8 +817,9 @@ int X509_check_issued(X509 *issuer, X509 *subject)
X509_get_issuer_name(subject)))
return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
x509v3_cache_extensions(issuer);
x509v3_cache_extensions(subject);
if (!X509v3_cache_extensions(issuer, NULL, NULL)
|| !X509v3_cache_extensions(subject, NULL, NULL))
return X509_V_ERR_UNSPECIFIED;
if (subject->akid) {
int ret = X509_check_akid(issuer, subject->akid);
@@ -861,7 +902,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 +912,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 +922,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);
}