add various checks for malformedness to static check_chain_extensions() in x509_vfc.c
improve error reporting of X509v3_cache_extensions() in v3_purp.c
add error reporting to x509_init_sig_info() in x509_set.c
improve static setup_dp() and related functions in v3_purp.c and v3_crld.c
add test case for non-conforming cert from https://tools.ietf.org/html/rfc8410#section-10.2
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12478)
X509V3_R_DIRNAME_ERROR:149:dirname error
X509V3_R_DISTPOINT_ALREADY_SET:160:distpoint already set
X509V3_R_DUPLICATE_ZONE_ID:133:duplicate zone id
+X509V3_R_EMPTY_KEY_USAGE:169:empty key usage
X509V3_R_ERROR_CONVERTING_ZONE:131:error converting zone
X509V3_R_ERROR_CREATING_EXTENSION:144:error creating extension
X509V3_R_ERROR_IN_EXTENSION:128:error in extension
X509V3_R_INVALID_ASNUMBER:162:invalid asnumber
X509V3_R_INVALID_ASRANGE:163:invalid asrange
X509V3_R_INVALID_BOOLEAN_STRING:104:invalid boolean string
+X509V3_R_INVALID_CERTIFICATE:158:invalid certificate
X509V3_R_INVALID_EMPTY_NAME:108:invalid empty name
X509V3_R_INVALID_EXTENSION_STRING:105:invalid extension string
X509V3_R_INVALID_INHERITANCE:165:invalid inheritance
X509V3_R_ISSUER_DECODE_ERROR:126:issuer decode error
X509V3_R_MISSING_VALUE:124:missing value
X509V3_R_NEED_ORGANIZATION_AND_NUMBERS:142:need organization and numbers
+X509V3_R_NEGATIVE_PATHLEN:168:negative pathlen
X509V3_R_NO_CONFIG_DATABASE:136:no config database
X509V3_R_NO_ISSUER_CERTIFICATE:121:no issuer certificate
X509V3_R_NO_ISSUER_DETAILS:127:no issuer details
X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table
X509_R_CRL_ALREADY_DELTA:127:crl already delta
X509_R_CRL_VERIFY_FAILURE:131:crl verify failure
+X509_R_ERROR_GETTING_MD_BY_NID:141:error getting md by nid
+X509_R_ERROR_USING_SIGINF_SET:142:error using siginf set
X509_R_IDP_MISMATCH:128:idp mismatch
X509_R_INVALID_ATTRIBUTES:138:invalid attributes
X509_R_INVALID_DIRECTORY:113:invalid directory
+X509_R_INVALID_DISTPOINT:143:invalid distpoint
X509_R_INVALID_FIELD_NAME:119:invalid field name
X509_R_INVALID_TRUST:123:invalid trust
X509_R_ISSUER_MISMATCH:129:issuer mismatch
X509_R_UNKNOWN_KEY_TYPE:117:unknown key type
X509_R_UNKNOWN_NID:109:unknown nid
X509_R_UNKNOWN_PURPOSE_ID:121:unknown purpose id
+X509_R_UNKNOWN_SIGID_ALGS:144:unknown sigid algs
X509_R_UNKNOWN_TRUST_ID:120:unknown trust id
X509_R_UNSUPPORTED_ALGORITHM:111:unsupported algorithm
X509_R_WRONG_LOOKUP_TYPE:112:wrong lookup type
return 1;
}
+/* Append any nameRelativeToCRLIssuer in dpn to iname, set in dpn->dpname */
int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname)
{
int i;
STACK_OF(X509_NAME_ENTRY) *frag;
X509_NAME_ENTRY *ne;
- if (!dpn || (dpn->type != 1))
+
+ if (dpn == NULL || dpn->type != 1)
return 1;
frag = dpn->name.relativename;
+ X509_NAME_free(dpn->dpname); /* just in case it was already set */
dpn->dpname = X509_NAME_dup(iname);
- if (!dpn->dpname)
+ if (dpn->dpname == NULL)
return 0;
for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
ne = sk_X509_NAME_ENTRY_value(frag, i);
- if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
- X509_NAME_free(dpn->dpname);
- dpn->dpname = NULL;
- return 0;
- }
+ if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
+ goto err;
}
/* generate cached encoding of name */
- if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
- X509_NAME_free(dpn->dpname);
- dpn->dpname = NULL;
- return 0;
- }
- return 1;
+ if (i2d_X509_NAME(dpn->dpname, NULL) >= 0)
+ return 1;
+
+ err:
+ X509_NAME_free(dpn->dpname);
+ dpn->dpname = NULL;
+ return 0;
}
return 0;
}
-static int setup_dp(X509 *x, DIST_POINT *dp)
+/* return 1 on success, 0 if x is invalid, -1 on (internal) error */
+static int setup_dp(const X509 *x, DIST_POINT *dp)
{
const X509_NAME *iname = NULL;
int i;
- if (dp->reasons) {
+ if (dp->distpoint == NULL && sk_GENERAL_NAME_num(dp->CRLissuer) <= 0) {
+ X509err(0, X509_R_INVALID_DISTPOINT);
+ return 0;
+ }
+ if (dp->reasons != NULL) {
if (dp->reasons->length > 0)
dp->dp_reasons = dp->reasons->data[0];
if (dp->reasons->length > 1)
dp->dp_reasons |= (dp->reasons->data[1] << 8);
dp->dp_reasons &= CRLDP_ALL_REASONS;
- } else
+ } else {
dp->dp_reasons = CRLDP_ALL_REASONS;
- if (!dp->distpoint || (dp->distpoint->type != 1))
+ }
+ if (dp->distpoint == NULL || dp->distpoint->type != 1)
return 1;
+
+ /* handle name fragment given by nameRelativeToCRLIssuer */
+ /*
+ * Note that the below way of determining iname is not really compliant
+ * with https://tools.ietf.org/html/rfc5280#section-4.2.1.13
+ * According to it, sk_GENERAL_NAME_num(dp->CRLissuer) MUST be <= 1
+ * and any CRLissuer could be of type different to GEN_DIRNAME.
+ */
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) {
iname = gen->d.directoryName;
break;
}
}
- if (!iname)
+ if (iname == NULL)
iname = X509_get_issuer_name(x);
-
- return DIST_POINT_set_dpname(dp->distpoint, iname);
+ return DIST_POINT_set_dpname(dp->distpoint, iname) ? 1 : -1;
}
+/* return 1 on success, 0 if x is invalid, -1 on (internal) error */
static int setup_crldp(X509 *x)
{
int 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;
+ int res = setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
+
+ if (res < 1)
+ return res;
}
return 1;
}
/*
* Cache info on various X.509v3 extensions and further derived information,
* e.g., if cert 'x' is self-issued, in x->ex_flags and other internal fields.
+ * X509_SIG_INFO_VALID is set in x->flags if x->siginf was filled successfully.
* Set EXFLAG_INVALID and return 0 in case the certificate is invalid.
*/
int x509v3_cache_extensions(X509 *x)
EXTENDED_KEY_USAGE *extusage;
X509_EXTENSION *ex;
int i;
+ int res;
#ifdef tsan_ld_acq
/* fast lock-free check, see end of the function for details. */
}
ERR_set_mark();
+ /* Cache the SHA1 digest of the cert */
if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL))
- x->ex_flags |= EXFLAG_INVALID;
+ /*
+ * Note that the cert is marked invalid also on internal malloc failure
+ * or on failure of EVP_MD_fetch(), potentially called by X509_digest().
+ */
+ x->ex_flags |= EXFLAG_INVALID;
/* V1 should mean no extensions ... */
if (X509_get_version(x) == 0)
x->ex_flags |= EXFLAG_V1;
/* Handle basic constraints */
+ x->ex_pathlen = -1;
if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL)) != NULL) {
if (bs->ca)
x->ex_flags |= EXFLAG_CA;
if (bs->pathlen != NULL) {
+ /*
+ * the error case !bs->ca is checked by check_chain_extensions()
+ * in case ctx->param->flags & X509_V_FLAG_X509_STRICT
+ */
if (bs->pathlen->type == V_ASN1_NEG_INTEGER) {
+ X509err(0, X509V3_R_NEGATIVE_PATHLEN);
x->ex_flags |= EXFLAG_INVALID;
- x->ex_pathlen = 0;
} 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;
|| X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
x->ex_flags |= EXFLAG_INVALID;
}
- if (pci->pcPathLengthConstraint) {
+ if (pci->pcPathLengthConstraint != NULL)
x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
- } else
+ else
x->ex_pcpathlen = -1;
PROXY_CERT_INFO_EXTENSION_free(pci);
x->ex_flags |= EXFLAG_PROXY;
x->ex_flags |= EXFLAG_INVALID;
}
- /* Handle (basic and extended) key usage */
+ /* Handle basic key usage */
if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL)) != NULL) {
x->ex_kusage = 0;
if (usage->length > 0) {
}
x->ex_flags |= EXFLAG_KUSAGE;
ASN1_BIT_STRING_free(usage);
+ /* Check for empty key usage according to RFC 5280 section 4.2.1.3 */
+ if (x->ex_kusage == 0) {
+ X509err(0, X509V3_R_EMPTY_KEY_USAGE);
+ x->ex_flags |= EXFLAG_INVALID;
+ }
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
}
+
+ /* Handle extended key usage */
x->ex_xkusage = 0;
if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL)) != NULL) {
x->ex_flags |= EXFLAG_XKUSAGE;
x->ex_xkusage |= XKU_ANYEKU;
break;
default:
+ /* ignore unknown extended key usage */
break;
}
}
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;
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))
+
+ /* Handle CRL distribution point entries */
+ res = setup_crldp(x);
+ if (res == 0)
x->ex_flags |= EXFLAG_INVALID;
+ else if (res < 0)
+ goto err;
#ifndef OPENSSL_NO_RFC3779
x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL);
#endif
for (i = 0; i < X509_get_ext_count(x); i++) {
ex = X509_get_ext(x, i);
- if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
- == NID_freshest_crl)
+ if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_freshest_crl)
x->ex_flags |= EXFLAG_FRESHEST;
if (!X509_EXTENSION_get_critical(ex))
continue;
}
}
- x509_init_sig_info(x);
+ /* Set x->siginf, ignoring errors due to unsupported algos */
+ (void)x509_init_sig_info(x);
x->ex_flags |= EXFLAG_SET; /* indicate that cert has been processed */
#ifdef tsan_st_rel
*/
#endif
ERR_pop_to_mark();
- CRYPTO_THREAD_unlock(x->lock);
+ if ((x->ex_flags & EXFLAG_INVALID) == 0) {
+ CRYPTO_THREAD_unlock(x->lock);
+ return 1;
+ }
+ X509err(0, X509V3_R_INVALID_CERTIFICATE);
- return (x->ex_flags & EXFLAG_INVALID) == 0;
+ err:
+ x->ex_flags |= EXFLAG_SET; /* indicate that cert has been processed */
+ CRYPTO_THREAD_unlock(x->lock);
+ return 0;
}
/*-
"distpoint already set"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_DUPLICATE_ZONE_ID),
"duplicate zone id"},
+ {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EMPTY_KEY_USAGE), "empty key usage"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CONVERTING_ZONE),
"error converting zone"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CREATING_EXTENSION),
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_ASRANGE), "invalid asrange"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_BOOLEAN_STRING),
"invalid boolean string"},
+ {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_CERTIFICATE),
+ "invalid certificate"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_EXTENSION_STRING),
"invalid extension string"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_INHERITANCE),
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_MISSING_VALUE), "missing value"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS),
"need organization and numbers"},
+ {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEGATIVE_PATHLEN),
+ "negative pathlen"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_CONFIG_DATABASE),
"no config database"},
{ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_ISSUER_CERTIFICATE),
{ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE),
"crl verify failure"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_GETTING_MD_BY_NID),
+ "error getting md by nid"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_USING_SIGINF_SET),
+ "error using siginf set"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_IDP_MISMATCH), "idp mismatch"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_ATTRIBUTES),
"invalid attributes"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DIRECTORY), "invalid directory"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DISTPOINT), "invalid distpoint"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_FIELD_NAME),
"invalid field name"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_TRUST), "invalid trust"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_NID), "unknown nid"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_PURPOSE_ID),
"unknown purpose id"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_SIGID_ALGS),
+ "unknown sigid algs"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_TRUST_ID), "unknown trust id"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_UNSUPPORTED_ALGORITHM),
"unsupported algorithm"},
return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags);
}
-static void x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
- const ASN1_STRING *sig)
+/* Modify *siginf according to alg and sig. Return 1 on success, else 0. */
+static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
+ const ASN1_STRING *sig)
{
int pknid, mdnid;
const EVP_MD *md;
+ const EVP_PKEY_ASN1_METHOD *ameth;
siginf->mdnid = NID_undef;
siginf->pknid = NID_undef;
siginf->secbits = -1;
siginf->flags = 0;
if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)
- || pknid == NID_undef)
- return;
+ || pknid == NID_undef) {
+ X509err(0, X509_R_UNKNOWN_SIGID_ALGS);
+ return 0;
+ }
+ siginf->mdnid = mdnid;
siginf->pknid = pknid;
- if (mdnid == NID_undef) {
+
+ switch (mdnid) {
+ case NID_undef:
/* If we have one, use a custom handler for this algorithm */
- const EVP_PKEY_ASN1_METHOD *ameth = EVP_PKEY_asn1_find(NULL, pknid);
+ ameth = EVP_PKEY_asn1_find(NULL, pknid);
if (ameth == NULL || ameth->siginf_set == NULL
- || ameth->siginf_set(siginf, alg, sig) == 0)
- return;
- siginf->flags |= X509_SIG_INFO_VALID;
- return;
- }
- siginf->flags |= X509_SIG_INFO_VALID;
- siginf->mdnid = mdnid;
- md = EVP_get_digestbynid(mdnid);
- if (md == NULL)
- return;
- /* Security bits: half number of bits in digest */
- siginf->secbits = EVP_MD_size(md) * 4;
- /*
- * SHA1 and MD5 are known to be broken. Reduce security bits so that
- * they're no longer accepted at security level 1. The real values don't
- * really matter as long as they're lower than 80, which is our security
- * level 1.
- * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for SHA1 at
- * 2^63.4
- * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf
- * puts a chosen-prefix attack for MD5 at 2^39.
- */
- if (mdnid == NID_sha1)
+ || !ameth->siginf_set(siginf, alg, sig)) {
+ X509err(0, X509_R_ERROR_USING_SIGINF_SET);
+ return 0;
+ }
+ break;
+ /*
+ * SHA1 and MD5 are known to be broken. Reduce security bits so that
+ * they're no longer accepted at security level 1.
+ * The real values don't really matter as long as they're lower than 80,
+ * which is our security level 1.
+ */
+ case NID_sha1:
+ /*
+ * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack
+ * for SHA1 at2^63.4
+ */
siginf->secbits = 63;
- else if (mdnid == NID_md5)
+ break;
+ case NID_md5:
+ /*
+ * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf
+ * puts a chosen-prefix attack for MD5 at 2^39.
+ */
siginf->secbits = 39;
+ break;
+ case NID_id_GostR3411_94:
+ /*
+ * There is a collision attack on GOST R 34.11-94 at 2^105, see
+ * https://link.springer.com/chapter/10.1007%2F978-3-540-85174-5_10
+ */
+ siginf->secbits = 105;
+ break;
+ default:
+ /* Security bits: half number of bits in digest */
+ if ((md = EVP_get_digestbynid(mdnid)) == NULL) {
+ X509err(0, X509_R_ERROR_GETTING_MD_BY_NID);
+ return 0;
+ }
+ siginf->secbits = EVP_MD_size(md) * 4;
+ break;
+ }
switch (mdnid) {
- case NID_sha1:
- case NID_sha256:
- case NID_sha384:
- case NID_sha512:
+ case NID_sha1:
+ case NID_sha256:
+ case NID_sha384:
+ case NID_sha512:
siginf->flags |= X509_SIG_INFO_TLS;
}
+ siginf->flags |= X509_SIG_INFO_VALID;
+ return 1;
}
-void x509_init_sig_info(X509 *x)
+/* Returns 1 on success, 0 on failure */
+int x509_init_sig_info(X509 *x)
{
- x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
+ return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
}
return "certificate chain too long";
case X509_V_ERR_CERT_REVOKED:
return "certificate revoked";
- case X509_V_ERR_INVALID_CA:
- return "invalid CA certificate";
+ case X509_V_ERR_NO_ISSUER_PUBLIC_KEY:
+ return "issuer certificate doesn't have a public key";
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
return "path length constraint exceeded";
case X509_V_ERR_INVALID_PURPOSE:
return "OCSP verification failed";
case X509_V_ERR_OCSP_CERT_UNKNOWN:
return "OCSP unknown cert";
- case X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH:
- return "subject signature algorithm and issuer public key algorithm mismatch";
- case X509_V_ERR_NO_ISSUER_PUBLIC_KEY:
- return "issuer certificate doesn't have a public key";
case X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM:
return "Cannot find certificate signature algorithm";
+ case X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH:
+ return "subject signature algorithm and issuer public key algorithm mismatch";
+ case X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY:
+ return "cert info siganature and signature algorithm mismatch";
+ case X509_V_ERR_INVALID_CA:
+ return "invalid CA certificate";
+ case X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA:
+ return "Path length invalid for non-CA cert";
+ case X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN:
+ return "Path length given without key usage keyCertSign";
+ case X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA:
+ return "Key usage keyCertSign invalid for non-CA cert";
+ case X509_V_ERR_ISSUER_NAME_EMPTY:
+ return "Issuer name empty";
+ case X509_V_ERR_SUBJECT_NAME_EMPTY:
+ return "Subject name empty";
+ case X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER:
+ return "Missing Authority Key Identifier";
+ case X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER:
+ return "Missing Subject Key Identifier";
+ case X509_V_ERR_EMPTY_SUBJECT_ALT_NAME:
+ return "Empty Subject Alternative Name extension";
default:
/* Printing an error number into a static buffer is not thread-safe */
for (i = 0; i < num; i++) {
int ret;
+
x = sk_X509_value(ctx->chain, i);
if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
&& (x->ex_flags & EXFLAG_CRITICAL)) {
ret = 1;
break;
}
- if ((x->ex_flags & EXFLAG_CA) == 0
- && x->ex_pathlen != -1
- && (ctx->param->flags & X509_V_FLAG_X509_STRICT)) {
- ctx->error = X509_V_ERR_INVALID_EXTENSION;
- ret = 0;
+ if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) != 0) {
+ /* Check Basic Constraints according to RFC 5280 section 4.2.1.9 */
+ if (x->ex_pathlen != -1) {
+ if ((x->ex_flags & EXFLAG_CA) == 0)
+ ctx->error = X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA;
+ if ((x->ex_kusage & KU_KEY_CERT_SIGN) == 0)
+ ctx->error = X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN;
+ }
+ /* TODO check basic constrains of CA cert are marked critical */
+ /* Check keyCertSign according to RFC 5280 section 4.2.1.3 */
+ if ((x->ex_flags & EXFLAG_CA) == 0
+ && (x->ex_kusage & KU_KEY_CERT_SIGN) != 0)
+ ctx->error = X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA;
+ /* Check issuer is non-empty acc. to RFC 5280 section 4.1.2.4 */
+ if (X509_NAME_entry_count(X509_get_issuer_name(x)) == 0)
+ ctx->error = X509_V_ERR_ISSUER_NAME_EMPTY;
+ /* Check subject is non-empty acc. to RFC 5280 section 4.1.2.6 */
+ if (((x->ex_flags & EXFLAG_CA) != 0
+ || (x->ex_kusage & KU_CRL_SIGN) != 0
+ || x->altname == NULL
+ ) && X509_NAME_entry_count(X509_get_subject_name(x)) == 0)
+ ctx->error = X509_V_ERR_SUBJECT_NAME_EMPTY;
+ /*
+ * TODO check: If subject naming information is present only in
+ * the subjectAltName extension,
+ * then the subject name MUST be an empty sequence
+ * and the subjectAltName extension MUST be critical.
+ */
+ /* Check SAN is non-empty according to RFC 5280 section 4.2.1.6 */
+ if (x->altname != NULL && sk_GENERAL_NAME_num(x->altname) <= 0)
+ ctx->error = X509_V_ERR_EMPTY_SUBJECT_ALT_NAME;
+ /* TODO add more checks on SAN entries */
+ /* Check sig alg consistency acc. to RFC 5280 section 4.1.1.2 */
+ if (X509_ALGOR_cmp(&x->sig_alg, &x->cert_info.signature) != 0)
+ ctx->error = X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY;
+ if (X509_get_version(x) >= 2) { /* at least X.509v3 */
+ /* Check AKID presence acc. to RFC 5280 section 4.2.1.1 */
+ if (i + 1 < num /*
+ * this means not last cert in chain,
+ * taken as "generated by conforming CAs"
+ */
+ && (x->akid == NULL || x->akid->keyid == NULL))
+ ctx->error = X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER;
+ /* TODO check that AKID extension is not critical */
+ /* Check SKID presence acc. to RFC 5280 section 4.2.1.2 */
+ if ((x->ex_flags & EXFLAG_CA) != 0 && x->skid == NULL)
+ ctx->error = X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER;
+ /* TODO check that SKID extension is not be critical */
+ }
}
+ if (ctx->error != X509_V_OK)
+ ret = 0;
if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK))
return 0;
/* check_purpose() makes the callback as needed */
--- /dev/null
+=pod
+
+=head1 NAME
+
+x509v3_cache_extensions
+- cache info on various X.509v3 extensions and further derived certificate data
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509v3.h>
+
+ int x509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq);
+
+=head1 DESCRIPTION
+
+This function processes any X509v3 extensions present in an X509 object I<x>
+and caches the result of that processing as well as further derived info,
+for instance whether the certificate is self-issued or has version X.509v1.
+It computes the SHA1 digest of the certificate using the default library context
+and property query string and stores the result in x->sha1_hash.
+It sets B<X509_SIG_INFO_VALID> in x->flags if x->siginf was filled successfully,
+which may not be possible if a referenced algorithm is unknown or not available.
+Many OpenSSL functions that use an X509 object call this function implicitly.
+
+=head1 RETURN VALUES
+
+This function returns 0 if the extensions or other portions of the certificate
+are invalid or an error occurred.
+Otherwise it returns 1.
+
+=head1 COPYRIGHT
+
+Copyright 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
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
=item B<-x509_strict>
This disables non-compliant workarounds for broken certificates.
+Thus errors are thrown on certificates not compliant with RFC 5280.
=item B<-ignore_critical>
int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm);
int x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags);
int x509v3_cache_extensions(X509 *x);
+int x509_init_sig_info(X509 *x);
+int x509_check_issued_int(X509 *issuer, X509 *subject, OPENSSL_CTX *libctx,
+ const char *propq);
+
int x509_set0_libctx(X509 *x, OPENSSL_CTX *libctx, const char *propq);
int x509_crl_set0_libctx(X509_CRL *x, OPENSSL_CTX *libctx, const char *propq);
-void x509_init_sig_info(X509 *x);
+int x509_init_sig_info(X509 *x);
int asn1_item_digest_with_libctx(const ASN1_ITEM *it, const EVP_MD *type,
void *data, unsigned char *md,
unsigned int *len, OPENSSL_CTX *libctx,
X509_LOOKUP_ctrl_with_libctx((x), X509_L_ADD_STORE, (name), 0, NULL, \
(libctx), (propq))
+# define X509_V_OK 0
+# define X509_V_ERR_UNSPECIFIED 1
+# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
+# define X509_V_ERR_UNABLE_TO_GET_CRL 3
+# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4
+# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5
+# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
+# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
+# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
+# define X509_V_ERR_CERT_NOT_YET_VALID 9
+# define X509_V_ERR_CERT_HAS_EXPIRED 10
+# define X509_V_ERR_CRL_NOT_YET_VALID 11
+# define X509_V_ERR_CRL_HAS_EXPIRED 12
+# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13
+# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14
+# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15
+# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16
+# define X509_V_ERR_OUT_OF_MEM 17
+# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
+# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
+# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
+# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
+# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
+# define X509_V_ERR_CERT_REVOKED 23
+# define X509_V_ERR_NO_ISSUER_PUBLIC_KEY 24
+# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
+# define X509_V_ERR_INVALID_PURPOSE 26
+# define X509_V_ERR_CERT_UNTRUSTED 27
+# define X509_V_ERR_CERT_REJECTED 28
-# define X509_V_OK 0
-# define X509_V_ERR_UNSPECIFIED 1
-# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
-# define X509_V_ERR_UNABLE_TO_GET_CRL 3
-# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4
-# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5
-# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
-# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
-# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
-# define X509_V_ERR_CERT_NOT_YET_VALID 9
-# define X509_V_ERR_CERT_HAS_EXPIRED 10
-# define X509_V_ERR_CRL_NOT_YET_VALID 11
-# define X509_V_ERR_CRL_HAS_EXPIRED 12
-# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13
-# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14
-# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15
-# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16
-# define X509_V_ERR_OUT_OF_MEM 17
-# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
-# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
-# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
-# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
-# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
-# define X509_V_ERR_CERT_REVOKED 23
-# define X509_V_ERR_INVALID_CA 24
-# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
-# define X509_V_ERR_INVALID_PURPOSE 26
-# define X509_V_ERR_CERT_UNTRUSTED 27
-# define X509_V_ERR_CERT_REJECTED 28
/* These are 'informational' when looking for issuer cert */
-# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29
-# define X509_V_ERR_AKID_SKID_MISMATCH 30
-# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31
-# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32
-# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33
-# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34
-# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35
-# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36
-# define X509_V_ERR_INVALID_NON_CA 37
-# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
-# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
-# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
-# define X509_V_ERR_INVALID_EXTENSION 41
-# define X509_V_ERR_INVALID_POLICY_EXTENSION 42
-# define X509_V_ERR_NO_EXPLICIT_POLICY 43
-# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
-# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
-# define X509_V_ERR_UNNESTED_RESOURCE 46
-# define X509_V_ERR_PERMITTED_VIOLATION 47
-# define X509_V_ERR_EXCLUDED_VIOLATION 48
-# define X509_V_ERR_SUBTREE_MINMAX 49
+# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29
+# define X509_V_ERR_AKID_SKID_MISMATCH 30
+# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31
+# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32
+# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33
+# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34
+# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35
+# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36
+# define X509_V_ERR_INVALID_NON_CA 37
+# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
+# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
+# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
+# define X509_V_ERR_INVALID_EXTENSION 41
+# define X509_V_ERR_INVALID_POLICY_EXTENSION 42
+# define X509_V_ERR_NO_EXPLICIT_POLICY 43
+# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
+# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
+# define X509_V_ERR_UNNESTED_RESOURCE 46
+# define X509_V_ERR_PERMITTED_VIOLATION 47
+# define X509_V_ERR_EXCLUDED_VIOLATION 48
+# define X509_V_ERR_SUBTREE_MINMAX 49
/* The application is not happy */
-# define X509_V_ERR_APPLICATION_VERIFICATION 50
-# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
-# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
-# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
-# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
+# define X509_V_ERR_APPLICATION_VERIFICATION 50
+# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
+# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
+# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
+# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
/* Another issuer check debug option */
-# define X509_V_ERR_PATH_LOOP 55
+# define X509_V_ERR_PATH_LOOP 55
/* Suite B mode algorithm violation */
-# define X509_V_ERR_SUITE_B_INVALID_VERSION 56
-# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57
-# define X509_V_ERR_SUITE_B_INVALID_CURVE 58
-# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59
-# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60
-# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+# define X509_V_ERR_SUITE_B_INVALID_VERSION 56
+# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57
+# define X509_V_ERR_SUITE_B_INVALID_CURVE 58
+# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59
+# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60
+# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
/* Host, email and IP check errors */
-# define X509_V_ERR_HOSTNAME_MISMATCH 62
-# define X509_V_ERR_EMAIL_MISMATCH 63
-# define X509_V_ERR_IP_ADDRESS_MISMATCH 64
+# define X509_V_ERR_HOSTNAME_MISMATCH 62
+# define X509_V_ERR_EMAIL_MISMATCH 63
+# define X509_V_ERR_IP_ADDRESS_MISMATCH 64
/* DANE TLSA errors */
-# define X509_V_ERR_DANE_NO_MATCH 65
+# define X509_V_ERR_DANE_NO_MATCH 65
/* security level errors */
-# define X509_V_ERR_EE_KEY_TOO_SMALL 66
-# define X509_V_ERR_CA_KEY_TOO_SMALL 67
-# define X509_V_ERR_CA_MD_TOO_WEAK 68
+# define X509_V_ERR_EE_KEY_TOO_SMALL 66
+# define X509_V_ERR_CA_KEY_TOO_SMALL 67
+# define X509_V_ERR_CA_MD_TOO_WEAK 68
/* Caller error */
-# define X509_V_ERR_INVALID_CALL 69
+# define X509_V_ERR_INVALID_CALL 69
/* Issuer lookup error */
-# define X509_V_ERR_STORE_LOOKUP 70
+# define X509_V_ERR_STORE_LOOKUP 70
/* Certificate transparency */
-# define X509_V_ERR_NO_VALID_SCTS 71
+# define X509_V_ERR_NO_VALID_SCTS 71
-# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72
+# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72
/* OCSP status errors */
-# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */
-# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */
-# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */
-
-# define X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH 76
-# define X509_V_ERR_NO_ISSUER_PUBLIC_KEY 77
-# define X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM 78
-
+# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */
+# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */
+# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */
+
+# define X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM 76
+# define X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH 77
+
+/* Errors in case a check in X509_V_FLAG_X509_STRICT mode fails */
+# define X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY 78
+# define X509_V_ERR_INVALID_CA 79
+# define X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA 80
+# define X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN 81
+# define X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA 82
+# define X509_V_ERR_ISSUER_NAME_EMPTY 83
+# define X509_V_ERR_SUBJECT_NAME_EMPTY 84
+# define X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER 85
+# define X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER 86
+# define X509_V_ERR_EMPTY_SUBJECT_ALT_NAME 87
/* Certificate verify flags */
# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101
# define X509_R_CRL_ALREADY_DELTA 127
# define X509_R_CRL_VERIFY_FAILURE 131
+# define X509_R_ERROR_GETTING_MD_BY_NID 141
+# define X509_R_ERROR_USING_SIGINF_SET 142
# define X509_R_IDP_MISMATCH 128
# define X509_R_INVALID_ATTRIBUTES 138
# define X509_R_INVALID_DIRECTORY 113
+# define X509_R_INVALID_DISTPOINT 143
# define X509_R_INVALID_FIELD_NAME 119
# define X509_R_INVALID_TRUST 123
# define X509_R_ISSUER_MISMATCH 129
# define X509_R_UNKNOWN_KEY_TYPE 117
# define X509_R_UNKNOWN_NID 109
# define X509_R_UNKNOWN_PURPOSE_ID 121
+# define X509_R_UNKNOWN_SIGID_ALGS 144
# define X509_R_UNKNOWN_TRUST_ID 120
# define X509_R_UNSUPPORTED_ALGORITHM 111
# define X509_R_WRONG_LOOKUP_TYPE 112
# define X509V3_R_DIRNAME_ERROR 149
# define X509V3_R_DISTPOINT_ALREADY_SET 160
# define X509V3_R_DUPLICATE_ZONE_ID 133
+# define X509V3_R_EMPTY_KEY_USAGE 169
# define X509V3_R_ERROR_CONVERTING_ZONE 131
# define X509V3_R_ERROR_CREATING_EXTENSION 144
# define X509V3_R_ERROR_IN_EXTENSION 128
# define X509V3_R_INVALID_ASNUMBER 162
# define X509V3_R_INVALID_ASRANGE 163
# define X509V3_R_INVALID_BOOLEAN_STRING 104
+# define X509V3_R_INVALID_CERTIFICATE 158
# define X509V3_R_INVALID_EXTENSION_STRING 105
# define X509V3_R_INVALID_INHERITANCE 165
# define X509V3_R_INVALID_IPADDRESS 166
# define X509V3_R_ISSUER_DECODE_ERROR 126
# define X509V3_R_MISSING_VALUE 124
# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142
+# define X509V3_R_NEGATIVE_PATHLEN 168
# define X509V3_R_NO_CONFIG_DATABASE 136
# define X509V3_R_NO_ISSUER_CERTIFICATE 121
# define X509V3_R_NO_ISSUER_DETAILS 127
run(app([@args]));
}
-plan tests => 144;
+plan tests => 145;
# Canonical success
ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
"accept trusted self-signed EE cert excluding key usage keyCertSign");
SKIP: {
- skip "Ed25519 is not supported by this OpenSSL build", 5
+ skip "Ed25519 is not supported by this OpenSSL build", 6
if disabled("ec");
# ED25519 certificate from draft-ietf-curdle-pkix-04
ok(verify("ee-ed25519", "sslserver", ["root-ed25519"], []),
"accept X25519 EE cert issued by trusted Ed25519 self-signed CA cert");
+ ok(!verify("ee-ed25519", "sslserver", ["root-ed25519"], [], "-x509_strict"),
+ "reject X25519 EE cert in strict mode since AKID is missing");
+
ok(!verify("root-ed25519", "sslserver", ["ee-ed25519"], []),
"fail Ed25519 CA and EE certs swapped");
-----BEGIN CERTIFICATE-----
-MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
-BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz
-MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
-RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF
-AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO
-/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE
-Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ
-zl9HYIMxATFyqSiD9jsx
+MIIBczCCAR0CFEqkMs9xq0qfdNflIpoqdDaOU/ThMA0GCSqGSIb3DQEBBAUAMDox
+CzAJBgNVBAYTAkFVMQwwCgYDVQQIDANRTEQxHTAbBgNVBAMMFFNTTGVheSByc2Eg
+dGVzdCBjZXJ0MCAXDTIwMDczMTE3MTM0NVoYDzIxMjAwNzA3MTcxMzQ1WjA6MQsw
+CQYDVQQGEwJBVTEMMAoGA1UECAwDUUxEMR0wGwYDVQQDDBRTU0xlYXkgcnNhIHRl
+c3QgY2VydDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDUZKgYSMuJdiw2aIQIG4LD
+vm9HbUnyJyj6WgPkpw98dVKTj0jo3F6n/e3anYzvSpOiPkTuvw209yslzJs40Sf7
+AgMBAAEwDQYJKoZIhvcNAQEEBQADQQBV1bQAvyLvJQrNt7WEKmo/inigwjsvQYwd
+nxmV6zWhqpQZmo86/ixumUa6zTlq+y4+wiiFngMZ7Bt0O769Nlzx
-----END CERTIFICATE-----