summary refs log tree commit diff
path: root/crypto/test
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-06-01 19:11:34 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-06-01 19:11:34 +0700
commit5cc0a46f4dbaafd9e3104643ec1fa5bf69ac5a6c (patch)
tree0ac8a1bd4557e3682c2fb2cbf889bd992402b1db /crypto/test
parentRemove extraneous output (diff)
downloadBouncyCastle.NET-ed25519-5cc0a46f4dbaafd9e3104643ec1fa5bf69ac5a6c.tar.xz
Name constraint validation updates from bc-java
Diffstat (limited to 'crypto/test')
-rw-r--r--crypto/test/UnitTests.csproj1
-rw-r--r--crypto/test/src/test/PkixNameConstraintsTest.cs34
-rw-r--r--crypto/test/src/test/nist/NistCertPathTest.cs139
-rw-r--r--crypto/test/src/test/nist/NistCertPathTest2.cs499
4 files changed, 584 insertions, 89 deletions
diff --git a/crypto/test/UnitTests.csproj b/crypto/test/UnitTests.csproj
index 63cf0b713..9420cc832 100644
--- a/crypto/test/UnitTests.csproj
+++ b/crypto/test/UnitTests.csproj
@@ -451,6 +451,7 @@
     <Compile Include="src\test\X509CertificatePairTest.cs" />
     <Compile Include="src\test\X509StoreTest.cs" />
     <Compile Include="src\test\nist\NistCertPathTest.cs" />
+    <Compile Include="src\test\nist\NistCertPathTest2.cs" />
     <Compile Include="src\test\rsa3\RSA3CertTest.cs" />
     <Compile Include="src\tsp\test\AllTests.cs" />
     <Compile Include="src\tsp\test\GenTimeAccuracyTest.cs" />
diff --git a/crypto/test/src/test/PkixNameConstraintsTest.cs b/crypto/test/src/test/PkixNameConstraintsTest.cs
index a20fc33c4..073f9f2a3 100644
--- a/crypto/test/src/test/PkixNameConstraintsTest.cs
+++ b/crypto/test/src/test/PkixNameConstraintsTest.cs
@@ -72,19 +72,23 @@ namespace Org.BouncyCastle.Tests
 
 		private readonly string[] dnIntersection = { "O=test org, OU=test org unit, CN=John Doe" };
 
-		private readonly string testDN = "O=test org, OU=test org unit, CN=John Doe";
+        // Note: In BC text conversion is ISO format - IETF starts at the back.
+        private readonly string testDN = "O=test org, OU=test org unit, CN=John Doe";
 
-		private readonly string[] testDNIsConstraint = {
-			"O=test org, OU=test org unit",
-			"O=test org, OU=test org unit, CN=John Doe" };
+        private readonly string[] testDNIsConstraint =
+        {
+            "O=test org, OU=test org unit",
+            "O=test org, OU=test org unit, CN=John Doe",
+        };
 
-		private readonly string[] testDNIsNotConstraint = {
-			"O=test org, OU=test org unit, CN=John Doe2",
-			"O=test org, OU=test org unit2",
-			"OU=test org unit, O=test org, CN=John Doe",
-			"O=test org, OU=test org unit, CN=John Doe, L=USA" };
+        private readonly string[] testDNIsNotConstraint =
+        {
+            "O=test org, OU=test org unit, CN=John Doe2",
+            "O=test org, OU=test org unit2",
+            "O=test org, OU=test org unit, CN=John Doe, L=USA"
+        };
 
-		private readonly string testDNS = "abc.test.com";
+        private readonly string testDNS = "abc.test.com";
 
 		private readonly string[] testDNSIsConstraint = { "test.com", "abc.test.com", "test.com" };
 
@@ -185,7 +189,15 @@ namespace Org.BouncyCastle.Tests
 				uriintersect);
 			TestConstraints(GeneralName.IPAddress, testIP, testIPIsConstraint,
 				testIPIsNotConstraint, ip1, ip2, ipunion, ipintersect);
-		}
+
+            PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+            constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+                new GeneralName(GeneralName.DirectoryName,
+                    new X509Name(true, "ou=permittedSubtree1, o=Test Certificates 2011, c=US")))));
+            constraintValidator.checkPermitted(
+                new GeneralName(GeneralName.DirectoryName,
+                    new X509Name(true, "cn=Valid DN nameConstraints EE Certificate Test1, ou=permittedSubtree1, o=Test Certificates 2011, c=US")));
+        }
 
 		/**
 		 * Tests string based GeneralNames for inclusion or exclusion.
diff --git a/crypto/test/src/test/nist/NistCertPathTest.cs b/crypto/test/src/test/nist/NistCertPathTest.cs
index 6a23cac22..13a85a980 100644
--- a/crypto/test/src/test/nist/NistCertPathTest.cs
+++ b/crypto/test/src/test/nist/NistCertPathTest.cs
@@ -35,15 +35,15 @@ namespace Org.BouncyCastle.Tests.Nist
 		private static readonly string NIST_TEST_POLICY_2 = "2.16.840.1.101.3.2.1.48.2";
 		private static readonly string NIST_TEST_POLICY_3 = "2.16.840.1.101.3.2.1.48.3";
 
-		private static IDictionary certs = new Hashtable();
-		private static IDictionary crls = new Hashtable();
+		private static readonly IDictionary certs = new Hashtable();
+        private static readonly IDictionary crls = new Hashtable();
 
-		private static ISet noPolicies = new HashSet();
-		private static ISet anyPolicy = new HashSet();
-		private static ISet nistTestPolicy1 = new HashSet();
-		private static ISet nistTestPolicy2 = new HashSet();
-		private static ISet nistTestPolicy3 = new HashSet();
-		private static ISet nistTestPolicy1And2 = new HashSet();
+        private static readonly ISet noPolicies = new HashSet();
+        private static readonly ISet anyPolicy = new HashSet();
+        private static readonly ISet nistTestPolicy1 = new HashSet();
+        private static readonly ISet nistTestPolicy2 = new HashSet();
+        private static readonly ISet nistTestPolicy3 = new HashSet();
+        private static readonly ISet nistTestPolicy1And2 = new HashSet();
 
 		static NistCertPathTest()
 		{
@@ -54,7 +54,6 @@ namespace Org.BouncyCastle.Tests.Nist
 			nistTestPolicy3.Add(NIST_TEST_POLICY_3);
 			nistTestPolicy1And2.Add(NIST_TEST_POLICY_1);
 			nistTestPolicy1And2.Add(NIST_TEST_POLICY_2);
-
 		}
 
 		[Test]
@@ -474,7 +473,7 @@ namespace Org.BouncyCastle.Tests.Nist
 			string[] certList = new string[] { "inhibitAnyPolicy1CACert", "inhibitAnyPolicy1SelfIssuedCACert", "inhibitAnyPolicy1subCA2Cert", "ValidSelfIssuedinhibitAnyPolicyTest7EE" };
 			string[] crlList = new string[] { TRUST_ANCHOR_ROOT_CRL, "inhibitAnyPolicy1CACRL", "inhibitAnyPolicy1subCA2CRL" };
 
-			doBuilderTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, false, false);
+			DoBuilderTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, false, false);
 		}
 
 		// 4.4.19
@@ -484,7 +483,7 @@ namespace Org.BouncyCastle.Tests.Nist
 			string[] certList = new string[] { "SeparateCertificateandCRLKeysCertificateSigningCACert", "SeparateCertificateandCRLKeysCRLSigningCert", "ValidSeparateCertificateandCRLKeysTest19EE" };
 			string[] crlList = new string[] { TRUST_ANCHOR_ROOT_CRL, "SeparateCertificateandCRLKeysCRL" };
 
-			doBuilderTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, false, false);
+			DoBuilderTest(TRUST_ANCHOR_ROOT_CERTIFICATE, certList, crlList, null, false, false);
 		}
 
 		[Test]
@@ -600,6 +599,7 @@ namespace Org.BouncyCastle.Tests.Nist
 			try
 			{
 				DoTest(trustAnchor, certs, crls, policies);
+
 				Assert.Fail("path accepted when should be rejected");
 			}
 			catch (PkixCertPathValidatorException e)
@@ -673,7 +673,6 @@ namespace Org.BouncyCastle.Tests.Nist
 				"CRL/Collection",
 				new X509CollectionStoreParameters(x509Crls));
 
-//			CertPathValidator validator = CertPathValidator.GetInstance("PKIX");
 			PkixCertPathValidator validator = new PkixCertPathValidator();
 			PkixParameters parameters = new PkixParameters(trustedSet);
 
@@ -693,7 +692,7 @@ namespace Org.BouncyCastle.Tests.Nist
 			return validator.Validate(certPath, parameters);
 		}
 
-		private PkixCertPathBuilderResult doBuilderTest(
+		private PkixCertPathBuilderResult DoBuilderTest(
 			string		trustAnchor,
 			string[]	certs,
 			string[]	crls,
@@ -727,7 +726,6 @@ namespace Org.BouncyCastle.Tests.Nist
 				"CRL/Collection",
 				new X509CollectionStoreParameters(x509Crls));
 
-//			CertPathBuilder builder = CertPathBuilder.GetInstance("PKIX");   
 			PkixCertPathBuilder builder = new PkixCertPathBuilder();
 
 			X509CertStoreSelector endSelector = new X509CertStoreSelector();
@@ -766,70 +764,55 @@ namespace Org.BouncyCastle.Tests.Nist
 			}
 		}
 
-		private X509Certificate LoadCert(
-			string certName)
-		{
-			X509Certificate cert = (X509Certificate)certs[certName];
-
-			if (cert != null)
-			{
-				return cert;
-			}
-
-			Stream fs = null;
-
-			try
-			{
-				fs = SimpleTest.GetTestDataAsStream("PKITS.certs." + certName + ".crt");
-
-				cert = new X509CertificateParser().ReadCertificate(fs);
-
-				certs[certName] = cert;
-
-				return cert;
-			}
-			catch (Exception e)
-			{
-				throw new InvalidOperationException("exception loading certificate " + certName + ": " + e);
-			}
-			finally
-			{
-				fs.Close();
-			}
-		}
-
-		private X509Crl LoadCrl(
-			string crlName)
-			//throws Exception
-		{
-			X509Crl crl = (X509Crl)certs[crlName];
-        
-			if (crl != null)
-			{
-				return crl;
-			}
-
-			Stream fs = null;
-
-			try
-			{
-				fs = SimpleTest.GetTestDataAsStream("PKITS.crls." + crlName + ".crl");
-
-				crl = new X509CrlParser().ReadCrl(fs);
-
-				crls[crlName] = crl;
-
-				return crl;
-			}
-			catch (Exception)
-			{
-				throw new InvalidOperationException("exception loading CRL: " + crlName);
-			}
-			finally
-			{
-				fs.Close();
-			}
-		}
+        private X509Certificate LoadCert(string certName)
+        {
+            X509Certificate cert = (X509Certificate)certs[certName];
+            if (null != cert)
+                return cert;
+
+            Stream fs = null;
+
+            try
+            {
+                fs = SimpleTest.GetTestDataAsStream("PKITS.certs." + certName + ".crt");
+                cert = new X509CertificateParser().ReadCertificate(fs);
+                certs[certName] = cert;
+                return cert;
+            }
+            catch (Exception e)
+            {
+                throw new InvalidOperationException("exception loading certificate " + certName + ": " + e);
+            }
+            finally
+            {
+                fs.Close();
+            }
+        }
+
+        private X509Crl LoadCrl(string crlName)
+        {
+            X509Crl crl = (X509Crl)crls[crlName];
+            if (null != crl)
+                return crl;
+
+            Stream fs = null;
+
+            try
+            {
+                fs = SimpleTest.GetTestDataAsStream("PKITS.crls." + crlName + ".crl");
+                crl = new X509CrlParser().ReadCrl(fs);
+                crls[crlName] = crl;
+                return crl;
+            }
+            catch (Exception)
+            {
+                throw new InvalidOperationException("exception loading CRL: " + crlName);
+            }
+            finally
+            {
+                fs.Close();
+            }
+        }
 
 		private TrustAnchor GetTrustAnchor(string trustAnchorName)
 		{
diff --git a/crypto/test/src/test/nist/NistCertPathTest2.cs b/crypto/test/src/test/nist/NistCertPathTest2.cs
new file mode 100644
index 000000000..e9dd7f959
--- /dev/null
+++ b/crypto/test/src/test/nist/NistCertPathTest2.cs
@@ -0,0 +1,499 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Reflection;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Pkix;
+using Org.BouncyCastle.Utilities.Collections;
+using Org.BouncyCastle.Utilities.Date;
+using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Extension;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.Tests.Nist
+{
+    /**
+     * NIST CertPath test data for RFC 3280
+     */
+	[TestFixture]
+    public class NistCertPathTest2
+    {
+        private static readonly string ANY_POLICY = "2.5.29.32.0";
+        private static readonly string NIST_TEST_POLICY_1 = "2.16.840.1.101.3.2.1.48.1";
+        private static readonly string NIST_TEST_POLICY_2 = "2.16.840.1.101.3.2.1.48.2";
+        private static readonly string NIST_TEST_POLICY_3 = "2.16.840.1.101.3.2.1.48.3";
+
+		private static readonly IDictionary certs = new Hashtable();
+		private static readonly IDictionary crls = new Hashtable();
+
+        private static readonly ISet noPolicies = new HashSet();
+        private static readonly ISet anyPolicy = new HashSet();
+        private static readonly ISet nistTestPolicy1 = new HashSet();
+        private static readonly ISet nistTestPolicy2 = new HashSet();
+        private static readonly ISet nistTestPolicy3 = new HashSet();
+        private static readonly ISet nistTestPolicy1And2 = new HashSet();
+
+        static NistCertPathTest2()
+		{
+			anyPolicy.Add(ANY_POLICY);
+
+			nistTestPolicy1.Add(NIST_TEST_POLICY_1);
+			nistTestPolicy2.Add(NIST_TEST_POLICY_2);
+			nistTestPolicy3.Add(NIST_TEST_POLICY_3);
+			nistTestPolicy1And2.Add(NIST_TEST_POLICY_1);
+			nistTestPolicy1And2.Add(NIST_TEST_POLICY_2);
+		}
+
+        // 4.13
+		[Test]
+        public void TestValidDNnameConstraintsTest1()
+        {
+            DoTest("TrustAnchorRootCertificate",
+                new string[] { "ValidDNnameConstraintsTest1EE", "nameConstraintsDN1CACert" },
+                new string[] { "nameConstraintsDN1CACRL", "TrustAnchorRootCRL" });
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest2()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest2EE", "nameConstraintsDN1CACert"},
+                new string[]{"nameConstraintsDN1CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest3()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest3EE", "nameConstraintsDN1CACert"},
+                new string[]{"nameConstraintsDN1CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject alternative name failed.");
+        }
+
+ 		[Test]
+       public void TestValidDNnameConstraintsTest4()
+        {
+            DoTest("TrustAnchorRootCertificate",
+                new string[] { "ValidDNnameConstraintsTest4EE", "nameConstraintsDN1CACert" },
+                new string[] { "nameConstraintsDN1CACRL", "TrustAnchorRootCRL" });
+        }
+
+		[Test]
+        public void TestValidDNnameConstraintsTest5()
+        {
+            DoTest("TrustAnchorRootCertificate",
+                new string[] { "ValidDNnameConstraintsTest5EE", "nameConstraintsDN2CACert" },
+                new string[] { "nameConstraintsDN2CACRL", "TrustAnchorRootCRL" });
+        }
+
+		[Test]
+        public void TestValidDNnameConstraintsTest6()
+        {
+            DoTest("TrustAnchorRootCertificate",
+                new string[] { "ValidDNnameConstraintsTest6EE", "nameConstraintsDN3CACert" },
+                new string[] { "nameConstraintsDN3CACRL", "TrustAnchorRootCRL" });
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest7()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest7EE", "nameConstraintsDN3CACert"},
+                new string[]{"nameConstraintsDN3CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest8()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest8EE", "nameConstraintsDN4CACert"},
+                new string[]{"nameConstraintsDN4CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest9()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest9EE", "nameConstraintsDN4CACert"},
+                new string[]{"nameConstraintsDN4CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest10()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest10EE", "nameConstraintsDN5CACert"},
+                new string[]{"nameConstraintsDN5CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestValidDNnameConstraintsTest11()
+        {
+            DoTest("TrustAnchorRootCertificate",
+                new string[] { "ValidDNnameConstraintsTest11EE", "nameConstraintsDN5CACert" },
+                new string[] { "nameConstraintsDN5CACRL", "TrustAnchorRootCRL" });
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest12()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest10EE", "nameConstraintsDN5CACert"},
+                new string[]{"nameConstraintsDN5CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest13()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest13EE", "nameConstraintsDN1subCA2Cert", "nameConstraintsDN1CACert"},
+                new string[]{"nameConstraintsDN1subCA2CRL", "nameConstraintsDN1CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestValidDNnameConstraintsTest14()
+        {
+            DoTest("TrustAnchorRootCertificate",
+                new string[] { "ValidDNnameConstraintsTest14EE", "nameConstraintsDN1subCA2Cert", "nameConstraintsDN1CACert" },
+                new string[] { "nameConstraintsDN1subCA2CRL", "nameConstraintsDN1CACRL", "TrustAnchorRootCRL" });
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest15()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest15EE", "nameConstraintsDN3subCA1Cert", "nameConstraintsDN3CACert"},
+                new string[]{"nameConstraintsDN3subCA1CRL", "nameConstraintsDN3CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest16()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest16EE", "nameConstraintsDN3subCA1Cert", "nameConstraintsDN3CACert"},
+                new string[]{"nameConstraintsDN3subCA1CRL", "nameConstraintsDN3CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+		[Test]
+        public void TestInvalidDNnameConstraintsTest17()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest17EE", "nameConstraintsDN3subCA2Cert", "nameConstraintsDN3CACert"},
+                new string[]{"nameConstraintsDN3subCA2CRL", "nameConstraintsDN3CACRL", "TrustAnchorRootCRL"},
+                0,
+                "Subtree check for certificate subject failed.");
+        }
+
+ 		[Test]
+        public void TestValidDNnameConstraintsTest18()
+        {
+            DoTest("TrustAnchorRootCertificate",
+                new string[] { "ValidDNnameConstraintsTest18EE", "nameConstraintsDN3subCA2Cert", "nameConstraintsDN3CACert" },
+                new string[] { "nameConstraintsDN3subCA2CRL", "nameConstraintsDN3CACRL", "TrustAnchorRootCRL" });
+        }
+
+ 		[Test]
+        public void TestValidDNnameConstraintsTest19()
+        {
+            DoBuilderTest("TrustAnchorRootCertificate",
+                new string[] { "ValidDNnameConstraintsTest19EE", "nameConstraintsDN1SelfIssuedCACert", "nameConstraintsDN1CACert" },
+                new string[] { "nameConstraintsDN1CACRL", "TrustAnchorRootCRL" },
+                null, false, false);
+        }
+
+ 		[Test]
+        public void TestInvalidDNnameConstraintsTest20()
+        {
+            DoExceptionTest("TrustAnchorRootCertificate",
+                new string[]{"InvalidDNnameConstraintsTest20EE", "nameConstraintsDN1CACert"},
+                new string[]{"nameConstraintsDN1CACRL", "TrustAnchorRootCRL"},
+                0,
+                "CertPath for CRL signer failed to validate.");   // due to a subtree failure
+        }
+
+		private void DoExceptionTest(
+			string		trustAnchor,
+			string[]	certs,
+			string[]	crls,
+			int			index,
+			string		message)
+		{
+			try
+			{
+				DoTest(trustAnchor, certs, crls);
+
+				Assert.Fail("path accepted when should be rejected");
+			}
+			catch (PkixCertPathValidatorException e)
+			{
+				Assert.AreEqual(index, e.Index);
+				Assert.AreEqual(message, e.Message);
+			}
+		}
+
+		private void DoExceptionTest(
+			string		trustAnchor,
+			string[]	certs,
+			string[]	crls,
+			ISet		policies,
+			int			index,
+			string		message)
+		{
+			try
+			{
+				DoTest(trustAnchor, certs, crls, policies);
+
+				Assert.Fail("path accepted when should be rejected");
+			}
+			catch (PkixCertPathValidatorException e)
+			{
+				Assert.AreEqual(index, e.Index);
+				Assert.AreEqual(message, e.Message);
+			}
+		}
+
+		private void DoExceptionTest(
+			string		trustAnchor,
+			string[]	certs,
+			string[]	crls,
+			int			index,
+			string		mesStart,
+			string		mesEnd)
+		{
+			try
+			{
+				DoTest(trustAnchor, certs, crls);
+
+				Assert.Fail("path accepted when should be rejected");
+			}
+			catch (PkixCertPathValidatorException e)
+			{
+				Assert.AreEqual(index, e.Index);
+				Assert.IsTrue(e.Message.StartsWith(mesStart));
+				Assert.IsTrue(e.Message.EndsWith(mesEnd));
+			}
+		}
+
+		private PkixCertPathValidatorResult DoTest(
+			string trustAnchor,
+			string[] certs,
+			string[] crls)
+		{
+			return DoTest(trustAnchor, certs, crls, null);
+		}
+
+		private PkixCertPathValidatorResult DoTest(
+			string trustAnchor,
+			string[] certs,
+			string[] crls,
+			ISet policies)
+		{
+			ISet trustedSet = new HashSet();
+			trustedSet.Add(GetTrustAnchor(trustAnchor));
+
+			IList x509Certs = new ArrayList();
+			IList x509Crls = new ArrayList();
+			X509Certificate endCert = LoadCert(certs[certs.Length - 1]);
+
+			for (int i = 0; i != certs.Length - 1; i++)
+			{
+				x509Certs.Add(LoadCert(certs[i]));
+			}
+
+			x509Certs.Add(endCert);
+
+			PkixCertPath certPath = new PkixCertPath(x509Certs);
+
+			for (int i = 0; i != crls.Length; i++)
+			{
+				x509Crls.Add(LoadCrl(crls[i]));
+			}
+
+			IX509Store x509CertStore = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(x509Certs));
+			IX509Store x509CrlStore = X509StoreFactory.Create(
+				"CRL/Collection",
+				new X509CollectionStoreParameters(x509Crls));
+
+            PkixCertPathValidator validator = new PkixCertPathValidator();
+			PkixParameters parameters = new PkixParameters(trustedSet);
+
+			parameters.AddStore(x509CertStore);
+			parameters.AddStore(x509CrlStore);
+			parameters.IsRevocationEnabled = true;
+
+			if (policies != null)
+			{
+				parameters.IsExplicitPolicyRequired = true;
+				parameters.SetInitialPolicies(policies);
+			}
+
+			// Perform validation as of this date since test certs expired
+			parameters.Date = new DateTimeObject(DateTime.Parse("1/1/2011"));
+
+			return validator.Validate(certPath, parameters);
+        }
+
+        private PkixCertPathBuilderResult DoBuilderTest(
+            string trustAnchor,
+            string[] certs,
+            string[] crls,
+            ISet initialPolicies,
+            bool policyMappingInhibited,
+            bool anyPolicyInhibited)
+        {
+            ISet trustedSet = new HashSet();
+            trustedSet.Add(GetTrustAnchor(trustAnchor));
+
+            IList x509Certs = new ArrayList();
+            IList x509Crls = new ArrayList();
+            X509Certificate endCert = LoadCert(certs[certs.Length - 1]);
+
+            for (int i = 0; i != certs.Length - 1; i++)
+            {
+                x509Certs.Add(LoadCert(certs[i]));
+            }
+
+            x509Certs.Add(endCert);
+
+            for (int i = 0; i != crls.Length; i++)
+            {
+                x509Crls.Add(LoadCrl(crls[i]));
+            }
+
+            IX509Store x509CertStore = X509StoreFactory.Create(
+                "Certificate/Collection",
+                new X509CollectionStoreParameters(x509Certs));
+            IX509Store x509CrlStore = X509StoreFactory.Create(
+                "CRL/Collection",
+                new X509CollectionStoreParameters(x509Crls));
+
+            PkixCertPathBuilder builder = new PkixCertPathBuilder();
+
+            X509CertStoreSelector endSelector = new X509CertStoreSelector();
+
+            endSelector.Certificate = endCert;
+
+            PkixBuilderParameters builderParams = new PkixBuilderParameters(trustedSet, endSelector);
+
+            if (initialPolicies != null)
+            {
+                builderParams.SetInitialPolicies(initialPolicies);
+                builderParams.IsExplicitPolicyRequired = true;
+            }
+            if (policyMappingInhibited)
+            {
+                builderParams.IsPolicyMappingInhibited = policyMappingInhibited;
+            }
+            if (anyPolicyInhibited)
+            {
+                builderParams.IsAnyPolicyInhibited = anyPolicyInhibited;
+            }
+
+            builderParams.AddStore(x509CertStore);
+            builderParams.AddStore(x509CrlStore);
+
+            // Perform validation as of this date since test certs expired
+            builderParams.Date = new DateTimeObject(DateTime.Parse("1/1/2011"));
+
+            try
+            {
+                return (PkixCertPathBuilderResult)builder.Build(builderParams);
+            }
+            catch (PkixCertPathBuilderException e)
+            {
+                throw e.InnerException;
+            }
+        }
+
+        private X509Certificate LoadCert(string certName)
+		{
+			X509Certificate cert = (X509Certificate)certs[certName];
+			if (null != cert)
+				return cert;
+
+            Stream fs = null;
+
+			try
+			{
+				fs = SimpleTest.GetTestDataAsStream("PKITS.certs." + certName + ".crt");
+				cert = new X509CertificateParser().ReadCertificate(fs);
+				certs[certName] = cert;
+				return cert;
+			}
+			catch (Exception e)
+			{
+				throw new InvalidOperationException("exception loading certificate " + certName + ": " + e);
+			}
+			finally
+			{
+				fs.Close();
+			}
+		}
+
+		private X509Crl LoadCrl(string crlName)
+		{
+			X509Crl crl = (X509Crl)crls[crlName];
+			if (null != crl)
+				return crl;
+
+            Stream fs = null;
+
+			try
+			{
+				fs = SimpleTest.GetTestDataAsStream("PKITS.crls." + crlName + ".crl");
+				crl = new X509CrlParser().ReadCrl(fs);
+				crls[crlName] = crl;
+				return crl;
+			}
+			catch (Exception)
+			{
+				throw new InvalidOperationException("exception loading CRL: " + crlName);
+			}
+			finally
+			{
+				fs.Close();
+			}
+		}
+
+        private TrustAnchor GetTrustAnchor(string trustAnchorName)
+		{
+			X509Certificate cert = LoadCert(trustAnchorName);
+			Asn1OctetString extBytes = cert.GetExtensionValue(X509Extensions.NameConstraints);
+
+			if (extBytes != null)
+			{
+				Asn1Encodable extValue = X509ExtensionUtilities.FromExtensionValue(extBytes);
+
+				return new TrustAnchor(cert, extValue.GetDerEncoded());
+			}
+
+			return new TrustAnchor(cert, null);
+		}
+    }
+}