summary refs log tree commit diff
path: root/crypto/src/pkix
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-06-26 20:47:24 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-06-26 20:47:24 +0700
commiteed964522f8e198a33267387942b1764018dfe1e (patch)
treec6bcead7e5e54c88845287d10bca6a1235e655e8 /crypto/src/pkix
parentCleanup in PQC code (diff)
downloadBouncyCastle.NET-ed25519-eed964522f8e198a33267387942b1764018dfe1e.tar.xz
Replace IX509Store API with new store/selector API
- overhaul Cms, Pkix, X509 APIs
Diffstat (limited to 'crypto/src/pkix')
-rw-r--r--crypto/src/pkix/PkixAttrCertChecker.cs2
-rw-r--r--crypto/src/pkix/PkixAttrCertPathBuilder.cs49
-rw-r--r--crypto/src/pkix/PkixAttrCertPathValidator.cs11
-rw-r--r--crypto/src/pkix/PkixBuilderParameters.cs22
-rw-r--r--crypto/src/pkix/PkixCertPath.cs6
-rw-r--r--crypto/src/pkix/PkixCertPathBuilder.cs24
-rw-r--r--crypto/src/pkix/PkixCertPathValidator.cs29
-rw-r--r--crypto/src/pkix/PkixCertPathValidatorUtilities.cs334
-rw-r--r--crypto/src/pkix/PkixCrlUtilities.cs30
-rw-r--r--crypto/src/pkix/PkixParameters.cs305
-rw-r--r--crypto/src/pkix/PkixPolicyNode.cs16
-rw-r--r--crypto/src/pkix/Rfc3280CertPathUtilities.cs224
-rw-r--r--crypto/src/pkix/Rfc3281CertPathUtilities.cs43
13 files changed, 448 insertions, 647 deletions
diff --git a/crypto/src/pkix/PkixAttrCertChecker.cs b/crypto/src/pkix/PkixAttrCertChecker.cs
index a6eab8480..ca49bbd12 100644
--- a/crypto/src/pkix/PkixAttrCertChecker.cs
+++ b/crypto/src/pkix/PkixAttrCertChecker.cs
@@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Pkix
 		* @throws CertPathValidatorException if the specified attribute certificate
 		*             does not pass the check.
 		*/
-		public abstract void Check(IX509AttributeCertificate attrCert, PkixCertPath certPath,
+		public abstract void Check(X509V2AttributeCertificate attrCert, PkixCertPath certPath,
 			PkixCertPath holderCertPath, ICollection unresolvedCritExts);
 
 		/**
diff --git a/crypto/src/pkix/PkixAttrCertPathBuilder.cs b/crypto/src/pkix/PkixAttrCertPathBuilder.cs
index a45f30bc9..1120003a8 100644
--- a/crypto/src/pkix/PkixAttrCertPathBuilder.cs
+++ b/crypto/src/pkix/PkixAttrCertPathBuilder.cs
@@ -1,5 +1,7 @@
 using System;
 using System.Collections;
+using System.Collections.Generic
+	;
 
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Security.Certificates;
@@ -18,13 +20,11 @@ namespace Org.BouncyCastle.Pkix
 		* @param params PKIXBuilderParameters object containing all information to
 		*            build the CertPath
 		*/
-		public virtual PkixCertPathBuilderResult Build(
-			PkixBuilderParameters pkixParams)
+		public virtual PkixCertPathBuilderResult Build(PkixBuilderParameters pkixParams)
 		{
 			// search target certificates
 
-			IX509Selector certSelect = pkixParams.GetTargetConstraints();
-			if (!(certSelect is X509AttrCertStoreSelector))
+			if (!(pkixParams.GetTargetConstraintsAttrCert() is X509AttrCertStoreSelector attrCertSelector))
 			{
 				throw new PkixCertPathBuilderException(
 					"TargetConstraints must be an instance of "
@@ -33,11 +33,10 @@ namespace Org.BouncyCastle.Pkix
 					+ typeof(PkixAttrCertPathBuilder).FullName + " class.");
 			}
 
-			ICollection targets;
+			HashSet<X509V2AttributeCertificate> targets;
 			try
 			{
-				targets = PkixCertPathValidatorUtilities.FindCertificates(
-					(X509AttrCertStoreSelector)certSelect, pkixParams.GetStores());
+				targets = FindAttributeCertificates(attrCertSelector, pkixParams.GetStoresAttrCert());
 			}
 			catch (Exception e)
 			{
@@ -53,18 +52,19 @@ namespace Org.BouncyCastle.Pkix
 			PkixCertPathBuilderResult result = null;
 
 			// check all potential target certificates
-			foreach (IX509AttributeCertificate cert in targets)
+			foreach (var target in targets)
 			{
-				X509CertStoreSelector selector = new X509CertStoreSelector();
-				X509Name[] principals = cert.Issuer.GetPrincipals();
+				X509CertStoreSelector certSelector = new X509CertStoreSelector();
+				X509Name[] principals = target.Issuer.GetPrincipals();
 				ISet issuers = new HashSet();
 				for (int i = 0; i < principals.Length; i++)
 				{
 					try
 					{
-						selector.Subject = principals[i];
+						certSelector.Subject = principals[i];
 
-						issuers.AddAll(PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetStores()));
+						issuers.AddAll(PkixCertPathValidatorUtilities.FindCertificates(certSelector,
+							pkixParams.GetStoresCert()));
 					}
 					catch (Exception e)
 					{
@@ -81,7 +81,7 @@ namespace Org.BouncyCastle.Pkix
 
 				foreach (X509Certificate issuer in issuers)
 				{
-					result = Build(cert, issuer, pkixParams, certPathList);
+					result = Build(target, issuer, pkixParams, certPathList);
 
 					if (result != null)
 						break;
@@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Pkix
 		private Exception certPathException;
 
 		private PkixCertPathBuilderResult Build(
-			IX509AttributeCertificate	attrCert,
+			X509V2AttributeCertificate  attrCert,
 			X509Certificate				tbvCert,
 			PkixBuilderParameters		pkixParams,
 			IList						tbvPath)
@@ -211,5 +211,26 @@ namespace Org.BouncyCastle.Pkix
 
 			return builderResult;
 		}
+
+		internal static HashSet<X509V2AttributeCertificate> FindAttributeCertificates(
+			ISelector<X509V2AttributeCertificate> attrCertSelector,
+			IList<IStore<X509V2AttributeCertificate>> attrCertStores)
+		{
+			var attrCerts = new HashSet<X509V2AttributeCertificate>();
+
+			foreach (var attrCertStore in attrCertStores)
+			{
+				try
+				{
+					attrCerts.UnionWith(attrCertStore.EnumerateMatches(attrCertSelector));
+				}
+				catch (Exception e)
+				{
+					throw new Exception("Problem while picking certificates from X.509 store.", e);
+				}
+			}
+
+			return attrCerts;
+		}
 	}
 }
diff --git a/crypto/src/pkix/PkixAttrCertPathValidator.cs b/crypto/src/pkix/PkixAttrCertPathValidator.cs
index 5f53bcde6..0ce3e959d 100644
--- a/crypto/src/pkix/PkixAttrCertPathValidator.cs
+++ b/crypto/src/pkix/PkixAttrCertPathValidator.cs
@@ -37,19 +37,16 @@ namespace Org.BouncyCastle.Pkix
 		*             inappropriate for this validator.
 		* @throws CertPathValidatorException if the verification fails.
 		*/
-		public virtual PkixCertPathValidatorResult Validate(
-			PkixCertPath	certPath,
-			PkixParameters	pkixParams)
+		public virtual PkixCertPathValidatorResult Validate(PkixCertPath certPath, PkixParameters pkixParams)
 		{
-			IX509Selector certSelect = pkixParams.GetTargetConstraints();
-			if (!(certSelect is X509AttrCertStoreSelector))
+			if (!(pkixParams.GetTargetConstraintsAttrCert() is X509AttrCertStoreSelector attrCertSelector))
 			{
 				throw new ArgumentException(
 					"TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName,
-					"pkixParams");
+					nameof(pkixParams));
 			}
-			IX509AttributeCertificate attrCert = ((X509AttrCertStoreSelector) certSelect).AttributeCert;
 
+			var attrCert = attrCertSelector.AttributeCert;
 			PkixCertPath holderCertPath = Rfc3281CertPathUtilities.ProcessAttrCert1(attrCert, pkixParams);
 			PkixCertPathValidatorResult result = Rfc3281CertPathUtilities.ProcessAttrCert2(certPath, pkixParams);
 			X509Certificate issuerCert = (X509Certificate)certPath.Certificates[0];
diff --git a/crypto/src/pkix/PkixBuilderParameters.cs b/crypto/src/pkix/PkixBuilderParameters.cs
index 9b8fb3dc3..1dcccb2f8 100644
--- a/crypto/src/pkix/PkixBuilderParameters.cs
+++ b/crypto/src/pkix/PkixBuilderParameters.cs
@@ -2,7 +2,7 @@ using System;
 using System.Text;
 
 using Org.BouncyCastle.Security;
-using Org.BouncyCastle.X509.Store;
+using Org.BouncyCastle.X509;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 
@@ -34,17 +34,23 @@ namespace Org.BouncyCastle.Pkix
 		{
 			PkixBuilderParameters parameters = new PkixBuilderParameters(
 				pkixParams.GetTrustAnchors(),
-				new X509CertStoreSelector(pkixParams.GetTargetCertConstraints()));
+				pkixParams.GetTargetConstraintsCert(),
+				pkixParams.GetTargetConstraintsAttrCert());
 			parameters.SetParams(pkixParams);
 			return parameters;
 		}
 
-		public PkixBuilderParameters(
-			ISet			trustAnchors,
-			IX509Selector	targetConstraints)
+		public PkixBuilderParameters(ISet trustAnchors, ISelector<X509Certificate> targetConstraintsCert)
+			: this(trustAnchors, targetConstraintsCert, null)
+		{
+		}
+
+		public PkixBuilderParameters(ISet trustAnchors, ISelector<X509Certificate> targetConstraintsCert,
+			ISelector<X509V2AttributeCertificate> targetConstraintsAttrCert)
 			: base(trustAnchors)
 		{
-			SetTargetCertConstraints(targetConstraints);
+			SetTargetConstraintsCert(targetConstraintsCert);
+			SetTargetConstraintsAttrCert(targetConstraintsAttrCert);
 		}
 
 		public virtual int MaxPathLength
@@ -120,7 +126,9 @@ namespace Org.BouncyCastle.Pkix
 		public override object Clone()
 		{
 			PkixBuilderParameters parameters = new PkixBuilderParameters(
-				GetTrustAnchors(), GetTargetCertConstraints());
+				GetTrustAnchors(),
+				GetTargetConstraintsCert(),
+				GetTargetConstraintsAttrCert());
 			parameters.SetParams(this);
 			return parameters;
 		}
diff --git a/crypto/src/pkix/PkixCertPath.cs b/crypto/src/pkix/PkixCertPath.cs
index 459c1612f..213b12eb4 100644
--- a/crypto/src/pkix/PkixCertPath.cs
+++ b/crypto/src/pkix/PkixCertPath.cs
@@ -94,11 +94,7 @@ namespace Org.BouncyCastle.Pkix
 
         private readonly IList certificates;
 
-		/**
-		 * @param certs
-		 */
-		private static IList SortCerts(
-			IList certs)
+		private static IList SortCerts(IList certs)
 		{
 			if (certs.Count < 2)
 				return certs;
diff --git a/crypto/src/pkix/PkixCertPathBuilder.cs b/crypto/src/pkix/PkixCertPathBuilder.cs
index 1bc7b8c9e..3ef66b1b9 100644
--- a/crypto/src/pkix/PkixCertPathBuilder.cs
+++ b/crypto/src/pkix/PkixCertPathBuilder.cs
@@ -36,20 +36,13 @@ namespace Org.BouncyCastle.Pkix
 		{
 			// search target certificates
 
-			IX509Selector certSelect = pkixParams.GetTargetCertConstraints();
-			if (!(certSelect is X509CertStoreSelector))
-			{
-				throw new PkixCertPathBuilderException(
-					"TargetConstraints must be an instance of "
-					+ typeof(X509CertStoreSelector).FullName + " for "
-					+ Platform.GetTypeName(this) + " class.");
-			}
+			var certSelector = pkixParams.GetTargetConstraintsCert();
 
 			ISet targets = new HashSet();
 			try
 			{
-				targets.AddAll(PkixCertPathValidatorUtilities.FindCertificates((X509CertStoreSelector)certSelect, pkixParams.GetStores()));
-				// TODO Should this include an entry for pkixParams.GetAdditionalStores() too?
+				targets.AddAll(
+					PkixCertPathValidatorUtilities.FindCertificates(certSelector, pkixParams.GetStoresCert()));
 			}
 			catch (Exception e)
 			{
@@ -122,23 +115,20 @@ namespace Org.BouncyCastle.Pkix
 				{
 					// exception message from possibly later tried certification
 					// chains
-					PkixCertPath certPath = null;
+					PkixCertPath certPath;
 					try
 					{
 						certPath = new PkixCertPath(tbvPath);
 					}
 					catch (Exception e)
 					{
-						throw new Exception(
-							"Certification path could not be constructed from certificate list.",
-							e);
+						throw new Exception("Certification path could not be constructed from certificate list.", e);
 					}
 
-					PkixCertPathValidatorResult result = null;
+					PkixCertPathValidatorResult result;
 					try
 					{
-						result = (PkixCertPathValidatorResult)validator.Validate(
-							certPath, pkixParams);
+						result = validator.Validate(certPath, pkixParams);
 					}
 					catch (Exception e)
 					{
diff --git a/crypto/src/pkix/PkixCertPathValidator.cs b/crypto/src/pkix/PkixCertPathValidator.cs
index a45102894..95939e0bd 100644
--- a/crypto/src/pkix/PkixCertPathValidator.cs
+++ b/crypto/src/pkix/PkixCertPathValidator.cs
@@ -1,13 +1,13 @@
 using System;
 using System.Collections;
-using Org.BouncyCastle.Asn1;
+using System.Collections.Generic;
+
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Security.Certificates;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.X509;
-using Org.BouncyCastle.X509.Store;
 
 namespace Org.BouncyCastle.Pkix
 {
@@ -96,7 +96,6 @@ namespace Org.BouncyCastle.Pkix
             //
             // (e), (f), (g) are part of the paramsPkix object.
             //
-            IEnumerator certIter;
             int index = 0;
             int i;
             // Certificate for each interation of the validation loop
@@ -108,18 +107,18 @@ namespace Org.BouncyCastle.Pkix
             //
             // (a)
             //
-            IList[] policyNodes = new IList[n + 1];
+            var policyNodes = new List<PkixPolicyNode>[n + 1];
             for (int j = 0; j < policyNodes.Length; j++)
             {
-                policyNodes[j] = Platform.CreateArrayList();
+                policyNodes[j] = new List<PkixPolicyNode>();
             }
 
             ISet policySet = new HashSet();
 
             policySet.Add(Rfc3280CertPathUtilities.ANY_POLICY);
 
-            PkixPolicyNode validPolicyTree = new PkixPolicyNode(Platform.CreateArrayList(), 0, policySet, null, new HashSet(),
-                    Rfc3280CertPathUtilities.ANY_POLICY, false);
+            var validPolicyTree = new PkixPolicyNode(new List<PkixPolicyNode>(), 0, policySet, null, new HashSet(),
+                Rfc3280CertPathUtilities.ANY_POLICY, false);
 
             policyNodes[0].Add(validPolicyTree);
 
@@ -218,8 +217,8 @@ namespace Org.BouncyCastle.Pkix
             // 6.1.3
             //
 
-			X509CertStoreSelector certConstraints = paramsPkix.GetTargetCertConstraints();
-            if (certConstraints != null && !certConstraints.Match((X509Certificate)certs[0]))
+			var targetConstraints = paramsPkix.GetTargetConstraintsCert();
+            if (targetConstraints != null && !targetConstraints.Match((X509Certificate)certs[0]))
             {
                 throw new PkixCertPathValidatorException(
 					"Target certificate in certification path does not match targetConstraints.", null, 0);
@@ -228,12 +227,10 @@ namespace Org.BouncyCastle.Pkix
             //
             // initialize CertPathChecker's
             //
-            IList pathCheckers = paramsPkix.GetCertPathCheckers();
-            certIter = pathCheckers.GetEnumerator();
-
-            while (certIter.MoveNext())
+            IList certPathCheckers = paramsPkix.GetCertPathCheckers();
+            foreach (PkixCertPathChecker certPathChecker in certPathCheckers)
             {
-                ((PkixCertPathChecker)certIter.Current).Init(false);
+                certPathChecker.Init(false);
             }
 
             X509Certificate cert = null;
@@ -353,7 +350,7 @@ namespace Org.BouncyCastle.Pkix
 					}
 
 					// (o)
-					Rfc3280CertPathUtilities.PrepareNextCertO(certPath, index, criticalExtensions1, pathCheckers);
+					Rfc3280CertPathUtilities.PrepareNextCertO(certPath, index, criticalExtensions1, certPathCheckers);
 
 					// set signing certificate for next round
                     sign = cert;
@@ -419,7 +416,7 @@ namespace Org.BouncyCastle.Pkix
                 criticalExtensions = new HashSet();
             }
 
-            Rfc3280CertPathUtilities.WrapupCertF(certPath, index + 1, pathCheckers, criticalExtensions);
+            Rfc3280CertPathUtilities.WrapupCertF(certPath, index + 1, certPathCheckers, criticalExtensions);
 
             PkixPolicyNode intersection = Rfc3280CertPathUtilities.WrapupCertG(certPath, paramsPkix, userInitialPolicySet,
                     index + 1, policyNodes, validPolicyTree, acceptablePolicies);
diff --git a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
index 86f9f4beb..731f8dfe0 100644
--- a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
+++ b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
@@ -1,7 +1,7 @@
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.IO;
-using System.Text;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.IsisMtt;
@@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Pkix
 	/// <summary>
 	/// Summary description for PkixCertPathValidatorUtilities.
 	/// </summary>
-	public class PkixCertPathValidatorUtilities
+	internal static class PkixCertPathValidatorUtilities
 	{
 		private static readonly PkixCrlUtilities CrlUtilities = new PkixCrlUtilities();
 
@@ -36,20 +36,20 @@ namespace Org.BouncyCastle.Pkix
 		internal static readonly int KEY_CERT_SIGN = 5;
 		internal static readonly int CRL_SIGN = 6;
 
-		internal static readonly string[] crlReasons = new string[]
-		{
-			"unspecified",
-			"keyCompromise",
-			"cACompromise",
-			"affiliationChanged",
-			"superseded",
-			"cessationOfOperation",
-			"certificateHold",
-			"unknown",
-			"removeFromCRL",
-			"privilegeWithdrawn",
-			"aACompromise"
-		};
+		//internal static readonly string[] crlReasons = new string[]
+		//{
+		//	"unspecified",
+		//	"keyCompromise",
+		//	"cACompromise",
+		//	"affiliationChanged",
+		//	"superseded",
+		//	"cessationOfOperation",
+		//	"certificateHold",
+		//	"unknown",
+		//	"removeFromCRL",
+		//	"privilegeWithdrawn",
+		//	"aACompromise"
+		//};
 
 		/// <summary>
 		/// Search the given Set of TrustAnchor's for one that is the
@@ -175,7 +175,7 @@ namespace Org.BouncyCastle.Pkix
 					{
 						// found
 						string temp = (string)list[1];
-						PkixCertPathValidatorUtilities.AddAdditionalStoreFromLocation(temp, pkixParams);
+						AddAdditionalStoreFromLocation(temp, pkixParams);
 					}
 				}
 			}
@@ -194,19 +194,25 @@ namespace Org.BouncyCastle.Pkix
 		/// <summary>
 		/// Returns the issuer of an attribute certificate or certificate.
 		/// </summary>
-		/// <param name="cert">The attribute certificate or certificate.</param>
+		/// <param name="obj">The attribute certificate or certificate.</param>
 		/// <returns>The issuer as <code>X500Principal</code>.</returns>
-		internal static X509Name GetIssuerPrincipal(
-			object cert)
+		internal static X509Name GetIssuerPrincipal(object obj)
 		{
-			if (cert is X509Certificate)
-			{
-				return ((X509Certificate)cert).IssuerDN;
-			}
-			else
-			{
-				return ((IX509AttributeCertificate)cert).Issuer.GetPrincipals()[0];
-			}
+			if (obj is X509Certificate cert)
+				return cert.IssuerDN;
+			if (obj is X509V2AttributeCertificate attrCert)
+				return attrCert.Issuer.GetPrincipals()[0];
+			throw new InvalidOperationException();
+		}
+
+		internal static X509Name GetIssuerPrincipal(X509V2AttributeCertificate attrCert)
+		{
+			return attrCert.Issuer.GetPrincipals()[0];
+		}
+
+		internal static X509Name GetIssuerPrincipal(X509Certificate cert)
+		{
+			return cert.IssuerDN;
 		}
 
 		internal static bool IsSelfIssued(
@@ -309,16 +315,14 @@ namespace Org.BouncyCastle.Pkix
 			ISet pq = new HashSet();
 
 			if (qualifiers == null)
-			{
 				return pq;
-			}
 
 			foreach (Asn1Encodable ae in qualifiers)
 			{
 				try
 				{
-//					pq.Add(PolicyQualifierInfo.GetInstance(Asn1Object.FromByteArray(ae.GetEncoded())));
-					pq.Add(PolicyQualifierInfo.GetInstance(ae.ToAsn1Object()));
+					pq.Add(PolicyQualifierInfo.GetInstance(Asn1Object.FromByteArray(ae.GetEncoded())));
+					//pq.Add(PolicyQualifierInfo.GetInstance(ae.ToAsn1Object()));
 				}
 				catch (IOException ex)
 				{
@@ -329,12 +333,10 @@ namespace Org.BouncyCastle.Pkix
 			return pq;
 		}
 
-		internal static PkixPolicyNode RemovePolicyNode(
-			PkixPolicyNode validPolicyTree,
-			IList[] policyNodes,
-			PkixPolicyNode _node)
+		internal static PkixPolicyNode RemovePolicyNode(PkixPolicyNode validPolicyTree,
+			IList<PkixPolicyNode>[] policyNodes, PkixPolicyNode _node)
 		{
-			PkixPolicyNode _parent = (PkixPolicyNode)_node.Parent;
+			PkixPolicyNode _parent = _node.Parent;
 
 			if (validPolicyTree == null)
 			{
@@ -345,7 +347,7 @@ namespace Org.BouncyCastle.Pkix
 			{
 				for (int j = 0; j < policyNodes.Length; j++)
 				{
-                    policyNodes[j] = Platform.CreateArrayList();
+					policyNodes[j] = new List<PkixPolicyNode>();
 				}
 
 				return null;
@@ -359,7 +361,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
-		private static void RemovePolicyNodeRecurse(IList[] policyNodes, PkixPolicyNode _node)
+		private static void RemovePolicyNodeRecurse(IList<PkixPolicyNode>[] policyNodes, PkixPolicyNode _node)
 		{
 			policyNodes[_node.Depth].Remove(_node);
 
@@ -446,12 +448,10 @@ namespace Org.BouncyCastle.Pkix
 							ci = critExtOids.Contains(X509Extensions.CertificatePolicies.Id);
 						}
 
-						PkixPolicyNode p_node = (PkixPolicyNode)node.Parent;
+						PkixPolicyNode p_node = node.Parent;
 						if (ANY_POLICY.Equals(p_node.ValidPolicy))
 						{
-							PkixPolicyNode c_node = new PkixPolicyNode(
-                                Platform.CreateArrayList(), i,
-								(ISet)m_idp[id_p],
+							PkixPolicyNode c_node = new PkixPolicyNode(new List<PkixPolicyNode>(), i, (ISet)m_idp[id_p],
 								p_node, pq, id_p, ci);
 							p_node.AddChild(c_node);
 							policyNodes[i].Add(c_node);
@@ -462,45 +462,39 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
-		internal static PkixPolicyNode PrepareNextCertB2(
-			int				i,
-			IList[]			policyNodes,
-			string			id_p,
-			PkixPolicyNode	validPolicyTree)
+		internal static PkixPolicyNode PrepareNextCertB2(int i, IList<PkixPolicyNode>[] policyNodes, string id_p,
+			PkixPolicyNode validPolicyTree)
 		{
 			int pos = 0;
 
 			// Copy to avoid RemoveAt calls interfering with enumeration
-            foreach (PkixPolicyNode node in Platform.CreateArrayList(policyNodes[i]))
+            foreach (var node in new List<PkixPolicyNode>(policyNodes[i]))
 			{
-				if (node.ValidPolicy.Equals(id_p))
-				{
-					PkixPolicyNode p_node = (PkixPolicyNode)node.Parent;
-					p_node.RemoveChild(node);
+				if (!node.ValidPolicy.Equals(id_p))
+                {
+					++pos;
+					continue;
+                }
+
+				node.Parent.RemoveChild(node);
 
-					// Removal of element at current iterator position not supported in C#
-					//nodes_i.remove();
-					policyNodes[i].RemoveAt(pos);
+				policyNodes[i].RemoveAt(pos);
 
-					for (int k = (i - 1); k >= 0; k--)
+				for (int k = i - 1; k >= 0; k--)
+				{
+					var nodes = policyNodes[k];
+
+					for (int l = 0; l < nodes.Count; l++)
 					{
-						IList nodes = policyNodes[k];
-						for (int l = 0; l < nodes.Count; l++)
+						var node2 = nodes[l];
+						if (!node2.HasChildren)
 						{
-							PkixPolicyNode node2 = (PkixPolicyNode)nodes[l];
-							if (!node2.HasChildren)
-							{
-								validPolicyTree = RemovePolicyNode(validPolicyTree, policyNodes, node2);
-								if (validPolicyTree == null)
-									break;
-							}
+							validPolicyTree = RemovePolicyNode(validPolicyTree, policyNodes, node2);
+							if (validPolicyTree == null)
+								break;
 						}
 					}
 				}
-				else
-				{
-					++pos;
-				}
 			}
 			return validPolicyTree;
 		}
@@ -511,7 +505,7 @@ namespace Org.BouncyCastle.Pkix
 			object cert,
 			CertStatus certStatus)
 		{
-			X509Crl bcCRL = null;
+			X509Crl bcCRL;
 
 			try
 			{
@@ -519,7 +513,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 			catch (Exception exception)
 			{
-				throw new Exception("Bouncy Castle X509Crl could not be created.", exception);
+				throw new Exception("X509Crl could not be created.", exception);
 			}
 
 			X509CrlEntry crl_entry = (X509CrlEntry)bcCRL.GetRevokedCertificate(GetSerialNumber(cert));
@@ -656,7 +650,7 @@ namespace Org.BouncyCastle.Pkix
 			// if end cert use given signing/encryption/... time
 			if (index <= 0)
 			{
-				return PkixCertPathValidatorUtilities.GetValidDate(paramsPkix);
+				return GetValidDate(paramsPkix);
 				// else use time when previous cert was created
 			}
 
@@ -694,40 +688,22 @@ namespace Org.BouncyCastle.Pkix
 		}
 
 		/// <summary>
-		/// Return a Collection of all certificates or attribute certificates found
-		/// in the X509Store's that are matching the certSelect criteriums.
+		/// Return a Collection of all certificates found
+		/// in the stores that are matching the certSelector criteria.
 		/// </summary>
-		/// <param name="certSelect">a {@link Selector} object that will be used to select
-		/// the certificates</param>
-		/// <param name="certStores">a List containing only X509Store objects. These
+		/// <param name="certSelector">an <see cref="ISelector{T}"/> object that will be used to select
+		/// the certificates.</param>
+		/// <param name="certStores">a List containing only IStore objects. These
 		/// are used to search for certificates.</param>
-		/// <returns>a Collection of all found <see cref="X509Certificate"/> or
-		/// <see cref="Org.BouncyCastle.X509.IX509AttributeCertificate"/> objects.
+		/// <returns>a Collection of all found <see cref="X509Certificate"/> objects.
 		/// May be empty but never <code>null</code>.</returns>
 		/// <exception cref="Exception"></exception>
-		internal static ICollection FindCertificates(
-			X509CertStoreSelector	certSelect,
-			IList					certStores)
+		internal static List<X509Certificate> FindCertificates(ISelector<X509Certificate> certSelector,
+			IList<IStore<X509Certificate>> certStores)
 		{
-			ISet certs = new HashSet();
-
-			foreach (IX509Store certStore in certStores)
-			{
-				try
-				{
-//					certs.AddAll(certStore.GetMatches(certSelect));
-					foreach (X509Certificate c in certStore.GetMatches(certSelect))
-					{
-						certs.Add(c);
-					}
-				}
-				catch (Exception e)
-				{
-					throw new Exception("Problem while picking certificates from X.509 store.", e);
-				}
-			}
-
-			return certs;
+			var result = new List<X509Certificate>();
+			CollectionUtilities.CollectMatches(result, certSelector, certStores);
+			return result;
 		}
 
 		/**
@@ -859,60 +835,41 @@ namespace Org.BouncyCastle.Pkix
 		 * @throws Exception if an exception occurs while picking the CRLs
 		 *             or no CRLs are found.
 		 */
-		internal static ISet GetCompleteCrls(
-			DistributionPoint	dp,
-			object				cert,
-			DateTime			currentDate,
-			PkixParameters		paramsPKIX)
+		internal static ISet<X509Crl> GetCompleteCrls(DistributionPoint dp, object certObj, DateTime currentDate,
+			PkixParameters paramsPKIX)
 		{
+			var certObjIssuer = GetIssuerPrincipal(certObj);
+
 			X509CrlStoreSelector crlselect = new X509CrlStoreSelector();
 			try
 			{
 				ISet issuers = new HashSet();
-				if (cert is X509V2AttributeCertificate)
-				{
-					issuers.Add(((X509V2AttributeCertificate)cert)
-						.Issuer.GetPrincipals()[0]);
-				}
-				else
-				{
-					issuers.Add(GetIssuerPrincipal(cert));
-				}
-				PkixCertPathValidatorUtilities.GetCrlIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX);
+				issuers.Add(certObjIssuer);
+
+				GetCrlIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX);
 			}
 			catch (Exception e)
 			{
 				throw new Exception("Could not get issuer information from distribution point.", e);
 			}
 
-			if (cert is X509Certificate)
-			{
-				crlselect.CertificateChecking = (X509Certificate)cert;
-			}
-			else if (cert is X509V2AttributeCertificate)
-			{
-				crlselect.AttrCertChecking = (IX509AttributeCertificate)cert;
-			}
-
-			crlselect.CompleteCrlEnabled = true;
-			ISet crls = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate);
-
-			if (crls.IsEmpty)
-			{
-				if (cert is IX509AttributeCertificate)
+            {
+				if (certObj is X509Certificate cert)
 				{
-					IX509AttributeCertificate aCert = (IX509AttributeCertificate)cert;
-
-					throw new Exception("No CRLs found for issuer \"" + aCert.Issuer.GetPrincipals()[0] + "\"");
+					crlselect.CertificateChecking = cert;
 				}
-				else
+				else if (certObj is X509V2AttributeCertificate attrCert)
 				{
-					X509Certificate xCert = (X509Certificate)cert;
-
-					throw new Exception("No CRLs found for issuer \"" + xCert.IssuerDN + "\"");
+					crlselect.AttrCertChecking = attrCert;
 				}
 			}
 
+			crlselect.CompleteCrlEnabled = true;
+
+			ISet<X509Crl> crls = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate);
+			if (crls.Count < 1)
+				throw new Exception("No CRLs found for issuer \"" + certObjIssuer + "\"");
+
 			return crls;
 		}
 
@@ -926,7 +883,7 @@ namespace Org.BouncyCastle.Pkix
 		 * @throws Exception if an exception occurs while picking the delta
 		 *             CRLs.
 		 */
-		internal static ISet GetDeltaCrls(
+		internal static ISet<X509Crl> GetDeltaCrls(
 			DateTime		currentDate,
 			PkixParameters	paramsPKIX,
 			X509Crl			completeCRL)
@@ -991,9 +948,9 @@ namespace Org.BouncyCastle.Pkix
 			deltaSelect.MaxBaseCrlNumber = completeCRLNumber;
 
 			// find delta CRLs
-			ISet temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate);
+			ISet<X509Crl> temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate);
 
-			ISet result = new HashSet();
+			var result = new HashSet<X509Crl>();
 
 			foreach (X509Crl crl in temp)
 			{
@@ -1014,32 +971,6 @@ namespace Org.BouncyCastle.Pkix
 			return critical.Contains(X509Extensions.DeltaCrlIndicator.Id);
 		}
 
-		internal static ICollection FindCertificates(
-			X509AttrCertStoreSelector	certSelect,
-			IList						certStores)
-		{
-			ISet certs = new HashSet();
-
-			foreach (IX509Store certStore in certStores)
-			{
-				try
-				{
-//					certs.AddAll(certStore.GetMatches(certSelect));
-					foreach (X509V2AttributeCertificate ac in certStore.GetMatches(certSelect))
-					{
-						certs.Add(ac);
-					}
-				}
-				catch (Exception e)
-				{
-					throw new Exception(
-						"Problem while picking certificates from X.509 store.", e);
-				}
-			}
-
-			return certs;
-		}
-
 		internal static void AddAdditionalStoresFromCrlDistributionPoint(
 			CrlDistPoint	crldp,
 			PkixParameters	pkixParams)
@@ -1071,10 +1002,8 @@ namespace Org.BouncyCastle.Pkix
 							{
 								if (genNames[j].TagNo == GeneralName.UniformResourceIdentifier)
 								{
-									string location = DerIA5String.GetInstance(
-										genNames[j].Name).GetString();
-									PkixCertPathValidatorUtilities.AddAdditionalStoreFromLocation(
-										location, pkixParams);
+									string location = DerIA5String.GetInstance(genNames[j].Name).GetString();
+									AddAdditionalStoreFromLocation(location, pkixParams);
 								}
 							}
 						}
@@ -1083,31 +1012,18 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
-		internal static bool ProcessCertD1i(
-			int					index,
-			IList[]				policyNodes,
-			DerObjectIdentifier	pOid,
-			ISet				pq)
+		internal static bool ProcessCertD1i(int index, IList<PkixPolicyNode>[] policyNodes, DerObjectIdentifier	pOid,
+			ISet pq)
 		{
-			IList policyNodeVec = policyNodes[index - 1];
-
-			for (int j = 0; j < policyNodeVec.Count; j++)
+			foreach (var node in policyNodes[index - 1])
 			{
-				PkixPolicyNode node = (PkixPolicyNode)policyNodeVec[j];
-				ISet expectedPolicies = node.ExpectedPolicies;
-
-				if (expectedPolicies.Contains(pOid.Id))
+				if (node.ExpectedPolicies.Contains(pOid.Id))
 				{
-					ISet childExpectedPolicies = new HashSet();
+					var childExpectedPolicies = new HashSet();
 					childExpectedPolicies.Add(pOid.Id);
 
-                    PkixPolicyNode child = new PkixPolicyNode(Platform.CreateArrayList(),
-						index,
-						childExpectedPolicies,
-						node,
-						pq,
-						pOid.Id,
-						false);
+                    var child = new PkixPolicyNode(new List<PkixPolicyNode>(), index, childExpectedPolicies, node, pq,
+						pOid.Id, false);
 					node.AddChild(child);
 					policyNodes[index].Add(child);
 
@@ -1118,32 +1034,21 @@ namespace Org.BouncyCastle.Pkix
 			return false;
 		}
 
-		internal static void ProcessCertD1ii(
-			int					index,
-			IList[]				policyNodes,
-			DerObjectIdentifier _poid,
-			ISet				_pq)
+		internal static void ProcessCertD1ii(int index, IList<PkixPolicyNode>[] policyNodes,
+			DerObjectIdentifier _poid, ISet _pq)
 		{
-			IList policyNodeVec = policyNodes[index - 1];
-
-			for (int j = 0; j < policyNodeVec.Count; j++)
+			foreach (var _node in policyNodes[index - 1])
 			{
-				PkixPolicyNode _node = (PkixPolicyNode)policyNodeVec[j];
-
 				if (ANY_POLICY.Equals(_node.ValidPolicy))
 				{
 					ISet _childExpectedPolicies = new HashSet();
 					_childExpectedPolicies.Add(_poid.Id);
 
-                    PkixPolicyNode _child = new PkixPolicyNode(Platform.CreateArrayList(),
-						index,
-						_childExpectedPolicies,
-						_node,
-						_pq,
-						_poid.Id,
-						false);
+                    var _child = new PkixPolicyNode(new List<PkixPolicyNode>(), index, _childExpectedPolicies, _node,
+						_pq, _poid.Id, false);
 					_node.AddChild(_child);
 					policyNodes[index].Add(_child);
+
 					return;
 				}
 			}
@@ -1161,15 +1066,14 @@ namespace Org.BouncyCastle.Pkix
 		* @exception Exception
 		*                if an error occurs.
 		*/
-		internal static ICollection FindIssuerCerts(
+		internal static HashSet<X509Certificate> FindIssuerCerts(
 			X509Certificate			cert,
 			PkixBuilderParameters	pkixParams)
 		{
-			X509CertStoreSelector certSelect = new X509CertStoreSelector();
-			ISet certs = new HashSet();
+			X509CertStoreSelector certSelector = new X509CertStoreSelector();
 			try
 			{
-				certSelect.Subject = cert.IssuerDN;
+				certSelector.Subject = cert.IssuerDN;
 			}
 			catch (IOException ex)
 			{
@@ -1177,10 +1081,10 @@ namespace Org.BouncyCastle.Pkix
 					"Subject criteria for certificate selector to find issuer certificate could not be set.", ex);
 			}
 
+			var certs = new HashSet<X509Certificate>();
 			try
 			{
-                certs.AddAll(PkixCertPathValidatorUtilities.FindCertificates(certSelect, pkixParams.GetStores()));
-                certs.AddAll(PkixCertPathValidatorUtilities.FindCertificates(certSelect, pkixParams.GetAdditionalStores()));
+				CollectionUtilities.CollectMatches(certs, certSelector, pkixParams.GetStoresCert());
 			}
 			catch (Exception e)
 			{
diff --git a/crypto/src/pkix/PkixCrlUtilities.cs b/crypto/src/pkix/PkixCrlUtilities.cs
index 06a7caa2a..341c9a514 100644
--- a/crypto/src/pkix/PkixCrlUtilities.cs
+++ b/crypto/src/pkix/PkixCrlUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Date;
@@ -10,22 +10,22 @@ namespace Org.BouncyCastle.Pkix
 {
 	public class PkixCrlUtilities
 	{
-		public virtual ISet FindCrls(X509CrlStoreSelector crlselect, PkixParameters paramsPkix, DateTime currentDate)
+		public virtual ISet<X509Crl> FindCrls(X509CrlStoreSelector crlSelector, PkixParameters paramsPkix,
+			DateTime currentDate)
 		{
-			ISet initialSet = new HashSet();
+			HashSet<X509Crl> initialSet;
 
 			// get complete CRL(s)
 			try
 			{
-				initialSet.AddAll(FindCrls(crlselect, paramsPkix.GetAdditionalStores()));
-				initialSet.AddAll(FindCrls(crlselect, paramsPkix.GetStores()));
+				initialSet = FindCrls(crlSelector, paramsPkix.GetStoresCrl());
 			}
 			catch (Exception e)
 			{
 				throw new Exception("Exception obtaining complete CRLs.", e);
 			}
 
-			ISet finalSet = new HashSet();
+			var finalSet = new HashSet<X509Crl>();
 			DateTime validityDate = currentDate;
 
 			if (paramsPkix.Date != null)
@@ -40,7 +40,7 @@ namespace Org.BouncyCastle.Pkix
 
                 if (null == nextUpdate || nextUpdate.Value.CompareTo(validityDate) > 0)
 				{
-					X509Certificate cert = crlselect.CertificateChecking;
+					X509Certificate cert = crlSelector.CertificateChecking;
 
                     if (null == cert || crl.ThisUpdate.CompareTo(cert.NotAfter) < 0)
                     {
@@ -52,14 +52,14 @@ namespace Org.BouncyCastle.Pkix
 			return finalSet;
 		}
 
-		public virtual ISet FindCrls(X509CrlStoreSelector crlselect, PkixParameters paramsPkix)
+		public virtual ISet FindCrls(X509CrlStoreSelector crlSelector, PkixParameters paramsPkix)
 		{
 			ISet completeSet = new HashSet();
 
 			// get complete CRL(s)
 			try
 			{
-				completeSet.AddAll(FindCrls(crlselect, paramsPkix.GetStores()));
+				completeSet.AddAll(FindCrls(crlSelector, paramsPkix.GetStoresCrl()));
 			}
 			catch (Exception e)
 			{
@@ -74,28 +74,28 @@ namespace Org.BouncyCastle.Pkix
 		/// Return a Collection of all CRLs found in the X509Store's that are
 		/// matching the crlSelect criteriums.
 		/// </summary>
-		/// <param name="crlSelect">a {@link X509CRLStoreSelector} object that will be used
+		/// <param name="crlSelector">a {@link X509CRLStoreSelector} object that will be used
 		/// to select the CRLs</param>
 		/// <param name="crlStores">a List containing only {@link org.bouncycastle.x509.X509Store
 		/// X509Store} objects. These are used to search for CRLs</param>
 		/// <returns>a Collection of all found {@link X509CRL X509CRL} objects. May be
 		/// empty but never <code>null</code>.
 		/// </returns>
-		private ICollection FindCrls(X509CrlStoreSelector crlSelect, IList crlStores)
+		private HashSet<X509Crl> FindCrls(ISelector<X509Crl> crlSelector, IList<IStore<X509Crl>> crlStores)
 		{
-			ISet crls = new HashSet();
+            var crls = new HashSet<X509Crl>();
 
 			Exception lastException = null;
 			bool foundValidStore = false;
 
-			foreach (IX509Store store in crlStores)
+			foreach (var crlStore in crlStores)
 			{
 				try
 				{
-					crls.AddAll(store.GetMatches(crlSelect));
+					crls.UnionWith(crlStore.EnumerateMatches(crlSelector));
 					foundValidStore = true;
 				}
-				catch (X509StoreException e)
+				catch (Exception e)
 				{
 					lastException = new Exception("Exception searching in X.509 CRL store.", e);
 				}
diff --git a/crypto/src/pkix/PkixParameters.cs b/crypto/src/pkix/PkixParameters.cs
index 54b077f29..32189acfb 100644
--- a/crypto/src/pkix/PkixParameters.cs
+++ b/crypto/src/pkix/PkixParameters.cs
@@ -1,9 +1,11 @@
 using System;
 using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Date;
+using Org.BouncyCastle.X509;
 using Org.BouncyCastle.X509.Store;
 
 namespace Org.BouncyCastle.Pkix
@@ -49,11 +51,15 @@ namespace Org.BouncyCastle.Pkix
 		private bool anyPolicyInhibited = false;
 		private bool policyMappingInhibited = false;
 		private bool policyQualifiersRejected = true;
-		private IX509Selector certSelector;
-		private IList stores;
-		private IX509Selector selector;
+
+		private List<IStore<X509V2AttributeCertificate>> m_storesAttrCert;
+		private List<IStore<X509Certificate>> m_storesCert;
+		private List<IStore<X509Crl>> m_storesCrl;
+
+		private ISelector<X509V2AttributeCertificate> m_targetConstraintsAttrCert;
+		private ISelector<X509Certificate> m_targetConstraintsCert;
+
 		private bool additionalLocationsEnabled;
-		private IList additionalStores;
 		private ISet trustedACIssuers;
 		private ISet necessaryACAttributes;
 		private ISet prohibitedACAttributes;
@@ -86,8 +92,9 @@ namespace Org.BouncyCastle.Pkix
 
 			this.initialPolicies = new HashSet();
 			this.certPathCheckers = Platform.CreateArrayList();
-            this.stores = Platform.CreateArrayList();
-			this.additionalStores = Platform.CreateArrayList();
+			this.m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>();
+			this.m_storesCert = new List<IStore<X509Certificate>>();
+			this.m_storesCrl = new List<IStore<X509Crl>>();
 			this.trustedACIssuers = new HashSet();
 			this.necessaryACAttributes = new HashSet();
 			this.prohibitedACAttributes = new HashSet();
@@ -206,6 +213,55 @@ namespace Org.BouncyCastle.Pkix
 		}
 
 		/**
+		* Returns the required constraints on the target certificate or attribute
+		* certificate. The constraints are returned as an instance of
+		* <code>IX509Selector</code>. If <code>null</code>, no constraints are
+		* defined.
+		*
+		* <p>
+		* The target certificate in a PKIX path may be a certificate or an
+		* attribute certificate.
+		* </p><p>
+		* Note that the <code>IX509Selector</code> returned is cloned to protect
+		* against subsequent modifications.
+		* </p>
+		* @return a <code>IX509Selector</code> specifying the constraints on the
+		*         target certificate or attribute certificate (or <code>null</code>)
+		* @see #setTargetConstraints
+		* @see X509CertStoreSelector
+		* @see X509AttributeCertStoreSelector
+		*/
+		public virtual ISelector<X509V2AttributeCertificate> GetTargetConstraintsAttrCert()
+		{
+			return (ISelector<X509V2AttributeCertificate>)m_targetConstraintsAttrCert?.Clone();
+		}
+
+		/**
+		* Sets the required constraints on the target certificate or attribute
+		* certificate. The constraints are specified as an instance of
+		* <code>IX509Selector</code>. If <code>null</code>, no constraints are
+		* defined.
+		* <p>
+		* The target certificate in a PKIX path may be a certificate or an
+		* attribute certificate.
+		* </p><p>
+		* Note that the <code>IX509Selector</code> specified is cloned to protect
+		* against subsequent modifications.
+		* </p>
+		*
+		* @param selector a <code>IX509Selector</code> specifying the constraints on
+		*            the target certificate or attribute certificate (or
+		*            <code>null</code>)
+		* @see #getTargetConstraints
+		* @see X509CertStoreSelector
+		* @see X509AttributeCertStoreSelector
+		*/
+		public virtual void SetTargetConstraintsAttrCert(ISelector<X509V2AttributeCertificate> targetConstraintsAttrCert)
+		{
+			this.m_targetConstraintsAttrCert = (ISelector<X509V2AttributeCertificate>)targetConstraintsAttrCert?.Clone();
+		}
+
+		/**
 		* Returns the required constraints on the target certificate. The
 		* constraints are returned as an instance of CertSelector. If
 		* <code>null</code>, no constraints are defined.<br />
@@ -218,14 +274,9 @@ namespace Org.BouncyCastle.Pkix
 		*
 		* @see #setTargetCertConstraints(CertSelector)
 		*/
-		public virtual X509CertStoreSelector GetTargetCertConstraints()
+		public virtual ISelector<X509Certificate> GetTargetConstraintsCert()
 		{
-			if (certSelector == null)
-			{
-				return null;
-			}
-
-			return (X509CertStoreSelector)certSelector.Clone();
+			return (ISelector<X509Certificate>)m_targetConstraintsCert?.Clone();
 		}
 
 		/**
@@ -242,17 +293,9 @@ namespace Org.BouncyCastle.Pkix
 		 *
 		 * @see #getTargetCertConstraints()
 		 */
-		public virtual void SetTargetCertConstraints(
-			IX509Selector selector)
+		public virtual void SetTargetConstraintsCert(ISelector<X509Certificate> targetConstraintsCert)
 		{
-			if (selector == null)
-			{
-				certSelector = null;
-			}
-			else
-			{
-				certSelector = (IX509Selector)selector.Clone();
-			}
+			m_targetConstraintsCert = (ISelector<X509Certificate>)targetConstraintsCert?.Clone();
 		}
 
 		/**
@@ -447,8 +490,7 @@ namespace Org.BouncyCastle.Pkix
 		* @param params Parameters to set. If this are
 		*            <code>ExtendedPkixParameters</code> they are copied to.
 		*/
-		protected virtual void SetParams(
-			PkixParameters parameters)
+		protected virtual void SetParams(PkixParameters parameters)
 		{
 			Date = parameters.Date;
 			SetCertPathCheckers(parameters.GetCertPathCheckers());
@@ -458,16 +500,18 @@ namespace Org.BouncyCastle.Pkix
 			IsRevocationEnabled = parameters.IsRevocationEnabled;
 			SetInitialPolicies(parameters.GetInitialPolicies());
 			IsPolicyQualifiersRejected = parameters.IsPolicyQualifiersRejected;
-			SetTargetCertConstraints(parameters.GetTargetCertConstraints());
 			SetTrustAnchors(parameters.GetTrustAnchors());
 
+			m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>(parameters.m_storesAttrCert);
+			m_storesCert = new List<IStore<X509Certificate>>(parameters.m_storesCert);
+			m_storesCrl = new List<IStore<X509Crl>>(parameters.m_storesCrl);
+
+			SetTargetConstraintsAttrCert(parameters.GetTargetConstraintsAttrCert());
+			SetTargetConstraintsCert(parameters.GetTargetConstraintsCert());
+
 			validityModel = parameters.validityModel;
 			useDeltas = parameters.useDeltas;
 			additionalLocationsEnabled = parameters.additionalLocationsEnabled;
-			selector = parameters.selector == null ? null
-				: (IX509Selector) parameters.selector.Clone();
-			stores = Platform.CreateArrayList(parameters.stores);
-            additionalStores = Platform.CreateArrayList(parameters.additionalStores);
 			trustedACIssuers = new HashSet(parameters.trustedACIssuers);
 			prohibitedACAttributes = new HashSet(parameters.prohibitedACAttributes);
 			necessaryACAttributes = new HashSet(parameters.necessaryACAttributes);
@@ -495,115 +539,79 @@ namespace Org.BouncyCastle.Pkix
 			set { validityModel = value; }
 		}
 
-		/**
-		* Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute
-		* certificates or cross certificates.
-		* <p>
-		* The <code>IList</code> is cloned.
-		* </p>
-		*
-		* @param stores A list of stores to use.
-		* @see #getStores
-		* @throws ClassCastException if an element of <code>stores</code> is not
-		*             a {@link Store}.
-		*/
-		public virtual void SetStores(
-			IList stores)
+		public virtual IList<IStore<X509V2AttributeCertificate>> GetStoresAttrCert()
+		{
+			return new List<IStore<X509V2AttributeCertificate>>(m_storesAttrCert);
+		}
+
+		public virtual IList<IStore<X509Certificate>> GetStoresCert()
 		{
-			if (stores == null)
+			return new List<IStore<X509Certificate>>(m_storesCert);
+		}
+
+		public virtual IList<IStore<X509Crl>> GetStoresCrl()
+		{
+			return new List<IStore<X509Crl>>(m_storesCrl);
+		}
+
+		public virtual void SetAttrStoresCert(IList<IStore<X509V2AttributeCertificate>> storesAttrCert)
+		{
+			if (storesAttrCert == null)
 			{
-                this.stores = Platform.CreateArrayList();
+				m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>();
 			}
 			else
 			{
-				foreach (object obj in stores)
-				{
-					if (!(obj is IX509Store))
-					{
-						throw new InvalidCastException(
-							"All elements of list must be of type " + typeof(IX509Store).FullName);
-					}
-				}
-                this.stores = Platform.CreateArrayList(stores);
+				m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>(storesAttrCert);
 			}
 		}
 
-		/**
-		* Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute
-		* certificates or cross certificates.
-		* <p>
-		* This method should be used to add local stores, like collection based
-		* X.509 stores, if available. Local stores should be considered first,
-		* before trying to use additional (remote) locations, because they do not
-		* need possible additional network traffic.
-		* </p><p>
-		* If <code>store</code> is <code>null</code> it is ignored.
-		* </p>
-		*
-		* @param store The store to add.
-		* @see #getStores
-		*/
-		public virtual void AddStore(
-			IX509Store store)
+		public virtual void SetStoresCert(IList<IStore<X509Certificate>> storesCert)
 		{
-			if (store != null)
+			if (storesCert == null)
 			{
-				stores.Add(store);
+				m_storesCert = new List<IStore<X509Certificate>>();
+			}
+			else
+			{
+				m_storesCert = new List<IStore<X509Certificate>>(storesCert);
 			}
 		}
 
-		/**
-		* Adds an additional Bouncy Castle {@link Store} to find CRLs, certificates,
-		* attribute certificates or cross certificates.
-		* <p>
-		* You should not use this method. This method is used for adding additional
-		* X.509 stores, which are used to add (remote) locations, e.g. LDAP, found
-		* during X.509 object processing, e.g. in certificates or CRLs. This method
-		* is used in PKIX certification path processing.
-		* </p><p>
-		* If <code>store</code> is <code>null</code> it is ignored.
-		* </p>
-		*
-		* @param store The store to add.
-		* @see #getStores()
-		*/
-		public virtual void AddAdditionalStore(
-			IX509Store store)
+		public virtual void SetStoresCrl(IList<IStore<X509Crl>> storesCrl)
 		{
-			if (store != null)
+			if (storesCrl == null)
+			{
+				m_storesCrl = new List<IStore<X509Crl>>();
+			}
+			else
 			{
-				additionalStores.Add(store);
+				m_storesCrl = new List<IStore<X509Crl>>(storesCrl);
 			}
 		}
 
-		/**
-		* Returns an <code>IList</code> of additional Bouncy Castle
-		* <code>Store</code>s used for finding CRLs, certificates, attribute
-		* certificates or cross certificates.
-		*
-		* @return an immutable <code>IList</code> of additional Bouncy Castle
-		*         <code>Store</code>s. Never <code>null</code>.
-		*
-		* @see #addAddionalStore(Store)
-		*/
-		public virtual IList GetAdditionalStores()
+		public virtual void AddStoreAttrCert(IStore<X509V2AttributeCertificate> storeAttrCert)
 		{
-            return Platform.CreateArrayList(additionalStores);
+			if (storeAttrCert != null)
+			{
+				m_storesAttrCert.Add(storeAttrCert);
+			}
 		}
 
-		/**
-		* Returns an <code>IList</code> of Bouncy Castle
-		* <code>Store</code>s used for finding CRLs, certificates, attribute
-		* certificates or cross certificates.
-		*
-		* @return an immutable <code>IList</code> of Bouncy Castle
-		*         <code>Store</code>s. Never <code>null</code>.
-		*
-		* @see #setStores(IList)
-		*/
-		public virtual IList GetStores()
+		public virtual void AddStoreCert(IStore<X509Certificate> storeCert)
 		{
-            return Platform.CreateArrayList(stores);
+			if (storeCert != null)
+			{
+				m_storesCert.Add(storeCert);
+			}
+		}
+
+		public virtual void AddStoreCrl(IStore<X509Crl> storeCrl)
+		{
+			if (storeCrl != null)
+			{
+				m_storesCrl.Add(storeCrl);
+			}
 		}
 
 		/**
@@ -630,69 +638,6 @@ namespace Org.BouncyCastle.Pkix
 		}
 
 		/**
-		* Returns the required constraints on the target certificate or attribute
-		* certificate. The constraints are returned as an instance of
-		* <code>IX509Selector</code>. If <code>null</code>, no constraints are
-		* defined.
-		*
-		* <p>
-		* The target certificate in a PKIX path may be a certificate or an
-		* attribute certificate.
-		* </p><p>
-		* Note that the <code>IX509Selector</code> returned is cloned to protect
-		* against subsequent modifications.
-		* </p>
-		* @return a <code>IX509Selector</code> specifying the constraints on the
-		*         target certificate or attribute certificate (or <code>null</code>)
-		* @see #setTargetConstraints
-		* @see X509CertStoreSelector
-		* @see X509AttributeCertStoreSelector
-		*/
-		public virtual IX509Selector GetTargetConstraints()
-		{
-			if (selector != null)
-			{
-				return (IX509Selector) selector.Clone();
-			}
-			else
-			{
-				return null;
-			}
-		}
-
-		/**
-		* Sets the required constraints on the target certificate or attribute
-		* certificate. The constraints are specified as an instance of
-		* <code>IX509Selector</code>. If <code>null</code>, no constraints are
-		* defined.
-		* <p>
-		* The target certificate in a PKIX path may be a certificate or an
-		* attribute certificate.
-		* </p><p>
-		* Note that the <code>IX509Selector</code> specified is cloned to protect
-		* against subsequent modifications.
-		* </p>
-		*
-		* @param selector a <code>IX509Selector</code> specifying the constraints on
-		*            the target certificate or attribute certificate (or
-		*            <code>null</code>)
-		* @see #getTargetConstraints
-		* @see X509CertStoreSelector
-		* @see X509AttributeCertStoreSelector
-		*/
-		public virtual void SetTargetConstraints(IX509Selector selector)
-		{
-			if (selector != null)
-			{
-				this.selector = (IX509Selector) selector.Clone();
-			}
-			else
-			{
-				this.selector = null;
-			}
-		}
-
-		/**
 		* Returns the trusted attribute certificate issuers. If attribute
 		* certificates is verified the trusted AC issuers must be set.
 		* <p>
diff --git a/crypto/src/pkix/PkixPolicyNode.cs b/crypto/src/pkix/PkixPolicyNode.cs
index fc5b82f6f..2e2e39caf 100644
--- a/crypto/src/pkix/PkixPolicyNode.cs
+++ b/crypto/src/pkix/PkixPolicyNode.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.Text;
 
 using Org.BouncyCastle.Utilities;
@@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Pkix
 	public class PkixPolicyNode
 //		: IPolicyNode
 	{
-		protected IList				mChildren;
+		protected IList<PkixPolicyNode> mChildren;
 		protected int				mDepth;
 		protected ISet				mExpectedPolicies;
 		protected PkixPolicyNode	mParent;
@@ -26,9 +26,9 @@ namespace Org.BouncyCastle.Pkix
 			get { return this.mDepth; }
 		}
 
-		public virtual IEnumerable Children
+		public virtual IEnumerable<PkixPolicyNode> Children
 		{
-			get { return new EnumerableProxy(mChildren); }
+			get { return CollectionUtilities.Proxy(mChildren); }
 		}
 
 		public virtual bool IsCritical
@@ -66,7 +66,7 @@ namespace Org.BouncyCastle.Pkix
 
 		/// Constructors
 		public PkixPolicyNode(
-			IList			children,
+			IEnumerable<PkixPolicyNode> children,
 			int				depth,
 			ISet			expectedPolicies,
 			PkixPolicyNode	parent,
@@ -76,11 +76,11 @@ namespace Org.BouncyCastle.Pkix
 		{
             if (children == null)
             {
-                this.mChildren = Platform.CreateArrayList();
+				this.mChildren = new List<PkixPolicyNode>();
             }
             else
             {
-                this.mChildren = Platform.CreateArrayList(children);
+				this.mChildren = new List<PkixPolicyNode>(children);
             }
 
             this.mDepth = depth;
@@ -137,7 +137,7 @@ namespace Org.BouncyCastle.Pkix
 		public virtual PkixPolicyNode Copy()
 		{
 			PkixPolicyNode node = new PkixPolicyNode(
-                Platform.CreateArrayList(),
+				new List<PkixPolicyNode>(),
 				mDepth,
 				new HashSet(mExpectedPolicies),
 				null,
diff --git a/crypto/src/pkix/Rfc3280CertPathUtilities.cs b/crypto/src/pkix/Rfc3280CertPathUtilities.cs
index 9001ba1d1..7359d2568 100644
--- a/crypto/src/pkix/Rfc3280CertPathUtilities.cs
+++ b/crypto/src/pkix/Rfc3280CertPathUtilities.cs
@@ -1,6 +1,6 @@
 using System;
 using System.Collections;
-using System.Globalization;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
@@ -11,13 +11,12 @@ using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Security.Certificates;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
-using Org.BouncyCastle.Utilities.Date;
 using Org.BouncyCastle.X509;
 using Org.BouncyCastle.X509.Store;
 
 namespace Org.BouncyCastle.Pkix
 {
-	public class Rfc3280CertPathUtilities
+	internal static class Rfc3280CertPathUtilities
 	{
 		private static readonly PkixCrlUtilities CrlUtilities = new PkixCrlUtilities();
 
@@ -367,25 +366,20 @@ namespace Org.BouncyCastle.Pkix
 							"Policy mappings extension contents could not be decoded.", e, index);
 					}
 
-					if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(issuerDomainPolicy.Id))
+					if (ANY_POLICY.Equals(issuerDomainPolicy.Id))
 						throw new PkixCertPathValidatorException(
 							"IssuerDomainPolicy is anyPolicy", null, index);
 
-					if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(subjectDomainPolicy.Id))
+					if (ANY_POLICY.Equals(subjectDomainPolicy.Id))
 						throw new PkixCertPathValidatorException(
 							"SubjectDomainPolicy is anyPolicy,", null, index);
 				}
 			}
 		}
 
-		internal static PkixPolicyNode ProcessCertD(
-			PkixCertPath	certPath,
-			int				index,
-			ISet			acceptablePolicies,
-			PkixPolicyNode	validPolicyTree,
-			IList[]			policyNodes,
-			int				inhibitAnyPolicy)
-			//throws CertPathValidatorException
+		/// <exception cref="PkixCertPathValidatorException"/>
+		internal static PkixPolicyNode ProcessCertD(PkixCertPath certPath, int index, ISet acceptablePolicies,
+			PkixPolicyNode validPolicyTree, IList<PkixPolicyNode>[] policyNodes, int inhibitAnyPolicy)
 		{
 			IList certs = certPath.Certificates;
 			X509Certificate cert = (X509Certificate)certs[index];
@@ -396,7 +390,7 @@ namespace Org.BouncyCastle.Pkix
 			// (d) policy Information checking against initial policy and
 			// policy mapping
 			//
-			Asn1Sequence certPolicies = null;
+			Asn1Sequence certPolicies;
 			try
 			{
 				certPolicies = Asn1Sequence.GetInstance(
@@ -421,7 +415,7 @@ namespace Org.BouncyCastle.Pkix
 
 					pols.Add(pOid.Id);
 
-					if (!Rfc3280CertPathUtilities.ANY_POLICY.Equals(pOid.Id))
+					if (!ANY_POLICY.Equals(pOid.Id))
 					{
 						ISet pq = null;
 						try
@@ -443,7 +437,7 @@ namespace Org.BouncyCastle.Pkix
 					}
 				}
 
-				if (acceptablePolicies.IsEmpty || acceptablePolicies.Contains(Rfc3280CertPathUtilities.ANY_POLICY))
+				if (acceptablePolicies.IsEmpty || acceptablePolicies.Contains(ANY_POLICY))
 				{
 					acceptablePolicies.Clear();
 					acceptablePolicies.AddAll(pols);
@@ -471,20 +465,14 @@ namespace Org.BouncyCastle.Pkix
 					foreach (Asn1Encodable ae in certPolicies)
 					{
 						PolicyInformation pInfo = PolicyInformation.GetInstance(ae.ToAsn1Object());
-						if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(pInfo.PolicyIdentifier.Id))
+						if (ANY_POLICY.Equals(pInfo.PolicyIdentifier.Id))
 						{
 							ISet _apq = PkixCertPathValidatorUtilities.GetQualifierSet(pInfo.PolicyQualifiers);
-							IList _nodes = policyNodes[i - 1];
 
-							for (int k = 0; k < _nodes.Count; k++)
+							foreach (var _node in policyNodes[i - 1])
 							{
-								PkixPolicyNode _node = (PkixPolicyNode)_nodes[k];
-
-								IEnumerator  _policySetIter = _node.ExpectedPolicies.GetEnumerator();
-								while (_policySetIter.MoveNext())
+								foreach (var _tmp in _node.ExpectedPolicies)
 								{
-									object _tmp = _policySetIter.Current;
-
 									string _policy;
 									if (_tmp is string)
 									{
@@ -511,10 +499,10 @@ namespace Org.BouncyCastle.Pkix
 
 									if (!_found)
 									{
-										ISet _newChildExpectedPolicies = new HashSet();
+										var _newChildExpectedPolicies = new HashSet();
 										_newChildExpectedPolicies.Add(_policy);
 
-										PkixPolicyNode _newChild = new PkixPolicyNode(Platform.CreateArrayList(), i,
+										var _newChild = new PkixPolicyNode(new List<PkixPolicyNode>(), i,
 											_newChildExpectedPolicies, _node, _apq, _policy, false);
 										_node.AddChild(_newChild);
 										policyNodes[i].Add(_newChild);
@@ -530,21 +518,19 @@ namespace Org.BouncyCastle.Pkix
 				//
 				// (d) (3)
 				//
-				for (int j = (i - 1); j >= 0; j--)
+				for (int j = i - 1; j >= 0; j--)
 				{
-					IList nodes = policyNodes[j];
+					var nodes = policyNodes[j];
 
 					for (int k = 0; k < nodes.Count; k++)
 					{
-						PkixPolicyNode node = (PkixPolicyNode)nodes[k];
+						var node = nodes[k];
 						if (!node.HasChildren)
 						{
-							_validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(_validPolicyTree, policyNodes,
-								node);
+							_validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(_validPolicyTree,
+								policyNodes, node);
 							if (_validPolicyTree == null)
-							{
 								break;
-							}
 						}
 					}
 				}
@@ -558,10 +544,8 @@ namespace Org.BouncyCastle.Pkix
 				{
 					bool critical = criticalExtensionOids.Contains(X509Extensions.CertificatePolicies.Id);
 
-					IList nodes = policyNodes[i];
-					for (int j = 0; j < nodes.Count; j++)
+					foreach (var node in policyNodes[i])
 					{
-						PkixPolicyNode node = (PkixPolicyNode)nodes[j];
 						node.IsCritical = critical;
 					}
 				}
@@ -730,10 +714,10 @@ namespace Org.BouncyCastle.Pkix
 			// (f)
 
 			// get issuer from CRL
-			X509CertStoreSelector selector = new X509CertStoreSelector();
+			X509CertStoreSelector certSelector = new X509CertStoreSelector();
 			try
 			{
-				selector.Subject = crl.IssuerDN;
+				certSelector.Subject = crl.IssuerDN;
 			}
 			catch (IOException e)
 			{
@@ -742,29 +726,25 @@ namespace Org.BouncyCastle.Pkix
 			}
 
 			// get CRL signing certs
-			IList coll = Platform.CreateArrayList();
+			var signingCerts = new HashSet<X509Certificate>();
 
 			try
 			{
-                CollectionUtilities.AddRange(coll, PkixCertPathValidatorUtilities.FindCertificates(selector, paramsPKIX.GetStores()));
-                CollectionUtilities.AddRange(coll, PkixCertPathValidatorUtilities.FindCertificates(selector, paramsPKIX.GetAdditionalStores()));
+				CollectionUtilities.CollectMatches(signingCerts, certSelector, paramsPKIX.GetStoresCert());
 			}
 			catch (Exception e)
 			{
 				throw new Exception("Issuer certificate for CRL cannot be searched.", e);
 			}
 
-			coll.Add(defaultCRLSignCert);
+			signingCerts.Add(defaultCRLSignCert);
 
-			IEnumerator cert_it = coll.GetEnumerator();
 
             IList validCerts = Platform.CreateArrayList();
             IList validKeys = Platform.CreateArrayList();
 
-			while (cert_it.MoveNext())
+			foreach (X509Certificate signingCert in signingCerts)
 			{
-				X509Certificate signingCert = (X509Certificate)cert_it.Current;
-
 				/*
 				 * CA of the certificate, for which this CRL is checked, has also
 				 * signed CRL, so skip the path validation, because is already done
@@ -777,16 +757,13 @@ namespace Org.BouncyCastle.Pkix
 				}
 				try
 				{
-//					CertPathBuilder builder = CertPathBuilder.GetInstance("PKIX");
 					PkixCertPathBuilder builder = new PkixCertPathBuilder();
-					selector = new X509CertStoreSelector();
-					selector.Certificate = signingCert;
 
-					PkixParameters temp = (PkixParameters)paramsPKIX.Clone();
-					temp.SetTargetCertConstraints(selector);
+					certSelector = new X509CertStoreSelector();
+					certSelector.Certificate = signingCert;
 
-					PkixBuilderParameters parameters = (PkixBuilderParameters)
-						PkixBuilderParameters.GetInstance(temp);
+					PkixBuilderParameters parameters = PkixBuilderParameters.GetInstance(paramsPKIX);
+					parameters.SetTargetConstraintsCert(certSelector);
 
 					/*
 					 * if signingCert is placed not higher on the cert path a
@@ -817,10 +794,6 @@ namespace Org.BouncyCastle.Pkix
                 {
                     throw new Exception("Public key of issuer certificate of CRL could not be retrieved.", e);
                 }
-                //catch (Exception e)
-                //{
-                //    throw new Exception(e.Message);
-                //}
 			}
 
 			ISet checkKeys = new HashSet();
@@ -874,9 +847,7 @@ namespace Org.BouncyCastle.Pkix
 			throw new Exception("Cannot verify CRL.", lastException);
 		}
 
-		internal static X509Crl ProcessCrlH(
-			ISet					deltaCrls,
-			AsymmetricKeyParameter	key)
+		internal static X509Crl ProcessCrlH(ISet<X509Crl> deltaCrls, AsymmetricKeyParameter key)
 		{
 			Exception lastException = null;
 			foreach (X509Crl crl in deltaCrls)
@@ -943,7 +914,7 @@ namespace Org.BouncyCastle.Pkix
 			 * getAdditionalStore()
 			 */
 
-			ISet crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, cert, currentDate, paramsPKIX);
+			ISet<X509Crl> crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, cert, currentDate, paramsPKIX);
 			bool validCrlFound = false;
 			Exception lastException = null;
 
@@ -980,7 +951,7 @@ namespace Org.BouncyCastle.Pkix
 					if (paramsPKIX.IsUseDeltasEnabled)
 					{
 						// get delta CRLs
-						ISet deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl);
+						ISet<X509Crl> deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl);
 						// we only want one valid delta CRL
 						// (h)
 						deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, key);
@@ -1087,7 +1058,7 @@ namespace Org.BouncyCastle.Pkix
 		 * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
 		 *                            or some error occurs.
 		 */
-		protected static void CheckCrls(
+		internal static void CheckCrls(
 			PkixParameters			paramsPKIX,
 			X509Certificate			cert,
 			DateTime				validDate,
@@ -1096,7 +1067,7 @@ namespace Org.BouncyCastle.Pkix
 			IList					certPathCerts)
 		{
 			Exception lastException = null;
-			CrlDistPoint crldp = null;
+			CrlDistPoint crldp;
 
 			try
 			{
@@ -1215,13 +1186,9 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
-		internal static PkixPolicyNode PrepareCertB(
-			PkixCertPath	certPath,
-			int				index,
-			IList[]			policyNodes,
-			PkixPolicyNode	validPolicyTree,
-			int				policyMapping)
-			//throws CertPathValidatorException
+		/// <exception cref="PkixCertPathValidatorException"/>
+		internal static PkixPolicyNode PrepareCertB(PkixCertPath certPath, int index,
+			IList<PkixPolicyNode>[] policyNodes, PkixPolicyNode validPolicyTree, int policyMapping)
 		{
 			IList certs = certPath.Certificates;
 			X509Certificate cert = (X509Certificate)certs[index];
@@ -1233,7 +1200,8 @@ namespace Org.BouncyCastle.Pkix
 			Asn1Sequence pm = null;
 			try
 			{
-				pm = (Asn1Sequence)Asn1Sequence.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyMappings));
+				pm = Asn1Sequence.GetInstance(
+					PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyMappings));
 			}
 			catch (Exception ex)
 			{
@@ -1279,11 +1247,9 @@ namespace Org.BouncyCastle.Pkix
 					if (policyMapping > 0)
 					{
 						bool idp_found = false;
-						IEnumerator nodes_i = policyNodes[i].GetEnumerator();
 
-						while (nodes_i.MoveNext())
+						foreach (PkixPolicyNode node in policyNodes[i])
 						{
-							PkixPolicyNode node = (PkixPolicyNode)nodes_i.Current;
 							if (node.ValidPolicy.Equals(id_p))
 							{
 								idp_found = true;
@@ -1294,11 +1260,9 @@ namespace Org.BouncyCastle.Pkix
 
 						if (!idp_found)
 						{
-							nodes_i = policyNodes[i].GetEnumerator();
-							while (nodes_i.MoveNext())
+							foreach (PkixPolicyNode node in policyNodes[i])
 							{
-								PkixPolicyNode node = (PkixPolicyNode)nodes_i.Current;
-								if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(node.ValidPolicy))
+								if (ANY_POLICY.Equals(node.ValidPolicy))
 								{
 									ISet pq = null;
 									Asn1Sequence policies = null;
@@ -1325,7 +1289,7 @@ namespace Org.BouncyCastle.Pkix
 											throw new PkixCertPathValidatorException(
 												"Policy information could not be decoded.", ex, index);
 										}
-										if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(pinfo.PolicyIdentifier.Id))
+										if (ANY_POLICY.Equals(pinfo.PolicyIdentifier.Id))
 										{
 											try
 											{
@@ -1347,10 +1311,10 @@ namespace Org.BouncyCastle.Pkix
 										ci = critExtOids.Contains(X509Extensions.CertificatePolicies.Id);
 									}
 
-									PkixPolicyNode p_node = (PkixPolicyNode)node.Parent;
-									if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(p_node.ValidPolicy))
+									PkixPolicyNode p_node = node.Parent;
+									if (ANY_POLICY.Equals(p_node.ValidPolicy))
 									{
-										PkixPolicyNode c_node = new PkixPolicyNode(Platform.CreateArrayList(), i,
+										var c_node = new PkixPolicyNode(new List<PkixPolicyNode>(), i,
 											(ISet)m_idp[id_p], p_node, pq, id_p, ci);
 										p_node.AddChild(c_node);
 										policyNodes[i].Add(c_node);
@@ -1366,7 +1330,7 @@ namespace Org.BouncyCastle.Pkix
 					}
 					else if (policyMapping <= 0)
 					{
-                        foreach (PkixPolicyNode node in Platform.CreateArrayList(policyNodes[i]))
+                        foreach (var node in new List<PkixPolicyNode>(policyNodes[i]))
                         {
 							if (node.ValidPolicy.Equals(id_p))
 							{
@@ -1374,7 +1338,7 @@ namespace Org.BouncyCastle.Pkix
 
                                 for (int k = i - 1; k >= 0; k--)
 								{
-                                    foreach (PkixPolicyNode node2 in Platform.CreateArrayList(policyNodes[k]))
+                                    foreach (var node2 in new List<PkixPolicyNode>(policyNodes[k]))
 									{
 										if (!node2.HasChildren)
 										{
@@ -1394,13 +1358,12 @@ namespace Org.BouncyCastle.Pkix
 			return _validPolicyTree;
 		}
 
-		internal static ISet[] ProcessCrlA1ii(
+		internal static ISet<X509Crl>[] ProcessCrlA1ii(
 			DateTime		currentDate,
 			PkixParameters	paramsPKIX,
 			X509Certificate	cert,
 			X509Crl			crl)
 		{
-			ISet deltaSet = new HashSet();
 			X509CrlStoreSelector crlselect = new X509CrlStoreSelector();
 			crlselect.CertificateChecking = cert;
 
@@ -1416,14 +1379,15 @@ namespace Org.BouncyCastle.Pkix
 			}
 
 			crlselect.CompleteCrlEnabled = true;
-			ISet completeSet = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate);
+			ISet<X509Crl> completeSet = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate);
+			var deltaSet = new HashSet<X509Crl>();
 
 			if (paramsPKIX.IsUseDeltasEnabled)
 			{
 				// get delta CRL(s)
 				try
 				{
-					deltaSet.AddAll(PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl));
+					deltaSet.UnionWith(PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl));
 				}
 				catch (Exception e)
 				{
@@ -1431,7 +1395,7 @@ namespace Org.BouncyCastle.Pkix
 				}
 			}
 
-			return new ISet[]{ completeSet, deltaSet };
+			return new []{ completeSet, deltaSet };
 		}
 
 		internal static ISet ProcessCrlA1i(
@@ -2101,14 +2065,9 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
-		internal static PkixPolicyNode WrapupCertG(
-			PkixCertPath	certPath,
-			PkixParameters	paramsPKIX,
-			ISet			userInitialPolicySet,
-			int				index,
-			IList[]			policyNodes,
-			PkixPolicyNode	validPolicyTree,
-			ISet			acceptablePolicies)
+		internal static PkixPolicyNode WrapupCertG(PkixCertPath certPath, PkixParameters paramsPKIX,
+			ISet userInitialPolicySet, int index, IList<PkixPolicyNode>[] policyNodes, PkixPolicyNode validPolicyTree,
+			ISet acceptablePolicies)
 		{
 			int n = certPath.Certificates.Count;
 
@@ -2140,19 +2099,15 @@ namespace Org.BouncyCastle.Pkix
 					}
 					else
 					{
-						ISet _validPolicyNodeSet = new HashSet();
+						var _validPolicyNodeSet = new HashSet<PkixPolicyNode>();
 
-						for (int j = 0; j < policyNodes.Length; j++)
+						foreach (var _nodeDepth in policyNodes)
 						{
-							IList _nodeDepth = policyNodes[j];
-
-							for (int k = 0; k < _nodeDepth.Count; k++)
-							{
-								PkixPolicyNode _node = (PkixPolicyNode)_nodeDepth[k];
-
-								if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(_node.ValidPolicy))
+                            foreach (var _node in _nodeDepth)
+                            {
+								if (ANY_POLICY.Equals(_node.ValidPolicy))
 								{
-									foreach (object o in _node.Children)
+									foreach (var o in _node.Children)
 									{
 										_validPolicyNodeSet.Add(o);
 									}
@@ -2160,11 +2115,9 @@ namespace Org.BouncyCastle.Pkix
 							}
 						}
 
-						foreach (PkixPolicyNode _node in _validPolicyNodeSet)
+						foreach (var _node in _validPolicyNodeSet)
 						{
-							string _validPolicy = _node.ValidPolicy;
-
-							if (!acceptablePolicies.Contains(_validPolicy))
+							if (!acceptablePolicies.Contains(_node.ValidPolicy))
 							{
 								// TODO?
 								// validPolicyTree =
@@ -2174,17 +2127,17 @@ namespace Org.BouncyCastle.Pkix
 						}
 						if (validPolicyTree != null)
 						{
-							for (int j = (n - 1); j >= 0; j--)
+							for (int j = n - 1; j >= 0; j--)
 							{
-								IList nodes = policyNodes[j];
+								var nodes = policyNodes[j];
 
 								for (int k = 0; k < nodes.Count; k++)
 								{
-									PkixPolicyNode node = (PkixPolicyNode)nodes[k];
+									var node = nodes[k];
 									if (!node.HasChildren)
 									{
-										validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree,
-											policyNodes, node);
+										validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(
+											validPolicyTree, policyNodes, node);
 									}
 								}
 							}
@@ -2209,21 +2162,17 @@ namespace Org.BouncyCastle.Pkix
 				//
 				// (g) (iii) 1
 				//
-				ISet _validPolicyNodeSet = new HashSet();
+				var _validPolicyNodeSet = new HashSet<PkixPolicyNode>();
 
-				for (int j = 0; j < policyNodes.Length; j++)
+				foreach (var _nodeDepth in policyNodes)
 				{
-					IList _nodeDepth = policyNodes[j];
-
-					for (int k = 0; k < _nodeDepth.Count; k++)
+					foreach (var _node in _nodeDepth)
 					{
-						PkixPolicyNode _node = (PkixPolicyNode)_nodeDepth[k];
-
-						if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(_node.ValidPolicy))
+						if (ANY_POLICY.Equals(_node.ValidPolicy))
 						{
 							foreach (PkixPolicyNode _c_node in _node.Children)
 							{
-								if (!Rfc3280CertPathUtilities.ANY_POLICY.Equals(_c_node.ValidPolicy))
+								if (!ANY_POLICY.Equals(_c_node.ValidPolicy))
 								{
 									_validPolicyNodeSet.Add(_c_node);
 								}
@@ -2235,15 +2184,12 @@ namespace Org.BouncyCastle.Pkix
 				//
 				// (g) (iii) 2
 				//
-				IEnumerator _vpnsIter = _validPolicyNodeSet.GetEnumerator();
-				while (_vpnsIter.MoveNext())
+				foreach (var _node in _validPolicyNodeSet)
 				{
-					PkixPolicyNode _node = (PkixPolicyNode)_vpnsIter.Current;
-					string _validPolicy = _node.ValidPolicy;
-
-					if (!userInitialPolicySet.Contains(_validPolicy))
+					if (!userInitialPolicySet.Contains(_node.ValidPolicy))
 					{
-						validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, policyNodes, _node);
+						validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, policyNodes,
+							_node);
 					}
 				}
 
@@ -2252,17 +2198,17 @@ namespace Org.BouncyCastle.Pkix
 				//
 				if (validPolicyTree != null)
 				{
-					for (int j = (n - 1); j >= 0; j--)
+					for (int j = n - 1; j >= 0; j--)
 					{
-						IList nodes = policyNodes[j];
+						var nodes = policyNodes[j];
 
 						for (int k = 0; k < nodes.Count; k++)
 						{
-							PkixPolicyNode node = (PkixPolicyNode)nodes[k];
+							var node = nodes[k];
 							if (!node.HasChildren)
 							{
-								validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, policyNodes,
-									node);
+								validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree,
+									policyNodes, node);
 							}
 						}
 					}
diff --git a/crypto/src/pkix/Rfc3281CertPathUtilities.cs b/crypto/src/pkix/Rfc3281CertPathUtilities.cs
index 66025f0fc..2e1ee3898 100644
--- a/crypto/src/pkix/Rfc3281CertPathUtilities.cs
+++ b/crypto/src/pkix/Rfc3281CertPathUtilities.cs
@@ -1,9 +1,7 @@
 using System;
 using System.Collections;
-using System.Globalization;
-using System.IO;
+using System.Collections.Generic;
 
-using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Security.Certificates;
@@ -13,10 +11,10 @@ using Org.BouncyCastle.X509.Store;
 
 namespace Org.BouncyCastle.Pkix
 {
-	internal class Rfc3281CertPathUtilities
+	internal static class Rfc3281CertPathUtilities
 	{
 		internal static void ProcessAttrCert7(
-			IX509AttributeCertificate	attrCert,
+			X509V2AttributeCertificate	attrCert,
 			PkixCertPath				certPath,
 			PkixCertPath				holderCertPath,
 			PkixParameters				pkixParams)
@@ -73,7 +71,7 @@ namespace Org.BouncyCastle.Pkix
 		*             status cannot be checked or some error occurs.
 		*/
 		internal static void CheckCrls(
-			IX509AttributeCertificate	attrCert,
+			X509V2AttributeCertificate  attrCert,
 			PkixParameters				paramsPKIX,
 			X509Certificate				issuerCert,
 			DateTime					validDate,
@@ -230,7 +228,7 @@ namespace Org.BouncyCastle.Pkix
 		}
 
 		internal static void AdditionalChecks(
-			IX509AttributeCertificate	attrCert,
+			X509V2AttributeCertificate  attrCert,
 			PkixParameters				pkixParams)
 		{
 			// 1
@@ -255,7 +253,7 @@ namespace Org.BouncyCastle.Pkix
 		}
 
 		internal static void ProcessAttrCert5(
-			IX509AttributeCertificate	attrCert,
+			X509V2AttributeCertificate  attrCert,
 			PkixParameters				pkixParams)
 		{
 			try
@@ -349,7 +347,7 @@ namespace Org.BouncyCastle.Pkix
 		*             </ul>
 		*/
 		internal static PkixCertPath ProcessAttrCert1(
-			IX509AttributeCertificate	attrCert,
+			X509V2AttributeCertificate  attrCert,
 			PkixParameters				pkixParams)
 		{
 			PkixCertPathBuilderResult result = null;
@@ -368,8 +366,8 @@ namespace Org.BouncyCastle.Pkix
 						{
 							selector.Issuer = principals[i];
 						}
-						holderPKCs.AddAll(PkixCertPathValidatorUtilities
-							.FindCertificates(selector, pkixParams.GetStores()));
+						holderPKCs.AddAll(
+							PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetStoresCert()));
 					}
 					catch (Exception e)
 					{
@@ -396,8 +394,8 @@ namespace Org.BouncyCastle.Pkix
 						{
 							selector.Issuer = principals[i];
 						}
-						holderPKCs.AddAll(PkixCertPathValidatorUtilities
-							.FindCertificates(selector, pkixParams.GetStores()));
+						holderPKCs.AddAll(
+							PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetStoresCert()));
 					}
 					catch (Exception e)
 					{
@@ -414,21 +412,21 @@ namespace Org.BouncyCastle.Pkix
 			}
 
 			// verify cert paths for PKCs
-			PkixBuilderParameters parameters = (PkixBuilderParameters)
-				PkixBuilderParameters.GetInstance(pkixParams);
+			PkixBuilderParameters parameters = PkixBuilderParameters.GetInstance(pkixParams);
 
 			PkixCertPathValidatorException lastException = null;
 			foreach (X509Certificate cert in holderPKCs)
 			{
-				X509CertStoreSelector selector = new X509CertStoreSelector();
-				selector.Certificate = cert;
-				parameters.SetTargetConstraints(selector);
+				X509CertStoreSelector certSelector = new X509CertStoreSelector();
+				certSelector.Certificate = cert;
+
+				parameters.SetTargetConstraintsCert(certSelector);
 
 				PkixCertPathBuilder builder = new PkixCertPathBuilder();
 
 				try
 				{
-					result = builder.Build(PkixBuilderParameters.GetInstance(parameters));
+					result = builder.Build(parameters);
 				}
 				catch (PkixCertPathBuilderException e)
 				{
@@ -463,7 +461,7 @@ namespace Org.BouncyCastle.Pkix
 		*/
 		private static void CheckCrl(
 			DistributionPoint			dp,
-			IX509AttributeCertificate	attrCert,
+			X509V2AttributeCertificate  attrCert,
 			PkixParameters				paramsPKIX,
 			DateTime					validDate,
 			X509Certificate				issuerCert,
@@ -496,8 +494,7 @@ namespace Org.BouncyCastle.Pkix
 			* CRLs must be enabled in the ExtendedPkixParameters and are in
 			* getAdditionalStore()
 			*/
-			ISet crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert,
-				currentDate, paramsPKIX);
+			ISet<X509Crl> crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert, currentDate, paramsPKIX);
 			bool validCrlFound = false;
 			Exception lastException = null;
 
@@ -536,7 +533,7 @@ namespace Org.BouncyCastle.Pkix
 					if (paramsPKIX.IsUseDeltasEnabled)
 					{
 						// get delta CRLs
-						ISet deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(
+						ISet<X509Crl> deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(
 							currentDate, paramsPKIX, crl);
 						// we only want one valid delta CRL
 						// (h)