Check chain extensions also for trusted certificates
This includes basic constraints, key usages, issuer EKUs and auxiliary trust OIDs (given a trust suitably related to the intended purpose). Added tests and updated documentation. Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
This commit is contained in:
parent
1b4cf96f9b
commit
0daccd4dc1
13
apps/opt.c
13
apps/opt.c
@ -496,14 +496,25 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm)
|
|||||||
X509_VERIFY_PARAM_add0_policy(vpm, otmp);
|
X509_VERIFY_PARAM_add0_policy(vpm, otmp);
|
||||||
break;
|
break;
|
||||||
case OPT_V_PURPOSE:
|
case OPT_V_PURPOSE:
|
||||||
|
/* purpose name -> purpose index */
|
||||||
i = X509_PURPOSE_get_by_sname(opt_arg());
|
i = X509_PURPOSE_get_by_sname(opt_arg());
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg());
|
BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* purpose index -> purpose object */
|
||||||
xptmp = X509_PURPOSE_get0(i);
|
xptmp = X509_PURPOSE_get0(i);
|
||||||
|
|
||||||
|
/* purpose object -> purpose value */
|
||||||
i = X509_PURPOSE_get_id(xptmp);
|
i = X509_PURPOSE_get_id(xptmp);
|
||||||
X509_VERIFY_PARAM_set_purpose(vpm, i);
|
|
||||||
|
if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) {
|
||||||
|
BIO_printf(bio_err,
|
||||||
|
"%s: Internal error setting purpose %s\n",
|
||||||
|
prog, opt_arg());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_V_VERIFY_NAME:
|
case OPT_V_VERIFY_NAME:
|
||||||
vtmp = X509_VERIFY_PARAM_lookup(opt_arg());
|
vtmp = X509_VERIFY_PARAM_lookup(opt_arg());
|
||||||
|
@ -276,7 +276,7 @@ static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
|
|||||||
|
|
||||||
static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
|
static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
|
||||||
{
|
{
|
||||||
if (x->aux)
|
if (x->aux && (x->aux->trust || x->aux->reject))
|
||||||
return obj_trust(trust->arg1, x, flags);
|
return obj_trust(trust->arg1, x, flags);
|
||||||
return X509_TRUST_UNTRUSTED;
|
return X509_TRUST_UNTRUSTED;
|
||||||
}
|
}
|
||||||
@ -293,23 +293,26 @@ static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
|
|||||||
|
|
||||||
static int obj_trust(int id, X509 *x, int flags)
|
static int obj_trust(int id, X509 *x, int flags)
|
||||||
{
|
{
|
||||||
ASN1_OBJECT *obj;
|
X509_CERT_AUX *ax = x->aux;
|
||||||
int i;
|
int i;
|
||||||
X509_CERT_AUX *ax;
|
|
||||||
ax = x->aux;
|
|
||||||
if (!ax)
|
if (!ax)
|
||||||
return X509_TRUST_UNTRUSTED;
|
return X509_TRUST_UNTRUSTED;
|
||||||
if (ax->reject) {
|
if (ax->reject) {
|
||||||
for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
|
for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
|
||||||
obj = sk_ASN1_OBJECT_value(ax->reject, i);
|
ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i);
|
||||||
if (OBJ_obj2nid(obj) == id)
|
int nid = OBJ_obj2nid(obj);
|
||||||
|
|
||||||
|
if (nid == id || nid == NID_anyExtendedKeyUsage)
|
||||||
return X509_TRUST_REJECTED;
|
return X509_TRUST_REJECTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ax->trust) {
|
if (ax->trust) {
|
||||||
for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
|
for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
|
||||||
obj = sk_ASN1_OBJECT_value(ax->trust, i);
|
ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i);
|
||||||
if (OBJ_obj2nid(obj) == id)
|
int nid = OBJ_obj2nid(obj);
|
||||||
|
|
||||||
|
if (nid == id || nid == NID_anyExtendedKeyUsage)
|
||||||
return X509_TRUST_TRUSTED;
|
return X509_TRUST_TRUSTED;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -362,6 +362,48 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm)
|
|||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check EE or CA certificate purpose. For trusted certificates explicit local
|
||||||
|
* auxiliary trust can be used to override EKU-restrictions.
|
||||||
|
*/
|
||||||
|
static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth,
|
||||||
|
int must_be_ca)
|
||||||
|
{
|
||||||
|
int pu_ok = X509_check_purpose(x, purpose, must_be_ca > 0);
|
||||||
|
int tr_ok = X509_TRUST_UNTRUSTED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For trusted certificates we want to see whether any auxiliary trust
|
||||||
|
* settings override the purpose constraints we failed to meet above.
|
||||||
|
*
|
||||||
|
* This is complicated by the fact that the trust ordinals in
|
||||||
|
* ctx->param->trust are entirely independent of the purpose ordinals in
|
||||||
|
* ctx->param->purpose!
|
||||||
|
*
|
||||||
|
* What connects them is their mutual initialization via calls from
|
||||||
|
* X509_STORE_CTX_set_default() into X509_VERIFY_PARAM_lookup() which sets
|
||||||
|
* related values of both param->trust and param->purpose. It is however
|
||||||
|
* typically possible to infer associated trust values from a purpose value
|
||||||
|
* via the X509_PURPOSE API.
|
||||||
|
*
|
||||||
|
* Therefore, we can only check for trust overrides when the purpose we're
|
||||||
|
* checking is the same as ctx->param->purpose and ctx->param->trust is
|
||||||
|
* also set, or can be inferred from the purpose.
|
||||||
|
*/
|
||||||
|
if (depth >= ctx->num_untrusted && purpose == ctx->param->purpose)
|
||||||
|
tr_ok = X509_check_trust(x, ctx->param->trust, X509_TRUST_NO_SS_COMPAT);
|
||||||
|
|
||||||
|
if (tr_ok != X509_TRUST_REJECTED &&
|
||||||
|
(pu_ok == 1 ||
|
||||||
|
(pu_ok != 0 && (ctx->param->flags & X509_V_FLAG_X509_STRICT) == 0)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ctx->error = X509_V_ERR_INVALID_PURPOSE;
|
||||||
|
ctx->error_depth = depth;
|
||||||
|
ctx->current_cert = x;
|
||||||
|
return ctx->verify_cb(0, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check a certificate chains extensions for consistency with the supplied
|
* Check a certificate chains extensions for consistency with the supplied
|
||||||
* purpose
|
* purpose
|
||||||
@ -369,11 +411,12 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm)
|
|||||||
|
|
||||||
static int check_chain_extensions(X509_STORE_CTX *ctx)
|
static int check_chain_extensions(X509_STORE_CTX *ctx)
|
||||||
{
|
{
|
||||||
int i, ok = 0, must_be_ca, plen = 0;
|
int i, must_be_ca, plen = 0;
|
||||||
X509 *x;
|
X509 *x;
|
||||||
int proxy_path_length = 0;
|
int proxy_path_length = 0;
|
||||||
int purpose;
|
int purpose;
|
||||||
int allow_proxy_certs;
|
int allow_proxy_certs;
|
||||||
|
int num = sk_X509_num(ctx->chain);
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* must_be_ca can have 1 of 3 values:
|
* must_be_ca can have 1 of 3 values:
|
||||||
@ -402,8 +445,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
|||||||
purpose = ctx->param->purpose;
|
purpose = ctx->param->purpose;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check all untrusted certificates */
|
for (i = 0; i < num; i++) {
|
||||||
for (i = 0; i == 0 || i < ctx->num_untrusted; i++) {
|
|
||||||
int ret;
|
int ret;
|
||||||
x = sk_X509_value(ctx->chain, i);
|
x = sk_X509_value(ctx->chain, i);
|
||||||
if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
|
if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
|
||||||
@ -411,17 +453,15 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
|||||||
ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
|
ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
|
||||||
ctx->error_depth = i;
|
ctx->error_depth = i;
|
||||||
ctx->current_cert = x;
|
ctx->current_cert = x;
|
||||||
ok = ctx->verify_cb(0, ctx);
|
if (!ctx->verify_cb(0, ctx))
|
||||||
if (!ok)
|
return 0;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
|
if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
|
||||||
ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
|
ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
|
||||||
ctx->error_depth = i;
|
ctx->error_depth = i;
|
||||||
ctx->current_cert = x;
|
ctx->current_cert = x;
|
||||||
ok = ctx->verify_cb(0, ctx);
|
if (!ctx->verify_cb(0, ctx))
|
||||||
if (!ok)
|
return 0;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
ret = X509_check_ca(x);
|
ret = X509_check_ca(x);
|
||||||
switch (must_be_ca) {
|
switch (must_be_ca) {
|
||||||
@ -453,22 +493,12 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
|||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ctx->error_depth = i;
|
ctx->error_depth = i;
|
||||||
ctx->current_cert = x;
|
ctx->current_cert = x;
|
||||||
ok = ctx->verify_cb(0, ctx);
|
if (! ctx->verify_cb(0, ctx))
|
||||||
if (!ok)
|
return 0;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
if (ctx->param->purpose > 0) {
|
if (purpose > 0) {
|
||||||
ret = X509_check_purpose(x, purpose, must_be_ca > 0);
|
if (!check_purpose(ctx, x, purpose, i, must_be_ca))
|
||||||
if ((ret == 0)
|
return 0;
|
||||||
|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
|
|
||||||
&& (ret != 1))) {
|
|
||||||
ctx->error = X509_V_ERR_INVALID_PURPOSE;
|
|
||||||
ctx->error_depth = i;
|
|
||||||
ctx->current_cert = x;
|
|
||||||
ok = ctx->verify_cb(0, ctx);
|
|
||||||
if (!ok)
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Check pathlen if not self issued */
|
/* Check pathlen if not self issued */
|
||||||
if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
|
if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
|
||||||
@ -477,9 +507,8 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
|||||||
ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
|
ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
|
||||||
ctx->error_depth = i;
|
ctx->error_depth = i;
|
||||||
ctx->current_cert = x;
|
ctx->current_cert = x;
|
||||||
ok = ctx->verify_cb(0, ctx);
|
if (!ctx->verify_cb(0, ctx))
|
||||||
if (!ok)
|
return 0;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
/* Increment path length if not self issued */
|
/* Increment path length if not self issued */
|
||||||
if (!(x->ex_flags & EXFLAG_SI))
|
if (!(x->ex_flags & EXFLAG_SI))
|
||||||
@ -494,18 +523,15 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
|||||||
ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
|
ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
|
||||||
ctx->error_depth = i;
|
ctx->error_depth = i;
|
||||||
ctx->current_cert = x;
|
ctx->current_cert = x;
|
||||||
ok = ctx->verify_cb(0, ctx);
|
if (!ctx->verify_cb(0, ctx))
|
||||||
if (!ok)
|
return 0;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
proxy_path_length++;
|
proxy_path_length++;
|
||||||
must_be_ca = 0;
|
must_be_ca = 0;
|
||||||
} else
|
} else
|
||||||
must_be_ca = 1;
|
must_be_ca = 1;
|
||||||
}
|
}
|
||||||
ok = 1;
|
return 1;
|
||||||
end:
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_name_constraints(X509_STORE_CTX *ctx)
|
static int check_name_constraints(X509_STORE_CTX *ctx)
|
||||||
@ -2016,11 +2042,20 @@ void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
|
|||||||
|
|
||||||
int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
|
int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* XXX: Why isn't this function always used to set the associated trust?
|
||||||
|
* Should there even be a VPM->trust field at all? Or should the trust
|
||||||
|
* always be inferred from the purpose by X509_STORE_CTX_init().
|
||||||
|
*/
|
||||||
return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
|
return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
|
int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* XXX: See above, this function would only be needed when the default
|
||||||
|
* trust for the purpose needs an override in a corner case.
|
||||||
|
*/
|
||||||
return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
|
return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2054,6 +2089,11 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
|
|||||||
ptmp = X509_PURPOSE_get0(idx);
|
ptmp = X509_PURPOSE_get0(idx);
|
||||||
if (ptmp->trust == X509_TRUST_DEFAULT) {
|
if (ptmp->trust == X509_TRUST_DEFAULT) {
|
||||||
idx = X509_PURPOSE_get_by_id(def_purpose);
|
idx = X509_PURPOSE_get_by_id(def_purpose);
|
||||||
|
/*
|
||||||
|
* XXX: In the two callers above def_purpose is always 0, which is
|
||||||
|
* not a known value, so idx will always be -1. How is the
|
||||||
|
* X509_TRUST_DEFAULT case actually supposed to be handled?
|
||||||
|
*/
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
|
X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
|
||||||
X509_R_UNKNOWN_PURPOSE_ID);
|
X509_R_UNKNOWN_PURPOSE_ID);
|
||||||
@ -2211,6 +2251,18 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: For now, continue to inherit trust from VPM, but infer from the
|
||||||
|
* purpose if this still yields the default value.
|
||||||
|
*/
|
||||||
|
if (ctx->param->trust == X509_TRUST_DEFAULT) {
|
||||||
|
int idx = X509_PURPOSE_get_by_id(ctx->param->purpose);
|
||||||
|
X509_PURPOSE *xp = X509_PURPOSE_get0(idx);
|
||||||
|
|
||||||
|
if (xp != NULL)
|
||||||
|
ctx->param->trust = X509_PURPOSE_get_trust(xp);
|
||||||
|
}
|
||||||
|
|
||||||
if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
|
if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
|
||||||
&ctx->ex_data))
|
&ctx->ex_data))
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -133,7 +133,7 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
|
|||||||
return;
|
return;
|
||||||
param->name = NULL;
|
param->name = NULL;
|
||||||
param->purpose = 0;
|
param->purpose = 0;
|
||||||
param->trust = 0;
|
param->trust = X509_TRUST_DEFAULT;
|
||||||
/*
|
/*
|
||||||
* param->inh_flags = X509_VP_FLAG_DEFAULT;
|
* param->inh_flags = X509_VP_FLAG_DEFAULT;
|
||||||
*/
|
*/
|
||||||
@ -243,7 +243,7 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
|
|||||||
to_overwrite = 0;
|
to_overwrite = 0;
|
||||||
|
|
||||||
x509_verify_param_copy(purpose, 0);
|
x509_verify_param_copy(purpose, 0);
|
||||||
x509_verify_param_copy(trust, 0);
|
x509_verify_param_copy(trust, X509_TRUST_DEFAULT);
|
||||||
x509_verify_param_copy(depth, -1);
|
x509_verify_param_copy(depth, -1);
|
||||||
|
|
||||||
/* If overwrite or check time not set, copy across */
|
/* If overwrite or check time not set, copy across */
|
||||||
@ -511,7 +511,7 @@ static const X509_VERIFY_PARAM default_table[] = {
|
|||||||
"default", /* X509 default parameters */
|
"default", /* X509 default parameters */
|
||||||
0, /* Check time */
|
0, /* Check time */
|
||||||
0, /* internal flags */
|
0, /* internal flags */
|
||||||
0, /* flags */
|
X509_V_FLAG_TRUSTED_FIRST, /* flags */
|
||||||
0, /* purpose */
|
0, /* purpose */
|
||||||
0, /* trust */
|
0, /* trust */
|
||||||
100, /* depth */
|
100, /* depth */
|
||||||
|
@ -198,14 +198,16 @@ When constructing the certificate chain, use the trusted certificates specified
|
|||||||
via B<-CAfile>, B<-CApath> or B<-trusted> before any certificates specified via
|
via B<-CAfile>, B<-CApath> or B<-trusted> before any certificates specified via
|
||||||
B<-untrusted>.
|
B<-untrusted>.
|
||||||
This can be useful in environments with Bridge or Cross-Certified CAs.
|
This can be useful in environments with Bridge or Cross-Certified CAs.
|
||||||
|
As of OpenSSL 1.1.0 this option is on by default and cannot be disabled.
|
||||||
|
|
||||||
=item B<-no_alt_chains>
|
=item B<-no_alt_chains>
|
||||||
|
|
||||||
When building a certificate chain, if the first certificate chain found is not
|
By default, unless B<-trusted_first> is specified, when building a certificate
|
||||||
trusted, then OpenSSL will continue to check to see if an alternative chain can
|
chain, if the first certificate chain found is not trusted, then OpenSSL will
|
||||||
be found that is trusted. With this option that behaviour is suppressed so that
|
attempt to replace untrusted issuer certificates with certificates from the
|
||||||
only the first chain found is ever used. Using this option will force the
|
trust store to see if an alternative chain can be found that is trusted.
|
||||||
behaviour to match that of OpenSSL versions prior to 1.1.0.
|
As of OpenSSL 1.1.0, with B<-trusted_first> always on, this option has no
|
||||||
|
effect.
|
||||||
|
|
||||||
=item B<-untrusted file>
|
=item B<-untrusted file>
|
||||||
|
|
||||||
@ -264,13 +266,17 @@ the subject certificate.
|
|||||||
|
|
||||||
Use default verification policies like trust model and required certificate
|
Use default verification policies like trust model and required certificate
|
||||||
policies identified by B<name>.
|
policies identified by B<name>.
|
||||||
|
The trust model determines which auxiliary trust or reject OIDs are applicable
|
||||||
|
to verifying the given certificate chain.
|
||||||
|
See the B<-addtrust> and B<-addreject> options of the L<x509(1)> command-line
|
||||||
|
utility.
|
||||||
Supported policy names include: B<default>, B<pkcs7>, B<smime_sign>,
|
Supported policy names include: B<default>, B<pkcs7>, B<smime_sign>,
|
||||||
B<ssl_client>, B<ssl_server>.
|
B<ssl_client>, B<ssl_server>.
|
||||||
This checks not only the purpose of the leaf certificate, but also the
|
These mimics the combinations of purpose and trust settings used in SSL, CMS
|
||||||
trust settings of the trusted CAs.
|
and S/MIME.
|
||||||
When in doubt, use this option rather than B<-purpose>.
|
As of OpenSSL 1.1.0, the trust model is inferred from the purpose when not
|
||||||
The B<-verify_name> option more closely matches how certificates are checked in
|
specified, so the B<-verify_name> options are functionally equivalent to the
|
||||||
e.g. SSL and S/MIME.
|
corresponding B<-purpose> settings.
|
||||||
|
|
||||||
=item B<-x509_strict>
|
=item B<-x509_strict>
|
||||||
|
|
||||||
|
@ -289,9 +289,12 @@ clears all the prohibited or rejected uses of the certificate.
|
|||||||
|
|
||||||
=item B<-addtrust arg>
|
=item B<-addtrust arg>
|
||||||
|
|
||||||
adds a trusted certificate use. Any object name can be used here
|
adds a trusted certificate use.
|
||||||
but currently only B<clientAuth> (SSL client use), B<serverAuth>
|
Any object name can be used here but currently only B<clientAuth> (SSL client
|
||||||
(SSL server use) and B<emailProtection> (S/MIME email) are used.
|
use), B<serverAuth> (SSL server use), B<emailProtection> (S/MIME email) and
|
||||||
|
B<anyExtendedKeyUsage> are used.
|
||||||
|
As of OpenSSL 1.1.0, the last of these blocks all purposes when rejected or
|
||||||
|
enables all purposes when trusted.
|
||||||
Other OpenSSL applications may define additional uses.
|
Other OpenSSL applications may define additional uses.
|
||||||
|
|
||||||
=item B<-addreject arg>
|
=item B<-addreject arg>
|
||||||
|
@ -197,11 +197,20 @@ verification. If this flag is set then additional status codes will be sent
|
|||||||
to the verification callback and it B<must> be prepared to handle such cases
|
to the verification callback and it B<must> be prepared to handle such cases
|
||||||
without assuming they are hard errors.
|
without assuming they are hard errors.
|
||||||
|
|
||||||
|
If B<X509_V_FLAG_TRUSTED_FIRST> is set, when constructing the certificate chain,
|
||||||
|
L<X509_verify_cert(3)> will search the trust store for issuer certificates before
|
||||||
|
searching the provided untrusted certificates.
|
||||||
|
As of OpenSSL 1.1.0 this option is on by default and cannot be disabled.
|
||||||
|
|
||||||
The B<X509_V_FLAG_NO_ALT_CHAINS> flag suppresses checking for alternative
|
The B<X509_V_FLAG_NO_ALT_CHAINS> flag suppresses checking for alternative
|
||||||
chains. By default, when building a certificate chain, if the first certificate
|
chains.
|
||||||
chain found is not trusted, then OpenSSL will continue to check to see if an
|
By default, unless B<X509_V_FLAG_TRUSTED_FIRST> is set, when building a
|
||||||
alternative chain can be found that is trusted. With this flag set the behaviour
|
certificate chain, if the first certificate chain found is not trusted, then
|
||||||
will match that of OpenSSL versions prior to 1.1.0.
|
OpenSSL will attempt to replace untrusted certificates supplied by the peer
|
||||||
|
with certificates from the trust store to see if an alternative chain can be
|
||||||
|
found that is trusted.
|
||||||
|
As of OpenSSL 1.1.0, with B<X509_V_FLAG_TRUSTED_FIRST> always set, this option
|
||||||
|
has no effect.
|
||||||
|
|
||||||
The B<X509_V_FLAG_NO_CHECK_TIME> flag suppresses checking the validity period
|
The B<X509_V_FLAG_NO_CHECK_TIME> flag suppresses checking the validity period
|
||||||
of certificates and CRLs against the current time. If X509_VERIFY_PARAM_set_time()
|
of certificates and CRLs against the current time. If X509_VERIFY_PARAM_set_time()
|
||||||
|
@ -183,7 +183,7 @@ DEFINE_STACK_OF(X509_TRUST)
|
|||||||
|
|
||||||
/* standard trust ids */
|
/* standard trust ids */
|
||||||
|
|
||||||
# define X509_TRUST_DEFAULT -1/* Only valid in purpose settings */
|
# define X509_TRUST_DEFAULT 0 /* Only valid in purpose settings */
|
||||||
|
|
||||||
# define X509_TRUST_COMPAT 1
|
# define X509_TRUST_COMPAT 1
|
||||||
# define X509_TRUST_SSL_CLIENT 2
|
# define X509_TRUST_SSL_CLIENT 2
|
||||||
|
18
test/certs/root+anyEKU.pem
Normal file
18
test/certs/root+anyEKU.pem
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN TRUSTED CERTIFICATE-----
|
||||||
|
MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
|
||||||
|
IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
|
||||||
|
DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
|
||||||
|
oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
|
||||||
|
feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
|
||||||
|
wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
|
||||||
|
MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
|
||||||
|
aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
|
||||||
|
tWgiQ35mJCOvxQIDAQABo1AwTjAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
|
||||||
|
o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
|
||||||
|
/zANBgkqhkiG9w0BAQsFAAOCAQEAyRRJx27WYOogPXZpPfAMt8ptapr/ugLWGLlw
|
||||||
|
bzKySoyLpoV2/YNAvTAGB90iFq6x/ujjrK41/ES0p3v38/Qfuxo24gcZgc/oYLV2
|
||||||
|
UqR+uGCx68p2OWLYctBsARtYWOEgPhHFb9aVxcOQKyZHtivDX0wLGX+nqZoHX9IY
|
||||||
|
mc0sbpRBRMzxRsChbzD5re9kZ5NrgkjA6DJ7jYh2GitOM6oIU3Dd9+pk3bCEkFUg
|
||||||
|
Ry9qN/k+AyeqH1Qcb5LU+MTmlw8bmyzmMOBZgdegtO4HshcBMO054KSB3WSfBPDO
|
||||||
|
bEhZ0vm/lw63TGi88yIMtlkmcU2g0RKpeQI96G6QeqHyKF3p8DAIMAYGBFUdJQA=
|
||||||
|
-----END TRUSTED CERTIFICATE-----
|
18
test/certs/root-anyEKU.pem
Normal file
18
test/certs/root-anyEKU.pem
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN TRUSTED CERTIFICATE-----
|
||||||
|
MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
|
||||||
|
IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
|
||||||
|
DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
|
||||||
|
oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
|
||||||
|
feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
|
||||||
|
wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
|
||||||
|
MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
|
||||||
|
aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
|
||||||
|
tWgiQ35mJCOvxQIDAQABo1AwTjAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
|
||||||
|
o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
|
||||||
|
/zANBgkqhkiG9w0BAQsFAAOCAQEAyRRJx27WYOogPXZpPfAMt8ptapr/ugLWGLlw
|
||||||
|
bzKySoyLpoV2/YNAvTAGB90iFq6x/ujjrK41/ES0p3v38/Qfuxo24gcZgc/oYLV2
|
||||||
|
UqR+uGCx68p2OWLYctBsARtYWOEgPhHFb9aVxcOQKyZHtivDX0wLGX+nqZoHX9IY
|
||||||
|
mc0sbpRBRMzxRsChbzD5re9kZ5NrgkjA6DJ7jYh2GitOM6oIU3Dd9+pk3bCEkFUg
|
||||||
|
Ry9qN/k+AyeqH1Qcb5LU+MTmlw8bmyzmMOBZgdegtO4HshcBMO054KSB3WSfBPDO
|
||||||
|
bEhZ0vm/lw63TGi88yIMtlkmcU2g0RKpeQI96G6QeqHyKF3p8DAIoAYGBFUdJQA=
|
||||||
|
-----END TRUSTED CERTIFICATE-----
|
19
test/certs/root2+clientAuth.pem
Normal file
19
test/certs/root2+clientAuth.pem
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
-----BEGIN TRUSTED CERTIFICATE-----
|
||||||
|
MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
|
||||||
|
IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
|
||||||
|
DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyB6dJAD5
|
||||||
|
wbStQf4HE0EhldtDShNVQ/jhDu6s2Ka30FdP4ml1+c2Py7ODUSjSCegXaBIOXCA+
|
||||||
|
R0zaBAJ3ZeqXx3UrE9PiXaHRGZcoPtX4mK9IOHhIdxwPUa6ceSOJn4cHY+p0cFLp
|
||||||
|
/5bnUErp4IqbL1bMd4v8fFxJ0ZDGJahfLiurnYUyalaNCHK+hK2+RaeRgPlsXfiU
|
||||||
|
/vwhhjFhdhixbPm8l+S+2xNySV1JAAzrUvEDdNZ0iBvuVcS2mlhSKTht5Zeg+0C6
|
||||||
|
7kYYqxM9CVZCwcV/aSUImwjeFsNMJsl/nFyEacu6vXz0rjvLwPzTAeVYZy592Gwv
|
||||||
|
akWOtiDdap7WJQIDAQABo1AwTjAdBgNVHQ4EFgQUnM5mQjCrHAgmX3MZbd8Pp65Y
|
||||||
|
Uh4wHwYDVR0jBBgwFoAUnM5mQjCrHAgmX3MZbd8Pp65YUh4wDAYDVR0TBAUwAwEB
|
||||||
|
/zANBgkqhkiG9w0BAQsFAAOCAQEADkH6+rUX2QD5TMBn8x4PR9mTQsxhD2k8K2bv
|
||||||
|
NpbsWX0ta2pDPhiBpIbrTrTmw656MMRkwMLYIAX7BFhyjO9gO0nVXfU1SSTDsso+
|
||||||
|
qu/K1t2US/rLeJQn8gYiTw6AqmvxHOndLaZQrYef4rUzsYnahNzxcoS1FMVxoJFM
|
||||||
|
o+1Wo0BFBlASv5Az0iFfjd1Uy3+AHB41+2vczNIWSki3mg4hzus2PSS4AA9IYeh+
|
||||||
|
zU/HJMddnVedLKNstTAfR85ftACtsP6JhBqCBqC4mCVsN2ZlgucETbsOMyWYB4+y
|
||||||
|
9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1zAMMAoGCCsGAQUF
|
||||||
|
BwMC
|
||||||
|
-----END TRUSTED CERTIFICATE-----
|
19
test/certs/root2+serverAuth.pem
Normal file
19
test/certs/root2+serverAuth.pem
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
-----BEGIN TRUSTED CERTIFICATE-----
|
||||||
|
MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
|
||||||
|
IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
|
||||||
|
DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyB6dJAD5
|
||||||
|
wbStQf4HE0EhldtDShNVQ/jhDu6s2Ka30FdP4ml1+c2Py7ODUSjSCegXaBIOXCA+
|
||||||
|
R0zaBAJ3ZeqXx3UrE9PiXaHRGZcoPtX4mK9IOHhIdxwPUa6ceSOJn4cHY+p0cFLp
|
||||||
|
/5bnUErp4IqbL1bMd4v8fFxJ0ZDGJahfLiurnYUyalaNCHK+hK2+RaeRgPlsXfiU
|
||||||
|
/vwhhjFhdhixbPm8l+S+2xNySV1JAAzrUvEDdNZ0iBvuVcS2mlhSKTht5Zeg+0C6
|
||||||
|
7kYYqxM9CVZCwcV/aSUImwjeFsNMJsl/nFyEacu6vXz0rjvLwPzTAeVYZy592Gwv
|
||||||
|
akWOtiDdap7WJQIDAQABo1AwTjAdBgNVHQ4EFgQUnM5mQjCrHAgmX3MZbd8Pp65Y
|
||||||
|
Uh4wHwYDVR0jBBgwFoAUnM5mQjCrHAgmX3MZbd8Pp65YUh4wDAYDVR0TBAUwAwEB
|
||||||
|
/zANBgkqhkiG9w0BAQsFAAOCAQEADkH6+rUX2QD5TMBn8x4PR9mTQsxhD2k8K2bv
|
||||||
|
NpbsWX0ta2pDPhiBpIbrTrTmw656MMRkwMLYIAX7BFhyjO9gO0nVXfU1SSTDsso+
|
||||||
|
qu/K1t2US/rLeJQn8gYiTw6AqmvxHOndLaZQrYef4rUzsYnahNzxcoS1FMVxoJFM
|
||||||
|
o+1Wo0BFBlASv5Az0iFfjd1Uy3+AHB41+2vczNIWSki3mg4hzus2PSS4AA9IYeh+
|
||||||
|
zU/HJMddnVedLKNstTAfR85ftACtsP6JhBqCBqC4mCVsN2ZlgucETbsOMyWYB4+y
|
||||||
|
9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1zAMMAoGCCsGAQUF
|
||||||
|
BwMB
|
||||||
|
-----END TRUSTED CERTIFICATE-----
|
19
test/certs/root2-serverAuth.pem
Normal file
19
test/certs/root2-serverAuth.pem
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
-----BEGIN TRUSTED CERTIFICATE-----
|
||||||
|
MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
|
||||||
|
IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
|
||||||
|
DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyB6dJAD5
|
||||||
|
wbStQf4HE0EhldtDShNVQ/jhDu6s2Ka30FdP4ml1+c2Py7ODUSjSCegXaBIOXCA+
|
||||||
|
R0zaBAJ3ZeqXx3UrE9PiXaHRGZcoPtX4mK9IOHhIdxwPUa6ceSOJn4cHY+p0cFLp
|
||||||
|
/5bnUErp4IqbL1bMd4v8fFxJ0ZDGJahfLiurnYUyalaNCHK+hK2+RaeRgPlsXfiU
|
||||||
|
/vwhhjFhdhixbPm8l+S+2xNySV1JAAzrUvEDdNZ0iBvuVcS2mlhSKTht5Zeg+0C6
|
||||||
|
7kYYqxM9CVZCwcV/aSUImwjeFsNMJsl/nFyEacu6vXz0rjvLwPzTAeVYZy592Gwv
|
||||||
|
akWOtiDdap7WJQIDAQABo1AwTjAdBgNVHQ4EFgQUnM5mQjCrHAgmX3MZbd8Pp65Y
|
||||||
|
Uh4wHwYDVR0jBBgwFoAUnM5mQjCrHAgmX3MZbd8Pp65YUh4wDAYDVR0TBAUwAwEB
|
||||||
|
/zANBgkqhkiG9w0BAQsFAAOCAQEADkH6+rUX2QD5TMBn8x4PR9mTQsxhD2k8K2bv
|
||||||
|
NpbsWX0ta2pDPhiBpIbrTrTmw656MMRkwMLYIAX7BFhyjO9gO0nVXfU1SSTDsso+
|
||||||
|
qu/K1t2US/rLeJQn8gYiTw6AqmvxHOndLaZQrYef4rUzsYnahNzxcoS1FMVxoJFM
|
||||||
|
o+1Wo0BFBlASv5Az0iFfjd1Uy3+AHB41+2vczNIWSki3mg4hzus2PSS4AA9IYeh+
|
||||||
|
zU/HJMddnVedLKNstTAfR85ftACtsP6JhBqCBqC4mCVsN2ZlgucETbsOMyWYB4+y
|
||||||
|
9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1zAMoAoGCCsGAQUF
|
||||||
|
BwMB
|
||||||
|
-----END TRUSTED CERTIFICATE-----
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Primary root: root-cert
|
# Primary root: root-cert
|
||||||
# root certs variants: CA:false, key2, DN2
|
# root certs variants: CA:false, key2, DN2
|
||||||
# trust variants: +serverAuth -serverAuth +clientAuth
|
# trust variants: +serverAuth -serverAuth +clientAuth +anyEKU -anyEKU
|
||||||
#
|
#
|
||||||
./mkcert.sh genroot "Root CA" root-key root-cert
|
./mkcert.sh genroot "Root CA" root-key root-cert
|
||||||
./mkcert.sh genss "Root CA" root-key root-nonca
|
./mkcert.sh genss "Root CA" root-key root-nonca
|
||||||
@ -15,6 +15,16 @@ openssl x509 -in root-cert.pem -trustout \
|
|||||||
-addreject serverAuth -out root-serverAuth.pem
|
-addreject serverAuth -out root-serverAuth.pem
|
||||||
openssl x509 -in root-cert.pem -trustout \
|
openssl x509 -in root-cert.pem -trustout \
|
||||||
-addtrust clientAuth -out root+clientAuth.pem
|
-addtrust clientAuth -out root+clientAuth.pem
|
||||||
|
openssl x509 -in root-cert.pem -trustout \
|
||||||
|
-addreject anyExtendedKeyUsage -out root-anyEKU.pem
|
||||||
|
openssl x509 -in root-cert.pem -trustout \
|
||||||
|
-addtrust anyExtendedKeyUsage -out root+anyEKU.pem
|
||||||
|
openssl x509 -in root-cert2.pem -trustout \
|
||||||
|
-addtrust serverAuth -out root2+serverAuth.pem
|
||||||
|
openssl x509 -in root-cert2.pem -trustout \
|
||||||
|
-addreject serverAuth -out root2-serverAuth.pem
|
||||||
|
openssl x509 -in root-cert2.pem -trustout \
|
||||||
|
-addtrust clientAuth -out root2+clientAuth.pem
|
||||||
|
|
||||||
# Primary intermediate ca: ca-cert
|
# Primary intermediate ca: ca-cert
|
||||||
# ca variants: CA:false, key2, DN2, issuer2, expired
|
# ca variants: CA:false, key2, DN2, issuer2, expired
|
||||||
|
@ -9,80 +9,110 @@ use OpenSSL::Test qw/:DEFAULT top_file/;
|
|||||||
setup("test_verify");
|
setup("test_verify");
|
||||||
|
|
||||||
sub verify {
|
sub verify {
|
||||||
my ($cert, $vname, $trusted, $untrusted, @opts) = @_;
|
my ($cert, $purpose, $trusted, $untrusted, @opts) = @_;
|
||||||
my @args = qw(openssl verify -verify_name);
|
my @args = qw(openssl verify -purpose);
|
||||||
my @path = qw(test certs);
|
my @path = qw(test certs);
|
||||||
push(@args, "$vname", @opts);
|
push(@args, "$purpose", @opts);
|
||||||
for (@$trusted) { push(@args, "-trusted", top_file(@path, "$_.pem")) }
|
for (@$trusted) { push(@args, "-trusted", top_file(@path, "$_.pem")) }
|
||||||
for (@$untrusted) { push(@args, "-untrusted", top_file(@path, "$_.pem")) }
|
for (@$untrusted) { push(@args, "-untrusted", top_file(@path, "$_.pem")) }
|
||||||
push(@args, top_file(@path, "$cert.pem"));
|
push(@args, top_file(@path, "$cert.pem"));
|
||||||
run(app([@args]));
|
run(app([@args]));
|
||||||
}
|
}
|
||||||
|
|
||||||
plan tests => 29;
|
plan tests => 38;
|
||||||
|
|
||||||
# Canonical success
|
# Canonical success
|
||||||
ok(verify("ee-cert", "ssl_server", ["root-cert"], ["ca-cert"]),
|
ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
|
||||||
"verify valid chain");
|
"verify valid chain");
|
||||||
|
|
||||||
# Root CA variants
|
# Root CA variants
|
||||||
ok(verify("ee-cert", "ssl_server", [qw(root-nonca)], [qw(ca-cert)]),
|
ok(!verify("ee-cert", "sslserver", [qw(root-nonca)], [qw(ca-cert)]),
|
||||||
"Trusted certs not subject to CA:true checks");
|
"Trusted CA certs now subject to CA:true checks");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(root-cert2)], [qw(ca-cert)]),
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert2)], [qw(ca-cert)]),
|
||||||
"fail wrong root key");
|
"fail wrong root key");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(root-name2)], [qw(ca-cert)]),
|
ok(!verify("ee-cert", "sslserver", [qw(root-name2)], [qw(ca-cert)]),
|
||||||
"fail wrong root DN");
|
"fail wrong root DN");
|
||||||
ok(verify("ee-cert", "ssl_server", [qw(root+serverAuth)], [qw(ca-cert)]),
|
ok(verify("ee-cert", "sslserver", [qw(root+serverAuth)], [qw(ca-cert)]),
|
||||||
"accept right EKU");
|
"accept right EKU");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(root-serverAuth)], [qw(ca-cert)]),
|
ok(verify("ee-cert", "sslserver", [qw(root+anyEKU)], [qw(ca-cert)]),
|
||||||
|
"accept anyEKU");
|
||||||
|
ok(!verify("ee-cert", "sslserver", [qw(root-serverAuth)], [qw(ca-cert)]),
|
||||||
"fail rejected EKU");
|
"fail rejected EKU");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(root+clientAuth)], [qw(ca-cert)]),
|
ok(!verify("ee-cert", "sslserver", [qw(root-anyEKU)], [qw(ca-cert)]),
|
||||||
|
"fail rejected anyEKU");
|
||||||
|
ok(!verify("ee-cert", "sslserver", [qw(root+clientAuth)], [qw(ca-cert)]),
|
||||||
"fail wrong EKU");
|
"fail wrong EKU");
|
||||||
|
|
||||||
|
# Check that trusted-first is on by setting up paths to different roots
|
||||||
|
# depending on whether the intermediate is the trusted or untrusted one.
|
||||||
|
#
|
||||||
|
ok(verify("ee-cert", "sslserver", [qw(root-serverAuth root-cert2 ca-root2)],
|
||||||
|
[qw(ca-cert)]),
|
||||||
|
"verify trusted-first path");
|
||||||
|
ok(verify("ee-cert", "sslserver", [qw(root-cert root2+serverAuth ca-root2)],
|
||||||
|
[qw(ca-cert)]),
|
||||||
|
"verify trusted-first path right EKU");
|
||||||
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert root2-serverAuth ca-root2)],
|
||||||
|
[qw(ca-cert)]),
|
||||||
|
"fail trusted-first path rejected EKU");
|
||||||
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert root2+clientAuth ca-root2)],
|
||||||
|
[qw(ca-cert)]),
|
||||||
|
"fail trusted-first path wrong EKU");
|
||||||
|
|
||||||
# CA variants
|
# CA variants
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(root-cert)], [qw(ca-nonca)]),
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-nonca)]),
|
||||||
"fail non-CA");
|
"fail non-CA");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(root-cert)], [qw(ca-cert2)]),
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-cert2)]),
|
||||||
"fail wrong CA key");
|
"fail wrong CA key");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(root-cert)], [qw(ca-name2)]),
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-name2)]),
|
||||||
"fail wrong CA DN");
|
"fail wrong CA DN");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(root-cert)], [qw(ca-root2)]),
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-root2)]),
|
||||||
"fail wrong CA issuer");
|
"fail wrong CA issuer");
|
||||||
ok(!verify("ee-cert", "ssl_server", [], [qw(ca-cert)], "-partial_chain"),
|
ok(!verify("ee-cert", "sslserver", [], [qw(ca-cert)], "-partial_chain"),
|
||||||
"fail untrusted partial");
|
"fail untrusted partial");
|
||||||
ok(!verify("ee-cert", "ssl_server", [], [qw(ca+serverAuth)], "-partial_chain"),
|
ok(!verify("ee-cert", "sslserver", [], [qw(ca+serverAuth)], "-partial_chain"),
|
||||||
"fail untrusted EKU partial");
|
"fail untrusted EKU partial");
|
||||||
ok(verify("ee-cert", "ssl_server", [qw(ca+serverAuth)], [], "-partial_chain"),
|
ok(verify("ee-cert", "sslserver", [qw(ca+serverAuth)], [], "-partial_chain"),
|
||||||
"accept trusted EKU partial");
|
"accept trusted EKU partial");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(ca-serverAuth)], [], "-partial_chain"),
|
ok(!verify("ee-cert", "sslserver", [qw(ca-serverAuth)], [], "-partial_chain"),
|
||||||
"fail rejected EKU partial");
|
"fail rejected EKU partial");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(ca+clientAuth)], [], "-partial_chain"),
|
ok(!verify("ee-cert", "sslserver", [qw(ca+clientAuth)], [], "-partial_chain"),
|
||||||
"fail wrong EKU partial");
|
"fail wrong EKU partial");
|
||||||
|
|
||||||
|
# We now test auxiliary trust even for intermediate trusted certs without
|
||||||
|
# -partial_chain. Note that "-trusted_first" is now always on and cannot
|
||||||
|
# be disabled.
|
||||||
|
ok(verify("ee-cert", "sslserver", [qw(root-cert ca+serverAuth)], [qw(ca-cert)]),
|
||||||
|
"accept trusted EKU");
|
||||||
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-serverAuth)], [qw(ca-cert)]),
|
||||||
|
"fail rejected EKU");
|
||||||
|
ok(!verify("ee-cert", "sslserver", [qw(root-cert ca+clientAuth)], [qw(ca-cert)]),
|
||||||
|
"fail wrong EKU");
|
||||||
|
|
||||||
# EE variants
|
# EE variants
|
||||||
ok(verify("ee-client", "ssl_client", [qw(root-cert)], [qw(ca-cert)]),
|
ok(verify("ee-client", "sslclient", [qw(root-cert)], [qw(ca-cert)]),
|
||||||
"accept client cert");
|
"accept client cert");
|
||||||
ok(!verify("ee-client", "ssl_server", [qw(root-cert)], [qw(ca-cert)]),
|
ok(!verify("ee-client", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
|
||||||
"fail wrong leaf purpose");
|
"fail wrong leaf purpose");
|
||||||
ok(!verify("ee-cert", "ssl_client", [qw(root-cert)], [qw(ca-cert)]),
|
ok(!verify("ee-cert", "sslclient", [qw(root-cert)], [qw(ca-cert)]),
|
||||||
"fail wrong leaf purpose");
|
"fail wrong leaf purpose");
|
||||||
ok(!verify("ee-cert2", "ssl_server", [qw(root-cert)], [qw(ca-cert)]),
|
ok(!verify("ee-cert2", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
|
||||||
"fail wrong CA key");
|
"fail wrong CA key");
|
||||||
ok(!verify("ee-name2", "ssl_server", [qw(root-cert)], [qw(ca-cert)]),
|
ok(!verify("ee-name2", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
|
||||||
"fail wrong CA name");
|
"fail wrong CA name");
|
||||||
ok(!verify("ee-expired", "ssl_server", [qw(root-cert)], [qw(ca-cert)]),
|
ok(!verify("ee-expired", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
|
||||||
"fail expired leaf");
|
"fail expired leaf");
|
||||||
ok(verify("ee-cert", "ssl_server", [qw(ee-cert)], [], "-partial_chain"),
|
ok(verify("ee-cert", "sslserver", [qw(ee-cert)], [], "-partial_chain"),
|
||||||
"accept last-resort direct leaf match");
|
"accept last-resort direct leaf match");
|
||||||
ok(verify("ee-client", "ssl_client", [qw(ee-client)], [], "-partial_chain"),
|
ok(verify("ee-client", "sslclient", [qw(ee-client)], [], "-partial_chain"),
|
||||||
"accept last-resort direct leaf match");
|
"accept last-resort direct leaf match");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(ee-client)], [], "-partial_chain"),
|
ok(!verify("ee-cert", "sslserver", [qw(ee-client)], [], "-partial_chain"),
|
||||||
"fail last-resort direct leaf non-match");
|
"fail last-resort direct leaf non-match");
|
||||||
ok(verify("ee-cert", "ssl_server", [qw(ee+serverAuth)], [], "-partial_chain"),
|
ok(verify("ee-cert", "sslserver", [qw(ee+serverAuth)], [], "-partial_chain"),
|
||||||
"accept direct match with trusted EKU");
|
"accept direct match with trusted EKU");
|
||||||
ok(!verify("ee-cert", "ssl_server", [qw(ee-serverAuth)], [], "-partial_chain"),
|
ok(!verify("ee-cert", "sslserver", [qw(ee-serverAuth)], [], "-partial_chain"),
|
||||||
"reject direct match with rejected EKU");
|
"reject direct match with rejected EKU");
|
||||||
ok(verify("ee-client", "ssl_client", [qw(ee+clientAuth)], [], "-partial_chain"),
|
ok(verify("ee-client", "sslclient", [qw(ee+clientAuth)], [], "-partial_chain"),
|
||||||
"accept direct match with trusted EKU");
|
"accept direct match with trusted EKU");
|
||||||
ok(!verify("ee-client", "ssl_client", [qw(ee-clientAuth)], [], "-partial_chain"),
|
ok(!verify("ee-client", "sslclient", [qw(ee-clientAuth)], [], "-partial_chain"),
|
||||||
"reject direct match with rejected EKU");
|
"reject direct match with rejected EKU");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user