summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2018-04-17 13:32:41 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2018-04-17 13:32:41 +0700
commitc1fe1982e3a7d0748e98ec4e4c54d098e74fc658 (patch)
tree00cc1ede3d38d257525270495a054d26cabe723d
parentPKIX: explicit validation of version number and extension repeats (diff)
downloadBouncyCastle.NET-ed25519-c1fe1982e3a7d0748e98ec4e4c54d098e74fc658.tar.xz
PKIX: Allow a V0 TA to appear at end of the cert path.
-rw-r--r--crypto/src/pkix/PkixAttrCertPathBuilder.cs2
-rw-r--r--crypto/src/pkix/PkixCertPathBuilder.cs2
-rw-r--r--crypto/src/pkix/PkixCertPathValidator.cs4
-rw-r--r--crypto/src/pkix/PkixCertPathValidatorUtilities.cs14
-rw-r--r--crypto/test/src/test/CertPathValidatorTest.cs26
5 files changed, 45 insertions, 3 deletions
diff --git a/crypto/src/pkix/PkixAttrCertPathBuilder.cs b/crypto/src/pkix/PkixAttrCertPathBuilder.cs
index 646cc5db5..3d5fa18e3 100644
--- a/crypto/src/pkix/PkixAttrCertPathBuilder.cs
+++ b/crypto/src/pkix/PkixAttrCertPathBuilder.cs
@@ -143,7 +143,7 @@ namespace Org.BouncyCastle.Pkix
 			try
 			{
 				// check whether the issuer of <tbvCert> is a TrustAnchor
-				if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null)
+				if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()))
 				{
 					PkixCertPath certPath = new PkixCertPath(tbvPath);
 					PkixCertPathValidatorResult result;
diff --git a/crypto/src/pkix/PkixCertPathBuilder.cs b/crypto/src/pkix/PkixCertPathBuilder.cs
index fa38a5ec0..37a1c8c9c 100644
--- a/crypto/src/pkix/PkixCertPathBuilder.cs
+++ b/crypto/src/pkix/PkixCertPathBuilder.cs
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Pkix
 			try
 			{
 				// check whether the issuer of <tbvCert> is a TrustAnchor
-				if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null)
+				if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()))
 				{
 					// exception message from possibly later tried certification
 					// chains
diff --git a/crypto/src/pkix/PkixCertPathValidator.cs b/crypto/src/pkix/PkixCertPathValidator.cs
index 1d7c00d7d..64039f9f1 100644
--- a/crypto/src/pkix/PkixCertPathValidator.cs
+++ b/crypto/src/pkix/PkixCertPathValidator.cs
@@ -289,6 +289,10 @@ namespace Org.BouncyCastle.Pkix
                 {
                     if (cert != null && cert.Version == 1)
                     {
+                        // we've found the trust anchor at the top of the path, ignore and keep going
+                        if ((i == 1) && cert.Equals(trust.TrustedCert))
+                            continue;
+
                         throw new PkixCertPathValidatorException(
 							"Version 1 certificates can't be used as CA ones.", null, certPath, index);
                     }
diff --git a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
index a2704a746..2ccaa32ce 100644
--- a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
+++ b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
@@ -143,6 +143,20 @@ namespace Org.BouncyCastle.Pkix
 			return trust;
 		}
 
+        internal static bool IsIssuerTrustAnchor(
+            X509Certificate cert,
+            ISet trustAnchors)
+        {
+            try
+            {
+                return FindTrustAnchor(cert, trustAnchors) != null;
+            }
+            catch (Exception e)
+            {
+                return false;
+            }
+        }
+
 		internal static void AddAdditionalStoresFromAltNames(
 			X509Certificate	cert,
 			PkixParameters	pkixParams)
diff --git a/crypto/test/src/test/CertPathValidatorTest.cs b/crypto/test/src/test/CertPathValidatorTest.cs
index f83ac850a..3f9ff57fa 100644
--- a/crypto/test/src/test/CertPathValidatorTest.cs
+++ b/crypto/test/src/test/CertPathValidatorTest.cs
@@ -165,6 +165,7 @@ namespace Org.BouncyCastle.Tests
             IList certchain = new ArrayList();
             certchain.Add(finalCert);
             certchain.Add(interCert);
+
 //			CertPath cp = CertificateFactory.GetInstance("X.509").GenerateCertPath(certchain);
             PkixCertPath cp = new PkixCertPath(certchain);
             ISet trust = new HashSet();
@@ -179,7 +180,7 @@ namespace Org.BouncyCastle.Tests
             MyChecker checker = new MyChecker();
             param.AddCertPathChecker(checker);
 
-            PkixCertPathValidatorResult result = (PkixCertPathValidatorResult) cpv.Validate(cp, param);
+            PkixCertPathValidatorResult result = (PkixCertPathValidatorResult)cpv.Validate(cp, param);
             PkixPolicyNode policyTree = result.PolicyTree;
             AsymmetricKeyParameter subjectPublicKey = result.SubjectPublicKey;
 
@@ -193,6 +194,28 @@ namespace Org.BouncyCastle.Tests
                 Fail("wrong public key returned");
             }
 
+            IsTrue(result.TrustAnchor.TrustedCert.Equals(rootCert));
+
+            // try a path with trust anchor included.
+            certchain.Clear();
+            certchain.Add(finalCert);
+            certchain.Add(interCert);
+            certchain.Add(rootCert);
+
+            cp = new PkixCertPath(certchain);
+
+            cpv = new PkixCertPathValidator();
+            param = new PkixParameters(trust);
+            param.AddStore(x509CertStore);
+            param.AddStore(x509CrlStore);
+            param.Date = new DateTimeObject(validDate);
+            checker = new MyChecker();
+            param.AddCertPathChecker(checker);
+
+            result = (PkixCertPathValidatorResult)cpv.Validate(cp, param);
+
+            IsTrue(result.TrustAnchor.TrustedCert.Equals(rootCert));
+
             //
             // invalid path containing a valid one test
             //
@@ -223,6 +246,7 @@ namespace Org.BouncyCastle.Tests
                 certchain = new ArrayList();
                 certchain.Add(finalCert);
                 certchain.Add(interCert);
+
 //				cp = CertificateFactory.GetInstance("X.509").GenerateCertPath(certchain);
                 cp = new PkixCertPath(certchain);
                 trust = new HashSet();