Skip to content

Instantly share code, notes, and snippets.

@h-yamamo
Last active February 25, 2016 14:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save h-yamamo/8f17f3a5a62b083bf3c8 to your computer and use it in GitHub Desktop.
Save h-yamamo/8f17f3a5a62b083bf3c8 to your computer and use it in GitHub Desktop.
Support CA alternate chains for ubuntu trusty openssl package - merged from openssl-1.0.1p
# See https://github.com/openssl/openssl commit log.
Commits on Aug 14, 2015
GH364: Free memory on an error path [OpenSSL_1_0_2-stable]
Commits on Jul 8, 2015
Fix alternate chains certificate forgery issue (CVE-2015-1793)
Fix alt chains bug
Reject calls to X509_verify_cert that have not been reinitialised
Commits on May 21, 2015
Add -no_alt_chains option ... 3 commits
In certain situations the server provided certificate chain may no ...
diff -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/apps/apps.c 2014-01-06 13:47:42.000000000 +0000
+++ b/apps/apps.c 2015-08-22 00:51:15.000000000 +0900
@@ -2361,6 +2361,8 @@
flags |= X509_V_FLAG_NOTIFY_POLICY;
else if (!strcmp(arg, "-check_ss_sig"))
flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
+ else if (!strcmp(arg, "-no_alt_chains"))
+ flags |= X509_V_FLAG_NO_ALT_CHAINS;
else
return 0;
diff -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/apps/cms.c 2014-01-06 13:47:42.000000000 +0000
+++ b/apps/cms.c 2015-08-22 00:51:15.000000000 +0900
@@ -642,6 +642,7 @@
BIO_printf (bio_err, "-text include or delete text MIME headers\n");
BIO_printf (bio_err, "-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");
#ifndef OPENSSL_NO_ENGINE
diff -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/apps/ocsp.c 2014-01-06 13:47:42.000000000 +0000
+++ b/apps/ocsp.c 2015-08-22 20:08:05.000000000 +0900
@@ -595,6 +595,7 @@
BIO_printf (bio_err, "-path path to use in OCSP request\n");
BIO_printf (bio_err, "-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, "-VAfile file validator certificates file\n");
BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
BIO_printf (bio_err, "-status_age n maximum status age in seconds\n");
diff -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/apps/s_client.c 2014-10-15 17:01:58.000000000 +0000
+++ b/apps/s_client.c 2015-08-22 00:51:15.000000000 +0900
@@ -298,6 +298,7 @@
BIO_printf(bio_err," -pass arg - private key file pass phrase source\n");
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");
BIO_printf(bio_err," -showcerts - show all certificates in the chain\n");
diff -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/apps/s_server.c 2015-06-08 15:28:33.000000000 +0000
+++ b/apps/s_server.c 2015-08-22 21:00:30.000000000 +0900
@@ -517,6 +517,7 @@
BIO_printf(bio_err," -state - Print the SSL states\n");
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");
BIO_printf(bio_err," -serverpref - Use server's cipher preferences\n");
diff -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/apps/smime.c 2014-01-06 13:47:42.000000000 +0000
+++ b/apps/smime.c 2015-08-22 00:51:15.000000000 +0900
@@ -479,6 +479,7 @@
BIO_printf (bio_err, "-text include or delete text MIME headers\n");
BIO_printf (bio_err, "-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");
#ifndef OPENSSL_NO_ENGINE
diff -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/apps/verify.c 2014-01-06 13:47:42.000000000 +0000
+++ b/apps/verify.c 2015-08-22 00:51:15.000000000 +0900
@@ -238,7 +238,7 @@
end:
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 -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/crypto/x509/x509_vfy.c 2015-06-08 13:56:53.000000000 +0000
+++ b/crypto/x509/x509_vfy.c 2015-08-28 23:29:30.000000000 +0900
@@ -153,11 +153,11 @@
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)
@@ -165,22 +165,27 @@
X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
return -1;
}
+ if (ctx->chain != NULL)
+ {
+ /* This X509_STORE_CTX has already been used to verify a cert. We
+ * cannot do another one.
+ */
+ X509err(X509_F_X509_VERIFY_CERT,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
cb=ctx->verify_cb;
/* first we make sure the chain we are going to build is
* present and that the first entry is in place */
- if (ctx->chain == NULL)
+ if (((ctx->chain = sk_X509_new_null()) == NULL) ||
+ (!sk_X509_push(ctx->chain, ctx->cert)))
{
- if ( ((ctx->chain=sk_X509_new_null()) == NULL) ||
- (!sk_X509_push(ctx->chain,ctx->cert)))
- {
- X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
- goto end;
- }
- CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
- ctx->last_untrusted=1;
+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ goto end;
}
+ CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
+ ctx->last_untrusted = 1;
/* We use a temporary STACK so we can chop and hack at it */
if (ctx->untrusted != NULL
@@ -231,82 +236,126 @@
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 (ctx->check_issued(ctx, x, x))
+ do
{
- /* we have a self signed certificate */
- if (sk_X509_num(ctx->chain) == 1)
+ /* 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 (ctx->check_issued(ctx, x, x))
{
- /* 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))
+ /* we have a self signed certificate */
+ if (sk_X509_num(ctx->chain) == 1)
{
- 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;
+ /* We have a single self signed certificate: see if
+ * we canfind 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
+ 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;
+ /* extract and save self signed certificate for later use */
+ chain_ss = sk_X509_pop(ctx->chain);
+ ctx->last_untrusted--;
+ num--;
+ j--;
+ x = sk_X509_value(ctx->chain, num - 1);
}
}
- else
+
+ /* We now lookup certs from the certificate store */
+ for (;;)
{
- /* 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);
- }
- }
+ /* 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 (ctx->check_issued(ctx, x, x)) break;
- /* If we are self signed, we break */
- if (ctx->check_issued(ctx,x,x)) break;
+ ok = ctx->get_issuer(&xtmp, ctx, x);
- ok = ctx->get_issuer(&xtmp, ctx, x);
+ if (ok < 0) return ok;
+ if (ok == 0) 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);
+ ok = 0;
+ goto end;
+ }
+ num++;
+ }
- x = xtmp;
- if (!sk_X509_push(ctx->chain,x))
+ /* If we haven't got a least one certificate from our store then check
+ * if there is an alternative chain that could be used. We only do this
+ * if the user hasn't switched off alternate chain checking
+ */
+ retry = 0;
+ if (num == ctx->last_untrusted &&
+ !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS))
{
- X509_free(xtmp);
- X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
- return 0;
+ while (j-- > 1)
+ {
+ xtmp2 = sk_X509_value(ctx->chain, j - 1);
+ ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
+ 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);
+
+ /* 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 = sk_X509_num(ctx->chain);
+ retry = 1;
+ break;
+ }
+ }
}
- num++;
}
-
- /* we now have our chain, lets check it... */
+ while (retry);
/* Is last certificate looked up self signed? */
if (!ctx->check_issued(ctx,x,x))
diff -ur openssl-1.0.1f-1ubuntu2.16 openssl-1.0.1f-1ubuntu2.16+alt
--- a/crypto/x509/x509_vfy.h 2014-01-06 13:47:42.000000000 +0000
+++ b/crypto/x509/x509_vfy.h 2015-08-22 00:51:15.000000000 +0900
@@ -389,6 +389,12 @@
#define X509_V_FLAG_USE_DELTAS 0x2000
/* Check selfsigned CA signature */
#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000
+/*
+ * If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.0.1n/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
--- openssl-1.0.1m/doc/apps/cms.pod 2015-03-19 22:37:10.000000000 +0900
+++ openssl-1.0.1p/doc/apps/cms.pod 2015-07-09 21:21:24.000000000 +0900
@@ -35,6 +35,7 @@
[B<-print>]
[B<-CAfile file>]
[B<-CApath dir>]
+[B<-no_alt_chains>]
[B<-md digest>]
[B<-[cipher]>]
[B<-nointern>]
@@ -406,7 +407,7 @@
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.
@@ -614,4 +615,6 @@
added in OpenSSL 1.0.0
+The -no_alt_chains options was first added to OpenSSL 1.0.1n and 1.0.2b.
+
=cut
--- openssl-1.0.1m/doc/apps/ocsp.pod 2015-03-19 22:19:00.000000000 +0900
+++ openssl-1.0.1p/doc/apps/ocsp.pod 2015-07-09 21:21:24.000000000 +0900
@@ -29,6 +29,7 @@
[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 @@
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 @@
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.1n and 1.0.2b.
+
+=cut
--- openssl-1.0.1m/doc/apps/s_client.pod 2015-03-19 22:37:10.000000000 +0900
+++ openssl-1.0.1p/doc/apps/s_client.pod 2015-07-09 21:21:24.000000000 +0900
@@ -19,6 +19,7 @@
[B<-pass arg>]
[B<-CApath directory>]
[B<-CAfile filename>]
+[B<-no_alt_chains>]
[B<-reconnect>]
[B<-pause>]
[B<-showcerts>]
@@ -116,7 +117,7 @@
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.
@@ -347,4 +348,8 @@
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.1n and 1.0.2b.
+
=cut
--- openssl-1.0.1m/doc/apps/s_server.pod 2015-03-19 22:37:10.000000000 +0900
+++ openssl-1.0.1p/doc/apps/s_server.pod 2015-08-22 20:21:28.000000000 +0900
@@ -33,6 +33,7 @@ update line 38 to fix fuzz with patch
[B<-state>]
[B<-CApath directory>]
[B<-CAfile filename>]
+[B<-no_alt_chains>]
[B<-nocert>]
[B<-cipher cipherlist>]
[B<-quiet>]
@@ -178,6 +179,10 @@
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.
@@ -398,4 +403,8 @@
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.1n and 1.0.2b.
+
=cut
--- openssl-1.0.1m/doc/apps/smime.pod 2015-01-20 21:33:36.000000000 +0900
+++ openssl-1.0.1p/doc/apps/smime.pod 2015-07-09 21:21:24.000000000 +0900
@@ -15,6 +15,7 @@
[B<-pk7out>]
[B<-[cipher]>]
[B<-in file>]
+[B<-no_alt_chains>]
[B<-certfile file>]
[B<-signer file>]
[B<-recip file>]
@@ -259,7 +260,7 @@
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 @@
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.1n and 1.0.2b.
=cut
--- openssl-1.0.1m/doc/apps/verify.pod 2015-03-19 22:37:10.000000000 +0900
+++ openssl-1.0.1p/doc/apps/verify.pod 2015-07-09 21:21:24.000000000 +0900
@@ -22,6 +22,7 @@
[B<-extended_crl>]
[B<-use_deltas>]
[B<-policy_print>]
+[B<-no_alt_chains>]
[B<-untrusted file>]
[B<-help>]
[B<-issuer_checks>]
@@ -108,6 +109,14 @@
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.
@@ -409,4 +418,8 @@
L<x509(1)|x509(1)>
+=head1 HISTORY
+
+The -no_alt_chains options was first added to OpenSSL 1.0.1n and 1.0.2b.
+
=cut
--- openssl-1.0.1m/doc/crypto/X509_STORE_CTX_new.pod 2015-01-20 21:33:36.000000000 +0900
+++ openssl-1.0.1p/doc/crypto/X509_STORE_CTX_new.pod 2015-07-09 20:53:21.000000000 +0900
@@ -39,10 +39,15 @@
is no longer valid.
X509_STORE_CTX_init() sets up B<ctx> for a subsequent verification operation.
-The trusted certificate store is set to B<store>, the end entity certificate
-to be verified is set to B<x509> and a set of additional certificates (which
-will be untrusted but may be used to build the chain) in B<chain>. Any or
-all of the B<store>, B<x509> and B<chain> parameters can be B<NULL>.
+It must be called before each call to X509_verify_cert(), i.e. a B<ctx> is only
+good for one call to X509_verify_cert(); if you want to verify a second
+certificate with the same B<ctx> then you must call X509_XTORE_CTX_cleanup()
+and then X509_STORE_CTX_init() again before the second call to
+X509_verify_cert(). The trusted certificate store is set to B<store>, the end
+entity certificate to be verified is set to B<x509> and a set of additional
+certificates (which will be untrusted but may be used to build the chain) in
+B<chain>. Any or all of the B<store>, B<x509> and B<chain> parameters can be
+B<NULL>.
X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B<ctx>
to B<sk>. This is an alternative way of specifying trusted certificates
--- openssl-1.0.1m/doc/crypto/X509_VERIFY_PARAM_set_flags.pod 2015-03-19 22:37:10.000000000 +0900
+++ openssl-1.0.1p/doc/crypto/X509_VERIFY_PARAM_set_flags.pod 2015-07-09 21:21:24.000000000 +0900
@@ -133,6 +133,12 @@
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.1n and 1.0.2b.
+
=head1 NOTES
The above functions should be used to manipulate verification parameters
@@ -166,6 +172,6 @@
=head1 HISTORY
-TBA
+The B<X509_V_FLAG_NO_ALT_CHAINS> flag was added in OpenSSL 1.0.1n and 1.0.2b
=cut
--- openssl-1.0.1m/doc/crypto/X509_verify_cert.pod 2015-01-20 21:33:36.000000000 +0900
+++ openssl-1.0.1p/doc/crypto/X509_verify_cert.pod 2015-07-09 20:53:21.000000000 +0900
@@ -32,7 +32,8 @@
SSL/TLS code.
The negative return value from X509_verify_cert() can only occur if no
-certificate is set in B<ctx> (due to a programming error) or if a retry
+certificate is set in B<ctx> (due to a programming error); if X509_verify_cert()
+twice without reinitialising B<ctx> in between; or if a retry
operation is requested during internal lookups (which never happens with
standard lookup methods). It is however recommended that application check
for <= 0 return value on error.
@h-yamamo
Copy link
Author

h-yamamo commented Feb 6, 2016

Fixed in openssl_1.0.1f-1ubuntu2.17, so no longer needed.

How to build package

apt-get -d source openssl
tar xf openssl_1.0.1f.orig.tar.gz
cd openssl-1.0.1f
tar xf ../openssl_1.0.1f-1ubuntu2.16.debian.tar.gz
cp (somewhere)/ca-alt-chains.patch debian/patches/
echo ca-alt-chains.patch >> debian/patches/series
vi debian/changelog  # add description about this patch
debuild -uc -us

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment