summary refs log tree commit diff
path: root/crypto/src/pkix
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-06-27 17:09:32 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-06-27 17:09:32 +0700
commit12d3743c290abc58c509312b0ec46994a2811002 (patch)
tree8cf011f381b40602c48cf6f24a363d2f7c87d6ad /crypto/src/pkix
parentGenerics migration in Pkcs (diff)
downloadBouncyCastle.NET-ed25519-12d3743c290abc58c509312b0ec46994a2811002.tar.xz
Generics migration in Pkix
Diffstat (limited to 'crypto/src/pkix')
-rw-r--r--crypto/src/pkix/PkixAttrCertPathBuilder.cs24
-rw-r--r--crypto/src/pkix/PkixCertPath.cs148
-rw-r--r--crypto/src/pkix/PkixCertPathBuilder.cs39
-rw-r--r--crypto/src/pkix/PkixCertPathValidator.cs20
-rw-r--r--crypto/src/pkix/PkixCertPathValidatorUtilities.cs46
-rw-r--r--crypto/src/pkix/PkixNameConstraintValidator.cs581
-rw-r--r--crypto/src/pkix/PkixParameters.cs34
-rw-r--r--crypto/src/pkix/Rfc3280CertPathUtilities.cs273
-rw-r--r--crypto/src/pkix/Rfc3281CertPathUtilities.cs8
9 files changed, 488 insertions, 685 deletions
diff --git a/crypto/src/pkix/PkixAttrCertPathBuilder.cs b/crypto/src/pkix/PkixAttrCertPathBuilder.cs
index 6902d76d6..b10f64d6b 100644
--- a/crypto/src/pkix/PkixAttrCertPathBuilder.cs
+++ b/crypto/src/pkix/PkixAttrCertPathBuilder.cs
@@ -1,11 +1,8 @@
 using System;
-using System.Collections;
-using System.Collections.Generic
-	;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Security.Certificates;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.X509;
 using Org.BouncyCastle.X509.Store;
@@ -44,10 +41,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 
 			if (targets.Count == 0)
-			{
-				throw new PkixCertPathBuilderException(
-					"No attribute certificate found matching targetConstraints.");
-			}
+				throw new PkixCertPathBuilderException("No attribute certificate found matching targetConstraints.");
 
 			PkixCertPathBuilderResult result = null;
 
@@ -77,7 +71,7 @@ namespace Org.BouncyCastle.Pkix
 				if (issuers.Count < 1)
 					throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found.");
 
-                IList certPathList = Platform.CreateArrayList();
+                var certPathList = new List<X509Certificate>();
 
 				foreach (X509Certificate issuer in issuers)
 				{
@@ -92,17 +86,11 @@ namespace Org.BouncyCastle.Pkix
 			}
 
 			if (result == null && certPathException != null)
-			{
-				throw new PkixCertPathBuilderException(
-					"Possible certificate chain could not be validated.",
+				throw new PkixCertPathBuilderException("Possible certificate chain could not be validated.",
 					certPathException);
-			}
 
 			if (result == null && certPathException == null)
-			{
-				throw new PkixCertPathBuilderException(
-					"Unable to find certificate chain.");
-			}
+				throw new PkixCertPathBuilderException("Unable to find certificate chain.");
 
 			return result;
 		}
@@ -113,7 +101,7 @@ namespace Org.BouncyCastle.Pkix
 			X509V2AttributeCertificate  attrCert,
 			X509Certificate				tbvCert,
 			PkixBuilderParameters		pkixParams,
-			IList						tbvPath)
+			IList<X509Certificate>      tbvPath)
 		{
 			// If tbvCert is readily present in tbvPath, it indicates having run
 			// into a cycle in the
diff --git a/crypto/src/pkix/PkixCertPath.cs b/crypto/src/pkix/PkixCertPath.cs
index 213b12eb4..54a3c8f6a 100644
--- a/crypto/src/pkix/PkixCertPath.cs
+++ b/crypto/src/pkix/PkixCertPath.cs
@@ -1,13 +1,11 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
-using System.Text;
+using System.Linq;
 
 using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Asn1.Cms;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Asn1.Pkcs;
-using Org.BouncyCastle.Cms;
 using Org.BouncyCastle.X509;
 using Org.BouncyCastle.OpenSsl;
 using Org.BouncyCastle.Security.Certificates;
@@ -81,34 +79,25 @@ namespace Org.BouncyCastle.Pkix
 	public class PkixCertPath
 //		: CertPath
 	{
-		internal static readonly IList certPathEncodings;
+		internal static readonly List<string> m_encodings = new List<string>{ "PkiPath", "PEM", "PKCS7" };
 
-        static PkixCertPath()
-        {
-            IList encodings = Platform.CreateArrayList();
-            encodings.Add("PkiPath");
-            encodings.Add("PEM");
-            encodings.Add("PKCS7");
-            certPathEncodings = CollectionUtilities.ReadOnly(encodings);
-        }
+        private readonly IList<X509Certificate> m_certificates;
 
-        private readonly IList certificates;
-
-		private static IList SortCerts(IList certs)
+		private static IList<X509Certificate> SortCerts(IList<X509Certificate> certs)
 		{
 			if (certs.Count < 2)
 				return certs;
 
-			X509Name issuer = ((X509Certificate)certs[0]).IssuerDN;
+			X509Name issuer = certs[0].IssuerDN;
 			bool okay = true;
 
 			for (int i = 1; i != certs.Count; i++)
 			{
-				X509Certificate cert = (X509Certificate)certs[i];
+				X509Certificate cert = certs[i];
 
 				if (issuer.Equivalent(cert.SubjectDN, true))
 				{
-					issuer = ((X509Certificate)certs[i]).IssuerDN;
+					issuer = cert.IssuerDN;
 				}
 				else
 				{
@@ -121,13 +110,13 @@ namespace Org.BouncyCastle.Pkix
 				return certs;
 
 			// find end-entity cert
-            IList retList = Platform.CreateArrayList(certs.Count);
-            IList orig = Platform.CreateArrayList(certs);
+            var retList = new List<X509Certificate>(certs.Count);
+            var orig = new List<X509Certificate>(certs);
 
 			for (int i = 0; i < certs.Count; i++)
 			{
-				X509Certificate cert = (X509Certificate)certs[i];
-				bool           found = false;
+				X509Certificate cert = certs[i];
+				bool found = false;
 
 				X509Name subject = cert.SubjectDN;
 				foreach (X509Certificate c in certs)
@@ -152,11 +141,11 @@ namespace Org.BouncyCastle.Pkix
 
 			for (int i = 0; i != retList.Count; i++)
 			{
-				issuer = ((X509Certificate)retList[i]).IssuerDN;
+				issuer = retList[i].IssuerDN;
 
 				for (int j = 0; j < certs.Count; j++)
 				{
-					X509Certificate c = (X509Certificate)certs[j];
+					X509Certificate c = certs[j];
 					if (issuer.Equivalent(c.SubjectDN, true))
 					{
 						retList.Add(c);
@@ -179,15 +168,12 @@ namespace Org.BouncyCastle.Pkix
 		 * a CertificateFactory to create CertPaths.
 		 * @param type the standard name of the type of Certificatesin this path
 		 **/
-		public PkixCertPath(
-			ICollection certificates)
-//			: base("X.509")
+		public PkixCertPath(IList<X509Certificate> certificates)
 		{
-			this.certificates = SortCerts(Platform.CreateArrayList(certificates));
+			m_certificates = SortCerts(new List<X509Certificate>(certificates));
 		}
 
-		public PkixCertPath(
-			Stream inStream)
+		public PkixCertPath(Stream inStream)
 			: this(inStream, "PkiPath")
 		{
 		}
@@ -199,17 +185,14 @@ namespace Org.BouncyCastle.Pkix
 		 *
 		 * @param type the standard name of the type of Certificatesin this path
 		 **/
-		public PkixCertPath(
-			Stream	inStream,
-			string	encoding)
-//			: base("X.509")
+		public PkixCertPath(Stream inStream, string encoding)
 		{
-            string upper = Platform.ToUpperInvariant(encoding);
+            //string upper = Platform.ToUpperInvariant(encoding);
 
-            IList certs;
+            IList<X509Certificate> certs;
 			try
 			{
-				if (upper.Equals(Platform.ToUpperInvariant("PkiPath")))
+				if (Platform.EqualsIgnoreCase("PkiPath", encoding))
 				{
 					Asn1InputStream derInStream = new Asn1InputStream(inStream);
 					Asn1Object derObject = derInStream.ReadObject();
@@ -219,7 +202,7 @@ namespace Org.BouncyCastle.Pkix
 							"input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath");
 					}
 
-                    certs = Platform.CreateArrayList();
+					certs = new List<X509Certificate>();
 
                     foreach (Asn1Encodable ae in (Asn1Sequence)derObject)
                     {
@@ -230,9 +213,10 @@ namespace Org.BouncyCastle.Pkix
                         certs.Insert(0, new X509CertificateParser().ReadCertificate(certInStream));
 					}
 				}
-                else if (upper.Equals("PKCS7") || upper.Equals("PEM"))
+				else if (Platform.EqualsIgnoreCase("PEM", encoding) ||
+					     Platform.EqualsIgnoreCase("PKCS7", encoding))
 				{
-                    certs = Platform.CreateArrayList(new X509CertificateParser().ReadCertificates(inStream));
+                    certs = new X509CertificateParser().ReadCertificates(inStream);
 				}
 				else
 				{
@@ -246,7 +230,7 @@ namespace Org.BouncyCastle.Pkix
 					+ ex.ToString());
 			}
 
-			this.certificates = SortCerts(certs);
+			m_certificates = SortCerts(certs);
 		}
 
 		/**
@@ -257,9 +241,9 @@ namespace Org.BouncyCastle.Pkix
 		 *
 		 * @return an Iterator over the names of the supported encodings (as Strings)
 		 **/
-		public virtual IEnumerable Encodings
+		public virtual IEnumerable<string> Encodings
 		{
-            get { return new EnumerableProxy(certPathEncodings); }
+            get { return CollectionUtilities.Proxy(m_encodings); }
 		}
 
 		/**
@@ -279,36 +263,28 @@ namespace Org.BouncyCastle.Pkix
 		*
 		* @see Object#hashCode() Object.hashCode()
 		*/
-		public override bool Equals(
-			object obj)
+		public override bool Equals(object obj)
 		{
 			if (this == obj)
 				return true;
 
-			PkixCertPath other = obj as PkixCertPath;
-			if (other == null)
+			if (!(obj is PkixCertPath that))
 				return false;
 
-//			if (!this.Type.Equals(other.Type))
-//				return false;
-
-			//return this.Certificates.Equals(other.Certificates);
-
-			// TODO Extract this to a utility class
-			IList thisCerts = this.Certificates;
-			IList otherCerts = other.Certificates;
+			var thisCerts = this.Certificates;
+			var thatCerts = that.Certificates;
 
-			if (thisCerts.Count != otherCerts.Count)
+			if (thisCerts.Count != thatCerts.Count)
 				return false;
 
-			IEnumerator e1 = thisCerts.GetEnumerator();
-			IEnumerator e2 = otherCerts.GetEnumerator();
+			var e1 = thisCerts.GetEnumerator();
+			var e2 = thatCerts.GetEnumerator();
 
 			while (e1.MoveNext())
 			{
 				e2.MoveNext();
 
-				if (!Platform.Equals(e1.Current, e2.Current))
+				if (!Equals(e1.Current, e2.Current))
 					return false;
 			}
 
@@ -317,8 +293,7 @@ namespace Org.BouncyCastle.Pkix
 
 		public override int GetHashCode()
 		{
-			// FIXME?
-			return this.Certificates.GetHashCode();
+			return m_certificates.GetHashCode();
 		}
 
 		/**
@@ -330,14 +305,7 @@ namespace Org.BouncyCastle.Pkix
 		 **/
 		public virtual byte[] GetEncoded()
 		{
-			foreach (object enc in Encodings)
-			{
-				if (enc is string)
-				{
-					return GetEncoded((string)enc);
-				}
-			}
-			return null;
+			return GetEncoded(m_encodings[0]);
 		}
 
 		/**
@@ -350,32 +318,29 @@ namespace Org.BouncyCastle.Pkix
 		 * occurs or the encoding requested is not supported
 		 *
 		 */
-		public virtual byte[] GetEncoded(
-			string encoding)
+		public virtual byte[] GetEncoded(string encoding)
 		{
 			if (Platform.EqualsIgnoreCase(encoding, "PkiPath"))
 			{
-				Asn1EncodableVector v = new Asn1EncodableVector();
-
-				for (int i = certificates.Count - 1; i >= 0; i--)
+				Asn1EncodableVector v = new Asn1EncodableVector(m_certificates.Count);
+				for (int i = m_certificates.Count - 1; i >= 0; i--)
 				{
-					v.Add(ToAsn1Object((X509Certificate) certificates[i]));
+					v.Add(ToAsn1Object(m_certificates[i]));
 				}
 
 				return ToDerEncoded(new DerSequence(v));
 			}
             else if (Platform.EqualsIgnoreCase(encoding, "PKCS7"))
 			{
-				Asn1.Pkcs.ContentInfo encInfo = new Asn1.Pkcs.ContentInfo(
-					PkcsObjectIdentifiers.Data, null);
+				ContentInfo encInfo = new ContentInfo(PkcsObjectIdentifiers.Data, null);
 
-				Asn1EncodableVector v = new Asn1EncodableVector();
-				for (int i = 0; i != certificates.Count; i++)
-				{
-					v.Add(ToAsn1Object((X509Certificate)certificates[i]));
-				}
+				Asn1EncodableVector v = new Asn1EncodableVector(m_certificates.Count);
+				foreach (var cert in m_certificates)
+                {
+                    v.Add(ToAsn1Object(cert));
+                }
 
-				Asn1.Pkcs.SignedData sd = new Asn1.Pkcs.SignedData(
+                SignedData sd = new SignedData(
 					new DerInteger(1),
 					new DerSet(),
 					encInfo,
@@ -383,7 +348,7 @@ namespace Org.BouncyCastle.Pkix
 					null,
 					new DerSet());
 
-				return ToDerEncoded(new Asn1.Pkcs.ContentInfo(PkcsObjectIdentifiers.SignedData, sd));
+				return ToDerEncoded(new ContentInfo(PkcsObjectIdentifiers.SignedData, sd));
 			}
             else if (Platform.EqualsIgnoreCase(encoding, "PEM"))
 			{
@@ -392,9 +357,9 @@ namespace Org.BouncyCastle.Pkix
 
 				try
 				{
-					for (int i = 0; i != certificates.Count; i++)
+					foreach (var cert in m_certificates)
 					{
-						pWrt.WriteObject(certificates[i]);
+						pWrt.WriteObject(cert);
 					}
 
                     Platform.Dispose(pWrt.Writer);
@@ -416,9 +381,9 @@ namespace Org.BouncyCastle.Pkix
 		/// Returns the list of certificates in this certification
 		/// path.
 		/// </summary>
-		public virtual IList Certificates
+		public virtual IList<X509Certificate> Certificates
 		{
-            get { return CollectionUtilities.ReadOnly(certificates); }
+            get { return CollectionUtilities.ReadOnly(m_certificates); }
 		}
 
 		/**
@@ -428,12 +393,11 @@ namespace Org.BouncyCastle.Pkix
 		 *
 		 * @return the DERObject
 		 **/
-		private Asn1Object ToAsn1Object(
-			X509Certificate cert)
+		private Asn1Object ToAsn1Object(X509Certificate cert)
 		{
 			try
 			{
-				return Asn1Object.FromByteArray(cert.GetEncoded());
+				return cert.CertificateStructure.ToAsn1Object();
 			}
 			catch (Exception e)
 			{
diff --git a/crypto/src/pkix/PkixCertPathBuilder.cs b/crypto/src/pkix/PkixCertPathBuilder.cs
index 970fceb99..a0abcc888 100644
--- a/crypto/src/pkix/PkixCertPathBuilder.cs
+++ b/crypto/src/pkix/PkixCertPathBuilder.cs
@@ -1,9 +1,7 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using Org.BouncyCastle.Security.Certificates;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.X509;
 
@@ -15,7 +13,6 @@ namespace Org.BouncyCastle.Pkix
 	* @see CertPathBuilderSpi
 	*/
 	public class PkixCertPathBuilder
-		//		: CertPathBuilderSpi
 	{
 		/**
 		 * Build and validate a CertPath using the given parameter.
@@ -23,8 +20,7 @@ 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
 
@@ -45,7 +41,7 @@ namespace Org.BouncyCastle.Pkix
 				throw new PkixCertPathBuilderException("No certificate found matching targetConstraints.");
 
 			PkixCertPathBuilderResult result = null;
-			IList certPathList = Platform.CreateArrayList();
+			var certPathList = new List<X509Certificate>();
 
 			// check all potential target certificates
 			foreach (X509Certificate cert in targets)
@@ -57,14 +53,10 @@ namespace Org.BouncyCastle.Pkix
 			}
 
 			if (result == null && certPathException != null)
-			{
 				throw new PkixCertPathBuilderException(certPathException.Message, certPathException.InnerException);
-			}
 
 			if (result == null && certPathException == null)
-			{
 				throw new PkixCertPathBuilderException("Unable to find certificate chain.");
-			}
 
 			return result;
 		}
@@ -74,15 +66,13 @@ namespace Org.BouncyCastle.Pkix
 		protected virtual PkixCertPathBuilderResult Build(
 			X509Certificate			tbvCert,
 			PkixBuilderParameters	pkixParams,
-			IList					tbvPath)
+			IList<X509Certificate>	tbvPath)
 		{
-			// If tbvCert is readily present in tbvPath, it indicates having run
-			// into a cycle in the PKI graph.
+			// If tbvCert is already present in tbvPath, it indicates having run into a cycle in the PKI graph.
 			if (tbvPath.Contains(tbvCert))
 				return null;
 
-			// step out, the certificate is not allowed to appear in a certification
-			// chain.
+			// step out, the certificate is not allowed to appear in a certification chain.
 			if (pkixParams.GetExcludedCerts().Contains(tbvCert))
 				return null;
 
@@ -95,7 +85,6 @@ namespace Org.BouncyCastle.Pkix
 
 			tbvPath.Add(tbvCert);
 
-//			X509CertificateParser certParser = new X509CertificateParser();
 			PkixCertPathBuilderResult builderResult = null;
 			PkixCertPathValidator validator = new PkixCertPathValidator();
 
@@ -104,8 +93,7 @@ namespace Org.BouncyCastle.Pkix
 				// check whether the issuer of <tbvCert> is a TrustAnchor
 				if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()))
 				{
-					// exception message from possibly later tried certification
-					// chains
+					// exception message from possibly later tried certification chains
 					PkixCertPath certPath;
 					try
 					{
@@ -127,22 +115,19 @@ namespace Org.BouncyCastle.Pkix
 							"Certification path could not be validated.", e);
 					}
 
-					return new PkixCertPathBuilderResult(certPath, result.TrustAnchor,
-						result.PolicyTree, result.SubjectPublicKey);
+					return new PkixCertPathBuilderResult(certPath, result.TrustAnchor, result.PolicyTree,
+						result.SubjectPublicKey);
 				}
 				else
 				{
 					// add additional X.509 stores from locations in certificate
 					try
 					{
-						PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(
-							tbvCert, pkixParams);
+						PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams);
 					}
 					catch (CertificateParsingException e)
 					{
-						throw new Exception(
-							"No additiontal X.509 stores can be added from certificate locations.",
-							e);
+						throw new Exception("No additiontal X.509 stores can be added from certificate locations.", e);
 					}
 
 					// try to get the issuer certificate from one of the stores
@@ -153,9 +138,7 @@ namespace Org.BouncyCastle.Pkix
 					}
 					catch (Exception e)
 					{
-						throw new Exception(
-							"Cannot find issuer certificate for certificate in certification path.",
-							e);
+						throw new Exception("Cannot find issuer certificate for certificate in certification path.", e);
 					}
 
 					if (issuers.IsEmpty)
diff --git a/crypto/src/pkix/PkixCertPathValidator.cs b/crypto/src/pkix/PkixCertPathValidator.cs
index cebeed46f..6fe3fd903 100644
--- a/crypto/src/pkix/PkixCertPathValidator.cs
+++ b/crypto/src/pkix/PkixCertPathValidator.cs
@@ -1,12 +1,9 @@
 using System;
-using System.Collections;
 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;
 
 namespace Org.BouncyCastle.Pkix
@@ -39,15 +36,13 @@ namespace Org.BouncyCastle.Pkix
     /// </summary>
     public class PkixCertPathValidator
     {
-        public virtual PkixCertPathValidatorResult Validate(
-			PkixCertPath	certPath,
-			PkixParameters	paramsPkix)
+        public virtual PkixCertPathValidatorResult Validate(PkixCertPath certPath, PkixParameters paramsPkix)
         {
 			if (paramsPkix.GetTrustAnchors() == null)
             {
                 throw new ArgumentException(
 					"trustAnchors is null, this is not allowed for certification path validation.",
-					"parameters");
+                    nameof(paramsPkix));
             }
 
             //
@@ -57,10 +52,10 @@ namespace Org.BouncyCastle.Pkix
             //
             // (a)
             //
-            IList certs = certPath.Certificates;
+            var certs = certPath.Certificates;
             int n = certs.Count;
 
-            if (certs.Count == 0)
+            if (n == 0)
                 throw new PkixCertPathValidatorException("Certification path is empty.", null, 0);
 
 			//
@@ -79,9 +74,8 @@ namespace Org.BouncyCastle.Pkix
             TrustAnchor trust;
             try
             {
-                trust = PkixCertPathValidatorUtilities.FindTrustAnchor(
-					(X509Certificate)certs[certs.Count - 1],
-					paramsPkix.GetTrustAnchors());
+                trust = PkixCertPathValidatorUtilities.FindTrustAnchor(certs[certs.Count - 1],
+                    paramsPkix.GetTrustAnchors());
 
                 if (trust == null)
                     throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, -1);
@@ -227,7 +221,7 @@ namespace Org.BouncyCastle.Pkix
             //
             // initialize CertPathChecker's
             //
-            IList certPathCheckers = paramsPkix.GetCertPathCheckers();
+            var certPathCheckers = paramsPkix.GetCertPathCheckers();
             foreach (PkixCertPathChecker certPathChecker in certPathCheckers)
             {
                 certPathChecker.Init(false);
diff --git a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
index fc65b2535..a1e37f09d 100644
--- a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
+++ b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
@@ -153,25 +153,20 @@ namespace Org.BouncyCastle.Pkix
             }
         }
 
-		internal static void AddAdditionalStoresFromAltNames(
-			X509Certificate	cert,
-			PkixParameters	pkixParams)
+		internal static void AddAdditionalStoresFromAltNames(X509Certificate cert, PkixParameters pkixParams)
 		{
 			// if in the IssuerAltName extension an URI
 			// is given, add an additinal X.509 store
-			if (cert.GetIssuerAlternativeNames() != null)
+			var issuerAltNames = cert.GetIssuerAlternativeNames();
+			if (issuerAltNames != null)
 			{
-				IEnumerator it = cert.GetIssuerAlternativeNames().GetEnumerator();
-				while (it.MoveNext())
+				foreach (IList list in issuerAltNames)
 				{
 					// look for URI
-					IList list = (IList)it.Current;
-					//if (list[0].Equals(new Integer(GeneralName.UniformResourceIdentifier)))
-					if (list[0].Equals(GeneralName.UniformResourceIdentifier))
+					if (list.Count >= 2 && list[0].Equals(GeneralName.UniformResourceIdentifier))
 					{
-						// found
-						string temp = (string)list[1];
-						AddAdditionalStoreFromLocation(temp, pkixParams);
+						string location = (string)list[1];
+						AddAdditionalStoreFromLocation(location, pkixParams);
 					}
 				}
 			}
@@ -571,12 +566,9 @@ namespace Org.BouncyCastle.Pkix
 		*         <code>index</code> extended with DSA parameters if applicable.
 		* @throws Exception if DSA parameters cannot be inherited.
 		*/
-		internal static AsymmetricKeyParameter GetNextWorkingKey(
-			IList	certs,
-			int		index)
+		internal static AsymmetricKeyParameter GetNextWorkingKey(IList<X509Certificate> certs, int index)
 		{
-			//Only X509Certificate
-			X509Certificate cert = (X509Certificate)certs[index];
+			X509Certificate cert = certs[index];
 
 			AsymmetricKeyParameter pubKey = cert.GetPublicKey();
 
@@ -590,7 +582,7 @@ namespace Org.BouncyCastle.Pkix
 
 			for (int i = index + 1; i < certs.Count; i++)
 			{
-				X509Certificate parentCert = (X509Certificate)certs[i];
+				X509Certificate parentCert = certs[i];
 				pubKey = parentCert.GetPublicKey();
 
 				if (!(pubKey is DsaPublicKeyParameters))
@@ -636,14 +628,14 @@ namespace Org.BouncyCastle.Pkix
 				// else use time when previous cert was created
 			}
 
+			var cert = certPath.Certificates[index - 1];
+
 			if (index - 1 == 0)
 			{
-				DerGeneralizedTime dateOfCertgen = null;
+				DerGeneralizedTime dateOfCertgen;
 				try
 				{
-					X509Certificate cert = (X509Certificate)certPath.Certificates[index - 1];
-					Asn1OctetString extVal = cert.GetExtensionValue(
-						IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen);
+					Asn1OctetString extVal = cert.GetExtensionValue(IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen);
 					dateOfCertgen = DerGeneralizedTime.GetInstance(extVal);
 				}
 				catch (ArgumentException)
@@ -666,7 +658,7 @@ namespace Org.BouncyCastle.Pkix
 				}
 			}
 
-			return ((X509Certificate)certPath.Certificates[index - 1]).NotBefore;
+			return cert.NotBefore;
 		}
 
 		/**
@@ -695,7 +687,7 @@ namespace Org.BouncyCastle.Pkix
 			X509CrlStoreSelector	selector,
 			PkixParameters			pkixParams)
 		{
-            IList issuers = Platform.CreateArrayList();
+            var issuers = new List<X509Name>();
 			// indirect CRL
 			if (dp.CrlIssuer != null)
 			{
@@ -711,9 +703,7 @@ namespace Org.BouncyCastle.Pkix
 						}
 						catch (IOException e)
 						{
-							throw new Exception(
-								"CRL issuer information from distribution point cannot be decoded.",
-								e);
+							throw new Exception("CRL issuer information from distribution point cannot be decoded.", e);
 						}
 					}
 				}
@@ -856,7 +846,7 @@ namespace Org.BouncyCastle.Pkix
 			// 5.2.4 (a)
 			try
 			{
-                IList deltaSelectIssuer = Platform.CreateArrayList();
+				var deltaSelectIssuer = new List<X509Name>();
 				deltaSelectIssuer.Add(completeCRL.IssuerDN);
 				deltaSelect.Issuers = deltaSelectIssuer;
 			}
diff --git a/crypto/src/pkix/PkixNameConstraintValidator.cs b/crypto/src/pkix/PkixNameConstraintValidator.cs
index 28e8f36ba..e3e8c2fa0 100644
--- a/crypto/src/pkix/PkixNameConstraintValidator.cs
+++ b/crypto/src/pkix/PkixNameConstraintValidator.cs
@@ -1,46 +1,43 @@
 using System;
-using System.Collections;
-using System.IO;
+using System.Collections.Generic;
+using System.Text;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X500;
 using Org.BouncyCastle.Asn1.X500.Style;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Pkix
 {
     public class PkixNameConstraintValidator
     {
-        // TODO Implement X500Name and styles
-        //private static readonly DerObjectIdentifier SerialNumberOid = Rfc4519Style.SerialNumber;
-        private static readonly DerObjectIdentifier SerialNumberOid = new DerObjectIdentifier("2.5.4.5");
+        private static readonly DerObjectIdentifier SerialNumberOid = X509Name.SerialNumber;
 
-        private ISet excludedSubtreesDN = new HashSet();
+        private ISet<Asn1Sequence> excludedSubtreesDN = new HashSet<Asn1Sequence>();
 
-        private ISet excludedSubtreesDNS = new HashSet();
+        private ISet<string> excludedSubtreesDns = new HashSet<string>();
 
-        private ISet excludedSubtreesEmail = new HashSet();
+        private ISet<string> excludedSubtreesEmail = new HashSet<string>();
 
-        private ISet excludedSubtreesURI = new HashSet();
+        private ISet<string> excludedSubtreesUri = new HashSet<string>();
 
-        private ISet excludedSubtreesIP = new HashSet();
+        private ISet<byte[]> excludedSubtreesIP = new HashSet<byte[]>();
 
-        private ISet excludedSubtreesOtherName = new HashSet();
+        private ISet<OtherName> excludedSubtreesOtherName = new HashSet<OtherName>();
 
-        private ISet permittedSubtreesDN;
+        private ISet<Asn1Sequence> permittedSubtreesDN;
 
-        private ISet permittedSubtreesDNS;
+        private ISet<string> permittedSubtreesDns;
 
-        private ISet permittedSubtreesEmail;
+        private ISet<string> permittedSubtreesEmail;
 
-        private ISet permittedSubtreesURI;
+        private ISet<string> permittedSubtreesUri;
 
-        private ISet permittedSubtreesIP;
+        private ISet<byte[]> permittedSubtreesIP;
 
-        private ISet permittedSubtreesOtherName;
+        private ISet<OtherName> permittedSubtreesOtherName;
 
         public PkixNameConstraintValidator()
         {
@@ -107,9 +104,9 @@ namespace Org.BouncyCastle.Pkix
             CheckExcludedDirectory(excludedSubtreesDN, dn);
         }
 
-        private ISet IntersectDN(ISet permitted, ISet dns)
+        private ISet<Asn1Sequence> IntersectDN(ISet<Asn1Sequence> permitted, ISet<GeneralSubtree> dns)
         {
-            ISet intersect = new HashSet();
+            var intersect = new HashSet<Asn1Sequence>();
             foreach (GeneralSubtree subtree1 in dns)
             {
                 Asn1Sequence dn1 = Asn1Sequence.GetInstance(subtree1.Base.Name);
@@ -122,10 +119,8 @@ namespace Org.BouncyCastle.Pkix
                 }
                 else
                 {
-                    foreach (object obj2 in permitted)
+                    foreach (var dn2 in permitted)
                     {
-                        Asn1Sequence dn2 = Asn1Sequence.GetInstance(obj2);
-
                         if (WithinDNSubtree(dn1, dn2))
                         {
                             intersect.Add(dn1);
@@ -140,9 +135,9 @@ namespace Org.BouncyCastle.Pkix
             return intersect;
         }
 
-        private ISet UnionDN(ISet excluded, Asn1Sequence dn)
+        private ISet<Asn1Sequence> UnionDN(ISet<Asn1Sequence> excluded, Asn1Sequence dn)
         {
-            if (excluded.IsEmpty)
+            if (excluded.Count < 1)
             {
                 if (dn == null)
                     return excluded;
@@ -150,36 +145,32 @@ namespace Org.BouncyCastle.Pkix
                 excluded.Add(dn);
                 return excluded;
             }
-            else
-            {
-                ISet union = new HashSet();
 
-                foreach (object obj in excluded)
-                {
-                    Asn1Sequence subtree = Asn1Sequence.GetInstance(obj);
+            var union = new HashSet<Asn1Sequence>();
 
-                    if (WithinDNSubtree(dn, subtree))
-                    {
-                        union.Add(subtree);
-                    }
-                    else if (WithinDNSubtree(subtree, dn))
-                    {
-                        union.Add(dn);
-                    }
-                    else
-                    {
-                        union.Add(subtree);
-                        union.Add(dn);
-                    }
+            foreach (var subtree in excluded)
+            {
+                if (WithinDNSubtree(dn, subtree))
+                {
+                    union.Add(subtree);
+                }
+                else if (WithinDNSubtree(subtree, dn))
+                {
+                    union.Add(dn);
+                }
+                else
+                {
+                    union.Add(subtree);
+                    union.Add(dn);
                 }
-
-                return union;
             }
+
+            return union;
         }
 
-        private ISet IntersectOtherName(ISet permitted, ISet otherNames)
+        private ISet<OtherName> IntersectOtherName(ISet<OtherName> permitted, ISet<GeneralSubtree> otherNames)
         {
-            ISet intersect = new HashSet();
+            var intersect = new HashSet<OtherName>();
             foreach (GeneralSubtree subtree1 in otherNames)
             {
                 OtherName otherName1 = OtherName.GetInstance(subtree1.Base.Name);
@@ -192,12 +183,8 @@ namespace Org.BouncyCastle.Pkix
                 }
                 else
                 {
-                    foreach (object obj2 in permitted)
+                    foreach (OtherName otherName2 in permitted)
                     {
-                        OtherName otherName2 = OtherName.GetInstance(obj2);
-                        if (otherName2 == null)
-                            continue;
-
                         IntersectOtherName(otherName1, otherName2, intersect);
                     }
                 }
@@ -205,7 +192,7 @@ namespace Org.BouncyCastle.Pkix
             return intersect;
         }
 
-        private void IntersectOtherName(OtherName otherName1, OtherName otherName2, ISet intersect)
+        private void IntersectOtherName(OtherName otherName1, OtherName otherName2, ISet<OtherName> intersect)
         {
             if (otherName1.Equals(otherName2))
             {
@@ -213,16 +200,16 @@ namespace Org.BouncyCastle.Pkix
             }
         }
 
-        private ISet UnionOtherName(ISet permitted, OtherName otherName)
+        private ISet<OtherName> UnionOtherName(ISet<OtherName> permitted, OtherName otherName)
         {
-            ISet union = permitted != null ? new HashSet(permitted) : new HashSet();
+            var union = permitted != null ? new HashSet<OtherName>(permitted) : new HashSet<OtherName>();
             union.Add(otherName);
             return union;
         }
 
-        private ISet IntersectEmail(ISet permitted, ISet emails)
+        private ISet<string> IntersectEmail(ISet<string> permitted, ISet<GeneralSubtree> emails)
         {
-            ISet intersect = new HashSet();
+            var intersect = new HashSet<string>();
             foreach (GeneralSubtree subtree1 in emails)
             {
                 string email = ExtractNameAsString(subtree1.Base);
@@ -245,26 +232,23 @@ namespace Org.BouncyCastle.Pkix
             return intersect;
         }
 
-        private ISet UnionEmail(ISet excluded, string email)
+        private ISet<string> UnionEmail(ISet<string> excluded, string email)
         {
-            if (excluded.IsEmpty)
+            if (excluded.Count < 1)
             {
                 if (email == null)
-                {
                     return excluded;
-                }
+
                 excluded.Add(email);
                 return excluded;
             }
-            else
+
+            var union = new HashSet<string>();
+            foreach (string _excluded in excluded)
             {
-                ISet union = new HashSet();
-                foreach (string _excluded in excluded)
-                {
-                    UnionEmail(_excluded, email, union);
-                }
-                return union;
+                UnionEmail(_excluded, email, union);
             }
+            return union;
         }
 
         /**
@@ -277,9 +261,9 @@ namespace Org.BouncyCastle.Pkix
          * @return The <code>Set</code> of permitted IP ranges intersected with
          *         <code>ip</code>.
          */
-        private ISet IntersectIP(ISet permitted, ISet ips)
+        private ISet<byte[]> IntersectIP(ISet<byte[]> permitted, ISet<GeneralSubtree> ips)
         {
-            ISet intersect = new HashSet();
+            var intersect = new HashSet<byte[]>();
             foreach (GeneralSubtree subtree in ips)
             {
                 byte[] ip = Asn1OctetString.GetInstance(subtree.Base.Name).GetOctets();
@@ -294,7 +278,7 @@ namespace Org.BouncyCastle.Pkix
                 {
                     foreach (byte[] _permitted in permitted)
                     {
-                        intersect.AddAll(IntersectIPRange(_permitted, ip));
+                        intersect.UnionWith(IntersectIPRange(_permitted, ip));
                     }
                 }
             }
@@ -311,27 +295,23 @@ namespace Org.BouncyCastle.Pkix
          * @return The <code>Set</code> of excluded IP ranges unified with
          *         <code>ip</code> as byte arrays.
          */
-        private ISet UnionIP(ISet excluded, byte[] ip)
+        private ISet<byte[]> UnionIP(ISet<byte[]> excluded, byte[] ip)
         {
-            if (excluded.IsEmpty)
+            if (excluded.Count < 1)
             {
                 if (ip == null)
-                {
                     return excluded;
-                }
-                excluded.Add(ip);
 
+                excluded.Add(ip);
                 return excluded;
             }
-            else
+
+            var union = new HashSet<byte[]>();
+            foreach (byte[] _excluded in excluded)
             {
-                ISet union = new HashSet();
-                foreach (byte[] _excluded in excluded)
-                {
-                    union.AddAll(UnionIPRange(_excluded, ip));
-                }
-                return union;
+                union.UnionWith(UnionIPRange(_excluded, ip));
             }
+            return union;
         }
 
         /**
@@ -341,9 +321,9 @@ namespace Org.BouncyCastle.Pkix
          * @param ipWithSubmask2 The second IP address with its subnet mask.
          * @return A <code>Set</code> with the union of both addresses.
          */
-        private ISet UnionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
+        private ISet<byte[]> UnionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
         {
-            ISet set = new HashSet();
+            var set = new HashSet<byte[]>();
             // difficult, adding always all IPs is not wrong
             if (Arrays.AreEqual(ipWithSubmask1, ipWithSubmask2))
             {
@@ -365,12 +345,12 @@ namespace Org.BouncyCastle.Pkix
          * @return A <code>Set</code> with the single IP address with its subnet
          *         mask as a byte array or an empty <code>Set</code>.
          */
-        private ISet IntersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
+        private ISet<byte[]> IntersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
         {
             if (ipWithSubmask1.Length != ipWithSubmask2.Length)
             {
                 //Collections.EMPTY_SET;
-                return new HashSet();
+                return new HashSet<byte[]>();
             }
 
             byte[][] temp = ExtractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2);
@@ -389,14 +369,14 @@ namespace Org.BouncyCastle.Pkix
             if (CompareTo(min, max) == 1)
             {
                 //return Collections.EMPTY_SET;
-                return new HashSet();
+                return new HashSet<byte[]>();
             }
             // OR keeps all significant bits
             byte[] ip = Or(minMax[0], minMax[2]);
             byte[] subnetmask = Or(subnetmask1, subnetmask2);
 
-                //return new HashSet( ICollectionsingleton(IpWithSubnetMask(ip, subnetmask));
-            ISet hs = new HashSet();
+            //return new HashSet( ICollectionsingleton(IpWithSubnetMask(ip, subnetmask));
+            var hs = new HashSet<byte[]>();
             hs.Add(IpWithSubnetMask(ip, subnetmask));
 
             return hs;
@@ -486,12 +466,10 @@ namespace Org.BouncyCastle.Pkix
             return constraint.Equals(otherName);
         }
 
-        private bool IsOtherNameConstrained(ISet constraints, OtherName otherName)
+        private bool IsOtherNameConstrained(ISet<OtherName> constraints, OtherName otherName)
         {
-            foreach (object obj in constraints)
+            foreach (OtherName constraint in constraints)
             {
-                OtherName constraint = OtherName.GetInstance(obj);
-
                 if (IsOtherNameConstrained(constraint, otherName))
                     return true;
             }
@@ -499,22 +477,16 @@ namespace Org.BouncyCastle.Pkix
             return false;
         }
 
-        private void CheckPermittedOtherName(ISet permitted, OtherName name)
+        private void CheckPermittedOtherName(ISet<OtherName> permitted, OtherName name)
         {
             if (permitted != null && !IsOtherNameConstrained(permitted, name))
-            {
-                throw new PkixNameConstraintValidatorException(
-                    "Subject OtherName is not from a permitted subtree.");
-            }
+                throw new PkixNameConstraintValidatorException("Subject OtherName is not from a permitted subtree.");
         }
 
-        private void CheckExcludedOtherName(ISet excluded, OtherName name)
+        private void CheckExcludedOtherName(ISet<OtherName> excluded, OtherName name)
         {
             if (IsOtherNameConstrained(excluded, name))
-            {
-                throw new PkixNameConstraintValidatorException(
-                    "OtherName is from an excluded subtree.");
-            }
+                throw new PkixNameConstraintValidatorException("OtherName is from an excluded subtree.");
         }
 
         private bool IsEmailConstrained(string constraint, string email)
@@ -544,7 +516,7 @@ namespace Org.BouncyCastle.Pkix
             return false;
         }
 
-        private bool IsEmailConstrained(ISet constraints, string email)
+        private bool IsEmailConstrained(ISet<string> constraints, string email)
         {
             foreach (string constraint in constraints)
             {
@@ -555,10 +527,10 @@ namespace Org.BouncyCastle.Pkix
             return false;
         }
 
-        private void CheckPermittedEmail(ISet permitted, string email)
+        private void CheckPermittedEmail(ISet<string> permitted, string email)
         {
             if (permitted != null
-                && !(email.Length == 0 && permitted.IsEmpty)
+                && !(email.Length == 0 && permitted.Count < 1)
                 && !IsEmailConstrained(permitted, email))
             {
                 throw new PkixNameConstraintValidatorException(
@@ -566,13 +538,10 @@ namespace Org.BouncyCastle.Pkix
             }
         }
 
-        private void CheckExcludedEmail(ISet excluded, string email)
+        private void CheckExcludedEmail(ISet<string> excluded, string email)
         {
             if (IsEmailConstrained(excluded, email))
-            {
-                throw new PkixNameConstraintValidatorException(
-                    "Email address is from an excluded subtree.");
-            }
+                throw new PkixNameConstraintValidatorException("Email address is from an excluded subtree.");
         }
 
         private bool IsDnsConstrained(string constraint, string dns)
@@ -580,9 +549,9 @@ namespace Org.BouncyCastle.Pkix
             return WithinDomain(dns, constraint) || Platform.EqualsIgnoreCase(dns, constraint);
         }
 
-        private bool IsDnsConstrained(ISet constraints, string dns)
+        private bool IsDnsConstrained(ISet<string> constraints, string dns)
         {
-            foreach (string constraint in constraints)
+            foreach (var constraint in constraints)
             {
                 if (IsDnsConstrained(constraint, dns))
                     return true;
@@ -591,32 +560,26 @@ namespace Org.BouncyCastle.Pkix
             return false;
         }
 
-        private void CheckPermittedDns(ISet permitted, string dns)
+        private void CheckPermittedDns(ISet<string> permitted, string dns)
         {
             if (permitted != null
-                && !(dns.Length == 0 && permitted.IsEmpty)
+                && !(dns.Length == 0 && permitted.Count < 1)
                 && !IsDnsConstrained(permitted, dns))
             {
-                throw new PkixNameConstraintValidatorException(
-                    "DNS is not from a permitted subtree.");
+                throw new PkixNameConstraintValidatorException("DNS is not from a permitted subtree.");
             }
         }
 
-        private void CheckExcludedDns(ISet excluded, string dns)
+        private void CheckExcludedDns(ISet<string> excluded, string dns)
         {
             if (IsDnsConstrained(excluded, dns))
-            {
-                throw new PkixNameConstraintValidatorException(
-                    "DNS is from an excluded subtree.");
-            }
+                throw new PkixNameConstraintValidatorException("DNS is from an excluded subtree.");
         }
 
-        private bool IsDirectoryConstrained(ISet constraints, Asn1Sequence directory)
+        private bool IsDirectoryConstrained(ISet<Asn1Sequence> constraints, Asn1Sequence directory)
         {
-            foreach (object obj in constraints)
+            foreach (var constraint in constraints)
             {
-                Asn1Sequence constraint = Asn1Sequence.GetInstance(obj);
-
                 if (WithinDNSubtree(directory, constraint))
                     return true;
             }
@@ -624,10 +587,10 @@ namespace Org.BouncyCastle.Pkix
             return false;
         }
 
-        private void CheckPermittedDirectory(ISet permitted, Asn1Sequence directory)
+        private void CheckPermittedDirectory(ISet<Asn1Sequence> permitted, Asn1Sequence directory)
         {
             if (permitted != null
-                && !(directory.Count == 0 && permitted.IsEmpty)
+                && !(directory.Count == 0 && permitted.Count < 1)
                 && !IsDirectoryConstrained(permitted, directory))
             {
                 throw new PkixNameConstraintValidatorException(
@@ -635,7 +598,7 @@ namespace Org.BouncyCastle.Pkix
             }
         }
 
-        private void CheckExcludedDirectory(ISet excluded, Asn1Sequence directory)
+        private void CheckExcludedDirectory(ISet<Asn1Sequence> excluded, Asn1Sequence directory)
         {
             if (IsDirectoryConstrained(excluded, directory))
             {
@@ -658,7 +621,7 @@ namespace Org.BouncyCastle.Pkix
             return Platform.EqualsIgnoreCase(host, constraint);
         }
 
-        private bool IsUriConstrained(ISet constraints, string uri)
+        private bool IsUriConstrained(ISet<string> constraints, string uri)
         {
             foreach (string constraint in constraints)
             {
@@ -669,24 +632,20 @@ namespace Org.BouncyCastle.Pkix
             return false;
         }
 
-        private void CheckPermittedUri(ISet permitted, string uri)
+        private void CheckPermittedUri(ISet<string> permitted, string uri)
         {
             if (permitted != null
-                && !(uri.Length == 0 && permitted.IsEmpty)
+                && !(uri.Length == 0 && permitted.Count < 1)
                 && !IsUriConstrained(permitted, uri))
             {
-                throw new PkixNameConstraintValidatorException(
-                    "URI is not from a permitted subtree.");
+                throw new PkixNameConstraintValidatorException("URI is not from a permitted subtree.");
             }
         }
 
-        private void CheckExcludedUri(ISet excluded, string uri)
+        private void CheckExcludedUri(ISet<string> excluded, string uri)
         {
             if (IsUriConstrained(excluded, uri))
-            {
-                throw new PkixNameConstraintValidatorException(
-                    "URI is from an excluded subtree.");
-            }
+                throw new PkixNameConstraintValidatorException("URI is from an excluded subtree.");
         }
 
         /**
@@ -703,9 +662,7 @@ namespace Org.BouncyCastle.Pkix
         {
             int ipLength = ip.Length;
             if (ipLength != (constraint.Length / 2))
-            {
                 return false;
-            }
 
             byte[] subnetMask = new byte[ipLength];
             Array.Copy(constraint, ipLength, subnetMask, 0, ipLength);
@@ -724,7 +681,7 @@ namespace Org.BouncyCastle.Pkix
             return Arrays.AreEqual(permittedSubnetAddress, ipSubnetAddress);
         }
 
-        private bool IsIPConstrained(ISet constraints, byte[] ip)
+        private bool IsIPConstrained(ISet<byte[]> constraints, byte[] ip)
         {
             foreach (byte[] constraint in constraints)
             {
@@ -745,14 +702,13 @@ namespace Org.BouncyCastle.Pkix
          * @throws PkixNameConstraintValidatorException
          *          if the IP is not permitted.
          */
-        private void CheckPermittedIP(ISet permitted, byte[] ip)
+        private void CheckPermittedIP(ISet<byte[]> permitted, byte[] ip)
         {
             if (permitted != null
-                && !(ip.Length == 0 && permitted.IsEmpty)
+                && !(ip.Length == 0 && permitted.Count < 1)
                 && !IsIPConstrained(permitted, ip))
             {
-                throw new PkixNameConstraintValidatorException(
-                    "IP is not from a permitted subtree.");
+                throw new PkixNameConstraintValidatorException("IP is not from a permitted subtree.");
             }
         }
 
@@ -766,13 +722,10 @@ namespace Org.BouncyCastle.Pkix
          * @throws PkixNameConstraintValidatorException
          *          if the IP is excluded.
          */
-        private void CheckExcludedIP(ISet excluded, byte[] ip)
+        private void CheckExcludedIP(ISet<byte[]> excluded, byte[] ip)
         {
             if (IsIPConstrained(excluded, ip))
-            {
-                throw new PkixNameConstraintValidatorException(
-                    "IP is from an excluded subtree.");
-            }
+                throw new PkixNameConstraintValidatorException("IP is from an excluded subtree.");
         }
 
         private bool WithinDomain(string testDomain, string domain)
@@ -817,7 +770,7 @@ namespace Org.BouncyCastle.Pkix
          * @param email2 Email address constraint 2.
          * @param union  The union.
          */
-        private void UnionEmail(string email1, string email2, ISet union)
+        private void UnionEmail(string email1, string email2, ISet<string> union)
         {
             // email1 is a particular address
             if (email1.IndexOf('@') != -1)
@@ -954,7 +907,7 @@ namespace Org.BouncyCastle.Pkix
             }
         }
 
-        private void unionURI(string email1, string email2, ISet union)
+        private void UnionUri(string email1, string email2, ISet<string> union)
         {
             // email1 is a particular address
             if (email1.IndexOf('@') != -1)
@@ -1092,9 +1045,9 @@ namespace Org.BouncyCastle.Pkix
             }
         }
 
-        private ISet IntersectDns(ISet permitted, ISet dnss)
+        private ISet<string> IntersectDns(ISet<string> permitted, ISet<GeneralSubtree> dnss)
         {
-            ISet intersect = new HashSet();
+            var intersect = new HashSet<string>();
             foreach (GeneralSubtree subtree in dnss)
             {
                 string dns = ExtractNameAsString(subtree.Base);
@@ -1120,13 +1073,12 @@ namespace Org.BouncyCastle.Pkix
                     }
                 }
             }
-
             return intersect;
         }
 
-        private ISet UnionDns(ISet excluded, string dns)
+        private ISet<string> UnionDns(ISet<string> excluded, string dns)
         {
-            if (excluded.IsEmpty)
+            if (excluded.Count < 1)
             {
                 if (dns == null)
                     return excluded;
@@ -1134,27 +1086,25 @@ namespace Org.BouncyCastle.Pkix
                 excluded.Add(dns);
                 return excluded;
             }
-            else
+
+            var union = new HashSet<string>();
+            foreach (string _excluded in excluded)
             {
-                ISet union = new HashSet();
-                foreach (string _excluded in excluded)
+                if (WithinDomain(_excluded, dns))
                 {
-                    if (WithinDomain(_excluded, dns))
-                    {
-                        union.Add(dns);
-                    }
-                    else if (WithinDomain(dns, _excluded))
-                    {
-                        union.Add(_excluded);
-                    }
-                    else
-                    {
-                        union.Add(_excluded);
-                        union.Add(dns);
-                    }
+                    union.Add(dns);
+                }
+                else if (WithinDomain(dns, _excluded))
+                {
+                    union.Add(_excluded);
+                }
+                else
+                {
+                    union.Add(_excluded);
+                    union.Add(dns);
                 }
-                return union;
             }
+            return union;
         }
 
         /**
@@ -1165,7 +1115,7 @@ namespace Org.BouncyCastle.Pkix
          * @param email2    Email address constraint 2.
          * @param intersect The intersection.
          */
-        private void IntersectEmail(string email1, string email2, ISet intersect)
+        private void IntersectEmail(string email1, string email2, ISet<string> intersect)
         {
             // email1 is a particular address
             if (email1.IndexOf('@') != -1)
@@ -1257,9 +1207,9 @@ namespace Org.BouncyCastle.Pkix
             }
         }
 
-        private ISet IntersectUri(ISet permitted, ISet uris)
+        private ISet<string> IntersectUri(ISet<string> permitted, ISet<GeneralSubtree> uris)
         {
-            ISet intersect = new HashSet();
+            var intersect = new HashSet<string>();
             foreach (GeneralSubtree subtree in uris)
             {
                 string uri = ExtractNameAsString(subtree.Base);
@@ -1281,9 +1231,9 @@ namespace Org.BouncyCastle.Pkix
             return intersect;
         }
 
-        private ISet UnionUri(ISet excluded, string uri)
+        private ISet<string> UnionUri(ISet<string> excluded, string uri)
         {
-            if (excluded.IsEmpty)
+            if (excluded.Count < 1)
             {
                 if (uri == null)
                     return excluded;
@@ -1291,18 +1241,16 @@ namespace Org.BouncyCastle.Pkix
                 excluded.Add(uri);
                 return excluded;
             }
-            else
+
+            var union = new HashSet<string>();
+            foreach (string _excluded in excluded)
             {
-                ISet union = new HashSet();
-                foreach (string _excluded in excluded)
-                {
-                    unionURI(_excluded, uri, union);
-                }
-                return union;
+                UnionUri(_excluded, uri, union);
             }
+            return union;
         }
 
-        private void IntersectUri(string email1, string email2, ISet intersect)
+        private void IntersectUri(string email1, string email2, ISet<string> intersect)
         {
             // email1 is a particular address
             if (email1.IndexOf('@') != -1)
@@ -1440,13 +1388,13 @@ namespace Org.BouncyCastle.Pkix
                 CheckPermittedEmail(permittedSubtreesEmail, ExtractNameAsString(name));
                 break;
             case GeneralName.DnsName:
-                CheckPermittedDns(permittedSubtreesDNS, ExtractNameAsString(name));
+                CheckPermittedDns(permittedSubtreesDns, ExtractNameAsString(name));
                 break;
             case GeneralName.DirectoryName:
                 CheckPermittedDN(Asn1Sequence.GetInstance(name.Name.ToAsn1Object()));
                 break;
             case GeneralName.UniformResourceIdentifier:
-                CheckPermittedUri(permittedSubtreesURI, ExtractNameAsString(name));
+                CheckPermittedUri(permittedSubtreesUri, ExtractNameAsString(name));
                 break;
             case GeneralName.IPAddress:
                 CheckPermittedIP(permittedSubtreesIP, Asn1OctetString.GetInstance(name.Name).GetOctets());
@@ -1474,13 +1422,13 @@ namespace Org.BouncyCastle.Pkix
                 CheckExcludedEmail(excludedSubtreesEmail, ExtractNameAsString(name));
                 break;
             case GeneralName.DnsName:
-                CheckExcludedDns(excludedSubtreesDNS, ExtractNameAsString(name));
+                CheckExcludedDns(excludedSubtreesDns, ExtractNameAsString(name));
                 break;
             case GeneralName.DirectoryName:
                 CheckExcludedDN(Asn1Sequence.GetInstance(name.Name.ToAsn1Object()));
                 break;
             case GeneralName.UniformResourceIdentifier:
-                CheckExcludedUri(excludedSubtreesURI, ExtractNameAsString(name));
+                CheckExcludedUri(excludedSubtreesUri, ExtractNameAsString(name));
                 break;
             case GeneralName.IPAddress:
                 CheckExcludedIP(excludedSubtreesIP, Asn1OctetString.GetInstance(name.Name).GetOctets());
@@ -1497,50 +1445,47 @@ namespace Org.BouncyCastle.Pkix
 
         public void IntersectPermittedSubtree(Asn1Sequence permitted)
         {
-            IDictionary subtreesMap = Platform.CreateHashtable();
+            var subtreesMap = new Dictionary<int, ISet<GeneralSubtree>>();
 
             // group in ISets in a map ordered by tag no.
-            foreach (object obj in permitted)
+            foreach (var element in permitted)
             {
-                GeneralSubtree subtree = GeneralSubtree.GetInstance(obj);
+                GeneralSubtree subtree = GeneralSubtree.GetInstance(element);
 
                 int tagNo = subtree.Base.TagNo;
-                if (subtreesMap[tagNo] == null)
+
+                ISet<GeneralSubtree> subtrees;
+                if (!subtreesMap.TryGetValue(tagNo, out subtrees))
                 {
-                    subtreesMap[tagNo] = new HashSet();
+                    subtrees = new HashSet<GeneralSubtree>();
+                    subtreesMap[tagNo] = subtrees;
                 }
 
-                ((ISet)subtreesMap[tagNo]).Add(subtree);
+                subtrees.Add(subtree);
             }
 
-            foreach (DictionaryEntry entry in subtreesMap)
+            foreach (var entry in subtreesMap)
             {
                 // go through all subtree groups
-                switch ((int)entry.Key)
+                switch (entry.Key)
                 {
                 case GeneralName.OtherName:
-                    permittedSubtreesOtherName = IntersectOtherName(permittedSubtreesOtherName,
-                        (ISet)entry.Value);
+                    permittedSubtreesOtherName = IntersectOtherName(permittedSubtreesOtherName, entry.Value);
                     break;
                 case GeneralName.Rfc822Name:
-                    permittedSubtreesEmail = IntersectEmail(permittedSubtreesEmail,
-                        (ISet)entry.Value);
+                    permittedSubtreesEmail = IntersectEmail(permittedSubtreesEmail, entry.Value);
                     break;
                 case GeneralName.DnsName:
-                    permittedSubtreesDNS = IntersectDns(permittedSubtreesDNS,
-                        (ISet)entry.Value);
+                    permittedSubtreesDns = IntersectDns(permittedSubtreesDns, entry.Value);
                     break;
                 case GeneralName.DirectoryName:
-                    permittedSubtreesDN = IntersectDN(permittedSubtreesDN,
-                        (ISet)entry.Value);
+                    permittedSubtreesDN = IntersectDN(permittedSubtreesDN, entry.Value);
                     break;
                 case GeneralName.UniformResourceIdentifier:
-                    permittedSubtreesURI = IntersectUri(permittedSubtreesURI,
-                        (ISet)entry.Value);
+                    permittedSubtreesUri = IntersectUri(permittedSubtreesUri, entry.Value);
                     break;
                 case GeneralName.IPAddress:
-                    permittedSubtreesIP = IntersectIP(permittedSubtreesIP,
-                        (ISet)entry.Value);
+                    permittedSubtreesIP = IntersectIP(permittedSubtreesIP, entry.Value);
                     break;
                 }
             }
@@ -1556,22 +1501,22 @@ namespace Org.BouncyCastle.Pkix
             switch (nameType)
             {
             case GeneralName.OtherName:
-                permittedSubtreesOtherName = new HashSet();
+                permittedSubtreesOtherName = new HashSet<OtherName>();
                 break;
             case GeneralName.Rfc822Name:
-                permittedSubtreesEmail = new HashSet();
+                permittedSubtreesEmail = new HashSet<string>();
                 break;
             case GeneralName.DnsName:
-                permittedSubtreesDNS = new HashSet();
+                permittedSubtreesDns = new HashSet<string>();
                 break;
             case GeneralName.DirectoryName:
-                permittedSubtreesDN = new HashSet();
+                permittedSubtreesDN = new HashSet<Asn1Sequence>();
                 break;
             case GeneralName.UniformResourceIdentifier:
-                permittedSubtreesURI = new HashSet();
+                permittedSubtreesUri = new HashSet<string>();
                 break;
             case GeneralName.IPAddress:
-                permittedSubtreesIP = new HashSet();
+                permittedSubtreesIP = new HashSet<byte[]>();
                 break;
             }
         }
@@ -1596,7 +1541,7 @@ namespace Org.BouncyCastle.Pkix
                     ExtractNameAsString(subTreeBase));
                 break;
             case GeneralName.DnsName:
-                excludedSubtreesDNS = UnionDns(excludedSubtreesDNS,
+                excludedSubtreesDns = UnionDns(excludedSubtreesDns,
                     ExtractNameAsString(subTreeBase));
                 break;
             case GeneralName.DirectoryName:
@@ -1604,7 +1549,7 @@ namespace Org.BouncyCastle.Pkix
                     (Asn1Sequence)subTreeBase.Name.ToAsn1Object());
                 break;
             case GeneralName.UniformResourceIdentifier:
-                excludedSubtreesURI = UnionUri(excludedSubtreesURI,
+                excludedSubtreesUri = UnionUri(excludedSubtreesUri,
                     ExtractNameAsString(subTreeBase));
                 break;
             case GeneralName.IPAddress:
@@ -1695,32 +1640,38 @@ namespace Org.BouncyCastle.Pkix
 		public override int GetHashCode()
         {
             return HashCollection(excludedSubtreesDN)
-                + HashCollection(excludedSubtreesDNS)
+                + HashCollection(excludedSubtreesDns)
                 + HashCollection(excludedSubtreesEmail)
                 + HashCollection(excludedSubtreesIP)
-                + HashCollection(excludedSubtreesURI)
+                + HashCollection(excludedSubtreesUri)
                 + HashCollection(excludedSubtreesOtherName)
                 + HashCollection(permittedSubtreesDN)
-                + HashCollection(permittedSubtreesDNS)
+                + HashCollection(permittedSubtreesDns)
                 + HashCollection(permittedSubtreesEmail)
                 + HashCollection(permittedSubtreesIP)
-                + HashCollection(permittedSubtreesURI)
+                + HashCollection(permittedSubtreesUri)
                 + HashCollection(permittedSubtreesOtherName);
         }
 
-        private int HashCollection(ICollection c)
+        private int HashCollection(IEnumerable<byte[]> c)
         {
-            if (c == null)
-                return 0;
-
             int hash = 0;
-            foreach (object o in c)
+            if (c != null)
             {
-                if (o is byte[])
+                foreach (byte[] o in c)
                 {
-                    hash += Arrays.GetHashCode((byte[])o);
+                    hash += Arrays.GetHashCode(o);
                 }
-                else
+            }
+            return hash;
+        }
+
+        private int HashCollection(IEnumerable<object> c)
+        {
+            int hash = 0;
+            if (c != null)
+            {
+                foreach (object o in c)
                 {
                     hash += o.GetHashCode();
                 }
@@ -1730,38 +1681,36 @@ namespace Org.BouncyCastle.Pkix
 
 		public override bool Equals(object o)
 		{
-			if (!(o is PkixNameConstraintValidator))
+			if (!(o is PkixNameConstraintValidator that))
 				return false;
 
-			PkixNameConstraintValidator constraintValidator = (PkixNameConstraintValidator)o;
-
-            return CollectionsAreEqual(constraintValidator.excludedSubtreesDN, excludedSubtreesDN)
-                && CollectionsAreEqual(constraintValidator.excludedSubtreesDNS, excludedSubtreesDNS)
-                && CollectionsAreEqual(constraintValidator.excludedSubtreesEmail, excludedSubtreesEmail)
-                && CollectionsAreEqual(constraintValidator.excludedSubtreesIP, excludedSubtreesIP)
-                && CollectionsAreEqual(constraintValidator.excludedSubtreesURI, excludedSubtreesURI)
-                && CollectionsAreEqual(constraintValidator.excludedSubtreesOtherName, excludedSubtreesOtherName)
-                && CollectionsAreEqual(constraintValidator.permittedSubtreesDN, permittedSubtreesDN)
-                && CollectionsAreEqual(constraintValidator.permittedSubtreesDNS, permittedSubtreesDNS)
-                && CollectionsAreEqual(constraintValidator.permittedSubtreesEmail, permittedSubtreesEmail)
-                && CollectionsAreEqual(constraintValidator.permittedSubtreesIP, permittedSubtreesIP)
-                && CollectionsAreEqual(constraintValidator.permittedSubtreesURI, permittedSubtreesURI)
-                && CollectionsAreEqual(constraintValidator.permittedSubtreesOtherName, permittedSubtreesOtherName);
+            return AreEqualSets(that.excludedSubtreesDN, excludedSubtreesDN)
+                && AreEqualSets(that.excludedSubtreesDns, excludedSubtreesDns)
+                && AreEqualSets(that.excludedSubtreesEmail, excludedSubtreesEmail)
+                && AreEqualSets(that.excludedSubtreesIP, excludedSubtreesIP)
+                && AreEqualSets(that.excludedSubtreesUri, excludedSubtreesUri)
+                && AreEqualSets(that.excludedSubtreesOtherName, excludedSubtreesOtherName)
+                && AreEqualSets(that.permittedSubtreesDN, permittedSubtreesDN)
+                && AreEqualSets(that.permittedSubtreesDns, permittedSubtreesDns)
+                && AreEqualSets(that.permittedSubtreesEmail, permittedSubtreesEmail)
+                && AreEqualSets(that.permittedSubtreesIP, permittedSubtreesIP)
+                && AreEqualSets(that.permittedSubtreesUri, permittedSubtreesUri)
+                && AreEqualSets(that.permittedSubtreesOtherName, permittedSubtreesOtherName);
 		}
 
-        private bool CollectionsAreEqual(ICollection coll1, ICollection coll2)
+        private bool AreEqualSets(ISet<byte[]> set1, ISet<byte[]> set2)
         {
-            if (coll1 == coll2)
+            if (set1 == set2)
                 return true;
-            if (coll1 == null || coll2 == null || coll1.Count != coll2.Count)
+            if (set1 == null || set2 == null || set1.Count != set2.Count)
                 return false;
 
-            foreach (object a in coll1)
+            foreach (byte[] a in set1)
             {
                 bool found = false;
-                foreach (object b in coll2)
+                foreach (byte[] b in set2)
                 {
-                    if (SpecialEquals(a, b))
+                    if (Arrays.AreEqual(a, b))
                     {
                         found = true;
                         break;
@@ -1774,24 +1723,19 @@ namespace Org.BouncyCastle.Pkix
             return true;
         }
 
-        private bool SpecialEquals(object o1, object o2)
+        private bool AreEqualSets<T>(ISet<T> set1, ISet<T> set2)
         {
-            if (o1 == o2)
-            {
+            if (set1 == set2)
                 return true;
-            }
-            if (o1 == null || o2 == null)
-            {
+            if (set1 == null || set2 == null || set1.Count != set2.Count)
                 return false;
-            }
-            if ((o1 is byte[]) && (o2 is byte[]))
-            {
-                return Arrays.AreEqual((byte[])o1, (byte[])o2);
-            }
-            else
+
+            foreach (T a in set1)
             {
-                return o1.Equals(o2);
+                if (!set2.Contains(a))
+                    return false;
             }
+            return true;
         }
 
         /**
@@ -1805,21 +1749,19 @@ namespace Org.BouncyCastle.Pkix
             string temp = "";
             for (int i = 0; i < ip.Length / 2; i++)
             {
-                //temp += Integer.toString(ip[i] & 0x00FF) + ".";
                 temp += (ip[i] & 0x00FF) + ".";
             }
             temp = temp.Substring(0, temp.Length - 1);
             temp += "/";
             for (int i = ip.Length / 2; i < ip.Length; i++)
             {
-                //temp += Integer.toString(ip[i] & 0x00FF) + ".";
                 temp += (ip[i] & 0x00FF) + ".";
             }
             temp = temp.Substring(0, temp.Length - 1);
             return temp;
         }
 
-        private string StringifyIPCollection(ISet ips)
+        private string StringifyIPCollection(ISet<byte[]> ips)
         {
             string temp = "";
             temp += "[";
@@ -1835,99 +1777,84 @@ namespace Org.BouncyCastle.Pkix
             return temp;
         }
 
-        private string StringifyOtherNameCollection(ISet otherNames)
+        private string StringifyOtherNameCollection(ISet<OtherName> otherNames)
         {
-            string temp = "";
-            temp += "[";
-            foreach (object obj in otherNames)
+            StringBuilder sb = new StringBuilder('[');
+            foreach (OtherName name in otherNames)
             {
-                OtherName name = OtherName.GetInstance(obj);
-                if (temp.Length > 1)
-                {
-                    temp += ",";
-                }
-                temp += name.TypeID.Id;
-                temp += ":";
-                try
-                {
-                    temp += Hex.ToHexString(name.Value.ToAsn1Object().GetEncoded());
-                }
-                catch (IOException e)
+                if (sb.Length > 1)
                 {
-                    temp += e.ToString();
+                    sb.Append(',');
                 }
+                sb.Append(name.TypeID.Id);
+                sb.Append(':');
+                sb.Append(Hex.ToHexString(name.Value.GetEncoded()));
             }
-            temp += "]";
-            return temp;
+            sb.Append(']');
+            return sb.ToString();
         }
 
         public override string ToString()
         {
-            string temp = "";
-
-            temp += "permitted:\n";
+            StringBuilder sb = new StringBuilder("permitted:\n");
             if (permittedSubtreesDN != null)
             {
-                temp += "DN:\n";
-                temp += permittedSubtreesDN.ToString() + "\n";
+                Append(sb, "DN", permittedSubtreesDN);
             }
-            if (permittedSubtreesDNS != null)
+            if (permittedSubtreesDns != null)
             {
-                temp += "DNS:\n";
-                temp += permittedSubtreesDNS.ToString() + "\n";
+                Append(sb, "DNS", permittedSubtreesDns);
             }
             if (permittedSubtreesEmail != null)
             {
-                temp += "Email:\n";
-                temp += permittedSubtreesEmail.ToString() + "\n";
+                Append(sb, "Email", permittedSubtreesEmail);
             }
-            if (permittedSubtreesURI != null)
+            if (permittedSubtreesUri != null)
             {
-                temp += "URI:\n";
-                temp += permittedSubtreesURI.ToString() + "\n";
+                Append(sb, "URI", permittedSubtreesUri);
             }
             if (permittedSubtreesIP != null)
             {
-                temp += "IP:\n";
-                temp += StringifyIPCollection(permittedSubtreesIP) + "\n";
+                Append(sb, "IP", StringifyIPCollection(permittedSubtreesIP));
             }
             if (permittedSubtreesOtherName != null)
             {
-                temp += "OtherName:\n";
-                temp += StringifyOtherNameCollection(permittedSubtreesOtherName);
+                Append(sb, "OtherName", StringifyOtherNameCollection(permittedSubtreesOtherName));
             }
-            temp += "excluded:\n";
-            if (!(excludedSubtreesDN.IsEmpty))
+            sb.Append("excluded:\n");
+            if (excludedSubtreesDN.Count > 0)
             {
-                temp += "DN:\n";
-                temp += excludedSubtreesDN.ToString() + "\n";
+                Append(sb, "DN", excludedSubtreesDN);
             }
-            if (!excludedSubtreesDNS.IsEmpty)
+            if (excludedSubtreesDns.Count > 0)
             {
-                temp += "DNS:\n";
-                temp += excludedSubtreesDNS.ToString() + "\n";
+                Append(sb, "DNS", excludedSubtreesDns);
             }
-            if (!excludedSubtreesEmail.IsEmpty)
+            if (excludedSubtreesEmail.Count > 0)
             {
-                temp += "Email:\n";
-                temp += excludedSubtreesEmail.ToString() + "\n";
+                Append(sb, "Email", excludedSubtreesEmail);
             }
-            if (!excludedSubtreesURI.IsEmpty)
+            if (excludedSubtreesUri.Count > 0)
             {
-                temp += "URI:\n";
-                temp += excludedSubtreesURI.ToString() + "\n";
+                Append(sb, "URI", excludedSubtreesUri);
             }
-            if (!excludedSubtreesIP.IsEmpty)
+            if (excludedSubtreesIP.Count > 0)
             {
-                temp += "IP:\n";
-                temp += StringifyIPCollection(excludedSubtreesIP) + "\n";
+                Append(sb, "IP", StringifyIPCollection(excludedSubtreesIP));
             }
-            if (!excludedSubtreesOtherName.IsEmpty)
+            if (excludedSubtreesOtherName.Count > 0)
             {
-                temp += "OtherName:\n";
-                temp += StringifyOtherNameCollection(excludedSubtreesOtherName);
+                Append(sb, "OtherName", StringifyOtherNameCollection(excludedSubtreesOtherName));
             }
-            return temp;
+            return sb.ToString();
+        }
+
+        private static void Append(StringBuilder sb, string name, object value)
+        {
+            sb.Append(name);
+            sb.Append(":\n");
+            sb.Append(value);
+            sb.Append('\n');
         }
     }
 }
diff --git a/crypto/src/pkix/PkixParameters.cs b/crypto/src/pkix/PkixParameters.cs
index eb741fece..cafa1115c 100644
--- a/crypto/src/pkix/PkixParameters.cs
+++ b/crypto/src/pkix/PkixParameters.cs
@@ -1,12 +1,9 @@
 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
 {
@@ -14,7 +11,6 @@ namespace Org.BouncyCastle.Pkix
 	/// Summary description for PkixParameters.
 	/// </summary>
 	public class PkixParameters
-//		: ICertPathParameters
 	{
 		/**
 		* This is the default PKIX validity model. Actually there are two variants
@@ -43,7 +39,7 @@ namespace Org.BouncyCastle.Pkix
 
 		private HashSet<TrustAnchor> trustAnchors;
 		private DateTimeObject date;
-		private IList certPathCheckers;
+		private List<PkixCertPathChecker> m_checkers;
 		private bool revocationEnabled = true;
 		private HashSet<string> initialPolicies;
 		//private bool checkOnlyEECertificateCrl = false;
@@ -90,7 +86,7 @@ namespace Org.BouncyCastle.Pkix
 			SetTrustAnchors(trustAnchors);
 
 			this.initialPolicies = new HashSet<string>();
-			this.certPathCheckers = Platform.CreateArrayList();
+			this.m_checkers = new List<PkixCertPathChecker>();
 			this.m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>();
 			this.m_storesCert = new List<IStore<X509Certificate>>();
 			this.m_storesCrl = new List<IStore<X509Crl>>();
@@ -389,14 +385,15 @@ namespace Org.BouncyCastle.Pkix
 		*                <code>java.security.cert.PKIXCertPathChecker</code>
 		* @see #getCertPathCheckers()
 		*/
-		public virtual void SetCertPathCheckers(IList checkers)
+		public virtual void SetCertPathCheckers(IList<PkixCertPathChecker> checkers)
 		{
-            certPathCheckers = Platform.CreateArrayList();
+			m_checkers = new List<PkixCertPathChecker>();
+
 			if (checkers != null)
 			{
-				foreach (PkixCertPathChecker obj in checkers)
+				foreach (var checker in checkers)
 				{
-					certPathCheckers.Add(obj.Clone());
+					m_checkers.Add((PkixCertPathChecker)checker.Clone());
 				}
 			}
 		}
@@ -410,14 +407,14 @@ namespace Org.BouncyCastle.Pkix
 		 *
 		 * @see #setCertPathCheckers(java.util.List)
 		 */
-		public virtual IList GetCertPathCheckers()
+		public virtual IList<PkixCertPathChecker> GetCertPathCheckers()
 		{
-			IList checkers = Platform.CreateArrayList();
-			foreach (PkixCertPathChecker obj in certPathCheckers)
-			{
-				checkers.Add(obj.Clone());
+			var result = new List<PkixCertPathChecker>(m_checkers.Count);
+			foreach (var checker in m_checkers)
+            {
+				result.Add((PkixCertPathChecker)checker.Clone());
 			}
-			return checkers;
+			return result;
 		}
 
 		/**
@@ -431,12 +428,11 @@ namespace Org.BouncyCastle.Pkix
 		 * @param checker a <code>PKIXCertPathChecker</code> to add to the list of
 		 * checks. If <code>null</code>, the checker is ignored (not added to list).
 		 */
-		public virtual void AddCertPathChecker(
-			PkixCertPathChecker checker)
+		public virtual void AddCertPathChecker(PkixCertPathChecker checker)
 		{
 			if (checker != null)
 			{
-				certPathCheckers.Add(checker.Clone());
+				m_checkers.Add((PkixCertPathChecker)checker.Clone());
 			}
 		}
 
diff --git a/crypto/src/pkix/Rfc3280CertPathUtilities.cs b/crypto/src/pkix/Rfc3280CertPathUtilities.cs
index 07293dfaf..a61d83679 100644
--- a/crypto/src/pkix/Rfc3280CertPathUtilities.cs
+++ b/crypto/src/pkix/Rfc3280CertPathUtilities.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 
@@ -57,12 +56,9 @@ namespace Org.BouncyCastle.Pkix
 		* @param crl  The CRL.
 		* @throws AnnotatedException if one of the conditions is not met or an error occurs.
 		*/
-		internal static void ProcessCrlB2(
-			DistributionPoint	dp,
-			object				cert,
-			X509Crl				crl)
+		internal static void ProcessCrlB2(DistributionPoint dp, object cert, X509Crl crl)
 		{
-			IssuingDistributionPoint idp = null;
+			IssuingDistributionPoint idp;
 			try
 			{
 				idp = IssuingDistributionPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.IssuingDistributionPoint));
@@ -71,6 +67,7 @@ namespace Org.BouncyCastle.Pkix
 			{
 				throw new Exception("0 Issuing distribution point extension could not be decoded.", e);
 			}
+
 			// (b) (2) (i)
 			// distribution point name is present
 			if (idp != null)
@@ -79,7 +76,7 @@ namespace Org.BouncyCastle.Pkix
 				{
 					// make list of names
 					DistributionPointName dpName = IssuingDistributionPoint.GetInstance(idp).DistributionPoint;
-					IList names = Platform.CreateArrayList();
+					var names = new List<GeneralName>();
 
 					if (dpName.PointType == DistributionPointName.FullName)
 					{
@@ -91,21 +88,15 @@ namespace Org.BouncyCastle.Pkix
 					}
 					if (dpName.PointType == DistributionPointName.NameRelativeToCrlIssuer)
 					{
-						Asn1EncodableVector vec = new Asn1EncodableVector();
-						try
-						{
-							IEnumerator e = Asn1Sequence.GetInstance(
-								Asn1Sequence.FromByteArray(crl.IssuerDN.GetEncoded())).GetEnumerator();
-							while (e.MoveNext())
-							{
-								vec.Add((Asn1Encodable)e.Current);
-							}
-						}
-						catch (IOException e)
+						var seq = Asn1Sequence.GetInstance(crl.IssuerDN.ToAsn1Object());
+
+						Asn1EncodableVector vec = new Asn1EncodableVector(seq.Count + 1);
+						foreach (var element in seq)
 						{
-							throw new Exception("Could not read CRL issuer.", e);
+							vec.Add(element);
 						}
 						vec.Add(dpName.Name);
+
 						names.Add(new GeneralName(X509Name.GetInstance(new DerSequence(vec))));
 					}
 					bool matches = false;
@@ -140,13 +131,15 @@ namespace Org.BouncyCastle.Pkix
 							}
 							for (int j = 0; j < genNames.Length; j++)
 							{
-								IEnumerator e = Asn1Sequence.GetInstance(genNames[j].Name.ToAsn1Object()).GetEnumerator();
-								Asn1EncodableVector vec = new Asn1EncodableVector();
-								while (e.MoveNext())
+								var seq = Asn1Sequence.GetInstance(genNames[j].Name.ToAsn1Object());
+
+								Asn1EncodableVector vec = new Asn1EncodableVector(seq.Count + 1);
+								foreach (var element in seq)
 								{
-									vec.Add((Asn1Encodable)e.Current);
+									vec.Add(element);
 								}
 								vec.Add(dpName.Name);
+
 								genNames[j] = new GeneralName(X509Name.GetInstance(new DerSequence(vec)));
 							}
 						}
@@ -227,14 +220,14 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static void ProcessCertBC(
 			PkixCertPath				certPath,
 			int							index,
 			PkixNameConstraintValidator	nameConstraintValidator)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 			int n = certs.Count;
 			// i as defined in the algorithm description
 			int i = n - index;
@@ -279,7 +272,7 @@ namespace Org.BouncyCastle.Pkix
 						"Subject alternative name extension could not be decoded.", e, index);
 				}
 
-				IList emails = X509Name.GetInstance(dns).GetValueList(X509Name.EmailAddress);
+				var emails = X509Name.GetInstance(dns).GetValueList(X509Name.EmailAddress);
 				foreach (string email in emails)
 				{
 					GeneralName emailAsGeneralName = new GeneralName(GeneralName.Rfc822Name, email);
@@ -323,18 +316,16 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
-		internal static void PrepareNextCertA(
-			PkixCertPath	certPath,
-			int				index)
-			//throws CertPathValidatorException
+		/// <exception cref="PkixCertPathValidatorException"/>
+		internal static void PrepareNextCertA(PkixCertPath certPath, int index)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 			//
 			//
 			// (a) check the policy mappings
 			//
-			Asn1Sequence pm = null;
+			Asn1Sequence pm;
 			try
 			{
 				pm = Asn1Sequence.GetInstance(
@@ -351,8 +342,8 @@ namespace Org.BouncyCastle.Pkix
 
 				for (int j = 0; j < mappings.Count; j++)
 				{
-					DerObjectIdentifier issuerDomainPolicy = null;
-					DerObjectIdentifier subjectDomainPolicy = null;
+					DerObjectIdentifier issuerDomainPolicy;
+					DerObjectIdentifier subjectDomainPolicy;
 					try
 					{
                         Asn1Sequence mapping = Asn1Sequence.GetInstance(mappings[j]);
@@ -381,8 +372,8 @@ namespace Org.BouncyCastle.Pkix
 		internal static PkixPolicyNode ProcessCertD(PkixCertPath certPath, int index, ISet<string> acceptablePolicies,
 			PkixPolicyNode validPolicyTree, IList<PkixPolicyNode>[] policyNodes, int inhibitAnyPolicy)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 			int n = certs.Count;
 			// i as defined in the algorithm description
 			int i = n - index;
@@ -689,7 +680,7 @@ namespace Org.BouncyCastle.Pkix
 			X509Certificate			defaultCRLSignCert,
 			AsymmetricKeyParameter	defaultCRLSignKey,
 			PkixParameters			paramsPKIX,
-			IList					certPathCerts)
+			IList<X509Certificate>	certPathCerts)
 		{
 			// (f)
 
@@ -762,7 +753,7 @@ namespace Org.BouncyCastle.Pkix
 					{
 						parameters.IsRevocationEnabled = true;
 					}
-					IList certs = builder.Build(parameters).CertPath.Certificates;
+					var certs = builder.Build(parameters).CertPath.Certificates;
 					validCerts.Add(signingCert);
 					validKeys.Add(PkixCertPathValidatorUtilities.GetNextWorkingKey(certs, 0));
 				}
@@ -874,8 +865,7 @@ namespace Org.BouncyCastle.Pkix
 			AsymmetricKeyParameter defaultCRLSignKey,
 			CertStatus certStatus,
 			ReasonsMask reasonMask,
-			IList certPathCerts)
-			//throws AnnotatedException
+			IList<X509Certificate> certPathCerts)
 		{
 			DateTime currentDate = DateTime.UtcNow;
 
@@ -1041,7 +1031,7 @@ namespace Org.BouncyCastle.Pkix
 			DateTime				validDate,
 			X509Certificate			sign,
 			AsymmetricKeyParameter	workingPublicKey,
-			IList					certPathCerts)
+			IList<X509Certificate>	certPathCerts)
 		{
 			Exception lastException = null;
 			CrlDistPoint crldp;
@@ -1168,14 +1158,14 @@ namespace Org.BouncyCastle.Pkix
 		internal static PkixPolicyNode PrepareCertB(PkixCertPath certPath, int index,
 			IList<PkixPolicyNode>[] policyNodes, PkixPolicyNode validPolicyTree, int policyMapping)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 			int n = certs.Count;
 			// i as defined in the algorithm description
 			int i = n - index;
 			// (b)
 			//
-			Asn1Sequence pm = null;
+			Asn1Sequence pm;
 			try
 			{
 				pm = Asn1Sequence.GetInstance(
@@ -1344,7 +1334,7 @@ namespace Org.BouncyCastle.Pkix
 
 			try
 			{
-				IList issuer = Platform.CreateArrayList();
+				var issuer = new List<X509Name>();
 				issuer.Add(crl.IssuerDN);
 				crlselect.Issuers = issuer;
 			}
@@ -1455,8 +1445,8 @@ namespace Org.BouncyCastle.Pkix
 			X509Name				workingIssuerName,
 			X509Certificate			sign)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 			//
 			// (a) verify
 			//
@@ -1525,8 +1515,8 @@ namespace Org.BouncyCastle.Pkix
 
 		internal static int PrepareNextCertI1(PkixCertPath certPath, int index, int explicitPolicy)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 			//
 			// (i)
 			//
@@ -1542,24 +1532,19 @@ namespace Org.BouncyCastle.Pkix
 					"Policy constraints extension cannot be decoded.", e, index);
 			}
 
-			int tmpInt;
-
 			if (pc != null)
 			{
-				IEnumerator policyConstraints = pc.GetEnumerator();
-
-				while (policyConstraints.MoveNext())
+				foreach (var policyConstraint in pc)
 				{
 					try
 					{
-						Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraints.Current);
-						if (constraint.TagNo == 0)
+						Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraint);
+						if (constraint.HasContextTag(0))
 						{
-                            tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
+                            int tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
 							if (tmpInt < explicitPolicy)
-							{
 								return tmpInt;
-							}
+
 							break;
 						}
 					}
@@ -1573,14 +1558,14 @@ namespace Org.BouncyCastle.Pkix
 			return explicitPolicy;
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static int PrepareNextCertI2(
 			PkixCertPath	certPath,
 			int				index,
 			int				policyMapping)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (i)
@@ -1596,24 +1581,19 @@ namespace Org.BouncyCastle.Pkix
 				throw new PkixCertPathValidatorException("Policy constraints extension cannot be decoded.", e, index);
 			}
 
-			int tmpInt;
-
 			if (pc != null)
 			{
-				IEnumerator policyConstraints = pc.GetEnumerator();
-
-				while (policyConstraints.MoveNext())
+				foreach (var policyConstraint in pc)
 				{
 					try
 					{
-						Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraints.Current);
-						if (constraint.TagNo == 1)
+						Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraint);
+						if (constraint.HasContextTag(1))
 						{
-                            tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
+                            int tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
 							if (tmpInt < policyMapping)
-							{
 								return tmpInt;
-							}
+
 							break;
 						}
 					}
@@ -1627,14 +1607,14 @@ namespace Org.BouncyCastle.Pkix
 			return policyMapping;
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static void PrepareNextCertG(
 			PkixCertPath				certPath,
 			int							index,
 			PkixNameConstraintValidator	nameConstraintValidator)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (g) handle the name constraints extension
@@ -1679,12 +1659,11 @@ namespace Org.BouncyCastle.Pkix
 				Asn1Sequence excluded = nc.ExcludedSubtrees;
 				if (excluded != null)
 				{
-					IEnumerator e = excluded.GetEnumerator();
 					try
 					{
-						while (e.MoveNext())
+						foreach (var excludedSubtree in excluded)
 						{
-							GeneralSubtree subtree = GeneralSubtree.GetInstance(e.Current);
+							GeneralSubtree subtree = GeneralSubtree.GetInstance(excludedSubtree);
 							nameConstraintValidator.AddExcludedSubtree(subtree);
 						}
 					}
@@ -1697,14 +1676,14 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static int PrepareNextCertJ(
 			PkixCertPath	certPath,
 			int				index,
 			int				inhibitAnyPolicy)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (j)
@@ -1730,17 +1709,17 @@ namespace Org.BouncyCastle.Pkix
 			return inhibitAnyPolicy;
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static void PrepareNextCertK(
 			PkixCertPath	certPath,
 			int				index)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 			//
 			// (k)
 			//
-			BasicConstraints bc = null;
+			BasicConstraints bc;
 			try
 			{
 				bc = BasicConstraints.GetInstance(
@@ -1761,42 +1740,40 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static int PrepareNextCertL(
 			PkixCertPath	certPath,
 			int				index,
 			int				maxPathLength)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 			//
 			// (l)
 			//
 			if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert))
 			{
 				if (maxPathLength <= 0)
-				{
 					throw new PkixCertPathValidatorException("Max path length not greater than zero", null, index);
-				}
 
 				return maxPathLength - 1;
 			}
 			return maxPathLength;
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static int PrepareNextCertM(
 			PkixCertPath	certPath,
 			int				index,
 			int				maxPathLength)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (m)
 			//
-			BasicConstraints bc = null;
+			BasicConstraints bc;
 			try
 			{
 				bc = BasicConstraints.GetInstance(
@@ -1823,13 +1800,13 @@ namespace Org.BouncyCastle.Pkix
 			return maxPathLength;
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static void PrepareNextCertN(
 			PkixCertPath	certPath,
 			int				index)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (n)
@@ -1843,25 +1820,21 @@ namespace Org.BouncyCastle.Pkix
 			}
 		}
 
-		internal static void PrepareNextCertO(
-			PkixCertPath	certPath,
-			int				index,
-			ISet<string>	criticalExtensions,
-			IList			pathCheckers)
-			//throws CertPathValidatorException
+		/// <exception cref="PkixCertPathValidatorException"/>
+		internal static void PrepareNextCertO(PkixCertPath certPath, int index, ISet<string> criticalExtensions,
+			IList<PkixCertPathChecker> checkers)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (o)
 			//
-			IEnumerator tmpIter = pathCheckers.GetEnumerator();
-			while (tmpIter.MoveNext())
+			foreach (var checker in checkers)
 			{
 				try
 				{
-					((PkixCertPathChecker)tmpIter.Current).Check(cert, criticalExtensions);
+					checker.Check(cert, criticalExtensions);
 				}
 				catch (PkixCertPathValidatorException e)
 				{
@@ -1879,8 +1852,8 @@ namespace Org.BouncyCastle.Pkix
 			int				index,
 			int				explicitPolicy)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (h)
@@ -1901,8 +1874,8 @@ namespace Org.BouncyCastle.Pkix
 			int				index,
 			int				policyMapping)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (h)
@@ -1924,8 +1897,8 @@ namespace Org.BouncyCastle.Pkix
 			int				index,
 			int				inhibitAnyPolicy)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (h)
@@ -1955,19 +1928,18 @@ namespace Org.BouncyCastle.Pkix
 			return explicitPolicy;
 		}
 
+		/// <exception cref="PkixCertPathValidatorException"/>
 		internal static int WrapupCertB(
 			PkixCertPath	certPath,
 			int				index,
 			int				explicitPolicy)
-			//throws CertPathValidatorException
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (b)
 			//
-			int tmpInt;
 			Asn1Sequence pc;
 			try
 			{
@@ -1981,50 +1953,43 @@ namespace Org.BouncyCastle.Pkix
 
 			if (pc != null)
 			{
-				IEnumerator policyConstraints = pc.GetEnumerator();
-
-				while (policyConstraints.MoveNext())
+				foreach (var policyConstraint in pc)
 				{
-					Asn1TaggedObject constraint = (Asn1TaggedObject)policyConstraints.Current;
-					switch (constraint.TagNo)
-					{
-						case 0:
-							try
-							{
-                                tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
-							}
-							catch (Exception e)
-							{
-								throw new PkixCertPathValidatorException(
-									"Policy constraints requireExplicitPolicy field could not be decoded.", e, index);
-							}
-							if (tmpInt == 0)
-							{
-								return 0;
-							}
-							break;
+					Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraint);
+					if (constraint.HasContextTag(0))
+                    {
+						int tmpInt;
+						try
+						{
+							tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
+						}
+						catch (Exception e)
+						{
+							throw new PkixCertPathValidatorException(
+								"Policy constraints requireExplicitPolicy field could not be decoded.", e, index);
+						}
+						if (tmpInt == 0)
+							return 0;
+
+						break;
 					}
 				}
 			}
 			return explicitPolicy;
 		}
 
-		internal static void WrapupCertF(
-			PkixCertPath	certPath,
-			int				index,
-			IList			pathCheckers,
-			ISet<string>	criticalExtensions)
-			//throws CertPathValidatorException
+		/// <exception cref="PkixCertPathValidatorException"/>
+		internal static void WrapupCertF(PkixCertPath certPath, int index, IList<PkixCertPathChecker> checkers,
+			ISet<string> criticalExtensions)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
-			IEnumerator tmpIter = pathCheckers.GetEnumerator();
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
-			while (tmpIter.MoveNext())
+			foreach (var checker in checkers)
 			{
 				try
 				{
-					((PkixCertPathChecker)tmpIter.Current).Check(cert, criticalExtensions);
+					checker.Check(cert, criticalExtensions);
 				}
 				catch (PkixCertPathValidatorException e)
 				{
@@ -2312,8 +2277,8 @@ namespace Org.BouncyCastle.Pkix
 			int				index,
 			PkixPolicyNode	validPolicyTree)
 		{
-			IList certs = certPath.Certificates;
-			X509Certificate cert = (X509Certificate)certs[index];
+			var certs = certPath.Certificates;
+			X509Certificate cert = certs[index];
 
 			//
 			// (e)
diff --git a/crypto/src/pkix/Rfc3281CertPathUtilities.cs b/crypto/src/pkix/Rfc3281CertPathUtilities.cs
index 39c03146c..a2673f2a1 100644
--- a/crypto/src/pkix/Rfc3281CertPathUtilities.cs
+++ b/crypto/src/pkix/Rfc3281CertPathUtilities.cs
@@ -74,12 +74,10 @@ namespace Org.BouncyCastle.Pkix
 			PkixParameters				paramsPKIX,
 			X509Certificate				issuerCert,
 			DateTime					validDate,
-			IList						certPathCerts)
+			IList<X509Certificate>		certPathCerts)
 		{
 			if (!paramsPKIX.IsRevocationEnabled)
-            {
                 return;
-            }
 
             // check if revocation is available
             if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
@@ -462,7 +460,7 @@ namespace Org.BouncyCastle.Pkix
 			X509Certificate				issuerCert,
 			CertStatus					certStatus,
 			ReasonsMask					reasonMask,
-			IList						certPathCerts)
+			IList<X509Certificate>		certPathCerts)
 		{
 			/*
 			* 4.3.6 No Revocation Available
@@ -472,9 +470,7 @@ namespace Org.BouncyCastle.Pkix
 			* available for this AC.
 			*/
 			if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
-			{
 				return;
-			}
 
 			DateTime currentDate = DateTime.UtcNow;
 			if (validDate.CompareTo(currentDate) > 0)