fc6854
diff -up openssl-1.0.1k/apps/apps.c.alt-chains openssl-1.0.1k/apps/apps.c
fc6854
--- openssl-1.0.1k/apps/apps.c.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/apps/apps.c	2015-04-30 14:25:49.220873338 +0200
fc6854
@@ -2365,6 +2365,8 @@ int args_verify(char ***pargs, int *parg
fc6854
 		flags |= X509_V_FLAG_NOTIFY_POLICY;
fc6854
 	else if (!strcmp(arg, "-check_ss_sig"))
fc6854
 		flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
fc6854
+	else if (!strcmp(arg, "-no_alt_chains"))
fc6854
+		flags |= X509_V_FLAG_NO_ALT_CHAINS;
fc6854
 	else if (!strcmp(arg, "-trusted_first"))
fc6854
 		flags |= X509_V_FLAG_TRUSTED_FIRST;
fc6854
 	else
fc6854
diff -up openssl-1.0.1k/apps/cms.c.alt-chains openssl-1.0.1k/apps/cms.c
fc6854
--- openssl-1.0.1k/apps/cms.c.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/apps/cms.c	2015-04-30 14:27:12.129773347 +0200
fc6854
@@ -642,6 +642,7 @@ int MAIN(int argc, char **argv)
fc6854
 		BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
fc6854
 		BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
fc6854
 		BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
fc6854
+		BIO_printf (bio_err, "-no_alt_chains only ever use the first certificate chain found\n");
fc6854
 		BIO_printf (bio_err, "-trusted_first use trusted certificates first when building the trust chain\n");
fc6854
 		BIO_printf (bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
fc6854
 		BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
fc6854
diff -up openssl-1.0.1k/apps/ocsp.c.alt-chains openssl-1.0.1k/apps/ocsp.c
fc6854
--- openssl-1.0.1k/apps/ocsp.c.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/apps/ocsp.c	2015-04-30 14:28:12.975167730 +0200
fc6854
@@ -605,6 +605,7 @@ int MAIN(int argc, char **argv)
fc6854
 		BIO_printf (bio_err, "-path                path to use in OCSP request\n");
fc6854
 		BIO_printf (bio_err, "-CApath dir          trusted certificates directory\n");
fc6854
 		BIO_printf (bio_err, "-CAfile file         trusted certificates file\n");
fc6854
+		BIO_printf (bio_err, "-no_alt_chains       only ever use the first certificate chain found\n");
fc6854
 		BIO_printf (bio_err, "-trusted_first       use trusted certificates first when building the trust chain\n");
fc6854
 		BIO_printf (bio_err, "-VAfile file         validator certificates file\n");
fc6854
 		BIO_printf (bio_err, "-validity_period n   maximum validity discrepancy in seconds\n");
fc6854
diff -up openssl-1.0.1k/apps/s_client.c.alt-chains openssl-1.0.1k/apps/s_client.c
fc6854
--- openssl-1.0.1k/apps/s_client.c.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/apps/s_client.c	2015-04-30 14:29:33.254006312 +0200
fc6854
@@ -299,6 +299,7 @@ static void sc_usage(void)
fc6854
 	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
fc6854
 	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
fc6854
 	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
fc6854
+	BIO_printf(bio_err," -no_alt_chains - only ever use the first certificate chain found\n");
fc6854
 	BIO_printf(bio_err," -trusted_first - Use trusted CA's first when building the trust chain\n");
fc6854
 	BIO_printf(bio_err," -reconnect    - Drop and re-make the connection with the same Session-ID\n");
fc6854
 	BIO_printf(bio_err," -pause        - sleep(1) after each read(2) and write(2) system call\n");
fc6854
diff -up openssl-1.0.1k/apps/smime.c.alt-chains openssl-1.0.1k/apps/smime.c
fc6854
--- openssl-1.0.1k/apps/smime.c.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/apps/smime.c	2015-04-30 14:30:44.456633094 +0200
fc6854
@@ -479,6 +479,7 @@ int MAIN(int argc, char **argv)
fc6854
 		BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
fc6854
 		BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
fc6854
 		BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
fc6854
+		BIO_printf (bio_err, "-no_alt_chains only ever use the first certificate chain found\n");
fc6854
 		BIO_printf (bio_err, "-trusted_first use trusted certificates first when building the trust chain\n");
fc6854
 		BIO_printf (bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
fc6854
 		BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
fc6854
diff -up openssl-1.0.1k/apps/s_server.c.alt-chains openssl-1.0.1k/apps/s_server.c
fc6854
--- openssl-1.0.1k/apps/s_server.c.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/apps/s_server.c	2015-04-30 14:30:06.420764081 +0200
fc6854
@@ -502,6 +502,7 @@ static void sv_usage(void)
fc6854
 	BIO_printf(bio_err," -state        - Print the SSL states\n");
fc6854
 	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
fc6854
 	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
fc6854
+	BIO_printf(bio_err," -no_alt_chains - only ever use the first certificate chain found\n");
fc6854
 	BIO_printf(bio_err," -trusted_first - Use trusted CA's first when building the trust chain\n");
fc6854
 	BIO_printf(bio_err," -nocert       - Don't use any certificates (Anon-DH)\n");
fc6854
 	BIO_printf(bio_err," -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
fc6854
diff -up openssl-1.0.1k/apps/verify.c.alt-chains openssl-1.0.1k/apps/verify.c
fc6854
--- openssl-1.0.1k/apps/verify.c.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/apps/verify.c	2015-04-30 14:31:20.055446426 +0200
fc6854
@@ -238,7 +238,7 @@ int MAIN(int argc, char **argv)
fc6854
 end:
fc6854
 	if (ret == 1) {
fc6854
 		BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-trusted_first] [-purpose purpose] [-crl_check]");
fc6854
-		BIO_printf(bio_err," [-attime timestamp]");
fc6854
+		BIO_printf(bio_err," [-no_alt_chains] [-attime timestamp]");
fc6854
 #ifndef OPENSSL_NO_ENGINE
fc6854
 		BIO_printf(bio_err," [-engine e]");
fc6854
 #endif
fc6854
diff -up openssl-1.0.1k/crypto/x509/x509_vfy.c.alt-chains openssl-1.0.1k/crypto/x509/x509_vfy.c
fc6854
--- openssl-1.0.1k/crypto/x509/x509_vfy.c.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/crypto/x509/x509_vfy.c	2015-04-30 14:22:37.183472452 +0200
fc6854
@@ -154,11 +154,11 @@ static int x509_subject_cmp(X509 **a, X5
fc6854
 
fc6854
 int X509_verify_cert(X509_STORE_CTX *ctx)
fc6854
 	{
fc6854
-	X509 *x,*xtmp,*chain_ss=NULL;
fc6854
+	X509 *x,*xtmp,*xtmp2,*chain_ss=NULL;
fc6854
 	int bad_chain = 0;
fc6854
 	X509_VERIFY_PARAM *param = ctx->param;
fc6854
 	int depth,i,ok=0;
fc6854
-	int num;
fc6854
+	int num, j, retry;
fc6854
 	int (*cb)(int xok,X509_STORE_CTX *xctx);
fc6854
 	STACK_OF(X509) *sktmp=NULL;
fc6854
 	if (ctx->cert == NULL)
fc6854
@@ -247,10 +247,14 @@ int X509_verify_cert(X509_STORE_CTX *ctx
fc6854
 		break;
fc6854
 		}
fc6854
 
fc6854
+	/* Remember how many untrusted certs we have */
fc6854
+	j = num;
fc6854
+
fc6854
 	/* at this point, chain should contain a list of untrusted
fc6854
 	 * certificates.  We now need to add at least one trusted one,
fc6854
 	 * if possible, otherwise we complain. */
fc6854
 
fc6854
+	do {
fc6854
 	/* Examine last certificate in chain and see if it
fc6854
  	 * is self signed.
fc6854
  	 */
fc6854
@@ -294,6 +298,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx
fc6854
 			chain_ss=sk_X509_pop(ctx->chain);
fc6854
 			ctx->last_untrusted--;
fc6854
 			num--;
fc6854
+			j--;
fc6854
 			x=sk_X509_value(ctx->chain,num-1);
fc6854
 			}
fc6854
 		}
fc6854
@@ -322,7 +327,42 @@ int X509_verify_cert(X509_STORE_CTX *ctx
fc6854
 		num++;
fc6854
 		}
fc6854
 
fc6854
-	/* we now have our chain, lets check it... */
fc6854
+        /*
fc6854
+         * If we haven't got a least one certificate from our store then check
fc6854
+         * if there is an alternative chain that could be used.  We only do this
fc6854
+         * if the user hasn't switched off alternate chain checking
fc6854
+         */
fc6854
+        retry = 0;
fc6854
+        if (j == ctx->last_untrusted &&
fc6854
+            !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
fc6854
+            while (j-- > 1) {
fc6854
+                xtmp2 = sk_X509_value(ctx->chain, j - 1);
fc6854
+                ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
fc6854
+                if (ok < 0)
fc6854
+                    goto end;
fc6854
+                /* Check if we found an alternate chain */
fc6854
+                if (ok > 0) {
fc6854
+                    /*
fc6854
+                     * Free up the found cert we'll add it again later
fc6854
+                     */
fc6854
+                    X509_free(xtmp);
fc6854
+
fc6854
+                    /*
fc6854
+                     * Dump all the certs above this point - we've found an
fc6854
+                     * alternate chain
fc6854
+                     */
fc6854
+                    while (num > j) {
fc6854
+                        xtmp = sk_X509_pop(ctx->chain);
fc6854
+                        X509_free(xtmp);
fc6854
+                        num--;
fc6854
+                        ctx->last_untrusted--;
fc6854
+                    }
fc6854
+                    retry = 1;
fc6854
+                    break;
fc6854
+                }
fc6854
+            }
fc6854
+        }
fc6854
+	} while (retry);
fc6854
 
fc6854
 	/* Is last certificate looked up self signed? */
fc6854
 	if (!ctx->check_issued(ctx,x,x))
fc6854
diff -up openssl-1.0.1k/crypto/x509/x509_vfy.h.alt-chains openssl-1.0.1k/crypto/x509/x509_vfy.h
fc6854
--- openssl-1.0.1k/crypto/x509/x509_vfy.h.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/crypto/x509/x509_vfy.h	2015-04-30 14:16:56.818672373 +0200
fc6854
@@ -391,7 +391,12 @@ void X509_STORE_CTX_set_depth(X509_STORE
fc6854
 #define X509_V_FLAG_CHECK_SS_SIGNATURE		0x4000
fc6854
 /* Use trusted store first */
fc6854
 #define X509_V_FLAG_TRUSTED_FIRST		0x8000
fc6854
-
fc6854
+/*
fc6854
+ * If the initial chain is not trusted, do not attempt to build an alternative
fc6854
+ * chain. Alternate chain checking was introduced in 1.0.1n/1.0.2b. Setting
fc6854
+ * this flag will force the behaviour to match that of previous versions.
fc6854
+ */
fc6854
+#define X509_V_FLAG_NO_ALT_CHAINS               0x100000
fc6854
 
fc6854
 #define X509_VP_FLAG_DEFAULT			0x1
fc6854
 #define X509_VP_FLAG_OVERWRITE			0x2
fc6854
diff -up openssl-1.0.1k/doc/apps/cms.pod.alt-chains openssl-1.0.1k/doc/apps/cms.pod
fc6854
--- openssl-1.0.1k/doc/apps/cms.pod.alt-chains	2015-04-30 14:32:50.736518235 +0200
fc6854
+++ openssl-1.0.1k/doc/apps/cms.pod	2015-04-30 14:36:11.989116293 +0200
fc6854
@@ -35,6 +35,7 @@ B<openssl> B<cms>
fc6854
 [B<-print>]
fc6854
 [B<-CAfile file>]
fc6854
 [B<-CApath dir>]
fc6854
+[B<-no_alt_chains>]
fc6854
 [B<-trusted_first>]
fc6854
 [B<-md digest>]
fc6854
 [B<-[cipher]>]
fc6854
@@ -413,7 +414,7 @@ portion of a message so they may be incl
fc6854
 then many S/MIME mail clients check the signers certificate's email
fc6854
 address matches that specified in the From: address.
fc6854
 
fc6854
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
fc6854
+=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>
fc6854
 
fc6854
 Set various certificate chain valiadition option. See the
fc6854
 L<b<verify>|verify(1)> manual page for details.
fc6854
diff -up openssl-1.0.1k/doc/apps/ocsp.pod.alt-chains openssl-1.0.1k/doc/apps/ocsp.pod
fc6854
--- openssl-1.0.1k/doc/apps/ocsp.pod.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/doc/apps/ocsp.pod	2015-04-30 14:34:40.398023692 +0200
fc6854
@@ -29,6 +29,7 @@ B<openssl> B<ocsp>
fc6854
 [B<-path>]
fc6854
 [B<-CApath dir>]
fc6854
 [B<-CAfile file>]
fc6854
+[B<-no_alt_chains>]]
fc6854
 [B<-trusted_first>]
fc6854
 [B<-VAfile file>]
fc6854
 [B<-validity_period n>]
fc6854
@@ -143,6 +144,10 @@ connection timeout to the OCSP responder
fc6854
 file or pathname containing trusted CA certificates. These are used to verify
fc6854
 the signature on the OCSP response.
fc6854
 
fc6854
+=item B<-no_alt_chains>
fc6854
+
fc6854
+See L<b<verify>|verify(1)> manual page for details.
fc6854
+
fc6854
 =item B<-trusted_first>
fc6854
 
fc6854
 Use certificates in CA file or CA directory over certificates provided
fc6854
diff -up openssl-1.0.1k/doc/apps/s_client.pod.alt-chains openssl-1.0.1k/doc/apps/s_client.pod
fc6854
--- openssl-1.0.1k/doc/apps/s_client.pod.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/doc/apps/s_client.pod	2015-04-30 14:35:23.284003518 +0200
fc6854
@@ -19,6 +19,7 @@ B<openssl> B<s_client>
fc6854
 [B<-pass arg>]
fc6854
 [B<-CApath directory>]
fc6854
 [B<-CAfile filename>]
fc6854
+[B<-no_alt_chains>]
fc6854
 [B<-trusted_first>]
fc6854
 [B<-reconnect>]
fc6854
 [B<-pause>]
fc6854
@@ -122,7 +123,7 @@ also used when building the client certi
fc6854
 A file containing trusted certificates to use during server authentication
fc6854
 and to use when attempting to build the client certificate chain.
fc6854
 
fc6854
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig, -trusted_first>
fc6854
+=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>
fc6854
 
fc6854
 Set various certificate chain valiadition option. See the
fc6854
 L<b<verify>|verify(1)> manual page for details.
fc6854
diff -up openssl-1.0.1k/doc/apps/smime.pod.alt-chains openssl-1.0.1k/doc/apps/smime.pod
fc6854
--- openssl-1.0.1k/doc/apps/smime.pod.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/doc/apps/smime.pod	2015-04-30 14:37:58.832557366 +0200
fc6854
@@ -17,6 +17,7 @@ B<openssl> B<smime>
fc6854
 [B<-in file>]
fc6854
 [B<-CAfile file>]
fc6854
 [B<-CApath dir>]
fc6854
+[B<-no_alt_chains>]
fc6854
 [B<-trusted_first>]
fc6854
 [B<-certfile file>]
fc6854
 [B<-signer file>]
fc6854
@@ -268,7 +269,7 @@ portion of a message so they may be incl
fc6854
 then many S/MIME mail clients check the signers certificate's email
fc6854
 address matches that specified in the From: address.
fc6854
 
fc6854
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
fc6854
+=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>
fc6854
 
fc6854
 Set various options of certificate chain verification. See
fc6854
 L<b<verify>|verify(1)> manual page for details.
fc6854
diff -up openssl-1.0.1k/doc/apps/s_server.pod.alt-chains openssl-1.0.1k/doc/apps/s_server.pod
fc6854
--- openssl-1.0.1k/doc/apps/s_server.pod.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/doc/apps/s_server.pod	2015-04-30 14:37:02.850278328 +0200
fc6854
@@ -33,6 +33,7 @@ B<openssl> B<s_server>
fc6854
 [B<-state>]
fc6854
 [B<-CApath directory>]
fc6854
 [B<-CAfile filename>]
fc6854
+[B<-no_alt_chains>]
fc6854
 [B<-trusted_first>]
fc6854
 [B<-nocert>]
fc6854
 [B<-cipher cipherlist>]
fc6854
@@ -179,6 +180,10 @@ and to use when attempting to build the
fc6854
 is also used in the list of acceptable client CAs passed to the client when
fc6854
 a certificate is requested.
fc6854
 
fc6854
+=item B<-no_alt_chains>
fc6854
+
fc6854
+See the L<b<verify>|verify(1)> manual page for details.
fc6854
+
fc6854
 =item B<-trusted_first>
fc6854
 
fc6854
 Use certificates in CA file or CA directory before other certificates 
fc6854
diff -up openssl-1.0.1k/doc/apps/verify.pod.alt-chains openssl-1.0.1k/doc/apps/verify.pod
fc6854
--- openssl-1.0.1k/doc/apps/verify.pod.alt-chains	2015-04-30 14:14:40.000000000 +0200
fc6854
+++ openssl-1.0.1k/doc/apps/verify.pod	2015-04-30 14:38:32.853334645 +0200
fc6854
@@ -23,6 +23,7 @@ B<openssl> B<verify>
fc6854
 [B<-extended_crl>]
fc6854
 [B<-use_deltas>]
fc6854
 [B<-policy_print>]
fc6854
+[B<-no_alt_chains>]
fc6854
 [B<-untrusted file>]
fc6854
 [B<-help>]
fc6854
 [B<-issuer_checks>]
fc6854
@@ -115,6 +116,14 @@ Set policy variable inhibit-any-policy (
fc6854
 
fc6854
 Set policy variable inhibit-policy-mapping (see RFC5280).
fc6854
 
fc6854
+=item B<-no_alt_chains>
fc6854
+
fc6854
+When building a certificate chain, if the first certificate chain found is not
fc6854
+trusted, then OpenSSL will continue to check to see if an alternative chain can
fc6854
+be found that is trusted. With this option that behaviour is suppressed so that
fc6854
+only the first chain found is ever used. Using this option will force the
fc6854
+behaviour to match that of previous OpenSSL versions.
fc6854
+
fc6854
 =item B<-policy_print>
fc6854
 
fc6854
 Print out diagnostics related to policy processing.
fc6854
diff -up openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod.alt-chains openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
fc6854
--- openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod.alt-chains	2014-10-15 14:51:06.000000000 +0200
fc6854
+++ openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod	2015-04-30 14:39:34.951753420 +0200
fc6854
@@ -133,6 +133,12 @@ verification. If this flag is set then a
fc6854
 to the verification callback and it B<must> be prepared to handle such cases
fc6854
 without assuming they are hard errors.
fc6854
 
fc6854
+The B<x509_v_flag_no_alt_chains> flag suppresses checking for alternative
fc6854
+chains. By default, when building a certificate chain, if the first certificate
fc6854
+chain found is not trusted, then OpenSSL will continue to check to see if an
fc6854
+alternative chain can be found that is trusted. With this flag set the behaviour
fc6854
+will match that of OpenSSL versions prior to 1.0.1n and 1.0.2b.
fc6854
+
fc6854
 =head1 NOTES
fc6854
 
fc6854
 The above functions should be used to manipulate verification parameters
fc6854
@@ -166,6 +172,6 @@ L
fc6854
 
fc6854
 =head1 HISTORY
fc6854
 
fc6854
-TBA
fc6854
+The B<x509_v_flag_no_alt_chains> flag was added in upstream OpenSSL 1.0.1n and 1.0.2b
fc6854
 
fc6854
 =cut