[openssl-commits] [openssl] master update

Viktor Dukhovni viktor at openssl.org
Mon Feb 1 02:26:10 UTC 2016


The branch master has been updated
       via  1d852772355105cdb1cb0e7451b28358dd475e04 (commit)
       via  33cc5dde478ba5ad79f8fd4acd8737f0e60e236e (commit)
       via  0daccd4dc1f1ac62181738a91714f35472e50f3c (commit)
      from  1b4cf96f9b82ec3b06e7902bb21620a09cadd94e (commit)


- Log -----------------------------------------------------------------
commit 1d852772355105cdb1cb0e7451b28358dd475e04
Author: Viktor Dukhovni <openssl-users at dukhovni.org>
Date:   Fri Jan 29 12:22:21 2016 -0500

    Add tests for non-ca trusted roots and intermediates
    
    Reviewed-by: Dr. Stephen Henson <steve at openssl.org>

commit 33cc5dde478ba5ad79f8fd4acd8737f0e60e236e
Author: Viktor Dukhovni <openssl-users at dukhovni.org>
Date:   Fri Jan 29 02:28:43 2016 -0500

    Compat self-signed trust with reject-only aux data
    
    When auxiliary data contains only reject entries, continue to trust
    self-signed objects just as when no auxiliary data is present.
    
    This makes it possible to reject specific uses without changing
    what's accepted (and thus overring the underlying EKU).
    
    Added new supported certs and doubled test count from 38 to 76.
    
    Reviewed-by: Dr. Stephen Henson <steve at openssl.org>

commit 0daccd4dc1f1ac62181738a91714f35472e50f3c
Author: Viktor Dukhovni <openssl-users at dukhovni.org>
Date:   Thu Jan 28 03:01:45 2016 -0500

    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 at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 apps/opt.c                                         |  13 +-
 crypto/x509/x509_trs.c                             |  66 +++---
 crypto/x509/x509_vfy.c                             | 130 +++++++++---
 crypto/x509/x509_vpm.c                             |   6 +-
 doc/apps/verify.pod                                |  26 ++-
 doc/apps/x509.pod                                  |   9 +-
 doc/crypto/X509_VERIFY_PARAM_set_flags.pod         |  17 +-
 include/openssl/x509.h                             |   7 +-
 test/certs/{ca-serverAuth.pem => ca+anyEKU.pem}    |   2 +-
 test/certs/{ca-serverAuth.pem => ca-anyEKU.pem}    |   2 +-
 .../certs/{ca-serverAuth.pem => ca-clientAuth.pem} |   2 +-
 test/certs/cca+anyEKU.pem                          |  19 ++
 test/certs/cca+clientAuth.pem                      |  19 ++
 test/certs/cca+serverAuth.pem                      |  19 ++
 test/certs/cca-anyEKU.pem                          |  19 ++
 test/certs/cca-cert.pem                            |  19 ++
 test/certs/cca-clientAuth.pem                      |  19 ++
 test/certs/cca-serverAuth.pem                      |  19 ++
 test/certs/croot+anyEKU.pem                        |  19 ++
 test/certs/croot+clientAuth.pem                    |  19 ++
 test/certs/croot+serverAuth.pem                    |  19 ++
 test/certs/croot-anyEKU.pem                        |  19 ++
 test/certs/croot-cert.pem                          |  19 ++
 test/certs/croot-clientAuth.pem                    |  19 ++
 test/certs/croot-serverAuth.pem                    |  19 ++
 test/certs/mkcert.sh                               |  10 +-
 test/certs/{ca-nonca.pem => nca+anyEKU.pem}        |   6 +-
 test/certs/{ca-nonca.pem => nca+serverAuth.pem}    |   6 +-
 test/certs/{root-nonca.pem => nroot+anyEKU.pem}    |   6 +-
 .../certs/{root-nonca.pem => nroot+serverAuth.pem} |   6 +-
 .../certs/{root+clientAuth.pem => root+anyEKU.pem} |   3 +-
 .../certs/{root+clientAuth.pem => root-anyEKU.pem} |   3 +-
 .../{root-serverAuth.pem => root-clientAuth.pem}   |   2 +-
 .../certs/{root-cert2.pem => root2+clientAuth.pem} |   7 +-
 .../certs/{root-cert2.pem => root2+serverAuth.pem} |   7 +-
 .../certs/{root-cert2.pem => root2-serverAuth.pem} |   7 +-
 test/certs/sca+anyEKU.pem                          |  19 ++
 test/certs/sca+clientAuth.pem                      |  19 ++
 test/certs/sca+serverAuth.pem                      |  19 ++
 test/certs/sca-anyEKU.pem                          |  19 ++
 test/certs/sca-cert.pem                            |  19 ++
 test/certs/sca-clientAuth.pem                      |  19 ++
 test/certs/sca-serverAuth.pem                      |  19 ++
 test/certs/setup.sh                                | 104 ++++++++-
 test/certs/sroot+anyEKU.pem                        |  19 ++
 test/certs/sroot+clientAuth.pem                    |  19 ++
 test/certs/sroot+serverAuth.pem                    |  19 ++
 test/certs/sroot-anyEKU.pem                        |  19 ++
 test/certs/sroot-cert.pem                          |  19 ++
 test/certs/sroot-clientAuth.pem                    |  19 ++
 test/certs/sroot-serverAuth.pem                    |  19 ++
 test/recipes/25-test_verify.t                      | 234 ++++++++++++++++-----
 52 files changed, 1043 insertions(+), 170 deletions(-)
 copy test/certs/{ca-serverAuth.pem => ca+anyEKU.pem} (94%)
 copy test/certs/{ca-serverAuth.pem => ca-anyEKU.pem} (94%)
 copy test/certs/{ca-serverAuth.pem => ca-clientAuth.pem} (94%)
 create mode 100644 test/certs/cca+anyEKU.pem
 create mode 100644 test/certs/cca+clientAuth.pem
 create mode 100644 test/certs/cca+serverAuth.pem
 create mode 100644 test/certs/cca-anyEKU.pem
 create mode 100644 test/certs/cca-cert.pem
 create mode 100644 test/certs/cca-clientAuth.pem
 create mode 100644 test/certs/cca-serverAuth.pem
 create mode 100644 test/certs/croot+anyEKU.pem
 create mode 100644 test/certs/croot+clientAuth.pem
 create mode 100644 test/certs/croot+serverAuth.pem
 create mode 100644 test/certs/croot-anyEKU.pem
 create mode 100644 test/certs/croot-cert.pem
 create mode 100644 test/certs/croot-clientAuth.pem
 create mode 100644 test/certs/croot-serverAuth.pem
 copy test/certs/{ca-nonca.pem => nca+anyEKU.pem} (90%)
 copy test/certs/{ca-nonca.pem => nca+serverAuth.pem} (90%)
 copy test/certs/{root-nonca.pem => nroot+anyEKU.pem} (89%)
 copy test/certs/{root-nonca.pem => nroot+serverAuth.pem} (89%)
 copy test/certs/{root+clientAuth.pem => root+anyEKU.pem} (93%)
 copy test/certs/{root+clientAuth.pem => root-anyEKU.pem} (93%)
 copy test/certs/{root-serverAuth.pem => root-clientAuth.pem} (99%)
 copy test/certs/{root-cert2.pem => root2+clientAuth.pem} (87%)
 copy test/certs/{root-cert2.pem => root2+serverAuth.pem} (87%)
 copy test/certs/{root-cert2.pem => root2-serverAuth.pem} (87%)
 create mode 100644 test/certs/sca+anyEKU.pem
 create mode 100644 test/certs/sca+clientAuth.pem
 create mode 100644 test/certs/sca+serverAuth.pem
 create mode 100644 test/certs/sca-anyEKU.pem
 create mode 100644 test/certs/sca-cert.pem
 create mode 100644 test/certs/sca-clientAuth.pem
 create mode 100644 test/certs/sca-serverAuth.pem
 create mode 100644 test/certs/sroot+anyEKU.pem
 create mode 100644 test/certs/sroot+clientAuth.pem
 create mode 100644 test/certs/sroot+serverAuth.pem
 create mode 100644 test/certs/sroot-anyEKU.pem
 create mode 100644 test/certs/sroot-cert.pem
 create mode 100644 test/certs/sroot-clientAuth.pem
 create mode 100644 test/certs/sroot-serverAuth.pem

diff --git a/apps/opt.c b/apps/opt.c
index 14e05de..2fbc9fe 100644
--- a/apps/opt.c
+++ b/apps/opt.c
@@ -496,14 +496,25 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm)
         X509_VERIFY_PARAM_add0_policy(vpm, otmp);
         break;
     case OPT_V_PURPOSE:
+        /* purpose name -> purpose index */
         i = X509_PURPOSE_get_by_sname(opt_arg());
         if (i < 0) {
             BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg());
             return 0;
         }
+
+        /* purpose index -> purpose object */
         xptmp = X509_PURPOSE_get0(i);
+
+        /* purpose object -> purpose value */
         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;
     case OPT_V_VERIFY_NAME:
         vtmp = X509_VERIFY_PARAM_lookup(opt_arg());
diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c
index 7392c55..4c5281a 100644
--- a/crypto/x509/x509_trs.c
+++ b/crypto/x509/x509_trs.c
@@ -117,13 +117,9 @@ int X509_check_trust(X509 *x, int id, int flags)
     int idx;
 
     /* We get this as a default value */
-    if (id == 0) {
-        int rv;
-        rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
-        if (rv != X509_TRUST_UNTRUSTED)
-            return rv;
-        return trust_compat(NULL, x, 0);
-    }
+    if (id == X509_TRUST_DEFAULT)
+        return obj_trust(NID_anyExtendedKeyUsage, x,
+                         flags | X509_TRUST_DO_SS_COMPAT);
     idx = X509_TRUST_get_by_id(id);
     if (idx == -1)
         return default_trust(id, x, flags);
@@ -265,20 +261,25 @@ int X509_TRUST_get_trust(X509_TRUST *xp)
 
 static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
 {
-    if (x->aux && (x->aux->trust || x->aux->reject))
-        return obj_trust(trust->arg1, x, flags);
     /*
-     * we don't have any trust settings: for compatibility we return trusted
-     * if it is self signed
+     * Declare the chain verified if the desired trust OID is not rejected in
+     * any auxiliary trust info for this certificate, and the OID is either
+     * expressly trusted, or else either "anyEKU" is trusted, or the
+     * certificate is self-signed.
      */
-    return trust_compat(trust, x, flags);
+    flags |= X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU;
+    return obj_trust(trust->arg1, x, flags);
 }
 
 static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
 {
-    if (x->aux)
-        return obj_trust(trust->arg1, x, flags);
-    return X509_TRUST_UNTRUSTED;
+    /*
+     * Declare the chain verified only if the desired trust OID is not
+     * rejected and is expressly trusted.  Neither "anyEKU" nor "compat"
+     * trust in self-signed certificates apply.
+     */
+    flags &= ~(X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU);
+    return obj_trust(trust->arg1, x, flags);
 }
 
 static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
@@ -293,23 +294,27 @@ static int trust_compat(X509_TRUST *trust, 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;
-    X509_CERT_AUX *ax;
-    ax = x->aux;
-    if (!ax)
-        return X509_TRUST_UNTRUSTED;
-    if (ax->reject) {
+
+    if (ax && ax->reject) {
         for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
-            obj = sk_ASN1_OBJECT_value(ax->reject, i);
-            if (OBJ_obj2nid(obj) == id)
+            ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i);
+            int nid = OBJ_obj2nid(obj);
+
+            if (nid == id || (nid == NID_anyExtendedKeyUsage &&
+                (flags & X509_TRUST_OK_ANY_EKU)))
                 return X509_TRUST_REJECTED;
         }
     }
-    if (ax->trust) {
+
+    if (ax && ax->trust) {
         for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
-            obj = sk_ASN1_OBJECT_value(ax->trust, i);
-            if (OBJ_obj2nid(obj) == id)
+            ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i);
+            int nid = OBJ_obj2nid(obj);
+
+            if (nid == id || (nid == NID_anyExtendedKeyUsage &&
+                (flags & X509_TRUST_OK_ANY_EKU)))
                 return X509_TRUST_TRUSTED;
         }
         /*
@@ -328,5 +333,12 @@ static int obj_trust(int id, X509 *x, int flags)
          */
         return X509_TRUST_REJECTED;
     }
-    return X509_TRUST_UNTRUSTED;
+
+    if ((flags & X509_TRUST_DO_SS_COMPAT) == 0)
+        return X509_TRUST_UNTRUSTED;
+
+    /*
+     * Not rejected, and there is no list of accepted uses, try compat.
+     */
+    return trust_compat(NULL, x, flags);
 }
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 39d37b9..1f3b2b9 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -363,17 +363,72 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm)
 }
 
 /*
+ * 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 tr_ok = X509_TRUST_UNTRUSTED;
+
+    /*
+     * For trusted certificates we want to see whether any auxiliary trust
+     * settings trump the purpose constraints.
+     *
+     * 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.
+     */
+    if (depth >= ctx->num_untrusted && purpose == ctx->param->purpose)
+        tr_ok = X509_check_trust(x, ctx->param->trust, X509_TRUST_NO_SS_COMPAT);
+
+    switch (tr_ok) {
+    case X509_TRUST_TRUSTED:
+        return 1;
+    case X509_TRUST_REJECTED:
+        break;
+    default:
+        switch (X509_check_purpose(x, purpose, must_be_ca > 0)) {
+        case 1:
+            return 1;
+        case 0:
+            break;
+        default:
+            if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) == 0)
+                return 1;
+        }
+        break;
+    }
+
+    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
  * purpose
  */
 
 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;
     int proxy_path_length = 0;
     int purpose;
     int allow_proxy_certs;
+    int num = sk_X509_num(ctx->chain);
 
     /*-
      *  must_be_ca can have 1 of 3 values:
@@ -402,8 +457,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
         purpose = ctx->param->purpose;
     }
 
-    /* Check all untrusted certificates */
-    for (i = 0; i == 0 || i < ctx->num_untrusted; i++) {
+    for (i = 0; i < num; i++) {
         int ret;
         x = sk_X509_value(ctx->chain, i);
         if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
@@ -411,17 +465,15 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
             ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
             ctx->error_depth = i;
             ctx->current_cert = x;
-            ok = ctx->verify_cb(0, ctx);
-            if (!ok)
-                goto end;
+            if (!ctx->verify_cb(0, ctx))
+                return 0;
         }
         if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
             ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
             ctx->error_depth = i;
             ctx->current_cert = x;
-            ok = ctx->verify_cb(0, ctx);
-            if (!ok)
-                goto end;
+            if (!ctx->verify_cb(0, ctx))
+                return 0;
         }
         ret = X509_check_ca(x);
         switch (must_be_ca) {
@@ -453,22 +505,12 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
         if (ret == 0) {
             ctx->error_depth = i;
             ctx->current_cert = x;
-            ok = ctx->verify_cb(0, ctx);
-            if (!ok)
-                goto end;
+            if (!ctx->verify_cb(0, ctx))
+                return 0;
         }
-        if (ctx->param->purpose > 0) {
-            ret = X509_check_purpose(x, purpose, must_be_ca > 0);
-            if ((ret == 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;
-            }
+        if (purpose > 0) {
+            if (!check_purpose(ctx, x, purpose, i, must_be_ca))
+                return 0;
         }
         /* Check pathlen if not self issued */
         if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
@@ -477,9 +519,8 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
             ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
             ctx->error_depth = i;
             ctx->current_cert = x;
-            ok = ctx->verify_cb(0, ctx);
-            if (!ok)
-                goto end;
+            if (!ctx->verify_cb(0, ctx))
+                return 0;
         }
         /* Increment path length if not self issued */
         if (!(x->ex_flags & EXFLAG_SI))
@@ -494,18 +535,15 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                 ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
                 ctx->error_depth = i;
                 ctx->current_cert = x;
-                ok = ctx->verify_cb(0, ctx);
-                if (!ok)
-                    goto end;
+                if (!ctx->verify_cb(0, ctx))
+                    return 0;
             }
             proxy_path_length++;
             must_be_ca = 0;
         } else
             must_be_ca = 1;
     }
-    ok = 1;
- end:
-    return ok;
+    return 1;
 }
 
 static int check_name_constraints(X509_STORE_CTX *ctx)
@@ -2016,11 +2054,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)
 {
+    /*
+     * 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);
 }
 
 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);
 }
 
@@ -2054,6 +2101,11 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
         ptmp = X509_PURPOSE_get0(idx);
         if (ptmp->trust == X509_TRUST_DEFAULT) {
             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) {
                 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
                         X509_R_UNKNOWN_PURPOSE_ID);
@@ -2211,6 +2263,18 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
         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,
                            &ctx->ex_data))
         return 1;
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index 295ce88..41b0fde 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -133,7 +133,7 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
         return;
     param->name = NULL;
     param->purpose = 0;
-    param->trust = 0;
+    param->trust = X509_TRUST_DEFAULT;
     /*
      * param->inh_flags = X509_VP_FLAG_DEFAULT;
      */
@@ -243,7 +243,7 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
         to_overwrite = 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);
 
     /* If overwrite or check time not set, copy across */
@@ -511,7 +511,7 @@ static const X509_VERIFY_PARAM default_table[] = {
      "default",                 /* X509 default parameters */
      0,                         /* Check time */
      0,                         /* internal flags */
-     0,                         /* flags */
+     X509_V_FLAG_TRUSTED_FIRST, /* flags */
      0,                         /* purpose */
      0,                         /* trust */
      100,                       /* depth */
diff --git a/doc/apps/verify.pod b/doc/apps/verify.pod
index e15a5de..6d54592 100644
--- a/doc/apps/verify.pod
+++ b/doc/apps/verify.pod
@@ -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
 B<-untrusted>.
 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>
 
-When building a certificate chain, if the first certificate chain found is not
-trusted, then OpenSSL will continue to check to see if an alternative chain can
-be found that is trusted. With this option that behaviour is suppressed so that
-only the first chain found is ever used. Using this option will force the
-behaviour to match that of OpenSSL versions prior to 1.1.0.
+By default, unless B<-trusted_first> is specified, when building a certificate
+chain, if the first certificate chain found is not trusted, then OpenSSL will
+attempt to replace untrusted issuer certificates 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<-trusted_first> always on, this option has no
+effect.
 
 =item B<-untrusted file>
 
@@ -264,13 +266,17 @@ the subject certificate.
 
 Use default verification policies like trust model and required certificate
 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>,
 B<ssl_client>, B<ssl_server>.
-This checks not only the purpose of the leaf certificate, but also the
-trust settings of the trusted CAs.
-When in doubt, use this option rather than B<-purpose>.
-The B<-verify_name> option more closely matches how certificates are checked in
-e.g. SSL and S/MIME.
+These mimics the combinations of purpose and trust settings used in SSL, CMS
+and S/MIME.
+As of OpenSSL 1.1.0, the trust model is inferred from the purpose when not
+specified, so the B<-verify_name> options are functionally equivalent to the
+corresponding B<-purpose> settings.
 
 =item B<-x509_strict>
 
diff --git a/doc/apps/x509.pod b/doc/apps/x509.pod
index 1c98e9d..637eedc 100644
--- a/doc/apps/x509.pod
+++ b/doc/apps/x509.pod
@@ -289,9 +289,12 @@ clears all the prohibited or rejected uses of the certificate.
 
 =item B<-addtrust arg>
 
-adds a trusted certificate use. Any object name can be used here
-but currently only B<clientAuth> (SSL client use), B<serverAuth>
-(SSL server use) and B<emailProtection> (S/MIME email) are used.
+adds a trusted certificate use.
+Any object name can be used here but currently only B<clientAuth> (SSL client
+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.
 
 =item B<-addreject arg>
diff --git a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
index a2219d2..53a063a 100644
--- a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
+++ b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
@@ -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
 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
-chains. By default, when building a certificate chain, if the first certificate
-chain found is not trusted, then OpenSSL will continue to check to see if an
-alternative chain can be found that is trusted. With this flag set the behaviour
-will match that of OpenSSL versions prior to 1.1.0.
+chains.
+By default, unless B<X509_V_FLAG_TRUSTED_FIRST> is set, when building a
+certificate chain, if the first certificate chain found is not trusted, then
+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
 of certificates and CRLs against the current time. If X509_VERIFY_PARAM_set_time()
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 31f784d..06fc99e 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -183,7 +183,7 @@ DEFINE_STACK_OF(X509_TRUST)
 
 /* 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_SSL_CLIENT   2
@@ -201,7 +201,12 @@ DEFINE_STACK_OF(X509_TRUST)
 /* trust_flags values */
 # define X509_TRUST_DYNAMIC      (1U << 0)
 # define X509_TRUST_DYNAMIC_NAME (1U << 1)
+/* No compat trust if self-signed, preempts "DO_SS" */
 # define X509_TRUST_NO_SS_COMPAT (1U << 2)
+/* Compat trust if no explicit accepted trust EKUs */
+# define X509_TRUST_DO_SS_COMPAT (1U << 3)
+/* Accept "anyEKU" as a wildcard trust OID */
+# define X509_TRUST_OK_ANY_EKU   (1U << 4)
 
 /* check_trust return codes */
 
diff --git a/test/certs/ca-serverAuth.pem b/test/certs/ca+anyEKU.pem
similarity index 94%
copy from test/certs/ca-serverAuth.pem
copy to test/certs/ca+anyEKU.pem
index f10155d..36ed837 100644
--- a/test/certs/ca-serverAuth.pem
+++ b/test/certs/ca+anyEKU.pem
@@ -14,5 +14,5 @@ IM9ox88wYKWynanPbra4n0zhepooKt+naeY2HLR8UgwT6sTi0Yfld9mjytA8/DP6
 AcqtIDDf60vNI00sgxjgZqofVayA9KShzIPzjBec4zI1sg5YzoSNyH28VXFstEpi
 8CVtmRYQHhc2gDI9MGge4sHRYwaIFkegzpwcEUnp6tTVe9ZvHawgsXF/rCGfH4M6
 uNO0D+9Md1bdW7382yOtWbkyibsugqnfBYCUH6hAhDlfYzpba2Smb0roc6Crq7HR
-5HpEYY6qEir9wFMkD5MZsWrNRGRuzd5am82J+aaHz/4wDKAKBggrBgEFBQcDAQ==
+5HpEYY6qEir9wFMkD5MZsWrNRGRuzd5am82J+aaHz/4wCDAGBgRVHSUA
 -----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/ca-serverAuth.pem b/test/certs/ca-anyEKU.pem
similarity index 94%
copy from test/certs/ca-serverAuth.pem
copy to test/certs/ca-anyEKU.pem
index f10155d..241d7b4 100644
--- a/test/certs/ca-serverAuth.pem
+++ b/test/certs/ca-anyEKU.pem
@@ -14,5 +14,5 @@ IM9ox88wYKWynanPbra4n0zhepooKt+naeY2HLR8UgwT6sTi0Yfld9mjytA8/DP6
 AcqtIDDf60vNI00sgxjgZqofVayA9KShzIPzjBec4zI1sg5YzoSNyH28VXFstEpi
 8CVtmRYQHhc2gDI9MGge4sHRYwaIFkegzpwcEUnp6tTVe9ZvHawgsXF/rCGfH4M6
 uNO0D+9Md1bdW7382yOtWbkyibsugqnfBYCUH6hAhDlfYzpba2Smb0roc6Crq7HR
-5HpEYY6qEir9wFMkD5MZsWrNRGRuzd5am82J+aaHz/4wDKAKBggrBgEFBQcDAQ==
+5HpEYY6qEir9wFMkD5MZsWrNRGRuzd5am82J+aaHz/4wCKAGBgRVHSUA
 -----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/ca-serverAuth.pem b/test/certs/ca-clientAuth.pem
similarity index 94%
copy from test/certs/ca-serverAuth.pem
copy to test/certs/ca-clientAuth.pem
index f10155d..838c70e 100644
--- a/test/certs/ca-serverAuth.pem
+++ b/test/certs/ca-clientAuth.pem
@@ -14,5 +14,5 @@ IM9ox88wYKWynanPbra4n0zhepooKt+naeY2HLR8UgwT6sTi0Yfld9mjytA8/DP6
 AcqtIDDf60vNI00sgxjgZqofVayA9KShzIPzjBec4zI1sg5YzoSNyH28VXFstEpi
 8CVtmRYQHhc2gDI9MGge4sHRYwaIFkegzpwcEUnp6tTVe9ZvHawgsXF/rCGfH4M6
 uNO0D+9Md1bdW7382yOtWbkyibsugqnfBYCUH6hAhDlfYzpba2Smb0roc6Crq7HR
-5HpEYY6qEir9wFMkD5MZsWrNRGRuzd5am82J+aaHz/4wDKAKBggrBgEFBQcDAQ==
+5HpEYY6qEir9wFMkD5MZsWrNRGRuzd5am82J+aaHz/4wDKAKBggrBgEFBQcDAg==
 -----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/cca+anyEKU.pem b/test/certs/cca+anyEKU.pem
new file mode 100644
index 0000000..46ee9fa
--- /dev/null
+++ b/test/certs/cca+anyEKU.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAB6mihrap7ByLl3w
+P/0XsqMvOkxCxoWTeI0cEwbxSpUXfMTE24oIQJiqIyHO6qeSRgSywk/DTU0uJWOB
+Idr6dPI6wPrS4jvFqcgoFH1OPjAJCpl5CuCJEH8gB3LJ4dNfj+O7shT0XeI+R1vw
+gp+fJ8v6jX4y8Nk/Bcy748dC1HZhMWHxQblzjRu8Xmd6lDiMskoWE2JAwgRK7b3M
+dCpuTCHMTsdCspwBUvQ4gNYNP5IURE+09DBtEBQicN/1RHyRZOw7YGs5ZOdc5mRe
+O5E+WHE1xiJ0QwUu2co55PFlukidWXx7LE02foNaNm+rw4OUTrzsqmmgkp1qqAab
+ap/RSXgwCDAGBgRVHSUA
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/cca+clientAuth.pem b/test/certs/cca+clientAuth.pem
new file mode 100644
index 0000000..0b857ee
--- /dev/null
+++ b/test/certs/cca+clientAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAB6mihrap7ByLl3w
+P/0XsqMvOkxCxoWTeI0cEwbxSpUXfMTE24oIQJiqIyHO6qeSRgSywk/DTU0uJWOB
+Idr6dPI6wPrS4jvFqcgoFH1OPjAJCpl5CuCJEH8gB3LJ4dNfj+O7shT0XeI+R1vw
+gp+fJ8v6jX4y8Nk/Bcy748dC1HZhMWHxQblzjRu8Xmd6lDiMskoWE2JAwgRK7b3M
+dCpuTCHMTsdCspwBUvQ4gNYNP5IURE+09DBtEBQicN/1RHyRZOw7YGs5ZOdc5mRe
+O5E+WHE1xiJ0QwUu2co55PFlukidWXx7LE02foNaNm+rw4OUTrzsqmmgkp1qqAab
+ap/RSXgwDDAKBggrBgEFBQcDAg==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/cca+serverAuth.pem b/test/certs/cca+serverAuth.pem
new file mode 100644
index 0000000..38a0bdb
--- /dev/null
+++ b/test/certs/cca+serverAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAB6mihrap7ByLl3w
+P/0XsqMvOkxCxoWTeI0cEwbxSpUXfMTE24oIQJiqIyHO6qeSRgSywk/DTU0uJWOB
+Idr6dPI6wPrS4jvFqcgoFH1OPjAJCpl5CuCJEH8gB3LJ4dNfj+O7shT0XeI+R1vw
+gp+fJ8v6jX4y8Nk/Bcy748dC1HZhMWHxQblzjRu8Xmd6lDiMskoWE2JAwgRK7b3M
+dCpuTCHMTsdCspwBUvQ4gNYNP5IURE+09DBtEBQicN/1RHyRZOw7YGs5ZOdc5mRe
+O5E+WHE1xiJ0QwUu2co55PFlukidWXx7LE02foNaNm+rw4OUTrzsqmmgkp1qqAab
+ap/RSXgwDDAKBggrBgEFBQcDAQ==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/cca-anyEKU.pem b/test/certs/cca-anyEKU.pem
new file mode 100644
index 0000000..cb3e708
--- /dev/null
+++ b/test/certs/cca-anyEKU.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAB6mihrap7ByLl3w
+P/0XsqMvOkxCxoWTeI0cEwbxSpUXfMTE24oIQJiqIyHO6qeSRgSywk/DTU0uJWOB
+Idr6dPI6wPrS4jvFqcgoFH1OPjAJCpl5CuCJEH8gB3LJ4dNfj+O7shT0XeI+R1vw
+gp+fJ8v6jX4y8Nk/Bcy748dC1HZhMWHxQblzjRu8Xmd6lDiMskoWE2JAwgRK7b3M
+dCpuTCHMTsdCspwBUvQ4gNYNP5IURE+09DBtEBQicN/1RHyRZOw7YGs5ZOdc5mRe
+O5E+WHE1xiJ0QwUu2co55PFlukidWXx7LE02foNaNm+rw4OUTrzsqmmgkp1qqAab
+ap/RSXgwCKAGBgRVHSUA
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/cca-cert.pem b/test/certs/cca-cert.pem
new file mode 100644
index 0000000..6bccc4c
--- /dev/null
+++ b/test/certs/cca-cert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAB6mihrap7ByLl3w
+P/0XsqMvOkxCxoWTeI0cEwbxSpUXfMTE24oIQJiqIyHO6qeSRgSywk/DTU0uJWOB
+Idr6dPI6wPrS4jvFqcgoFH1OPjAJCpl5CuCJEH8gB3LJ4dNfj+O7shT0XeI+R1vw
+gp+fJ8v6jX4y8Nk/Bcy748dC1HZhMWHxQblzjRu8Xmd6lDiMskoWE2JAwgRK7b3M
+dCpuTCHMTsdCspwBUvQ4gNYNP5IURE+09DBtEBQicN/1RHyRZOw7YGs5ZOdc5mRe
+O5E+WHE1xiJ0QwUu2co55PFlukidWXx7LE02foNaNm+rw4OUTrzsqmmgkp1qqAab
+ap/RSXg=
+-----END CERTIFICATE-----
diff --git a/test/certs/cca-clientAuth.pem b/test/certs/cca-clientAuth.pem
new file mode 100644
index 0000000..0b857ee
--- /dev/null
+++ b/test/certs/cca-clientAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAB6mihrap7ByLl3w
+P/0XsqMvOkxCxoWTeI0cEwbxSpUXfMTE24oIQJiqIyHO6qeSRgSywk/DTU0uJWOB
+Idr6dPI6wPrS4jvFqcgoFH1OPjAJCpl5CuCJEH8gB3LJ4dNfj+O7shT0XeI+R1vw
+gp+fJ8v6jX4y8Nk/Bcy748dC1HZhMWHxQblzjRu8Xmd6lDiMskoWE2JAwgRK7b3M
+dCpuTCHMTsdCspwBUvQ4gNYNP5IURE+09DBtEBQicN/1RHyRZOw7YGs5ZOdc5mRe
+O5E+WHE1xiJ0QwUu2co55PFlukidWXx7LE02foNaNm+rw4OUTrzsqmmgkp1qqAab
+ap/RSXgwDDAKBggrBgEFBQcDAg==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/cca-serverAuth.pem b/test/certs/cca-serverAuth.pem
new file mode 100644
index 0000000..46cbce0
--- /dev/null
+++ b/test/certs/cca-serverAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAB6mihrap7ByLl3w
+P/0XsqMvOkxCxoWTeI0cEwbxSpUXfMTE24oIQJiqIyHO6qeSRgSywk/DTU0uJWOB
+Idr6dPI6wPrS4jvFqcgoFH1OPjAJCpl5CuCJEH8gB3LJ4dNfj+O7shT0XeI+R1vw
+gp+fJ8v6jX4y8Nk/Bcy748dC1HZhMWHxQblzjRu8Xmd6lDiMskoWE2JAwgRK7b3M
+dCpuTCHMTsdCspwBUvQ4gNYNP5IURE+09DBtEBQicN/1RHyRZOw7YGs5ZOdc5mRe
+O5E+WHE1xiJ0QwUu2co55PFlukidWXx7LE02foNaNm+rw4OUTrzsqmmgkp1qqAab
+ap/RSXgwDKAKBggrBgEFBQcDAQ==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/croot+anyEKU.pem b/test/certs/croot+anyEKU.pem
new file mode 100644
index 0000000..88ce120
--- /dev/null
+++ b/test/certs/croot+anyEKU.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAi/mR+SIa
+bs1egGRRSAzqu4KkrOG1vGVQNj0XfHn1WeAdmwEAjNi+llErpkMyY08Cjb/3fiQc
+6H9CA36utf/Ym84OQOY64m4C1Kikxw8EHudoPNvSWQAFEpCk5gs6rCJEnj9QolL3
+32IvZQ1m+GcrjGg976PccEaM7S362kTj+kcAswmS8iJmDAJ2b+ghHTFrFQS4GAw7
+XOcqQbinx9ntGn135VsJLOXKveYvQSD7sHKCd4RFrFTSEwWmtBL96vRXmTV5wTAr
+tpkKKKw5N9CiHnbhNyVrSRiLCzVDTpYQDaBJhb7XOsHi+/HOzmbK6LHe0Lt1nP+k
+4PR8O0S5WC0PlzAIMAYGBFUdJQA=
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/croot+clientAuth.pem b/test/certs/croot+clientAuth.pem
new file mode 100644
index 0000000..aa45a06
--- /dev/null
+++ b/test/certs/croot+clientAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAi/mR+SIa
+bs1egGRRSAzqu4KkrOG1vGVQNj0XfHn1WeAdmwEAjNi+llErpkMyY08Cjb/3fiQc
+6H9CA36utf/Ym84OQOY64m4C1Kikxw8EHudoPNvSWQAFEpCk5gs6rCJEnj9QolL3
+32IvZQ1m+GcrjGg976PccEaM7S362kTj+kcAswmS8iJmDAJ2b+ghHTFrFQS4GAw7
+XOcqQbinx9ntGn135VsJLOXKveYvQSD7sHKCd4RFrFTSEwWmtBL96vRXmTV5wTAr
+tpkKKKw5N9CiHnbhNyVrSRiLCzVDTpYQDaBJhb7XOsHi+/HOzmbK6LHe0Lt1nP+k
+4PR8O0S5WC0PlzAMMAoGCCsGAQUFBwMC
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/croot+serverAuth.pem b/test/certs/croot+serverAuth.pem
new file mode 100644
index 0000000..3564769
--- /dev/null
+++ b/test/certs/croot+serverAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAi/mR+SIa
+bs1egGRRSAzqu4KkrOG1vGVQNj0XfHn1WeAdmwEAjNi+llErpkMyY08Cjb/3fiQc
+6H9CA36utf/Ym84OQOY64m4C1Kikxw8EHudoPNvSWQAFEpCk5gs6rCJEnj9QolL3
+32IvZQ1m+GcrjGg976PccEaM7S362kTj+kcAswmS8iJmDAJ2b+ghHTFrFQS4GAw7
+XOcqQbinx9ntGn135VsJLOXKveYvQSD7sHKCd4RFrFTSEwWmtBL96vRXmTV5wTAr
+tpkKKKw5N9CiHnbhNyVrSRiLCzVDTpYQDaBJhb7XOsHi+/HOzmbK6LHe0Lt1nP+k
+4PR8O0S5WC0PlzAMMAoGCCsGAQUFBwMB
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/croot-anyEKU.pem b/test/certs/croot-anyEKU.pem
new file mode 100644
index 0000000..50fffbf
--- /dev/null
+++ b/test/certs/croot-anyEKU.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAi/mR+SIa
+bs1egGRRSAzqu4KkrOG1vGVQNj0XfHn1WeAdmwEAjNi+llErpkMyY08Cjb/3fiQc
+6H9CA36utf/Ym84OQOY64m4C1Kikxw8EHudoPNvSWQAFEpCk5gs6rCJEnj9QolL3
+32IvZQ1m+GcrjGg976PccEaM7S362kTj+kcAswmS8iJmDAJ2b+ghHTFrFQS4GAw7
+XOcqQbinx9ntGn135VsJLOXKveYvQSD7sHKCd4RFrFTSEwWmtBL96vRXmTV5wTAr
+tpkKKKw5N9CiHnbhNyVrSRiLCzVDTpYQDaBJhb7XOsHi+/HOzmbK6LHe0Lt1nP+k
+4PR8O0S5WC0PlzAIoAYGBFUdJQA=
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/croot-cert.pem b/test/certs/croot-cert.pem
new file mode 100644
index 0000000..f3459f4
--- /dev/null
+++ b/test/certs/croot-cert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAi/mR+SIa
+bs1egGRRSAzqu4KkrOG1vGVQNj0XfHn1WeAdmwEAjNi+llErpkMyY08Cjb/3fiQc
+6H9CA36utf/Ym84OQOY64m4C1Kikxw8EHudoPNvSWQAFEpCk5gs6rCJEnj9QolL3
+32IvZQ1m+GcrjGg976PccEaM7S362kTj+kcAswmS8iJmDAJ2b+ghHTFrFQS4GAw7
+XOcqQbinx9ntGn135VsJLOXKveYvQSD7sHKCd4RFrFTSEwWmtBL96vRXmTV5wTAr
+tpkKKKw5N9CiHnbhNyVrSRiLCzVDTpYQDaBJhb7XOsHi+/HOzmbK6LHe0Lt1nP+k
+4PR8O0S5WC0Plw==
+-----END CERTIFICATE-----
diff --git a/test/certs/croot-clientAuth.pem b/test/certs/croot-clientAuth.pem
new file mode 100644
index 0000000..7845641
--- /dev/null
+++ b/test/certs/croot-clientAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAi/mR+SIa
+bs1egGRRSAzqu4KkrOG1vGVQNj0XfHn1WeAdmwEAjNi+llErpkMyY08Cjb/3fiQc
+6H9CA36utf/Ym84OQOY64m4C1Kikxw8EHudoPNvSWQAFEpCk5gs6rCJEnj9QolL3
+32IvZQ1m+GcrjGg976PccEaM7S362kTj+kcAswmS8iJmDAJ2b+ghHTFrFQS4GAw7
+XOcqQbinx9ntGn135VsJLOXKveYvQSD7sHKCd4RFrFTSEwWmtBL96vRXmTV5wTAr
+tpkKKKw5N9CiHnbhNyVrSRiLCzVDTpYQDaBJhb7XOsHi+/HOzmbK6LHe0Lt1nP+k
+4PR8O0S5WC0PlzAMoAoGCCsGAQUFBwMC
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/croot-serverAuth.pem b/test/certs/croot-serverAuth.pem
new file mode 100644
index 0000000..7e4ffa7
--- /dev/null
+++ b/test/certs/croot-serverAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAi/mR+SIa
+bs1egGRRSAzqu4KkrOG1vGVQNj0XfHn1WeAdmwEAjNi+llErpkMyY08Cjb/3fiQc
+6H9CA36utf/Ym84OQOY64m4C1Kikxw8EHudoPNvSWQAFEpCk5gs6rCJEnj9QolL3
+32IvZQ1m+GcrjGg976PccEaM7S362kTj+kcAswmS8iJmDAJ2b+ghHTFrFQS4GAw7
+XOcqQbinx9ntGn135VsJLOXKveYvQSD7sHKCd4RFrFTSEwWmtBL96vRXmTV5wTAr
+tpkKKKw5N9CiHnbhNyVrSRiLCzVDTpYQDaBJhb7XOsHi+/HOzmbK6LHe0Lt1nP+k
+4PR8O0S5WC0PlzAMoAoGCCsGAQUFBwMB
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/mkcert.sh b/test/certs/mkcert.sh
index 5116daa..d5870c7 100755
--- a/test/certs/mkcert.sh
+++ b/test/certs/mkcert.sh
@@ -85,6 +85,10 @@ genroot() {
     local akid="authorityKeyIdentifier = keyid"
 
     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = CA:true")
+    for eku in "$@"
+    do
+        exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
+    done
     csr=$(req "$key" "$cn") || return 1
     echo "$csr" |
        cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
@@ -100,10 +104,14 @@ genca() {
     local akid="authorityKeyIdentifier = keyid"
 
     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = CA:true")
+    for eku in "$@"
+    do
+        exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
+    done
     csr=$(req "$key" "$cn") || return 1
     echo "$csr" |
         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
-	    -set_serial 2 -days "${DAYS}" "$@"
+	    -set_serial 2 -days "${DAYS}"
 }
 
 genee() {
diff --git a/test/certs/ca-nonca.pem b/test/certs/nca+anyEKU.pem
similarity index 90%
copy from test/certs/ca-nonca.pem
copy to test/certs/nca+anyEKU.pem
index cdb2cd1..b97a455 100644
--- a/test/certs/ca-nonca.pem
+++ b/test/certs/nca+anyEKU.pem
@@ -1,4 +1,4 @@
------BEGIN CERTIFICATE-----
+-----BEGIN TRUSTED CERTIFICATE-----
 MIIDDTCCAfWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
 IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjANMQswCQYDVQQD
 DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
@@ -15,5 +15,5 @@ X390IUWrRJ8C7SJtyGOhbh2E6Zn7TveI77Mnw2CZpGhy+xieqTFmaIIWJgZVzaTT
 3hMhnXImn06k8eJiJiQQAHKr9XKDK9HIiESyBpujIW5hI7wrklkn0asl6DwiXcUw
 AuXqNffWpomWI4ZZceOJkr5dSFM9HyksQi4uzj0qYTDyDHJ6BLuGYWbUoB64pnKF
 wCn0cPOmbo866l0XqzJlxQYPvwOicAptX8jTjSpYsx5SLripS4KwyfxbGy5If8mT
-X4st+BN48+n9wHuDQJ97sBs=
------END CERTIFICATE-----
+X4st+BN48+n9wHuDQJ97sBswDDAKBggrBgEFBQcDAQ==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/ca-nonca.pem b/test/certs/nca+serverAuth.pem
similarity index 90%
copy from test/certs/ca-nonca.pem
copy to test/certs/nca+serverAuth.pem
index cdb2cd1..b97a455 100644
--- a/test/certs/ca-nonca.pem
+++ b/test/certs/nca+serverAuth.pem
@@ -1,4 +1,4 @@
------BEGIN CERTIFICATE-----
+-----BEGIN TRUSTED CERTIFICATE-----
 MIIDDTCCAfWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
 IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjANMQswCQYDVQQD
 DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
@@ -15,5 +15,5 @@ X390IUWrRJ8C7SJtyGOhbh2E6Zn7TveI77Mnw2CZpGhy+xieqTFmaIIWJgZVzaTT
 3hMhnXImn06k8eJiJiQQAHKr9XKDK9HIiESyBpujIW5hI7wrklkn0asl6DwiXcUw
 AuXqNffWpomWI4ZZceOJkr5dSFM9HyksQi4uzj0qYTDyDHJ6BLuGYWbUoB64pnKF
 wCn0cPOmbo866l0XqzJlxQYPvwOicAptX8jTjSpYsx5SLripS4KwyfxbGy5If8mT
-X4st+BN48+n9wHuDQJ97sBs=
------END CERTIFICATE-----
+X4st+BN48+n9wHuDQJ97sBswDDAKBggrBgEFBQcDAQ==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/root-nonca.pem b/test/certs/nroot+anyEKU.pem
similarity index 89%
copy from test/certs/root-nonca.pem
copy to test/certs/nroot+anyEKU.pem
index 5c86abe..395b844 100644
--- a/test/certs/root-nonca.pem
+++ b/test/certs/nroot+anyEKU.pem
@@ -1,4 +1,4 @@
------BEGIN CERTIFICATE-----
+-----BEGIN TRUSTED CERTIFICATE-----
 MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
 IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
 DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
@@ -15,5 +15,5 @@ fF0nLoRb/6iCd0VnJlliTKky/p8aaG4+VooQPTxwpat6zir4G1N2dWwYbMTDpVfh
 836wHNPmmFvCUSKZcoLAEmMVRrNU9gBXkS64FfoP0FCoWeHb9NSlQY5YFb0BO8C/
 6AZlMGCt1HDPEK+gE/Uwayk7Yo3npSb+ZgnwZpA0ip0lPJ0Uf5cZ5Q/RBP0H+nxi
 KLKzBpY01IJ67/7R1Ioc27JiUpBGmKQzjg48POSMOECFolv0dH33O6aXJaXtw9Kq
-m8y3rPQqNPehWzbRq75txC/sayQZXNUrteVz
------END CERTIFICATE-----
+m8y3rPQqNPehWzbRq75txC/sayQZXNUrteVzMAgwBgYEVR0lAA==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/root-nonca.pem b/test/certs/nroot+serverAuth.pem
similarity index 89%
copy from test/certs/root-nonca.pem
copy to test/certs/nroot+serverAuth.pem
index 5c86abe..7b84f26 100644
--- a/test/certs/root-nonca.pem
+++ b/test/certs/nroot+serverAuth.pem
@@ -1,4 +1,4 @@
------BEGIN CERTIFICATE-----
+-----BEGIN TRUSTED CERTIFICATE-----
 MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
 IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
 DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
@@ -15,5 +15,5 @@ fF0nLoRb/6iCd0VnJlliTKky/p8aaG4+VooQPTxwpat6zir4G1N2dWwYbMTDpVfh
 836wHNPmmFvCUSKZcoLAEmMVRrNU9gBXkS64FfoP0FCoWeHb9NSlQY5YFb0BO8C/
 6AZlMGCt1HDPEK+gE/Uwayk7Yo3npSb+ZgnwZpA0ip0lPJ0Uf5cZ5Q/RBP0H+nxi
 KLKzBpY01IJ67/7R1Ioc27JiUpBGmKQzjg48POSMOECFolv0dH33O6aXJaXtw9Kq
-m8y3rPQqNPehWzbRq75txC/sayQZXNUrteVz
------END CERTIFICATE-----
+m8y3rPQqNPehWzbRq75txC/sayQZXNUrteVzMAwwCgYIKwYBBQUHAwE=
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/root+clientAuth.pem b/test/certs/root+anyEKU.pem
similarity index 93%
copy from test/certs/root+clientAuth.pem
copy to test/certs/root+anyEKU.pem
index 8004e63..97e0732 100644
--- a/test/certs/root+clientAuth.pem
+++ b/test/certs/root+anyEKU.pem
@@ -14,6 +14,5 @@ bzKySoyLpoV2/YNAvTAGB90iFq6x/ujjrK41/ES0p3v38/Qfuxo24gcZgc/oYLV2
 UqR+uGCx68p2OWLYctBsARtYWOEgPhHFb9aVxcOQKyZHtivDX0wLGX+nqZoHX9IY
 mc0sbpRBRMzxRsChbzD5re9kZ5NrgkjA6DJ7jYh2GitOM6oIU3Dd9+pk3bCEkFUg
 Ry9qN/k+AyeqH1Qcb5LU+MTmlw8bmyzmMOBZgdegtO4HshcBMO054KSB3WSfBPDO
-bEhZ0vm/lw63TGi88yIMtlkmcU2g0RKpeQI96G6QeqHyKF3p8DAMMAoGCCsGAQUF
-BwMC
+bEhZ0vm/lw63TGi88yIMtlkmcU2g0RKpeQI96G6QeqHyKF3p8DAIMAYGBFUdJQA=
 -----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/root+clientAuth.pem b/test/certs/root-anyEKU.pem
similarity index 93%
copy from test/certs/root+clientAuth.pem
copy to test/certs/root-anyEKU.pem
index 8004e63..712b1f5 100644
--- a/test/certs/root+clientAuth.pem
+++ b/test/certs/root-anyEKU.pem
@@ -14,6 +14,5 @@ bzKySoyLpoV2/YNAvTAGB90iFq6x/ujjrK41/ES0p3v38/Qfuxo24gcZgc/oYLV2
 UqR+uGCx68p2OWLYctBsARtYWOEgPhHFb9aVxcOQKyZHtivDX0wLGX+nqZoHX9IY
 mc0sbpRBRMzxRsChbzD5re9kZ5NrgkjA6DJ7jYh2GitOM6oIU3Dd9+pk3bCEkFUg
 Ry9qN/k+AyeqH1Qcb5LU+MTmlw8bmyzmMOBZgdegtO4HshcBMO054KSB3WSfBPDO
-bEhZ0vm/lw63TGi88yIMtlkmcU2g0RKpeQI96G6QeqHyKF3p8DAMMAoGCCsGAQUF
-BwMC
+bEhZ0vm/lw63TGi88yIMtlkmcU2g0RKpeQI96G6QeqHyKF3p8DAIoAYGBFUdJQA=
 -----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/root-serverAuth.pem b/test/certs/root-clientAuth.pem
similarity index 99%
copy from test/certs/root-serverAuth.pem
copy to test/certs/root-clientAuth.pem
index 37b49f6..8d82866 100644
--- a/test/certs/root-serverAuth.pem
+++ b/test/certs/root-clientAuth.pem
@@ -15,5 +15,5 @@ UqR+uGCx68p2OWLYctBsARtYWOEgPhHFb9aVxcOQKyZHtivDX0wLGX+nqZoHX9IY
 mc0sbpRBRMzxRsChbzD5re9kZ5NrgkjA6DJ7jYh2GitOM6oIU3Dd9+pk3bCEkFUg
 Ry9qN/k+AyeqH1Qcb5LU+MTmlw8bmyzmMOBZgdegtO4HshcBMO054KSB3WSfBPDO
 bEhZ0vm/lw63TGi88yIMtlkmcU2g0RKpeQI96G6QeqHyKF3p8DAMoAoGCCsGAQUF
-BwMB
+BwMC
 -----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/root-cert2.pem b/test/certs/root2+clientAuth.pem
similarity index 87%
copy from test/certs/root-cert2.pem
copy to test/certs/root2+clientAuth.pem
index e47e91e..41355b0 100644
--- a/test/certs/root-cert2.pem
+++ b/test/certs/root2+clientAuth.pem
@@ -1,4 +1,4 @@
------BEGIN CERTIFICATE-----
+-----BEGIN TRUSTED CERTIFICATE-----
 MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
 IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
 DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyB6dJAD5
@@ -14,5 +14,6 @@ NpbsWX0ta2pDPhiBpIbrTrTmw656MMRkwMLYIAX7BFhyjO9gO0nVXfU1SSTDsso+
 qu/K1t2US/rLeJQn8gYiTw6AqmvxHOndLaZQrYef4rUzsYnahNzxcoS1FMVxoJFM
 o+1Wo0BFBlASv5Az0iFfjd1Uy3+AHB41+2vczNIWSki3mg4hzus2PSS4AA9IYeh+
 zU/HJMddnVedLKNstTAfR85ftACtsP6JhBqCBqC4mCVsN2ZlgucETbsOMyWYB4+y
-9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1w==
------END CERTIFICATE-----
+9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1zAMMAoGCCsGAQUF
+BwMC
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/root-cert2.pem b/test/certs/root2+serverAuth.pem
similarity index 87%
copy from test/certs/root-cert2.pem
copy to test/certs/root2+serverAuth.pem
index e47e91e..52053f1 100644
--- a/test/certs/root-cert2.pem
+++ b/test/certs/root2+serverAuth.pem
@@ -1,4 +1,4 @@
------BEGIN CERTIFICATE-----
+-----BEGIN TRUSTED CERTIFICATE-----
 MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
 IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
 DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyB6dJAD5
@@ -14,5 +14,6 @@ NpbsWX0ta2pDPhiBpIbrTrTmw656MMRkwMLYIAX7BFhyjO9gO0nVXfU1SSTDsso+
 qu/K1t2US/rLeJQn8gYiTw6AqmvxHOndLaZQrYef4rUzsYnahNzxcoS1FMVxoJFM
 o+1Wo0BFBlASv5Az0iFfjd1Uy3+AHB41+2vczNIWSki3mg4hzus2PSS4AA9IYeh+
 zU/HJMddnVedLKNstTAfR85ftACtsP6JhBqCBqC4mCVsN2ZlgucETbsOMyWYB4+y
-9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1w==
------END CERTIFICATE-----
+9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1zAMMAoGCCsGAQUF
+BwMB
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/root-cert2.pem b/test/certs/root2-serverAuth.pem
similarity index 87%
copy from test/certs/root-cert2.pem
copy to test/certs/root2-serverAuth.pem
index e47e91e..dae848a 100644
--- a/test/certs/root-cert2.pem
+++ b/test/certs/root2-serverAuth.pem
@@ -1,4 +1,4 @@
------BEGIN CERTIFICATE-----
+-----BEGIN TRUSTED CERTIFICATE-----
 MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
 IENBMCAXDTE2MDExNTA4MTk0OVoYDzIxMTYwMTE2MDgxOTQ5WjASMRAwDgYDVQQD
 DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyB6dJAD5
@@ -14,5 +14,6 @@ NpbsWX0ta2pDPhiBpIbrTrTmw656MMRkwMLYIAX7BFhyjO9gO0nVXfU1SSTDsso+
 qu/K1t2US/rLeJQn8gYiTw6AqmvxHOndLaZQrYef4rUzsYnahNzxcoS1FMVxoJFM
 o+1Wo0BFBlASv5Az0iFfjd1Uy3+AHB41+2vczNIWSki3mg4hzus2PSS4AA9IYeh+
 zU/HJMddnVedLKNstTAfR85ftACtsP6JhBqCBqC4mCVsN2ZlgucETbsOMyWYB4+y
-9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1w==
------END CERTIFICATE-----
+9b6JIYDA1wxNVBXwN+D4MyALxjmjwcTsL6pXgoVc0JEJWVqQ1zAMoAoGCCsGAQUF
+BwMB
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sca+anyEKU.pem b/test/certs/sca+anyEKU.pem
new file mode 100644
index 0000000..459a4dc
--- /dev/null
+++ b/test/certs/sca+anyEKU.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAB4hlnzu/V80J5+R
+rT57HXi0ufIjXLTC4zEghc/xL3V5vKst2dDPTKJ6SqG6PWSlVg1nJJbjekR3kH+G
+knFp8wMIDp4EZDt1vU2jHtEyLTEmuFPY/MiR2fnLtX4jlPk5EpuMCA7n69lBAD3I
+rlyQxv/DVfBSxkXJYFKZCTghxYHsP7TrHvmI4qQ3Of0OXeH0vn7j8mqA8xBERUQl
+ZCRUQWZoHd5zJX1ELv0iBaB7pQbV4f3ILhEBfWE04m8GxkbRNdEi4+i5BIvjSqw7
+SBKP9nn4g4+CfKFex6cHGafkAb+gBCoUWMofXJCNr1b7FBc6Zi6xnBMHwhUnhEdj
+LGCBSw0wCDAGBgRVHSUA
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sca+clientAuth.pem b/test/certs/sca+clientAuth.pem
new file mode 100644
index 0000000..3807805
--- /dev/null
+++ b/test/certs/sca+clientAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAB4hlnzu/V80J5+R
+rT57HXi0ufIjXLTC4zEghc/xL3V5vKst2dDPTKJ6SqG6PWSlVg1nJJbjekR3kH+G
+knFp8wMIDp4EZDt1vU2jHtEyLTEmuFPY/MiR2fnLtX4jlPk5EpuMCA7n69lBAD3I
+rlyQxv/DVfBSxkXJYFKZCTghxYHsP7TrHvmI4qQ3Of0OXeH0vn7j8mqA8xBERUQl
+ZCRUQWZoHd5zJX1ELv0iBaB7pQbV4f3ILhEBfWE04m8GxkbRNdEi4+i5BIvjSqw7
+SBKP9nn4g4+CfKFex6cHGafkAb+gBCoUWMofXJCNr1b7FBc6Zi6xnBMHwhUnhEdj
+LGCBSw0wDDAKBggrBgEFBQcDAg==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sca+serverAuth.pem b/test/certs/sca+serverAuth.pem
new file mode 100644
index 0000000..952d288
--- /dev/null
+++ b/test/certs/sca+serverAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAB4hlnzu/V80J5+R
+rT57HXi0ufIjXLTC4zEghc/xL3V5vKst2dDPTKJ6SqG6PWSlVg1nJJbjekR3kH+G
+knFp8wMIDp4EZDt1vU2jHtEyLTEmuFPY/MiR2fnLtX4jlPk5EpuMCA7n69lBAD3I
+rlyQxv/DVfBSxkXJYFKZCTghxYHsP7TrHvmI4qQ3Of0OXeH0vn7j8mqA8xBERUQl
+ZCRUQWZoHd5zJX1ELv0iBaB7pQbV4f3ILhEBfWE04m8GxkbRNdEi4+i5BIvjSqw7
+SBKP9nn4g4+CfKFex6cHGafkAb+gBCoUWMofXJCNr1b7FBc6Zi6xnBMHwhUnhEdj
+LGCBSw0wDDAKBggrBgEFBQcDAQ==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sca-anyEKU.pem b/test/certs/sca-anyEKU.pem
new file mode 100644
index 0000000..a43c021
--- /dev/null
+++ b/test/certs/sca-anyEKU.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAB4hlnzu/V80J5+R
+rT57HXi0ufIjXLTC4zEghc/xL3V5vKst2dDPTKJ6SqG6PWSlVg1nJJbjekR3kH+G
+knFp8wMIDp4EZDt1vU2jHtEyLTEmuFPY/MiR2fnLtX4jlPk5EpuMCA7n69lBAD3I
+rlyQxv/DVfBSxkXJYFKZCTghxYHsP7TrHvmI4qQ3Of0OXeH0vn7j8mqA8xBERUQl
+ZCRUQWZoHd5zJX1ELv0iBaB7pQbV4f3ILhEBfWE04m8GxkbRNdEi4+i5BIvjSqw7
+SBKP9nn4g4+CfKFex6cHGafkAb+gBCoUWMofXJCNr1b7FBc6Zi6xnBMHwhUnhEdj
+LGCBSw0wCKAGBgRVHSUA
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sca-cert.pem b/test/certs/sca-cert.pem
new file mode 100644
index 0000000..6b800b6
--- /dev/null
+++ b/test/certs/sca-cert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAB4hlnzu/V80J5+R
+rT57HXi0ufIjXLTC4zEghc/xL3V5vKst2dDPTKJ6SqG6PWSlVg1nJJbjekR3kH+G
+knFp8wMIDp4EZDt1vU2jHtEyLTEmuFPY/MiR2fnLtX4jlPk5EpuMCA7n69lBAD3I
+rlyQxv/DVfBSxkXJYFKZCTghxYHsP7TrHvmI4qQ3Of0OXeH0vn7j8mqA8xBERUQl
+ZCRUQWZoHd5zJX1ELv0iBaB7pQbV4f3ILhEBfWE04m8GxkbRNdEi4+i5BIvjSqw7
+SBKP9nn4g4+CfKFex6cHGafkAb+gBCoUWMofXJCNr1b7FBc6Zi6xnBMHwhUnhEdj
+LGCBSw0=
+-----END CERTIFICATE-----
diff --git a/test/certs/sca-clientAuth.pem b/test/certs/sca-clientAuth.pem
new file mode 100644
index 0000000..62a98ff
--- /dev/null
+++ b/test/certs/sca-clientAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAB4hlnzu/V80J5+R
+rT57HXi0ufIjXLTC4zEghc/xL3V5vKst2dDPTKJ6SqG6PWSlVg1nJJbjekR3kH+G
+knFp8wMIDp4EZDt1vU2jHtEyLTEmuFPY/MiR2fnLtX4jlPk5EpuMCA7n69lBAD3I
+rlyQxv/DVfBSxkXJYFKZCTghxYHsP7TrHvmI4qQ3Of0OXeH0vn7j8mqA8xBERUQl
+ZCRUQWZoHd5zJX1ELv0iBaB7pQbV4f3ILhEBfWE04m8GxkbRNdEi4+i5BIvjSqw7
+SBKP9nn4g4+CfKFex6cHGafkAb+gBCoUWMofXJCNr1b7FBc6Zi6xnBMHwhUnhEdj
+LGCBSw0wDKAKBggrBgEFBQcDAg==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sca-serverAuth.pem b/test/certs/sca-serverAuth.pem
new file mode 100644
index 0000000..0620874
--- /dev/null
+++ b/test/certs/sca-serverAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjANMQswCQYDVQQD
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
+CLNNsUcCAwEAAaNlMGMwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8G
+A1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMAwGA1UdEwQFMAMBAf8wEwYD
+VR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAB4hlnzu/V80J5+R
+rT57HXi0ufIjXLTC4zEghc/xL3V5vKst2dDPTKJ6SqG6PWSlVg1nJJbjekR3kH+G
+knFp8wMIDp4EZDt1vU2jHtEyLTEmuFPY/MiR2fnLtX4jlPk5EpuMCA7n69lBAD3I
+rlyQxv/DVfBSxkXJYFKZCTghxYHsP7TrHvmI4qQ3Of0OXeH0vn7j8mqA8xBERUQl
+ZCRUQWZoHd5zJX1ELv0iBaB7pQbV4f3ILhEBfWE04m8GxkbRNdEi4+i5BIvjSqw7
+SBKP9nn4g4+CfKFex6cHGafkAb+gBCoUWMofXJCNr1b7FBc6Zi6xnBMHwhUnhEdj
+LGCBSw0wDKAKBggrBgEFBQcDAQ==
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/setup.sh b/test/certs/setup.sh
index b50f7e3..8cf27ee 100755
--- a/test/certs/setup.sh
+++ b/test/certs/setup.sh
@@ -1,8 +1,8 @@
 #! /bin/sh
 
 # Primary root: root-cert
-# root certs variants: CA:false, key2, DN2
-# trust variants: +serverAuth -serverAuth +clientAuth
+# root cert variants: CA:false, key2, DN2
+# trust variants: +serverAuth -serverAuth +clientAuth -clientAuth +anyEKU -anyEKU
 #
 ./mkcert.sh genroot "Root CA" root-key root-cert
 ./mkcert.sh genss "Root CA" root-key root-nonca
@@ -15,10 +15,62 @@ openssl x509 -in root-cert.pem -trustout \
     -addreject serverAuth -out root-serverAuth.pem
 openssl x509 -in root-cert.pem -trustout \
     -addtrust clientAuth -out root+clientAuth.pem
+openssl x509 -in root-cert.pem -trustout \
+    -addreject 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
+openssl x509 -in root-nonca.pem -trustout \
+    -addtrust serverAuth -out nroot+serverAuth.pem
+openssl x509 -in root-nonca.pem -trustout \
+    -addtrust anyExtendedKeyUsage -out nroot+anyEKU.pem
+
+# primary client-EKU root: croot-cert
+# trust variants: +serverAuth -serverAuth +clientAuth +anyEKU -anyEKU
+#
+./mkcert.sh genroot "Root CA" root-key croot-cert clientAuth
+#
+openssl x509 -in croot-cert.pem -trustout \
+    -addtrust serverAuth -out croot+serverAuth.pem
+openssl x509 -in croot-cert.pem -trustout \
+    -addreject serverAuth -out croot-serverAuth.pem
+openssl x509 -in croot-cert.pem -trustout \
+    -addtrust clientAuth -out croot+clientAuth.pem
+openssl x509 -in croot-cert.pem -trustout \
+    -addreject clientAuth -out croot-clientAuth.pem
+openssl x509 -in croot-cert.pem -trustout \
+    -addreject anyExtendedKeyUsage -out croot-anyEKU.pem
+openssl x509 -in croot-cert.pem -trustout \
+    -addtrust anyExtendedKeyUsage -out croot+anyEKU.pem
+
+# primary server-EKU root: sroot-cert
+# trust variants: +serverAuth -serverAuth +clientAuth +anyEKU -anyEKU
+#
+./mkcert.sh genroot "Root CA" root-key sroot-cert serverAuth
+#
+openssl x509 -in sroot-cert.pem -trustout \
+    -addtrust serverAuth -out sroot+serverAuth.pem
+openssl x509 -in sroot-cert.pem -trustout \
+    -addreject serverAuth -out sroot-serverAuth.pem
+openssl x509 -in sroot-cert.pem -trustout \
+    -addtrust clientAuth -out sroot+clientAuth.pem
+openssl x509 -in sroot-cert.pem -trustout \
+    -addreject clientAuth -out sroot-clientAuth.pem
+openssl x509 -in sroot-cert.pem -trustout \
+    -addreject anyExtendedKeyUsage -out sroot-anyEKU.pem
+openssl x509 -in sroot-cert.pem -trustout \
+    -addtrust anyExtendedKeyUsage -out sroot+anyEKU.pem
 
 # Primary intermediate ca: ca-cert
 # ca variants: CA:false, key2, DN2, issuer2, expired
-# trust variants: +serverAuth, -serverAuth, +clientAuth
+# trust variants: +serverAuth, -serverAuth, +clientAuth, -clientAuth, -anyEKU, +anyEKU
 #
 ./mkcert.sh genca "CA" ca-key ca-cert root-key root-cert
 ./mkcert.sh genee "CA" ca-key ca-nonca root-key root-cert
@@ -33,6 +85,52 @@ openssl x509 -in ca-cert.pem -trustout \
     -addreject serverAuth -out ca-serverAuth.pem
 openssl x509 -in ca-cert.pem -trustout \
     -addtrust clientAuth -out ca+clientAuth.pem
+openssl x509 -in ca-cert.pem -trustout \
+    -addreject clientAuth -out ca-clientAuth.pem
+openssl x509 -in ca-cert.pem -trustout \
+    -addreject anyExtendedKeyUsage -out ca-anyEKU.pem
+openssl x509 -in ca-cert.pem -trustout \
+    -addtrust anyExtendedKeyUsage -out ca+anyEKU.pem
+openssl x509 -in ca-nonca.pem -trustout \
+    -addtrust serverAuth -out nca+serverAuth.pem
+openssl x509 -in ca-nonca.pem -trustout \
+    -addtrust serverAuth -out nca+anyEKU.pem
+
+# client intermediate ca: cca-cert
+# trust variants: +serverAuth, -serverAuth, +clientAuth, -clientAuth
+#
+./mkcert.sh genca "CA" ca-key cca-cert root-key root-cert clientAuth
+#
+openssl x509 -in cca-cert.pem -trustout \
+    -addtrust serverAuth -out cca+serverAuth.pem
+openssl x509 -in cca-cert.pem -trustout \
+    -addreject serverAuth -out cca-serverAuth.pem
+openssl x509 -in cca-cert.pem -trustout \
+    -addtrust clientAuth -out cca+clientAuth.pem
+openssl x509 -in cca-cert.pem -trustout \
+    -addtrust clientAuth -out cca-clientAuth.pem
+openssl x509 -in cca-cert.pem -trustout \
+    -addreject anyExtendedKeyUsage -out cca-anyEKU.pem
+openssl x509 -in cca-cert.pem -trustout \
+    -addtrust anyExtendedKeyUsage -out cca+anyEKU.pem
+
+# server intermediate ca: sca-cert
+# trust variants: +serverAuth, -serverAuth, +clientAuth, -clientAuth, -anyEKU, +anyEKU
+#
+./mkcert.sh genca "CA" ca-key sca-cert root-key root-cert serverAuth
+#
+openssl x509 -in sca-cert.pem -trustout \
+    -addtrust serverAuth -out sca+serverAuth.pem
+openssl x509 -in sca-cert.pem -trustout \
+    -addreject serverAuth -out sca-serverAuth.pem
+openssl x509 -in sca-cert.pem -trustout \
+    -addtrust clientAuth -out sca+clientAuth.pem
+openssl x509 -in sca-cert.pem -trustout \
+    -addreject clientAuth -out sca-clientAuth.pem
+openssl x509 -in sca-cert.pem -trustout \
+    -addreject anyExtendedKeyUsage -out sca-anyEKU.pem
+openssl x509 -in sca-cert.pem -trustout \
+    -addtrust anyExtendedKeyUsage -out sca+anyEKU.pem
 
 # Primary leaf cert: ee-cert
 # ee variants: expired, issuer-key2, issuer-name2
diff --git a/test/certs/sroot+anyEKU.pem b/test/certs/sroot+anyEKU.pem
new file mode 100644
index 0000000..9beefa9
--- /dev/null
+++ b/test/certs/sroot+anyEKU.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAknUQhKHR
+lI3BOPTuD+DMabjdfZ6Sb5ICpIOcvYFnlZV0lkyK3TuOw+iSlUUzHT3MlMos1w2a
+mYPb1BpACTpB1vOcRZPaoSZqiOJrKzes+oUZG7R75lz+TK4Y1lQlWObsnUlFUDzr
+c3P3mbCALr9RPee+Mqd10E/57jjIF0sb3Cq74l7MEzD/3JWKhxEtTmChG+Q29bzW
+foaDqVaePdyk4M+TMQMioGqXYqu/4bzCnZyls1J5FfwBCtPGJ1/3wxLwk+Pavu9w
+TSagWsC90QGRYH0EauS1KqlJ6dR6Tyf6G5HHmDPufzHT0ouL5Db6C59XSMWud6RG
+E3ODKNXOOP3jsDAIMAYGBFUdJQA=
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sroot+clientAuth.pem b/test/certs/sroot+clientAuth.pem
new file mode 100644
index 0000000..939e3e8
--- /dev/null
+++ b/test/certs/sroot+clientAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAknUQhKHR
+lI3BOPTuD+DMabjdfZ6Sb5ICpIOcvYFnlZV0lkyK3TuOw+iSlUUzHT3MlMos1w2a
+mYPb1BpACTpB1vOcRZPaoSZqiOJrKzes+oUZG7R75lz+TK4Y1lQlWObsnUlFUDzr
+c3P3mbCALr9RPee+Mqd10E/57jjIF0sb3Cq74l7MEzD/3JWKhxEtTmChG+Q29bzW
+foaDqVaePdyk4M+TMQMioGqXYqu/4bzCnZyls1J5FfwBCtPGJ1/3wxLwk+Pavu9w
+TSagWsC90QGRYH0EauS1KqlJ6dR6Tyf6G5HHmDPufzHT0ouL5Db6C59XSMWud6RG
+E3ODKNXOOP3jsDAMMAoGCCsGAQUFBwMC
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sroot+serverAuth.pem b/test/certs/sroot+serverAuth.pem
new file mode 100644
index 0000000..447d2e3
--- /dev/null
+++ b/test/certs/sroot+serverAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAknUQhKHR
+lI3BOPTuD+DMabjdfZ6Sb5ICpIOcvYFnlZV0lkyK3TuOw+iSlUUzHT3MlMos1w2a
+mYPb1BpACTpB1vOcRZPaoSZqiOJrKzes+oUZG7R75lz+TK4Y1lQlWObsnUlFUDzr
+c3P3mbCALr9RPee+Mqd10E/57jjIF0sb3Cq74l7MEzD/3JWKhxEtTmChG+Q29bzW
+foaDqVaePdyk4M+TMQMioGqXYqu/4bzCnZyls1J5FfwBCtPGJ1/3wxLwk+Pavu9w
+TSagWsC90QGRYH0EauS1KqlJ6dR6Tyf6G5HHmDPufzHT0ouL5Db6C59XSMWud6RG
+E3ODKNXOOP3jsDAMMAoGCCsGAQUFBwMB
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sroot-anyEKU.pem b/test/certs/sroot-anyEKU.pem
new file mode 100644
index 0000000..7f1766a
--- /dev/null
+++ b/test/certs/sroot-anyEKU.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAknUQhKHR
+lI3BOPTuD+DMabjdfZ6Sb5ICpIOcvYFnlZV0lkyK3TuOw+iSlUUzHT3MlMos1w2a
+mYPb1BpACTpB1vOcRZPaoSZqiOJrKzes+oUZG7R75lz+TK4Y1lQlWObsnUlFUDzr
+c3P3mbCALr9RPee+Mqd10E/57jjIF0sb3Cq74l7MEzD/3JWKhxEtTmChG+Q29bzW
+foaDqVaePdyk4M+TMQMioGqXYqu/4bzCnZyls1J5FfwBCtPGJ1/3wxLwk+Pavu9w
+TSagWsC90QGRYH0EauS1KqlJ6dR6Tyf6G5HHmDPufzHT0ouL5Db6C59XSMWud6RG
+E3ODKNXOOP3jsDAIoAYGBFUdJQA=
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sroot-cert.pem b/test/certs/sroot-cert.pem
new file mode 100644
index 0000000..55508d9
--- /dev/null
+++ b/test/certs/sroot-cert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAknUQhKHR
+lI3BOPTuD+DMabjdfZ6Sb5ICpIOcvYFnlZV0lkyK3TuOw+iSlUUzHT3MlMos1w2a
+mYPb1BpACTpB1vOcRZPaoSZqiOJrKzes+oUZG7R75lz+TK4Y1lQlWObsnUlFUDzr
+c3P3mbCALr9RPee+Mqd10E/57jjIF0sb3Cq74l7MEzD/3JWKhxEtTmChG+Q29bzW
+foaDqVaePdyk4M+TMQMioGqXYqu/4bzCnZyls1J5FfwBCtPGJ1/3wxLwk+Pavu9w
+TSagWsC90QGRYH0EauS1KqlJ6dR6Tyf6G5HHmDPufzHT0ouL5Db6C59XSMWud6RG
+E3ODKNXOOP3jsA==
+-----END CERTIFICATE-----
diff --git a/test/certs/sroot-clientAuth.pem b/test/certs/sroot-clientAuth.pem
new file mode 100644
index 0000000..e91f1d2
--- /dev/null
+++ b/test/certs/sroot-clientAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAknUQhKHR
+lI3BOPTuD+DMabjdfZ6Sb5ICpIOcvYFnlZV0lkyK3TuOw+iSlUUzHT3MlMos1w2a
+mYPb1BpACTpB1vOcRZPaoSZqiOJrKzes+oUZG7R75lz+TK4Y1lQlWObsnUlFUDzr
+c3P3mbCALr9RPee+Mqd10E/57jjIF0sb3Cq74l7MEzD/3JWKhxEtTmChG+Q29bzW
+foaDqVaePdyk4M+TMQMioGqXYqu/4bzCnZyls1J5FfwBCtPGJ1/3wxLwk+Pavu9w
+TSagWsC90QGRYH0EauS1KqlJ6dR6Tyf6G5HHmDPufzHT0ouL5Db6C59XSMWud6RG
+E3ODKNXOOP3jsDAMoAoGCCsGAQUFBwMC
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/certs/sroot-serverAuth.pem b/test/certs/sroot-serverAuth.pem
new file mode 100644
index 0000000..2fd78cc
--- /dev/null
+++ b/test/certs/sroot-serverAuth.pem
@@ -0,0 +1,19 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDEyOTA0NDc0NloYDzIxMTYwMTMwMDQ0NzQ2WjASMRAwDgYDVQQD
+DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8
+oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS
+feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN
+wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g
+MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u
+aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff
+tWgiQ35mJCOvxQIDAQABo2UwYzAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3
+o1IwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDAYDVR0TBAUwAwEB
+/zATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAknUQhKHR
+lI3BOPTuD+DMabjdfZ6Sb5ICpIOcvYFnlZV0lkyK3TuOw+iSlUUzHT3MlMos1w2a
+mYPb1BpACTpB1vOcRZPaoSZqiOJrKzes+oUZG7R75lz+TK4Y1lQlWObsnUlFUDzr
+c3P3mbCALr9RPee+Mqd10E/57jjIF0sb3Cq74l7MEzD/3JWKhxEtTmChG+Q29bzW
+foaDqVaePdyk4M+TMQMioGqXYqu/4bzCnZyls1J5FfwBCtPGJ1/3wxLwk+Pavu9w
+TSagWsC90QGRYH0EauS1KqlJ6dR6Tyf6G5HHmDPufzHT0ouL5Db6C59XSMWud6RG
+E3ODKNXOOP3jsDAMoAoGCCsGAQUFBwMB
+-----END TRUSTED CERTIFICATE-----
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index 56d8307..444f69b 100644
--- a/test/recipes/25-test_verify.t
+++ b/test/recipes/25-test_verify.t
@@ -9,80 +9,204 @@ use OpenSSL::Test qw/:DEFAULT top_file/;
 setup("test_verify");
 
 sub verify {
-    my ($cert, $vname, $trusted, $untrusted, @opts) = @_;
-    my @args = qw(openssl verify -verify_name);
+    my ($cert, $purpose, $trusted, $untrusted, @opts) = @_;
+    my @args = qw(openssl verify -purpose);
     my @path = qw(test certs);
-    push(@args, "$vname", @opts);
+    push(@args, "$purpose", @opts);
     for (@$trusted) { push(@args, "-trusted", top_file(@path, "$_.pem")) }
     for (@$untrusted) { push(@args, "-untrusted", top_file(@path, "$_.pem")) }
     push(@args, top_file(@path, "$cert.pem"));
     run(app([@args]));
 }
 
-plan tests => 29;
+plan tests => 81;
 
 # Canonical success
-ok(verify("ee-cert", "ssl_server", ["root-cert"], ["ca-cert"]),
-   "verify valid chain");
+ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
+   "accept compat trust");
 
 # Root CA variants
-ok(verify("ee-cert", "ssl_server", [qw(root-nonca)], [qw(ca-cert)]),
-   "Trusted certs not subject to CA:true checks");
-ok(!verify("ee-cert", "ssl_server", [qw(root-cert2)], [qw(ca-cert)]),
+ok(!verify("ee-cert", "sslserver", [qw(root-nonca)], [qw(ca-cert)]),
+   "fail trusted non-ca root");
+ok(!verify("ee-cert", "sslserver", [qw(nroot+serverAuth)], [qw(ca-cert)]),
+   "fail server trust non-ca root");
+ok(!verify("ee-cert", "sslserver", [qw(nroot+anyEKU)], [qw(ca-cert)]),
+   "fail wildcard trust non-ca root");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert2)], [qw(ca-cert)]),
    "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");
-ok(verify("ee-cert", "ssl_server", [qw(root+serverAuth)], [qw(ca-cert)]),
-   "accept right EKU");
-ok(!verify("ee-cert", "ssl_server", [qw(root-serverAuth)], [qw(ca-cert)]),
+
+# Explicit trust/purpose combinations
+#
+ok(verify("ee-cert", "sslserver", [qw(sroot-cert)], [qw(ca-cert)]),
+   "accept server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(croot-cert)], [qw(ca-cert)]),
+   "fail client purpose");
+ok(verify("ee-cert", "sslserver", [qw(root+serverAuth)], [qw(ca-cert)]),
+   "accept server trust");
+ok(verify("ee-cert", "sslserver", [qw(sroot+serverAuth)], [qw(ca-cert)]),
+   "accept server trust with server purpose");
+ok(verify("ee-cert", "sslserver", [qw(croot+serverAuth)], [qw(ca-cert)]),
+   "accept server trust with client purpose");
+# Wildcard trust
+ok(verify("ee-cert", "sslserver", [qw(root+anyEKU)], [qw(ca-cert)]),
+   "accept wildcard trust");
+ok(verify("ee-cert", "sslserver", [qw(sroot+anyEKU)], [qw(ca-cert)]),
+   "accept wildcard trust with server purpose");
+ok(verify("ee-cert", "sslserver", [qw(croot+anyEKU)], [qw(ca-cert)]),
+   "accept wildcard trust with client purpose");
+# Inapplicable mistrust
+ok(verify("ee-cert", "sslserver", [qw(root-clientAuth)], [qw(ca-cert)]),
+   "accept client mistrust");
+ok(verify("ee-cert", "sslserver", [qw(sroot-clientAuth)], [qw(ca-cert)]),
+   "accept client mistrust with server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(croot-clientAuth)], [qw(ca-cert)]),
+   "fail client mistrust with client purpose");
+# Inapplicable trust
+ok(!verify("ee-cert", "sslserver", [qw(root+clientAuth)], [qw(ca-cert)]),
+   "fail client trust");
+ok(!verify("ee-cert", "sslserver", [qw(sroot+clientAuth)], [qw(ca-cert)]),
+   "fail client trust with server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(croot+clientAuth)], [qw(ca-cert)]),
+   "fail client trust with client purpose");
+# Server mistrust
+ok(!verify("ee-cert", "sslserver", [qw(root-serverAuth)], [qw(ca-cert)]),
    "fail rejected EKU");
-ok(!verify("ee-cert", "ssl_server", [qw(root+clientAuth)], [qw(ca-cert)]),
-   "fail wrong EKU");
+ok(!verify("ee-cert", "sslserver", [qw(sroot-serverAuth)], [qw(ca-cert)]),
+   "fail server mistrust with server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(croot-serverAuth)], [qw(ca-cert)]),
+   "fail server mistrust with client purpose");
+# Wildcard mistrust
+ok(!verify("ee-cert", "sslserver", [qw(root-anyEKU)], [qw(ca-cert)]),
+   "fail wildcard mistrust");
+ok(!verify("ee-cert", "sslserver", [qw(sroot-anyEKU)], [qw(ca-cert)]),
+   "fail wildcard mistrust with server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(croot-anyEKU)], [qw(ca-cert)]),
+   "fail wildcard mistrust with client purpose");
+
+# 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)]),
+   "accept trusted-first path");
+ok(verify("ee-cert", "sslserver", [qw(root-cert root2+serverAuth ca-root2)],
+          [qw(ca-cert)]),
+   "accept trusted-first path with server trust");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert root2-serverAuth ca-root2)],
+           [qw(ca-cert)]),
+   "fail trusted-first path with server mistrust");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert root2+clientAuth ca-root2)],
+           [qw(ca-cert)]),
+   "fail trusted-first path with client trust");
 
 # CA variants
-ok(!verify("ee-cert", "ssl_server", [qw(root-cert)], [qw(ca-nonca)]),
-   "fail non-CA");
-ok(!verify("ee-cert", "ssl_server", [qw(root-cert)], [qw(ca-cert2)]),
-   "fail wrong CA key");
-ok(!verify("ee-cert", "ssl_server", [qw(root-cert)], [qw(ca-name2)]),
-   "fail wrong CA DN");
-ok(!verify("ee-cert", "ssl_server", [qw(root-cert)], [qw(ca-root2)]),
-   "fail wrong CA issuer");
-ok(!verify("ee-cert", "ssl_server", [], [qw(ca-cert)], "-partial_chain"),
-   "fail untrusted partial");
-ok(!verify("ee-cert", "ssl_server", [], [qw(ca+serverAuth)], "-partial_chain"),
-   "fail untrusted EKU partial");
-ok(verify("ee-cert", "ssl_server", [qw(ca+serverAuth)], [], "-partial_chain"),
-   "accept trusted EKU partial");
-ok(!verify("ee-cert", "ssl_server", [qw(ca-serverAuth)], [], "-partial_chain"),
-   "fail rejected EKU partial");
-ok(!verify("ee-cert", "ssl_server", [qw(ca+clientAuth)], [], "-partial_chain"),
-   "fail wrong EKU partial");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-nonca)]),
+   "fail non-CA untrusted intermediate");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-nonca)], []),
+   "fail non-CA trusted intermediate");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert nca+serverAuth)], []),
+   "fail non-CA server trust intermediate");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert nca+anyEKU)], []),
+   "fail non-CA wildcard trust intermediate");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-cert2)]),
+   "fail wrong intermediate CA key");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-name2)]),
+   "fail wrong intermediate CA DN");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-root2)]),
+   "fail wrong intermediate CA issuer");
+ok(!verify("ee-cert", "sslserver", [], [qw(ca-cert)], "-partial_chain"),
+   "fail untrusted partial chain");
+ok(verify("ee-cert", "sslserver", [qw(ca-cert)], [], "-partial_chain"),
+   "accept trusted partial chain");
+ok(verify("ee-cert", "sslserver", [qw(sca-cert)], [], "-partial_chain"),
+   "accept partial chain with server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(cca-cert)], [], "-partial_chain"),
+   "fail partial chain with client purpose");
+ok(verify("ee-cert", "sslserver", [qw(ca+serverAuth)], [], "-partial_chain"),
+   "accept server trust partial chain");
+ok(verify("ee-cert", "sslserver", [qw(cca+serverAuth)], [], "-partial_chain"),
+   "accept server trust client purpose partial chain");
+ok(verify("ee-cert", "sslserver", [qw(ca-clientAuth)], [], "-partial_chain"),
+   "accept client mistrust partial chain");
+ok(verify("ee-cert", "sslserver", [qw(ca+anyEKU)], [], "-partial_chain"),
+   "accept wildcard trust partial chain");
+ok(!verify("ee-cert", "sslserver", [], [qw(ca+serverAuth)], "-partial_chain"),
+   "fail untrusted partial issuer with ignored server trust");
+ok(!verify("ee-cert", "sslserver", [qw(ca-serverAuth)], [], "-partial_chain"),
+   "fail server mistrust partial chain");
+ok(!verify("ee-cert", "sslserver", [qw(ca+clientAuth)], [], "-partial_chain"),
+   "fail client trust partial chain");
+ok(!verify("ee-cert", "sslserver", [qw(ca-anyEKU)], [], "-partial_chain"),
+   "fail wildcard mistrust partial chain");
+
+# 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 server trust");
+ok(verify("ee-cert", "sslserver", [qw(root-cert ca+anyEKU)], [qw(ca-cert)]),
+   "accept wildcard trust");
+ok(verify("ee-cert", "sslserver", [qw(root-cert sca-cert)], [qw(ca-cert)]),
+   "accept server purpose");
+ok(verify("ee-cert", "sslserver", [qw(root-cert sca+serverAuth)], [qw(ca-cert)]),
+   "accept server trust and purpose");
+ok(verify("ee-cert", "sslserver", [qw(root-cert sca+anyEKU)], [qw(ca-cert)]),
+   "accept wildcard trust and server purpose");
+ok(verify("ee-cert", "sslserver", [qw(root-cert sca-clientAuth)], [qw(ca-cert)]),
+   "accept client mistrust and server purpose");
+ok(verify("ee-cert", "sslserver", [qw(root-cert cca+serverAuth)], [qw(ca-cert)]),
+   "accept server trust and client purpose");
+ok(verify("ee-cert", "sslserver", [qw(root-cert cca+anyEKU)], [qw(ca-cert)]),
+   "accept wildcard trust and client purpose");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-cert)], [qw(ca-cert)]),
+   "fail client purpose");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-anyEKU)], [qw(ca-cert)]),
+   "fail wildcard mistrust");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-serverAuth)], [qw(ca-cert)]),
+   "fail server mistrust");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert ca+clientAuth)], [qw(ca-cert)]),
+   "fail client trust");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert sca+clientAuth)], [qw(ca-cert)]),
+   "fail client trust and server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert cca+clientAuth)], [qw(ca-cert)]),
+   "fail client trust and client purpose");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-serverAuth)], [qw(ca-cert)]),
+   "fail server mistrust and client purpose");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-clientAuth)], [qw(ca-cert)]),
+   "fail client mistrust and client purpose");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert sca-serverAuth)], [qw(ca-cert)]),
+   "fail server mistrust and server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert sca-anyEKU)], [qw(ca-cert)]),
+   "fail wildcard mistrust and server purpose");
+ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-anyEKU)], [qw(ca-cert)]),
+   "fail wildcard mistrust and client purpose");
 
 # EE variants
-ok(verify("ee-client", "ssl_client", [qw(root-cert)], [qw(ca-cert)]),
-   "accept client cert");
-ok(!verify("ee-client", "ssl_server", [qw(root-cert)], [qw(ca-cert)]),
-   "fail wrong leaf purpose");
-ok(!verify("ee-cert", "ssl_client", [qw(root-cert)], [qw(ca-cert)]),
-   "fail wrong leaf purpose");
-ok(!verify("ee-cert2", "ssl_server", [qw(root-cert)], [qw(ca-cert)]),
-   "fail wrong CA key");
-ok(!verify("ee-name2", "ssl_server", [qw(root-cert)], [qw(ca-cert)]),
-   "fail wrong CA name");
-ok(!verify("ee-expired", "ssl_server", [qw(root-cert)], [qw(ca-cert)]),
+ok(verify("ee-client", "sslclient", [qw(root-cert)], [qw(ca-cert)]),
+   "accept client chain");
+ok(!verify("ee-client", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
+   "fail server leaf purpose");
+ok(!verify("ee-cert", "sslclient", [qw(root-cert)], [qw(ca-cert)]),
+   "fail client leaf purpose");
+ok(!verify("ee-cert2", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
+   "fail wrong intermediate CA key");
+ok(!verify("ee-name2", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
+   "fail wrong intermediate CA DN");
+ok(!verify("ee-expired", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
    "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");
-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");
-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");
-ok(verify("ee-cert", "ssl_server", [qw(ee+serverAuth)], [], "-partial_chain"),
-   "accept direct match with trusted EKU");
-ok(!verify("ee-cert", "ssl_server", [qw(ee-serverAuth)], [], "-partial_chain"),
-   "reject direct match with rejected EKU");
-ok(verify("ee-client", "ssl_client", [qw(ee+clientAuth)], [], "-partial_chain"),
-   "accept direct match with trusted EKU");
-ok(!verify("ee-client", "ssl_client", [qw(ee-clientAuth)], [], "-partial_chain"),
-   "reject direct match with rejected EKU");
+ok(verify("ee-cert", "sslserver", [qw(ee+serverAuth)], [], "-partial_chain"),
+   "accept direct match with server trust");
+ok(!verify("ee-cert", "sslserver", [qw(ee-serverAuth)], [], "-partial_chain"),
+   "fail direct match with server mistrust");
+ok(verify("ee-client", "sslclient", [qw(ee+clientAuth)], [], "-partial_chain"),
+   "accept direct match with client trust");
+ok(!verify("ee-client", "sslclient", [qw(ee-clientAuth)], [], "-partial_chain"),
+   "reject direct match with client mistrust");


More information about the openssl-commits mailing list