[openssl-commits] [openssl] OpenSSL_1_0_2-stable update

Matt Caswell matt at openssl.org
Mon Apr 20 12:44:47 UTC 2015


The branch OpenSSL_1_0_2-stable has been updated
       via  47daa155a31b0a54ce09ad2ed4d55fad74096dab (commit)
       via  be856c0391d65c8c179721ffa8f35374fddf5892 (commit)
       via  017a06c7d1ed92a5dfbe2586ca96bef268c04895 (commit)
       via  dfd3322d72a2d49f597b86dab6f37a8cf0f26dbf (commit)
       via  6281abc79623419eae6a64768c478272d5d3a426 (commit)
      from  3661bb4e7934668bd99ca777ea8b30eedfafa871 (commit)


- Log -----------------------------------------------------------------
commit 47daa155a31b0a54ce09ad2ed4d55fad74096dab
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Tue Mar 24 16:21:21 2015 +0000

    Fix verify algorithm.
    
    Disable loop checking when we retry verification with an alternative path.
    This fixes the case where an intermediate CA is explicitly trusted and part
    of the untrusted certificate list. By disabling loop checking for this case
    the untrusted CA can be replaced by the explicitly trusted case and
    verification will succeed.
    
    Signed-off-by: Matt Caswell <matt at openssl.org>
    (cherry picked from commit e5991ec528b1c339062440811e2641f5ea2b328b)
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit be856c0391d65c8c179721ffa8f35374fddf5892
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Jan 27 11:15:15 2015 +0000

    Add documentation for the -no_alt_chains option for various apps, as well as
    the X509_V_FLAG_NO_ALT_CHAINS flag.
    
    Conflicts:
    	doc/apps/cms.pod
    	doc/apps/ocsp.pod
    	doc/apps/s_client.pod
    	doc/apps/s_server.pod
    	doc/apps/smime.pod
    	doc/apps/verify.pod
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 017a06c7d1ed92a5dfbe2586ca96bef268c04895
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Jan 27 10:50:38 2015 +0000

    Add -no_alt_chains option to apps to implement the new
    X509_V_FLAG_NO_ALT_CHAINS flag. Using this option means that when building
    certificate chains, the first chain found will be the one used. Without this
    flag, if the first chain found is not trusted then we will keep looking to
    see if we can build an alternative chain instead.
    
    Conflicts:
    	apps/cms.c
    	apps/ocsp.c
    	apps/s_client.c
    	apps/s_server.c
    	apps/smime.c
    	apps/verify.c
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit dfd3322d72a2d49f597b86dab6f37a8cf0f26dbf
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Jan 27 10:35:27 2015 +0000

    Add flag to inhibit checking for alternate certificate chains. Setting this
    behaviour will force behaviour as per previous versions of OpenSSL
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 6281abc79623419eae6a64768c478272d5d3a426
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Jan 27 10:03:29 2015 +0000

    In certain situations the server provided certificate chain may no longer be
    valid. However the issuer of the leaf, or some intermediate cert is in fact
    in the trust store.
    
    When building a trust chain if the first attempt fails, then try to see if
    alternate chains could be constructed that are trusted.
    
    RT3637
    RT3621
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

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

Summary of changes:
 apps/apps.c                                |   2 +
 apps/cms.c                                 |   2 +
 apps/ocsp.c                                |   2 +
 apps/s_client.c                            |   2 +
 apps/s_server.c                            |   2 +
 apps/smime.c                               |   2 +
 apps/verify.c                              |   2 +-
 crypto/x509/x509_vfy.c                     | 185 ++++++++++++++++++-----------
 crypto/x509/x509_vfy.h                     |   6 +
 doc/apps/cms.pod                           |   5 +-
 doc/apps/ocsp.pod                          |  11 ++
 doc/apps/s_client.pod                      |   7 +-
 doc/apps/s_server.pod                      |   9 ++
 doc/apps/smime.pod                         |   4 +-
 doc/apps/verify.pod                        |  13 ++
 doc/crypto/X509_VERIFY_PARAM_set_flags.pod |   8 +-
 16 files changed, 187 insertions(+), 75 deletions(-)

diff --git a/apps/apps.c b/apps/apps.c
index 6d22a08..7478fc3 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -2371,6 +2371,8 @@ int args_verify(char ***pargs, int *pargc,
         flags |= X509_V_FLAG_SUITEB_192_LOS;
     else if (!strcmp(arg, "-partial_chain"))
         flags |= X509_V_FLAG_PARTIAL_CHAIN;
+    else if (!strcmp(arg, "-no_alt_chains"))
+        flags |= X509_V_FLAG_NO_ALT_CHAINS;
     else
         return 0;
 
diff --git a/apps/cms.c b/apps/cms.c
index d287a2b..6047937 100644
--- a/apps/cms.c
+++ b/apps/cms.c
@@ -646,6 +646,8 @@ int MAIN(int argc, char **argv)
                    "-CApath dir    trusted certificates directory\n");
         BIO_printf(bio_err, "-CAfile file   trusted certificates file\n");
         BIO_printf(bio_err,
+                   "-no_alt_chains only ever use the first certificate chain found\n");
+        BIO_printf(bio_err,
                    "-crl_check     check revocation status of signer's certificate using CRLs\n");
         BIO_printf(bio_err,
                    "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
diff --git a/apps/ocsp.c b/apps/ocsp.c
index ebb3732..b858b8d 100644
--- a/apps/ocsp.c
+++ b/apps/ocsp.c
@@ -536,6 +536,8 @@ int MAIN(int argc, char **argv)
         BIO_printf(bio_err,
                    "-CAfile file         trusted certificates file\n");
         BIO_printf(bio_err,
+                   "-no_alt_chains       only ever use the first certificate chain found\n");
+        BIO_printf(bio_err,
                    "-VAfile file         validator certificates file\n");
         BIO_printf(bio_err,
                    "-validity_period n   maximum validity discrepancy in seconds\n");
diff --git a/apps/s_client.c b/apps/s_client.c
index d53bca1..e55f2c5 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -332,6 +332,8 @@ static void sc_usage(void)
     BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
     BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
     BIO_printf(bio_err,
+               " -no_alt_chains - only ever use the first certificate chain found\n");
+    BIO_printf(bio_err,
                " -reconnect    - Drop and re-make the connection with the same Session-ID\n");
     BIO_printf(bio_err,
                " -pause        - sleep(1) after each read(2) and write(2) system call\n");
diff --git a/apps/s_server.c b/apps/s_server.c
index 2597e8c..5d58fe0 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -554,6 +554,8 @@ static void sv_usage(void)
     BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
     BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
     BIO_printf(bio_err,
+               " -no_alt_chains - only ever use the first certificate chain found\n");
+    BIO_printf(bio_err,
                " -nocert       - Don't use any certificates (Anon-DH)\n");
     BIO_printf(bio_err,
                " -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
diff --git a/apps/smime.c b/apps/smime.c
index 764509f..6044ccf 100644
--- a/apps/smime.c
+++ b/apps/smime.c
@@ -442,6 +442,8 @@ int MAIN(int argc, char **argv)
                    "-CApath dir    trusted certificates directory\n");
         BIO_printf(bio_err, "-CAfile file   trusted certificates file\n");
         BIO_printf(bio_err,
+                   "-no_alt_chains only ever use the first certificate chain found\n");
+        BIO_printf(bio_err,
                    "-crl_check     check revocation status of signer's certificate using CRLs\n");
         BIO_printf(bio_err,
                    "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
diff --git a/apps/verify.c b/apps/verify.c
index b3ba53d..78e729f 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -232,7 +232,7 @@ int MAIN(int argc, char **argv)
     if (ret == 1) {
         BIO_printf(bio_err,
                    "usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
-        BIO_printf(bio_err, " [-attime timestamp]");
+        BIO_printf(bio_err, " [-no_alt_chains] [-attime timestamp]");
 #ifndef OPENSSL_NO_ENGINE
         BIO_printf(bio_err, " [-engine e]");
 #endif
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 1196a2a..c0f6a5d 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -187,11 +187,11 @@ static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
 
 int X509_verify_cert(X509_STORE_CTX *ctx)
 {
-    X509 *x, *xtmp, *chain_ss = NULL;
+    X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
     int bad_chain = 0;
     X509_VERIFY_PARAM *param = ctx->param;
     int depth, i, ok = 0;
-    int num;
+    int num, j, retry;
     int (*cb) (int xok, X509_STORE_CTX *xctx);
     STACK_OF(X509) *sktmp = NULL;
     if (ctx->cert == NULL) {
@@ -276,91 +276,136 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
         break;
     }
 
+    /* Remember how many untrusted certs we have */
+    j = num;
     /*
      * at this point, chain should contain a list of untrusted certificates.
      * We now need to add at least one trusted one, if possible, otherwise we
      * complain.
      */
 
-    /*
-     * Examine last certificate in chain and see if it is self signed.
-     */
-
-    i = sk_X509_num(ctx->chain);
-    x = sk_X509_value(ctx->chain, i - 1);
-    if (cert_self_signed(x)) {
-        /* we have a self signed certificate */
-        if (sk_X509_num(ctx->chain) == 1) {
-            /*
-             * We have a single self signed certificate: see if we can find
-             * it in the store. We must have an exact match to avoid possible
-             * impersonation.
-             */
-            ok = ctx->get_issuer(&xtmp, ctx, x);
-            if ((ok <= 0) || X509_cmp(x, xtmp)) {
-                ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
-                ctx->current_cert = x;
-                ctx->error_depth = i - 1;
-                if (ok == 1)
-                    X509_free(xtmp);
-                bad_chain = 1;
-                ok = cb(0, ctx);
-                if (!ok)
-                    goto end;
+    do {
+        /*
+         * Examine last certificate in chain and see if it is self signed.
+         */
+        i = sk_X509_num(ctx->chain);
+        x = sk_X509_value(ctx->chain, i - 1);
+        if (cert_self_signed(x)) {
+            /* we have a self signed certificate */
+            if (sk_X509_num(ctx->chain) == 1) {
+                /*
+                 * We have a single self signed certificate: see if we can
+                 * find it in the store. We must have an exact match to avoid
+                 * possible impersonation.
+                 */
+                ok = ctx->get_issuer(&xtmp, ctx, x);
+                if ((ok <= 0) || X509_cmp(x, xtmp)) {
+                    ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
+                    ctx->current_cert = x;
+                    ctx->error_depth = i - 1;
+                    if (ok == 1)
+                        X509_free(xtmp);
+                    bad_chain = 1;
+                    ok = cb(0, ctx);
+                    if (!ok)
+                        goto end;
+                } else {
+                    /*
+                     * We have a match: replace certificate with store
+                     * version so we get any trust settings.
+                     */
+                    X509_free(x);
+                    x = xtmp;
+                    (void)sk_X509_set(ctx->chain, i - 1, x);
+                    ctx->last_untrusted = 0;
+                }
             } else {
                 /*
-                 * We have a match: replace certificate with store version so
-                 * we get any trust settings.
+                 * extract and save self signed certificate for later use
                  */
-                X509_free(x);
-                x = xtmp;
-                (void)sk_X509_set(ctx->chain, i - 1, x);
-                ctx->last_untrusted = 0;
+                chain_ss = sk_X509_pop(ctx->chain);
+                ctx->last_untrusted--;
+                num--;
+                j--;
+                x = sk_X509_value(ctx->chain, num - 1);
             }
-        } else {
-            /*
-             * extract and save self signed certificate for later use
-             */
-            chain_ss = sk_X509_pop(ctx->chain);
-            ctx->last_untrusted--;
-            num--;
-            x = sk_X509_value(ctx->chain, num - 1);
         }
-    }
-
-    /* We now lookup certs from the certificate store */
-    for (;;) {
-        /* If we have enough, we break */
-        if (depth < num)
-            break;
+        /* We now lookup certs from the certificate store */
+        for (;;) {
+            /* If we have enough, we break */
+            if (depth < num)
+                break;
+            /* If we are self signed, we break */
+            if (cert_self_signed(x))
+                break;
+            ok = ctx->get_issuer(&xtmp, ctx, x);
 
-        /* If we are self signed, we break */
-        if (cert_self_signed(x))
-            break;
+            if (ok < 0)
+                return ok;
+            if (ok == 0)
+                break;
+            x = xtmp;
+            if (!sk_X509_push(ctx->chain, x)) {
+                X509_free(xtmp);
+                X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+            num++;
+        }
 
-        ok = ctx->get_issuer(&xtmp, ctx, x);
+        /* we now have our chain, lets check it... */
+        i = check_trust(ctx);
 
-        if (ok < 0)
-            return ok;
-        if (ok == 0)
-            break;
+        /* If explicitly rejected error */
+        if (i == X509_TRUST_REJECTED)
+            goto end;
+        /*
+         * If it's not explicitly trusted then check if there is an alternative
+         * chain that could be used. We only do this if we haven't already
+         * checked via TRUSTED_FIRST and the user hasn't switched off alternate
+         * chain checking
+         */
+        retry = 0;
+        if (i != X509_TRUST_TRUSTED
+            && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
+            && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
+            while (j-- > 1) {
+                STACK_OF(X509) *chtmp = ctx->chain;
+                xtmp2 = sk_X509_value(ctx->chain, j - 1);
+                /*
+                 * Temporarily set chain to NULL so we don't discount
+                 * duplicates: the same certificate could be an untrusted
+                 * CA found in the trusted store.
+                 */
+                ctx->chain = NULL;
+                ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
+                ctx->chain = chtmp;
+                if (ok < 0)
+                    goto end;
+                /* Check if we found an alternate chain */
+                if (ok > 0) {
+                    /*
+                     * Free up the found cert we'll add it again later
+                     */
+                    X509_free(xtmp);
 
-        x = xtmp;
-        if (!sk_X509_push(ctx->chain, x)) {
-            X509_free(xtmp);
-            X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
-            return 0;
+                    /*
+                     * Dump all the certs above this point - we've found an
+                     * alternate chain
+                     */
+                    while (num > j) {
+                        xtmp = sk_X509_pop(ctx->chain);
+                        X509_free(xtmp);
+                        num--;
+                        ctx->last_untrusted--;
+                    }
+                    retry = 1;
+                    break;
+                }
+            }
         }
-        num++;
-    }
+    } while (retry);
 
-    /* we now have our chain, lets check it... */
-
-    i = check_trust(ctx);
-
-    /* If explicitly rejected error */
-    if (i == X509_TRUST_REJECTED)
-        goto end;
     /*
      * If not explicitly trusted then indicate error unless it's a single
      * self signed certificate in which case we've indicated an error already
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
index a6f0df5..bd8613c 100644
--- a/crypto/x509/x509_vfy.h
+++ b/crypto/x509/x509_vfy.h
@@ -432,6 +432,12 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
 
 /* Allow partial chains if at least one certificate is in trusted store */
 # define X509_V_FLAG_PARTIAL_CHAIN               0x80000
+/*
+ * If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag
+ * will force the behaviour to match that of previous versions.
+ */
+# define X509_V_FLAG_NO_ALT_CHAINS               0x100000
 
 # define X509_VP_FLAG_DEFAULT                    0x1
 # define X509_VP_FLAG_OVERWRITE                  0x2
diff --git a/doc/apps/cms.pod b/doc/apps/cms.pod
index 76dbf2c..4eaedbc 100644
--- a/doc/apps/cms.pod
+++ b/doc/apps/cms.pod
@@ -35,6 +35,7 @@ B<openssl> B<cms>
 [B<-print>]
 [B<-CAfile file>]
 [B<-CApath dir>]
+[B<-no_alt_chains>]
 [B<-md digest>]
 [B<-[cipher]>]
 [B<-nointern>]
@@ -419,7 +420,7 @@ portion of a message so they may be included manually. If signing
 then many S/MIME mail clients check the signers certificate's email
 address matches that specified in the From: address.
 
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains>
 
 Set various certificate chain valiadition option. See the
 L<B<verify>|verify(1)> manual page for details.
@@ -655,4 +656,6 @@ Support for RSA-OAEP and RSA-PSS was first added to OpenSSL 1.1.0.
 The use of non-RSA keys with B<-encrypt> and B<-decrypt> was first added
 to OpenSSL 1.1.0.
 
+The -no_alt_chains options was first added to OpenSSL 1.0.2b.
+
 =cut
diff --git a/doc/apps/ocsp.pod b/doc/apps/ocsp.pod
index 2372b37..4639502 100644
--- a/doc/apps/ocsp.pod
+++ b/doc/apps/ocsp.pod
@@ -29,6 +29,7 @@ B<openssl> B<ocsp>
 [B<-path>]
 [B<-CApath dir>]
 [B<-CAfile file>]
+[B<-no_alt_chains>]]
 [B<-VAfile file>]
 [B<-validity_period n>]
 [B<-status_age n>]
@@ -143,6 +144,10 @@ connection timeout to the OCSP responder in seconds
 file or pathname containing trusted CA certificates. These are used to verify
 the signature on the OCSP response.
 
+=item B<-no_alt_chains>
+
+See L<B<verify>|verify(1)> manual page for details.
+
 =item B<-verify_other file>
 
 file containing additional certificates to search when attempting to locate
@@ -379,3 +384,9 @@ second file.
 
  openssl ocsp -index demoCA/index.txt -rsigner rcert.pem -CA demoCA/cacert.pem
      -reqin req.der -respout resp.der
+
+=head1 HISTORY
+
+The -no_alt_chains options was first added to OpenSSL 1.0.2b.
+
+=cut
diff --git a/doc/apps/s_client.pod b/doc/apps/s_client.pod
index aad59b1..84d0527 100644
--- a/doc/apps/s_client.pod
+++ b/doc/apps/s_client.pod
@@ -19,6 +19,7 @@ B<openssl> B<s_client>
 [B<-pass arg>]
 [B<-CApath directory>]
 [B<-CAfile filename>]
+[B<-no_alt_chains>]
 [B<-reconnect>]
 [B<-pause>]
 [B<-showcerts>]
@@ -120,7 +121,7 @@ also used when building the client certificate chain.
 A file containing trusted certificates to use during server authentication
 and to use when attempting to build the client certificate chain.
 
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains>
 
 Set various certificate chain valiadition option. See the
 L<B<verify>|verify(1)> manual page for details.
@@ -361,4 +362,8 @@ information whenever a session is renegotiated.
 
 L<sess_id(1)|sess_id(1)>, L<s_server(1)|s_server(1)>, L<ciphers(1)|ciphers(1)>
 
+=head1 HISTORY
+
+The -no_alt_chains options was first added to OpenSSL 1.0.2b.
+
 =cut
diff --git a/doc/apps/s_server.pod b/doc/apps/s_server.pod
index b37f410..baca779 100644
--- a/doc/apps/s_server.pod
+++ b/doc/apps/s_server.pod
@@ -33,6 +33,7 @@ B<openssl> B<s_server>
 [B<-state>]
 [B<-CApath directory>]
 [B<-CAfile filename>]
+[B<-no_alt_chains>]
 [B<-nocert>]
 [B<-cipher cipherlist>]
 [B<-serverpref>]
@@ -174,6 +175,10 @@ and to use when attempting to build the server certificate chain. The list
 is also used in the list of acceptable client CAs passed to the client when
 a certificate is requested.
 
+=item B<-no_alt_chains>
+
+See the L<B<verify>|verify(1)> manual page for details.
+
 =item B<-state>
 
 prints out the SSL session states.
@@ -406,4 +411,8 @@ unknown cipher suites a client says it supports.
 
 L<sess_id(1)|sess_id(1)>, L<s_client(1)|s_client(1)>, L<ciphers(1)|ciphers(1)>
 
+=head1 HISTORY
+
+The -no_alt_chains options was first added to OpenSSL 1.0.2b.
+
 =cut
diff --git a/doc/apps/smime.pod b/doc/apps/smime.pod
index d39a59a..d5618c8 100644
--- a/doc/apps/smime.pod
+++ b/doc/apps/smime.pod
@@ -15,6 +15,7 @@ B<openssl> B<smime>
 [B<-pk7out>]
 [B<-[cipher]>]
 [B<-in file>]
+[B<-no_alt_chains>]
 [B<-certfile file>]
 [B<-signer file>]
 [B<-recip  file>]
@@ -259,7 +260,7 @@ portion of a message so they may be included manually. If signing
 then many S/MIME mail clients check the signers certificate's email
 address matches that specified in the From: address.
 
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains>
 
 Set various options of certificate chain verification. See
 L<B<verify>|verify(1)> manual page for details.
@@ -441,5 +442,6 @@ structures may cause parsing errors.
 The use of multiple B<-signer> options and the B<-resign> command were first
 added in OpenSSL 1.0.0
 
+The -no_alt_chains options was first added to OpenSSL 1.0.2b.
 
 =cut
diff --git a/doc/apps/verify.pod b/doc/apps/verify.pod
index df01534..df1b86d 100644
--- a/doc/apps/verify.pod
+++ b/doc/apps/verify.pod
@@ -25,6 +25,7 @@ B<openssl> B<verify>
 [B<-extended_crl>]
 [B<-use_deltas>]
 [B<-policy_print>]
+[B<-no_alt_chains>]
 [B<-untrusted file>]
 [B<-help>]
 [B<-issuer_checks>]
@@ -124,6 +125,14 @@ Set policy variable inhibit-any-policy (see RFC5280).
 
 Set policy variable inhibit-policy-mapping (see RFC5280).
 
+=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 previous OpenSSL versions.
+
 =item B<-policy_print>
 
 Print out diagnostics related to policy processing.
@@ -425,4 +434,8 @@ B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY> error codes.
 
 L<x509(1)|x509(1)>
 
+=head1 HISTORY
+
+The -no_alt_chains options was first added to OpenSSL 1.0.2b.
+
 =cut
diff --git a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
index 347d48d..44792f9 100644
--- a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
+++ b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
@@ -197,6 +197,12 @@ 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.
 
+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.0.2b.
+
 =head1 NOTES
 
 The above functions should be used to manipulate verification parameters
@@ -233,6 +239,6 @@ L<X509_check_ip(3)|X509_check_ip(3)>
 
 =head1 HISTORY
 
-TBA
+The B<X509_V_FLAG_NO_ALT_CHAINS> flag was added in OpenSSL 1.0.2b
 
 =cut


More information about the openssl-commits mailing list