From db28aa86e00b9121bee94d1e65506bf22d5ca6e3 Mon Sep 17 00:00:00 2001
From: "Dr. Stephen Henson" <steve@openssl.org>
Date: Thu, 25 Feb 2010 12:21:48 +0000
Subject: [PATCH] add -trusted_first option and verify flag

---
 CHANGES                |  4 ++++
 apps/apps.c            |  2 ++
 crypto/x509/x509_vfy.c | 15 +++++++++++++++
 crypto/x509/x509_vfy.h |  2 ++
 4 files changed, 23 insertions(+)

diff --git a/CHANGES b/CHANGES
index 7aae336e3..1a7d4c35f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  Changes between 1.0.0 and 1.1.0  [xx XXX xxxx]
 
+  *) Add -trusted_first option which attempts to find certificates in the
+     trusted store even if an untrusted chain is also supplied.
+     [Steve Henson]
+
   *) Initial experimental support for explicitly trusted non-root CAs. 
      OpenSSL still tries to build a complete chain to a root but if an
      intermediate CA has a trust setting included that is used. The first
diff --git a/apps/apps.c b/apps/apps.c
index 468822421..3edb76c87 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -2333,6 +2333,8 @@ int args_verify(char ***pargs, int *pargc,
 		flags |= X509_V_FLAG_NOTIFY_POLICY;
 	else if (!strcmp(arg, "-check_ss_sig"))
 		flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
+	else if (!strcmp(arg, "-trusted_first"))
+		flags |= X509_V_FLAG_TRUSTED_FIRST;
 	else
 		return 0;
 
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 70011fd73..7bac3c6f2 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -215,6 +215,21 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
 		/* If we are self signed, we break */
 		if (cert_self_signed(x))
 			break;
+		/* If asked see if we can find issuer in trusted store first */
+		if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
+			{
+			ok = ctx->get_issuer(&xtmp, ctx, x);
+			if (ok < 0)
+				return ok;
+			/* If successful for now free up cert so it
+			 * will be picked up again later.
+			 */
+			if (ok > 0)
+				{
+				X509_free(xtmp);
+				break;
+				}
+			}
 
 		/* If we were passed a cert chain, use it first */
 		if (ctx->untrusted != NULL)
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
index 5a8276dea..992005f22 100644
--- a/crypto/x509/x509_vfy.h
+++ b/crypto/x509/x509_vfy.h
@@ -389,6 +389,8 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
 #define X509_V_FLAG_USE_DELTAS			0x2000
 /* Check selfsigned CA signature */
 #define X509_V_FLAG_CHECK_SS_SIGNATURE		0x4000
+/* Use trusted store first */
+#define X509_V_FLAG_TRUSTED_FIRST		0x8000
 
 
 #define X509_VP_FLAG_DEFAULT			0x1