From fc6854bd38f0a020118914e09bb7ef00964a9435 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 30 Apr 2015 15:08:45 +0200 Subject: [PATCH] try to find alternative cert chains (#1166614) --- openssl-1.0.1k-alt-chains.patch | 334 ++++++++++++++++++++++++++++++++ openssl.spec | 7 +- 2 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 openssl-1.0.1k-alt-chains.patch diff --git a/openssl-1.0.1k-alt-chains.patch b/openssl-1.0.1k-alt-chains.patch new file mode 100644 index 0000000..6424d66 --- /dev/null +++ b/openssl-1.0.1k-alt-chains.patch @@ -0,0 +1,334 @@ +diff -up openssl-1.0.1k/apps/apps.c.alt-chains openssl-1.0.1k/apps/apps.c +--- openssl-1.0.1k/apps/apps.c.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/apps/apps.c 2015-04-30 14:25:49.220873338 +0200 +@@ -2365,6 +2365,8 @@ int args_verify(char ***pargs, int *parg + 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 if (!strcmp(arg, "-trusted_first")) + flags |= X509_V_FLAG_TRUSTED_FIRST; + else +diff -up openssl-1.0.1k/apps/cms.c.alt-chains openssl-1.0.1k/apps/cms.c +--- openssl-1.0.1k/apps/cms.c.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/apps/cms.c 2015-04-30 14:27:12.129773347 +0200 +@@ -642,6 +642,7 @@ int MAIN(int argc, char **argv) + 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, "-trusted_first use trusted certificates first when building the trust chain\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 -up openssl-1.0.1k/apps/ocsp.c.alt-chains openssl-1.0.1k/apps/ocsp.c +--- openssl-1.0.1k/apps/ocsp.c.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/apps/ocsp.c 2015-04-30 14:28:12.975167730 +0200 +@@ -605,6 +605,7 @@ int MAIN(int argc, char **argv) + 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, "-trusted_first use trusted certificates first when building the trust chain\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 -up openssl-1.0.1k/apps/s_client.c.alt-chains openssl-1.0.1k/apps/s_client.c +--- openssl-1.0.1k/apps/s_client.c.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/apps/s_client.c 2015-04-30 14:29:33.254006312 +0200 +@@ -299,6 +299,7 @@ static void sc_usage(void) + 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," -trusted_first - Use trusted CA's first when building the trust chain\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 -up openssl-1.0.1k/apps/smime.c.alt-chains openssl-1.0.1k/apps/smime.c +--- openssl-1.0.1k/apps/smime.c.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/apps/smime.c 2015-04-30 14:30:44.456633094 +0200 +@@ -479,6 +479,7 @@ int MAIN(int argc, char **argv) + 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, "-trusted_first use trusted certificates first when building the trust chain\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 -up openssl-1.0.1k/apps/s_server.c.alt-chains openssl-1.0.1k/apps/s_server.c +--- openssl-1.0.1k/apps/s_server.c.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/apps/s_server.c 2015-04-30 14:30:06.420764081 +0200 +@@ -502,6 +502,7 @@ static void sv_usage(void) + 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," -trusted_first - Use trusted CA's first when building the trust chain\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 -up openssl-1.0.1k/apps/verify.c.alt-chains openssl-1.0.1k/apps/verify.c +--- openssl-1.0.1k/apps/verify.c.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/apps/verify.c 2015-04-30 14:31:20.055446426 +0200 +@@ -238,7 +238,7 @@ int MAIN(int argc, char **argv) + end: + if (ret == 1) { + BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-trusted_first] [-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 -up openssl-1.0.1k/crypto/x509/x509_vfy.c.alt-chains openssl-1.0.1k/crypto/x509/x509_vfy.c +--- openssl-1.0.1k/crypto/x509/x509_vfy.c.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/crypto/x509/x509_vfy.c 2015-04-30 14:22:37.183472452 +0200 +@@ -154,11 +154,11 @@ static int x509_subject_cmp(X509 **a, X5 + + 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) +@@ -247,10 +247,14 @@ 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. */ + ++ do { + /* Examine last certificate in chain and see if it + * is self signed. + */ +@@ -294,6 +298,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx + chain_ss=sk_X509_pop(ctx->chain); + ctx->last_untrusted--; + num--; ++ j--; + x=sk_X509_value(ctx->chain,num-1); + } + } +@@ -322,7 +327,42 @@ int X509_verify_cert(X509_STORE_CTX *ctx + num++; + } + +- /* we now have our chain, lets check it... */ ++ /* ++ * 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 (j == ctx->last_untrusted && ++ !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { ++ 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--; ++ } ++ retry = 1; ++ break; ++ } ++ } ++ } ++ } while (retry); + + /* Is last certificate looked up self signed? */ + if (!ctx->check_issued(ctx,x,x)) +diff -up openssl-1.0.1k/crypto/x509/x509_vfy.h.alt-chains openssl-1.0.1k/crypto/x509/x509_vfy.h +--- openssl-1.0.1k/crypto/x509/x509_vfy.h.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/crypto/x509/x509_vfy.h 2015-04-30 14:16:56.818672373 +0200 +@@ -391,7 +391,12 @@ void X509_STORE_CTX_set_depth(X509_STORE + #define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 + /* Use trusted store first */ + #define X509_V_FLAG_TRUSTED_FIRST 0x8000 +- ++/* ++ * 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 + #define X509_VP_FLAG_OVERWRITE 0x2 +diff -up openssl-1.0.1k/doc/apps/cms.pod.alt-chains openssl-1.0.1k/doc/apps/cms.pod +--- openssl-1.0.1k/doc/apps/cms.pod.alt-chains 2015-04-30 14:32:50.736518235 +0200 ++++ openssl-1.0.1k/doc/apps/cms.pod 2015-04-30 14:36:11.989116293 +0200 +@@ -35,6 +35,7 @@ B B + [B<-print>] + [B<-CAfile file>] + [B<-CApath dir>] ++[B<-no_alt_chains>] + [B<-trusted_first>] + [B<-md digest>] + [B<-[cipher]>] +@@ -413,7 +414,7 @@ portion of a message so they may be incl + 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|verify(1)> manual page for details. +diff -up openssl-1.0.1k/doc/apps/ocsp.pod.alt-chains openssl-1.0.1k/doc/apps/ocsp.pod +--- openssl-1.0.1k/doc/apps/ocsp.pod.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/doc/apps/ocsp.pod 2015-04-30 14:34:40.398023692 +0200 +@@ -29,6 +29,7 @@ B B + [B<-path>] + [B<-CApath dir>] + [B<-CAfile file>] ++[B<-no_alt_chains>]] + [B<-trusted_first>] + [B<-VAfile file>] + [B<-validity_period n>] +@@ -143,6 +144,10 @@ connection timeout to the OCSP responder + 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|verify(1)> manual page for details. ++ + =item B<-trusted_first> + + Use certificates in CA file or CA directory over certificates provided +diff -up openssl-1.0.1k/doc/apps/s_client.pod.alt-chains openssl-1.0.1k/doc/apps/s_client.pod +--- openssl-1.0.1k/doc/apps/s_client.pod.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/doc/apps/s_client.pod 2015-04-30 14:35:23.284003518 +0200 +@@ -19,6 +19,7 @@ B B + [B<-pass arg>] + [B<-CApath directory>] + [B<-CAfile filename>] ++[B<-no_alt_chains>] + [B<-trusted_first>] + [B<-reconnect>] + [B<-pause>] +@@ -122,7 +123,7 @@ also used when building the client certi + 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, -trusted_first> ++=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|verify(1)> manual page for details. +diff -up openssl-1.0.1k/doc/apps/smime.pod.alt-chains openssl-1.0.1k/doc/apps/smime.pod +--- openssl-1.0.1k/doc/apps/smime.pod.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/doc/apps/smime.pod 2015-04-30 14:37:58.832557366 +0200 +@@ -17,6 +17,7 @@ B B + [B<-in file>] + [B<-CAfile file>] + [B<-CApath dir>] ++[B<-no_alt_chains>] + [B<-trusted_first>] + [B<-certfile file>] + [B<-signer file>] +@@ -268,7 +269,7 @@ portion of a message so they may be incl + 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|verify(1)> manual page for details. +diff -up openssl-1.0.1k/doc/apps/s_server.pod.alt-chains openssl-1.0.1k/doc/apps/s_server.pod +--- openssl-1.0.1k/doc/apps/s_server.pod.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/doc/apps/s_server.pod 2015-04-30 14:37:02.850278328 +0200 +@@ -33,6 +33,7 @@ B B + [B<-state>] + [B<-CApath directory>] + [B<-CAfile filename>] ++[B<-no_alt_chains>] + [B<-trusted_first>] + [B<-nocert>] + [B<-cipher cipherlist>] +@@ -179,6 +180,10 @@ and to use when attempting to build the + 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|verify(1)> manual page for details. ++ + =item B<-trusted_first> + + Use certificates in CA file or CA directory before other certificates +diff -up openssl-1.0.1k/doc/apps/verify.pod.alt-chains openssl-1.0.1k/doc/apps/verify.pod +--- openssl-1.0.1k/doc/apps/verify.pod.alt-chains 2015-04-30 14:14:40.000000000 +0200 ++++ openssl-1.0.1k/doc/apps/verify.pod 2015-04-30 14:38:32.853334645 +0200 +@@ -23,6 +23,7 @@ B B + [B<-extended_crl>] + [B<-use_deltas>] + [B<-policy_print>] ++[B<-no_alt_chains>] + [B<-untrusted file>] + [B<-help>] + [B<-issuer_checks>] +@@ -115,6 +116,14 @@ Set policy variable inhibit-any-policy ( + + 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. +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 +--- openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod.alt-chains 2014-10-15 14:51:06.000000000 +0200 ++++ openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod 2015-04-30 14:39:34.951753420 +0200 +@@ -133,6 +133,12 @@ verification. If this flag is set then a + to the verification callback and it B be prepared to handle such cases + without assuming they are hard errors. + ++The B 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 @@ L flag was added in upstream OpenSSL 1.0.1n and 1.0.2b + + =cut diff --git a/openssl.spec b/openssl.spec index 433d87b..7573615 100644 --- a/openssl.spec +++ b/openssl.spec @@ -23,7 +23,7 @@ Summary: Utilities from the general purpose cryptography library with TLS implementation Name: openssl Version: 1.0.1k -Release: 7%{?dist} +Release: 8%{?dist} Epoch: 1 # We have to remove certain patented algorithms from the openssl source # tarball with the hobble-openssl script which is included below. @@ -96,6 +96,7 @@ Patch103: openssl-1.0.1e-cve-2015-0287.patch Patch104: openssl-1.0.1e-cve-2015-0288.patch Patch105: openssl-1.0.1k-cve-2015-0289.patch Patch106: openssl-1.0.1e-cve-2015-0293.patch +Patch107: openssl-1.0.1k-alt-chains.patch License: OpenSSL Group: System Environment/Libraries @@ -225,6 +226,7 @@ cp %{SOURCE12} %{SOURCE13} crypto/ec/ %patch104 -p1 -b .req-null-deref %patch105 -p1 -b .pkcs7-null-deref %patch106 -p1 -b .ssl2-assert +%patch107 -p1 -b .alt-chains sed -i 's/SHLIB_VERSION_NUMBER "1.0.0"/SHLIB_VERSION_NUMBER "%{version}"/' crypto/opensslv.h @@ -492,6 +494,9 @@ rm -rf $RPM_BUILD_ROOT/%{_libdir}/fipscanister.* %postun libs -p /sbin/ldconfig %changelog +* Thu Apr 30 2015 Tomáš Mráz 1.0.1k-8 +- try to find alternative cert chains (#1166614) + * Thu Apr 9 2015 Tomáš Mráz 1.0.1k-7 - drop the AES-GCM restriction of 2^32 operations because the IV is always 96 bits (32 bit fixed field + 64 bit invocation field)