summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/asn1/x509/X509Name.cs31
-rw-r--r--crypto/src/openssl/PEMWriter.cs25
-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
-rw-r--r--crypto/src/util/collections/CollectionUtilities.cs5
-rw-r--r--crypto/src/util/collections/ReadOnlyList.cs57
-rw-r--r--crypto/src/x509/X509Certificate.cs42
-rw-r--r--crypto/src/x509/X509CertificateParser.cs69
-rw-r--r--crypto/src/x509/X509CrlParser.cs78
-rw-r--r--crypto/src/x509/X509Utilities.cs227
-rw-r--r--crypto/src/x509/X509V3CertificateGenerator.cs35
-rw-r--r--crypto/src/x509/store/X509CertStoreSelector.cs4
-rw-r--r--crypto/test/src/asn1/test/X509NameTest.cs28
-rw-r--r--crypto/test/src/test/CertPathTest.cs7
-rw-r--r--crypto/test/src/test/CertPathValidatorTest.cs12
-rw-r--r--crypto/test/src/test/CertTest.cs48
23 files changed, 777 insertions, 1064 deletions
diff --git a/crypto/src/asn1/x509/X509Name.cs b/crypto/src/asn1/x509/X509Name.cs
index 33c395712..0683b380c 100644
--- a/crypto/src/asn1/x509/X509Name.cs
+++ b/crypto/src/asn1/x509/X509Name.cs
@@ -1,12 +1,9 @@
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Text;
 
-#if PORTABLE
-using System.Collections.Generic;
-#endif
-
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Encoders;
@@ -340,7 +337,7 @@ namespace Org.BouncyCastle.Asn1.X509
             DefaultLookup.Add("telephonenumber", TelephoneNumber);
         }
 
-        private readonly IList ordering = Platform.CreateArrayList();
+        private readonly List<DerObjectIdentifier> ordering = new List<DerObjectIdentifier>();
         private readonly X509NameEntryConverter converter;
 
         private IList		    values = Platform.CreateArrayList();
@@ -469,9 +466,7 @@ namespace Org.BouncyCastle.Asn1.X509
         /**
         * Takes two vectors one of the oids and the other of the values.
         */
-        public X509Name(
-            IList   oids,
-            IList   values)
+        public X509Name(IList<DerObjectIdentifier> oids, IList values)
             : this(oids, values, new X509DefaultEntryConverter())
         {
         }
@@ -482,10 +477,7 @@ namespace Org.BouncyCastle.Asn1.X509
         * The passed in converter will be used to convert the strings into their
         * ASN.1 counterparts.</p>
         */
-        public X509Name(
-            IList			    	oids,
-            IList		    		values,
-            X509NameEntryConverter	converter)
+        public X509Name(IList<DerObjectIdentifier> oids, IList values, X509NameEntryConverter converter)
         {
             this.converter = converter;
 
@@ -506,8 +498,7 @@ namespace Org.BouncyCastle.Asn1.X509
         * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
         * some such, converting it into an ordered set of name attributes.
         */
-        public X509Name(
-            string dirName)
+        public X509Name(string dirName)
             : this(DefaultReverse, (IDictionary)DefaultLookup, dirName)
         {
         }
@@ -666,7 +657,7 @@ namespace Org.BouncyCastle.Asn1.X509
 //				this.ordering.Reverse();
 //				this.values.Reverse();
 //				this.added.Reverse();
-                IList o = Platform.CreateArrayList();
+                var o = new List<DerObjectIdentifier>();
                 IList v = Platform.CreateArrayList();
                 IList a = Platform.CreateArrayList();
                 int count = 1;
@@ -694,16 +685,16 @@ namespace Org.BouncyCastle.Asn1.X509
         /**
         * return an IList of the oids in the name, in the order they were found.
         */
-        public IList GetOidList()
+        public IList<DerObjectIdentifier> GetOidList()
         {
-            return Platform.CreateArrayList(ordering);
+            return new List<DerObjectIdentifier>(ordering);
         }
 
         /**
         * return an IList of the values found in the name, in the order they
         * were found.
         */
-        public IList GetValueList()
+        public IList<string> GetValueList()
         {
             return GetValueList(null);
         }
@@ -712,9 +703,9 @@ namespace Org.BouncyCastle.Asn1.X509
          * return an IList of the values found in the name, in the order they
          * were found, with the DN label corresponding to passed in oid.
          */
-        public IList GetValueList(DerObjectIdentifier oid)
+        public IList<string> GetValueList(DerObjectIdentifier oid)
         {
-            IList v = Platform.CreateArrayList();
+            var v = new List<string>();
             for (int i = 0; i != values.Count; i++)
             {
                 if (null == oid || oid.Equals(ordering[i]))
diff --git a/crypto/src/openssl/PEMWriter.cs b/crypto/src/openssl/PEMWriter.cs
index aefb018f3..e6332ec02 100644
--- a/crypto/src/openssl/PEMWriter.cs
+++ b/crypto/src/openssl/PEMWriter.cs
@@ -1,40 +1,21 @@
-using System;
-using System.Diagnostics;
-using System.Globalization;
 using System.IO;
-using System.Text;
 
-using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Asn1.CryptoPro;
-using Org.BouncyCastle.Asn1.Pkcs;
-using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Asn1.X9;
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Generators;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Pkcs;
 using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Security.Certificates;
-using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.Utilities.IO.Pem;
-using Org.BouncyCastle.X509;
 
 namespace Org.BouncyCastle.OpenSsl
 {
 	/// <remarks>General purpose writer for OpenSSL PEM objects.</remarks>
 	public class PemWriter
-		: Org.BouncyCastle.Utilities.IO.Pem.PemWriter
+		: Utilities.IO.Pem.PemWriter
 	{
 		/// <param name="writer">The TextWriter object to write the output to.</param>
-		public PemWriter(
-			TextWriter writer)
+		public PemWriter(TextWriter writer)
 			: base(writer)
 		{
 		}
 
-		public void WriteObject(
-			object obj) 
+		public void WriteObject(object obj) 
 		{
 			try
 			{
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)
diff --git a/crypto/src/util/collections/CollectionUtilities.cs b/crypto/src/util/collections/CollectionUtilities.cs
index f1d2bac21..4a42cf19d 100644
--- a/crypto/src/util/collections/CollectionUtilities.cs
+++ b/crypto/src/util/collections/CollectionUtilities.cs
@@ -66,6 +66,11 @@ namespace Org.BouncyCastle.Utilities.Collections
             return new UnmodifiableListProxy(l);
         }
 
+        public static IList<T> ReadOnly<T>(IList<T> l)
+        {
+            return new ReadOnlyListProxy<T>(l);
+        }
+
         public static ISet ReadOnly(ISet s)
         {
             return new UnmodifiableSetProxy(s);
diff --git a/crypto/src/util/collections/ReadOnlyList.cs b/crypto/src/util/collections/ReadOnlyList.cs
new file mode 100644
index 000000000..70103022f
--- /dev/null
+++ b/crypto/src/util/collections/ReadOnlyList.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Org.BouncyCastle.Utilities.Collections
+{
+    internal abstract class ReadOnlyList<T>
+        : IList<T>
+    {
+        public T this[int index]
+        {
+            get { return Lookup(index); }
+            set { throw new NotSupportedException(); }
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        public bool IsReadOnly => true;
+
+        public void Add(T item) => throw new NotSupportedException();
+        public void Clear() => throw new NotSupportedException();
+        public void Insert(int index, T item) => throw new NotSupportedException();
+        public bool Remove(T item) => throw new NotSupportedException();
+        public void RemoveAt(int index) => throw new NotSupportedException();
+
+        public abstract int Count { get; }
+
+        public abstract bool Contains(T item);
+        public abstract void CopyTo(T[] array, int arrayIndex);
+        public abstract IEnumerator<T> GetEnumerator();
+        public abstract int IndexOf(T item);
+
+        protected abstract T Lookup(int index);
+    }
+
+    internal class ReadOnlyListProxy<T>
+        : ReadOnlyList<T>
+    {
+        private readonly IList<T> m_target;
+
+        internal ReadOnlyListProxy(IList<T> target)
+        {
+            m_target = target;
+        }
+
+        public override int Count => m_target.Count;
+        public override bool Contains(T item) => m_target.Contains(item);
+        public override void CopyTo(T[] array, int arrayIndex) => m_target.CopyTo(array, arrayIndex);
+        public override IEnumerator<T> GetEnumerator() => m_target.GetEnumerator();
+        public override int IndexOf(T item) => m_target.IndexOf(item);
+
+        protected override T Lookup(int index) => m_target[index];
+    }
+}
diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs
index 985ec0aeb..2fbad4ba5 100644
--- a/crypto/src/x509/X509Certificate.cs
+++ b/crypto/src/x509/X509Certificate.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 using System.Text;
 
@@ -96,12 +97,10 @@ namespace Org.BouncyCastle.X509
 
             try
             {
-                Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.19"));
-
+                Asn1OctetString str = GetExtensionValue(X509Extensions.BasicConstraints);
                 if (str != null)
                 {
-                    basicConstraints = BasicConstraints.GetInstance(
-                        X509ExtensionUtilities.FromExtensionValue(str));
+                    basicConstraints = BasicConstraints.GetInstance(X509ExtensionUtilities.FromExtensionValue(str));
                 }
             }
             catch (Exception e)
@@ -111,12 +110,10 @@ namespace Org.BouncyCastle.X509
 
             try
             {
-                Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.15"));
-
+                Asn1OctetString str = GetExtensionValue(X509Extensions.KeyUsage);
                 if (str != null)
                 {
-                    DerBitString bits = DerBitString.GetInstance(
-                        X509ExtensionUtilities.FromExtensionValue(str));
+                    DerBitString bits = DerBitString.GetInstance(X509ExtensionUtilities.FromExtensionValue(str));
 
                     byte[] bytes = bits.GetBytes();
                     int length = (bytes.Length * 8) - bits.PadBits;
@@ -343,26 +340,23 @@ namespace Org.BouncyCastle.X509
         }
 
         // TODO Replace with something that returns a list of DerObjectIdentifier
-        public virtual IList GetExtendedKeyUsage()
+        public virtual IList<DerObjectIdentifier> GetExtendedKeyUsage()
         {
-            Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.37"));
+            Asn1OctetString str = GetExtensionValue(X509Extensions.ExtendedKeyUsage);
 
             if (str == null)
                 return null;
 
             try
             {
-                Asn1Sequence seq = Asn1Sequence.GetInstance(
-                    X509ExtensionUtilities.FromExtensionValue(str));
-
-                IList list = Platform.CreateArrayList();
+                Asn1Sequence seq = Asn1Sequence.GetInstance(X509ExtensionUtilities.FromExtensionValue(str));
 
+                var result = new List<DerObjectIdentifier>();
                 foreach (DerObjectIdentifier oid in seq)
                 {
-                    list.Add(oid.Id);
+                    result.Add(oid);
                 }
-
-                return list;
+                return result;
             }
             catch (Exception e)
             {
@@ -387,19 +381,17 @@ namespace Org.BouncyCastle.X509
 
         public virtual ICollection GetSubjectAlternativeNames()
         {
-            return GetAlternativeNames("2.5.29.17");
+            return GetAlternativeNames(X509Extensions.SubjectAlternativeName);
         }
 
         public virtual ICollection GetIssuerAlternativeNames()
         {
-            return GetAlternativeNames("2.5.29.18");
+            return GetAlternativeNames(X509Extensions.IssuerAlternativeName);
         }
 
-        protected virtual ICollection GetAlternativeNames(
-            string oid)
+        protected virtual ICollection GetAlternativeNames(DerObjectIdentifier oid)
         {
-            Asn1OctetString altNames = GetExtensionValue(new DerObjectIdentifier(oid));
-
+            Asn1OctetString altNames = GetExtensionValue(oid);
             if (altNames == null)
                 return null;
 
@@ -549,7 +541,7 @@ namespace Org.BouncyCastle.X509
 
             if (extensions != null)
             {
-                IEnumerator e = extensions.ExtensionOids.GetEnumerator();
+                var e = extensions.ExtensionOids.GetEnumerator();
 
                 if (e.MoveNext())
                 {
@@ -558,7 +550,7 @@ namespace Org.BouncyCastle.X509
 
                 do
                 {
-                    DerObjectIdentifier oid = (DerObjectIdentifier)e.Current;
+                    DerObjectIdentifier oid = e.Current;
                     X509Extension ext = extensions.GetExtension(oid);
 
                     if (ext.Value != null)
diff --git a/crypto/src/x509/X509CertificateParser.cs b/crypto/src/x509/X509CertificateParser.cs
index ceab31108..ce50dc8ed 100644
--- a/crypto/src/x509/X509CertificateParser.cs
+++ b/crypto/src/x509/X509CertificateParser.cs
@@ -1,12 +1,11 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Security.Certificates;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
 namespace Org.BouncyCastle.X509
@@ -22,12 +21,11 @@ namespace Org.BouncyCastle.X509
 	{
 		private static readonly PemParser PemCertParser = new PemParser("CERTIFICATE");
 
-		private Asn1Set	sData;
-		private int		sDataObjectCount;
-		private Stream	currentStream;
+		private Asn1Set sData;
+		private int sDataObjectCount;
+		private Stream currentStream;
 
-		private X509Certificate ReadDerCertificate(
-			Asn1InputStream dIn)
+		private X509Certificate ReadDerCertificate(Asn1InputStream dIn)
 		{
 			Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject();
 
@@ -42,7 +40,14 @@ namespace Org.BouncyCastle.X509
 				}
 			}
 
-			return CreateX509Certificate(X509CertificateStructure.GetInstance(seq));
+			return new X509Certificate(X509CertificateStructure.GetInstance(seq));
+		}
+
+		private X509Certificate ReadPemCertificate(Stream inStream)
+		{
+			Asn1Sequence seq = PemCertParser.ReadPemObject(inStream);
+
+			return seq == null ? null : new X509Certificate(X509CertificateStructure.GetInstance(seq));
 		}
 
 		private X509Certificate GetCertificate()
@@ -54,38 +59,18 @@ namespace Org.BouncyCastle.X509
 					object obj = sData[sDataObjectCount++];
 
 					if (obj is Asn1Sequence)
-					{
-						return CreateX509Certificate(
-							X509CertificateStructure.GetInstance(obj));
-					}
+						return new X509Certificate(X509CertificateStructure.GetInstance(obj));
 				}
 			}
 
 			return null;
 		}
 
-		private X509Certificate ReadPemCertificate(
-			Stream inStream)
-		{
-			Asn1Sequence seq = PemCertParser.ReadPemObject(inStream);
-
-			return seq == null
-				?	null
-				:	CreateX509Certificate(X509CertificateStructure.GetInstance(seq));
-		}
-
-		protected virtual X509Certificate CreateX509Certificate(
-			X509CertificateStructure c)
-		{
-			return new X509Certificate(c);
-		}
-
 		/// <summary>
 		/// Create loading data from byte array.
 		/// </summary>
 		/// <param name="input"></param>
-		public X509Certificate ReadCertificate(
-			byte[] input)
+		public X509Certificate ReadCertificate(byte[] input)
 		{
 			return ReadCertificate(new MemoryStream(input, false));
 		}
@@ -94,8 +79,7 @@ namespace Org.BouncyCastle.X509
 		/// Create loading data from byte array.
 		/// </summary>
 		/// <param name="input"></param>
-		public ICollection ReadCertificates(
-			byte[] input)
+		public IList<X509Certificate> ReadCertificates(byte[] input)
 		{
 			return ReadCertificates(new MemoryStream(input, false));
 		}
@@ -104,8 +88,7 @@ namespace Org.BouncyCastle.X509
 		 * Generates a certificate object and initializes it with the data
 		 * read from the input stream inStream.
 		 */
-		public X509Certificate ReadCertificate(
-			Stream inStream)
+		public X509Certificate ReadCertificate(Stream inStream)
 		{
 			if (inStream == null)
 				throw new ArgumentNullException("inStream");
@@ -130,9 +113,7 @@ namespace Org.BouncyCastle.X509
 				if (sData != null)
 				{
 					if (sDataObjectCount != sData.Count)
-					{
 						return GetCertificate();
-					}
 
 					sData = null;
 					sDataObjectCount = 0;
@@ -155,9 +136,7 @@ namespace Org.BouncyCastle.X509
                 }
 
                 if (tag != 0x30)  // assume ascii PEM encoded.
-				{
 					return ReadPemCertificate(inStream);
-				}
 
 				return ReadDerCertificate(new Asn1InputStream(inStream));
 			}
@@ -171,18 +150,18 @@ namespace Org.BouncyCastle.X509
 		 * Returns a (possibly empty) collection view of the certificates
 		 * read from the given input stream inStream.
 		 */
-		public ICollection ReadCertificates(
-			Stream inStream)
+		public IList<X509Certificate> ReadCertificates(Stream inStream)
 		{
-			X509Certificate cert;
-            IList certs = Platform.CreateArrayList();
+			return new List<X509Certificate>(ParseCertificates(inStream));
+		}
 
+		public IEnumerable<X509Certificate> ParseCertificates(Stream inStream)
+		{
+			X509Certificate cert;
 			while ((cert = ReadCertificate(inStream)) != null)
 			{
-				certs.Add(cert);
+				yield return cert;
 			}
-
-			return certs;
 		}
 	}
 }
diff --git a/crypto/src/x509/X509CrlParser.cs b/crypto/src/x509/X509CrlParser.cs
index f0bb9f98f..ad2b4f704 100644
--- a/crypto/src/x509/X509CrlParser.cs
+++ b/crypto/src/x509/X509CrlParser.cs
@@ -1,12 +1,11 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Security.Certificates;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
 namespace Org.BouncyCastle.X509
@@ -17,33 +16,16 @@ namespace Org.BouncyCastle.X509
 
 		private readonly bool lazyAsn1;
 
-		private Asn1Set	sCrlData;
-		private int		sCrlDataObjectCount;
-		private Stream	currentCrlStream;
+		private Asn1Set sCrlData;
+		private int sCrlDataObjectCount;
+		private Stream currentCrlStream;
 
-		public X509CrlParser()
-			: this(false)
-		{
-		}
-
-		public X509CrlParser(
-			bool lazyAsn1)
+		public X509CrlParser(bool lazyAsn1 = false)
 		{
 			this.lazyAsn1 = lazyAsn1;
 		}
 
-		private X509Crl ReadPemCrl(
-			Stream inStream)
-		{
-			Asn1Sequence seq = PemCrlParser.ReadPemObject(inStream);
-
-			return seq == null
-				?	null
-				:	CreateX509Crl(CertificateList.GetInstance(seq));
-		}
-
-		private X509Crl ReadDerCrl(
-			Asn1InputStream dIn)
+		private X509Crl ReadDerCrl(Asn1InputStream dIn)
 		{
 			Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject();
 
@@ -58,33 +40,29 @@ namespace Org.BouncyCastle.X509
 				}
 			}
 
-			return CreateX509Crl(CertificateList.GetInstance(seq));
+			return new X509Crl(CertificateList.GetInstance(seq));
 		}
 
-		private X509Crl GetCrl()
+		private X509Crl ReadPemCrl(Stream inStream)
 		{
-			if (sCrlData == null || sCrlDataObjectCount >= sCrlData.Count)
-			{
-				return null;
-			}
+			Asn1Sequence seq = PemCrlParser.ReadPemObject(inStream);
 
-			return CreateX509Crl(
-				CertificateList.GetInstance(
-					sCrlData[sCrlDataObjectCount++]));
+			return seq == null ? null : new X509Crl(CertificateList.GetInstance(seq));
 		}
 
-		protected virtual X509Crl CreateX509Crl(
-			CertificateList c)
+		private X509Crl GetCrl()
 		{
-			return new X509Crl(c);
+			if (sCrlData == null || sCrlDataObjectCount >= sCrlData.Count)
+				return null;
+
+			return new X509Crl(CertificateList.GetInstance(sCrlData[sCrlDataObjectCount++]));
 		}
 
 		/// <summary>
 		/// Create loading data from byte array.
 		/// </summary>
 		/// <param name="input"></param>
-		public X509Crl ReadCrl(
-			byte[] input)
+		public X509Crl ReadCrl(byte[] input)
 		{
 			return ReadCrl(new MemoryStream(input, false));
 		}
@@ -93,8 +71,7 @@ namespace Org.BouncyCastle.X509
 		/// Create loading data from byte array.
 		/// </summary>
 		/// <param name="input"></param>
-		public ICollection ReadCrls(
-			byte[] input)
+		public IList<X509Crl> ReadCrls(byte[] input)
 		{
 			return ReadCrls(new MemoryStream(input, false));
 		}
@@ -103,8 +80,7 @@ namespace Org.BouncyCastle.X509
 		 * Generates a certificate revocation list (CRL) object and initializes
 		 * it with the data read from the input stream inStream.
 		 */
-		public X509Crl ReadCrl(
-			Stream inStream)
+		public X509Crl ReadCrl(Stream inStream)
 		{
 			if (inStream == null)
 				throw new ArgumentNullException("inStream");
@@ -129,9 +105,7 @@ namespace Org.BouncyCastle.X509
 				if (sCrlData != null)
 				{
 					if (sCrlDataObjectCount != sCrlData.Count)
-					{
 						return GetCrl();
-					}
 
 					sCrlData = null;
 					sCrlDataObjectCount = 0;
@@ -154,9 +128,7 @@ namespace Org.BouncyCastle.X509
                 }
 
                 if (tag != 0x30)	// assume ascii PEM encoded.
-				{
 					return ReadPemCrl(inStream);
-				}
 
 				Asn1InputStream asn1 = lazyAsn1
 					?	new LazyAsn1InputStream(inStream)
@@ -183,18 +155,18 @@ namespace Org.BouncyCastle.X509
 		 * only significant field being crls.  In particular the signature
 		 * and the contents are ignored.
 		 */
-		public ICollection ReadCrls(
-			Stream inStream)
+		public IList<X509Crl> ReadCrls(Stream inStream)
 		{
-			X509Crl crl;
-			IList crls = Platform.CreateArrayList();
+			return new List<X509Crl>(ParseCrls(inStream));
+		}
 
+		public IEnumerable<X509Crl> ParseCrls(Stream inStream)
+		{
+			X509Crl crl;
 			while ((crl = ReadCrl(inStream)) != null)
 			{
-				crls.Add(crl);
+				yield return crl;
 			}
-
-			return crls;
 		}
 	}
 }
diff --git a/crypto/src/x509/X509Utilities.cs b/crypto/src/x509/X509Utilities.cs
index 85f24f26a..30ca0b080 100644
--- a/crypto/src/x509/X509Utilities.cs
+++ b/crypto/src/x509/X509Utilities.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
@@ -10,122 +9,120 @@ using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.TeleTrust;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Asn1.X9;
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.X509
 {
 	internal class X509Utilities
 	{
-        private static readonly IDictionary algorithms = Platform.CreateHashtable();
-        private static readonly IDictionary exParams = Platform.CreateHashtable();
-		private static readonly HashSet<DerObjectIdentifier> noParams = new HashSet<DerObjectIdentifier>();
+        private static readonly Dictionary<string, DerObjectIdentifier> m_algorithms =
+			new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<string, Asn1Encodable> m_exParams =
+			new Dictionary<string, Asn1Encodable>(StringComparer.OrdinalIgnoreCase);
+		private static readonly HashSet<DerObjectIdentifier> m_noParams = new HashSet<DerObjectIdentifier>();
 
 		static X509Utilities()
 		{
-			algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption);
-			algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption);
-			algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption);
-			algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption);
-            algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
-            algorithms.Add("SHA-1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
-            algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
-            algorithms.Add("SHA-1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
-            algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
-            algorithms.Add("SHA-224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
-            algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
-            algorithms.Add("SHA-224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
-            algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
-            algorithms.Add("SHA-256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
-            algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
-            algorithms.Add("SHA-256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
-            algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
-            algorithms.Add("SHA-384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
-            algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
-            algorithms.Add("SHA-384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
-            algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
-            algorithms.Add("SHA-512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
-            algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
-            algorithms.Add("SHA-512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
-            algorithms.Add("SHA512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption);
-            algorithms.Add("SHA-512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption);
-            algorithms.Add("SHA512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption);
-            algorithms.Add("SHA-512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption);
-            algorithms.Add("SHA512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
-            algorithms.Add("SHA-512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
-            algorithms.Add("SHA512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
-            algorithms.Add("SHA-512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
-            algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
-			algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
-			algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
-			algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
-			algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
-			algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
-			algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1);
-			algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1);
-			algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224);
-			algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256);
-			algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384);
-			algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512);
-			algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1);
-			algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1);
-			algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224);
-			algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256);
-			algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384);
-			algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512);
-			algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
-			algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
-			algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
-			algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
-			algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+			m_algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption);
+			m_algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption);
+			m_algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption);
+			m_algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption);
+            m_algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
+            m_algorithms.Add("SHA-1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
+            m_algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
+            m_algorithms.Add("SHA-1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
+            m_algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
+            m_algorithms.Add("SHA-224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
+            m_algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
+            m_algorithms.Add("SHA-224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
+            m_algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
+            m_algorithms.Add("SHA-256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
+            m_algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
+            m_algorithms.Add("SHA-256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
+            m_algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
+            m_algorithms.Add("SHA-384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
+            m_algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
+            m_algorithms.Add("SHA-384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
+            m_algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
+            m_algorithms.Add("SHA-512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
+            m_algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
+            m_algorithms.Add("SHA-512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
+            m_algorithms.Add("SHA512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption);
+            m_algorithms.Add("SHA-512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption);
+            m_algorithms.Add("SHA512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption);
+            m_algorithms.Add("SHA-512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption);
+            m_algorithms.Add("SHA512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
+            m_algorithms.Add("SHA-512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
+            m_algorithms.Add("SHA512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
+            m_algorithms.Add("SHA-512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
+            m_algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+			m_algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+			m_algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+			m_algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+			m_algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+			m_algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
+			m_algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
+			m_algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
+			m_algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
+			m_algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
+			m_algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
+			m_algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1);
+			m_algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1);
+			m_algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224);
+			m_algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256);
+			m_algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384);
+			m_algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512);
+			m_algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1);
+			m_algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1);
+			m_algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224);
+			m_algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256);
+			m_algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384);
+			m_algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512);
+			m_algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+			m_algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+			m_algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+			m_algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+			m_algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
 
 			//
 			// According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
 			// The parameters field SHALL be NULL for RSA based signature algorithms.
 			//
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1);
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224);
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256);
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384);
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512);
-			noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1);
-            noParams.Add(OiwObjectIdentifiers.DsaWithSha1);
-            noParams.Add(NistObjectIdentifiers.DsaWithSha224);
-			noParams.Add(NistObjectIdentifiers.DsaWithSha256);
-			noParams.Add(NistObjectIdentifiers.DsaWithSha384);
-			noParams.Add(NistObjectIdentifiers.DsaWithSha512);
+			m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1);
+			m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224);
+			m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256);
+			m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384);
+			m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512);
+			m_noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1);
+            m_noParams.Add(OiwObjectIdentifiers.DsaWithSha1);
+            m_noParams.Add(NistObjectIdentifiers.DsaWithSha224);
+			m_noParams.Add(NistObjectIdentifiers.DsaWithSha256);
+			m_noParams.Add(NistObjectIdentifiers.DsaWithSha384);
+			m_noParams.Add(NistObjectIdentifiers.DsaWithSha512);
 
 			//
 			// RFC 4491
 			//
-			noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
-			noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+			m_noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+			m_noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
 
 			//
 			// explicit params
 			//
 			AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
-			exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20));
+			m_exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20));
 
 			AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance);
-			exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28));
+			m_exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28));
 
 			AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
-			exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32));
+			m_exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32));
 
 			AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
-			exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48));
+			m_exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48));
 
 			AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
-			exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64));
+			m_exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64));
 		}
 
 		private static RsassaPssParameters CreatePssParams(
@@ -139,68 +136,28 @@ namespace Org.BouncyCastle.X509
 				new DerInteger(1));
 		}
 
-		internal static DerObjectIdentifier GetAlgorithmOid(
-			string algorithmName)
+		internal static DerObjectIdentifier GetAlgorithmOid(string algorithmName)
 		{
-			algorithmName = Platform.ToUpperInvariant(algorithmName);
-
-            if (algorithms.Contains(algorithmName))
-			{
-				return (DerObjectIdentifier) algorithms[algorithmName];
-			}
+			if (m_algorithms.TryGetValue(algorithmName, out var oid))
+				return oid;
 
 			return new DerObjectIdentifier(algorithmName);
 		}
 
-		internal static AlgorithmIdentifier GetSigAlgID(
-			DerObjectIdentifier sigOid,
-			string				algorithmName)
+		internal static AlgorithmIdentifier GetSigAlgID(DerObjectIdentifier sigOid, string algorithmName)
 		{
-			if (noParams.Contains(sigOid))
-			{
+			if (m_noParams.Contains(sigOid))
 				return new AlgorithmIdentifier(sigOid);
-			}
-
-            algorithmName = Platform.ToUpperInvariant(algorithmName);
 
-			if (exParams.Contains(algorithmName))
-			{
-				return new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]);
-			}
+			if (m_exParams.TryGetValue(algorithmName, out var explicitParameters))
+				return new AlgorithmIdentifier(sigOid, explicitParameters);
 
 			return new AlgorithmIdentifier(sigOid, DerNull.Instance);
 		}
 
-		internal static IEnumerable GetAlgNames()
-		{
-			return new EnumerableProxy(algorithms.Keys);
-		}
-
-		internal static byte[] GetSignatureForObject(
-			DerObjectIdentifier		sigOid, // TODO Redundant now?
-			string					sigName,
-			AsymmetricKeyParameter	privateKey,
-			SecureRandom			random,
-			Asn1Encodable			ae)
+		internal static IEnumerable<string> GetAlgNames()
 		{
-			if (sigOid == null)
-				throw new ArgumentNullException("sigOid");
-
-			ISigner sig = SignerUtilities.GetSigner(sigName);
-
-			if (random != null)
-			{
-				sig.Init(true, new ParametersWithRandom(privateKey, random));
-			}
-			else
-			{
-				sig.Init(true, privateKey);
-			}
-
-			byte[] encoded = ae.GetDerEncoded();
-			sig.BlockUpdate(encoded, 0, encoded.Length);
-
-			return sig.GenerateSignature();
+			return CollectionUtilities.Proxy(m_algorithms.Keys);
 		}
 	}
 }
diff --git a/crypto/src/x509/X509V3CertificateGenerator.cs b/crypto/src/x509/X509V3CertificateGenerator.cs
index 47e58ddb5..7930ab23b 100644
--- a/crypto/src/x509/X509V3CertificateGenerator.cs
+++ b/crypto/src/x509/X509V3CertificateGenerator.cs
@@ -1,12 +1,11 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
+using System.IO;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Operators;
 using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Security.Certificates;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.X509.Extension;
@@ -226,11 +225,8 @@ namespace Org.BouncyCastle.X509
 			X509Certificate		cert)
 		{
 			Asn1OctetString extValue = cert.GetExtensionValue(oid);
-
 			if (extValue == null)
-			{
 				throw new CertificateParsingException("extension " + oid + " not present");
-			}
 
 			try
 			{
@@ -251,7 +247,9 @@ namespace Org.BouncyCastle.X509
 		/// <returns>An X509Certificate.</returns>
 		public X509Certificate Generate(ISignatureFactory signatureCalculatorFactory)
 		{
-			tbsGen.SetSignature ((AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails);
+			var sigAlgID = (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails;
+
+			tbsGen.SetSignature(sigAlgID);
 
             if (!extGenerator.IsEmpty)
             {
@@ -261,29 +259,20 @@ namespace Org.BouncyCastle.X509
             TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate();
 
 			IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator();
+			using (Stream sigStream = streamCalculator.Stream)
+            {
+				tbsCert.EncodeTo(sigStream, Asn1Encodable.Der);
+			}
 
-			byte[] encoded = tbsCert.GetDerEncoded();
-
-			streamCalculator.Stream.Write(encoded, 0, encoded.Length);
-
-            Platform.Dispose(streamCalculator.Stream);
+			var signature = ((IBlockResult)streamCalculator.GetResult()).Collect();
 
-            return GenerateJcaObject(tbsCert, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect());
-		}
-
-		private X509Certificate GenerateJcaObject(
-			TbsCertificateStructure	tbsCert,
-			AlgorithmIdentifier     sigAlg,
-			byte[]					signature)
-		{
-			return new X509Certificate(
-				new X509CertificateStructure(tbsCert, sigAlg, new DerBitString(signature)));
+			return new X509Certificate(new X509CertificateStructure(tbsCert, sigAlgID, new DerBitString(signature)));
 		}
 
 		/// <summary>
 		/// Allows enumeration of the signature names supported by the generator.
 		/// </summary>
-		public IEnumerable SignatureAlgNames
+		public IEnumerable<string> SignatureAlgNames
 		{
 			get { return X509Utilities.GetAlgNames(); }
 		}
diff --git a/crypto/src/x509/store/X509CertStoreSelector.cs b/crypto/src/x509/store/X509CertStoreSelector.cs
index b351f1cf3..197e8f26d 100644
--- a/crypto/src/x509/store/X509CertStoreSelector.cs
+++ b/crypto/src/x509/store/X509CertStoreSelector.cs
@@ -192,7 +192,7 @@ namespace Org.BouncyCastle.X509.Store
 
 			if (extendedKeyUsage != null)
 			{
-				IList eku = c.GetExtendedKeyUsage();
+				var eku = c.GetExtendedKeyUsage();
 
 				// Note: if no extended key usage set, all key purposes are implicitly allowed
 
@@ -200,7 +200,7 @@ namespace Org.BouncyCastle.X509.Store
 				{
 					foreach (DerObjectIdentifier oid in extendedKeyUsage)
 					{
-						if (!eku.Contains(oid.Id))
+						if (!eku.Contains(oid))
 							return false;
 					}
 				}
diff --git a/crypto/test/src/asn1/test/X509NameTest.cs b/crypto/test/src/asn1/test/X509NameTest.cs
index 0df3a020e..c6de1b1db 100644
--- a/crypto/test/src/asn1/test/X509NameTest.cs
+++ b/crypto/test/src/asn1/test/X509NameTest.cs
@@ -1,6 +1,6 @@
 using System;
 using System.Collections;
-using System.IO;
+using System.Collections.Generic;
 
 using NUnit.Framework;
 
@@ -170,7 +170,7 @@ namespace Org.BouncyCastle.Asn1.Tests
                 Fail("Failed same name test - in Order");
             }
 
-            IList ord1 = new ArrayList();
+            var ord1 = new List<DerObjectIdentifier>();
 
             ord1.Add(X509Name.C);
             ord1.Add(X509Name.O);
@@ -178,7 +178,7 @@ namespace Org.BouncyCastle.Asn1.Tests
             ord1.Add(X509Name.ST);
             ord1.Add(X509Name.E);
 
-            IList ord2 = new ArrayList();
+            var ord2 = new List<DerObjectIdentifier>();
 
             ord2.Add(X509Name.E);
             ord2.Add(X509Name.ST);
@@ -210,13 +210,13 @@ namespace Org.BouncyCastle.Asn1.Tests
                 Fail("Failed reverse name test - in Order false");
             }
 
-            IList oids = name1.GetOidList();
+            var oids = name1.GetOidList();
             if (!CompareVectors(oids, ord1))
             {
                 Fail("oid comparison test");
             }
 
-            IList val1 = new ArrayList();
+            var val1 = new List<string>();
 
             val1.Add("AU");
             val1.Add("The Legion of the Bouncy Castle");
@@ -226,13 +226,13 @@ namespace Org.BouncyCastle.Asn1.Tests
 
             name1 = new X509Name(ord1, val1);
 
-            IList values = name1.GetValueList();
+            var values = name1.GetValueList();
             if (!CompareVectors(values, val1))
             {
                 Fail("value comparison test");
             }
 
-            ord2 = new ArrayList();
+            ord2 = new List<DerObjectIdentifier>();
 
             ord2.Add(X509Name.ST);
             ord2.Add(X509Name.ST);
@@ -248,7 +248,7 @@ namespace Org.BouncyCastle.Asn1.Tests
                 Fail("Failed different name test");
             }
 
-            ord2 = new ArrayList();
+            ord2 = new List<DerObjectIdentifier>();
 
             ord2.Add(X509Name.ST);
             ord2.Add(X509Name.L);
@@ -270,14 +270,14 @@ namespace Org.BouncyCastle.Asn1.Tests
             //
             // getValues test
             //
-            IList v1 = name1.GetValueList(X509Name.O);
+            var v1 = name1.GetValueList(X509Name.O);
 
             if (v1.Count != 1 || !v1[0].Equals("The Legion of the Bouncy Castle"))
             {
                 Fail("O test failed");
             }
 
-            IList v2 = name1.GetValueList(X509Name.L);
+            var v2 = name1.GetValueList(X509Name.L);
 
             if (v2.Count != 1 || !v2[0].Equals("Melbourne"))
             {
@@ -505,7 +505,7 @@ namespace Org.BouncyCastle.Asn1.Tests
                 Fail("# string not properly escaped.");
             }
 
-            IList vls = n.GetValueList(X509Name.CN);
+            var vls = n.GetValueList(X509Name.CN);
             if (vls.Count != 1 || !vls[0].Equals("#nothex#string"))
             {
                 Fail("Escaped # not reduced properly");
@@ -633,16 +633,14 @@ namespace Org.BouncyCastle.Asn1.Tests
             }
         }
 
-        private bool CompareVectors(
-            IList	one,
-            IList	two)
+        private bool CompareVectors<T>(IList<T> one, IList<T> two)
         {
             if (one.Count != two.Count)
                 return false;
 
             for (int i = 0; i < one.Count; ++i)
             {
-                if (!one[i].Equals(two[i]))
+                if (!Equals(one[i], two[i]))
                     return false;
             }
 
diff --git a/crypto/test/src/test/CertPathTest.cs b/crypto/test/src/test/CertPathTest.cs
index e254e0c41..869ffd6a0 100644
--- a/crypto/test/src/test/CertPathTest.cs
+++ b/crypto/test/src/test/CertPathTest.cs
@@ -173,9 +173,8 @@ namespace Org.BouncyCastle.Tests
 			X509Certificate finalCert = cf.ReadCertificate(finalCertBin);
 
 			//Testing CertPath generation from List
-			IList list = new ArrayList();
+			var list = new List<X509Certificate>();
 			list.Add(interCert);
-//			CertPath certPath1 = cf.generateCertPath(list);
 			PkixCertPath certPath1 = new PkixCertPath(list);
 
 			//Testing CertPath encoding as PkiPath
@@ -183,7 +182,6 @@ namespace Org.BouncyCastle.Tests
 
 			//Testing CertPath generation from InputStream
 			MemoryStream inStream = new MemoryStream(encoded, false);
-//			CertPath certPath2 = cf.generateCertPath(inStream, "PkiPath");
 			PkixCertPath certPath2 = new PkixCertPath(inStream, "PkiPath");
 
 			//Comparing both CertPathes
@@ -221,9 +219,8 @@ namespace Org.BouncyCastle.Tests
 			//
 			// empty list test
 			//
-			list = new ArrayList();
+			list = new List<X509Certificate>();
 
-//			CertPath certPath = CertificateFactory.GetInstance("X.509","BC").generateCertPath(list);
 			PkixCertPath certPath = new PkixCertPath(list);
 			if (certPath.Certificates.Count != 0)
 			{
diff --git a/crypto/test/src/test/CertPathValidatorTest.cs b/crypto/test/src/test/CertPathValidatorTest.cs
index b4d5d7773..88ffe7938 100644
--- a/crypto/test/src/test/CertPathValidatorTest.cs
+++ b/crypto/test/src/test/CertPathValidatorTest.cs
@@ -154,16 +154,14 @@ namespace Org.BouncyCastle.Tests
             DateTime validDate = new DateTime(2008, 9, 4, 5, 49, 10);
 
             //validating path
-            IList certchain = new ArrayList();
+            var certchain = new List<X509Certificate>();
             certchain.Add(finalCert);
             certchain.Add(interCert);
 
-//			CertPath cp = CertificateFactory.GetInstance("X.509").GenerateCertPath(certchain);
             PkixCertPath cp = new PkixCertPath(certchain);
             var trust = new HashSet<TrustAnchor>();
             trust.Add(new TrustAnchor(rootCert, null));
 
-//			CertPathValidator cpv = CertPathValidator.GetInstance("PKIX");
             PkixCertPathValidator cpv = new PkixCertPathValidator();
             PkixParameters param = new PkixParameters(trust);
             param.AddStoreCert(x509CertStore);
@@ -172,7 +170,7 @@ namespace Org.BouncyCastle.Tests
             MyChecker checker = new MyChecker();
             param.AddCertPathChecker(checker);
 
-            PkixCertPathValidatorResult result = (PkixCertPathValidatorResult)cpv.Validate(cp, param);
+            PkixCertPathValidatorResult result = cpv.Validate(cp, param);
             PkixPolicyNode policyTree = result.PolicyTree;
             AsymmetricKeyParameter subjectPublicKey = result.SubjectPublicKey;
 
@@ -230,23 +228,21 @@ namespace Org.BouncyCastle.Tests
                 validDate = new DateTime(2004, 3, 20, 19, 21, 10);
 
                 //validating path
-                certchain = new ArrayList();
+                certchain = new List<X509Certificate>();
                 certchain.Add(finalCert);
                 certchain.Add(interCert);
 
-//				cp = CertificateFactory.GetInstance("X.509").GenerateCertPath(certchain);
                 cp = new PkixCertPath(certchain);
                 trust = new HashSet<TrustAnchor>();
                 trust.Add(new TrustAnchor(rootCert, null));
 
-//				cpv = CertPathValidator.GetInstance("PKIX");
                 cpv = new PkixCertPathValidator();
                 param = new PkixParameters(trust);
                 param.AddStoreCert(x509CertStore);
                 param.IsRevocationEnabled = false;
                 param.Date = new DateTimeObject(validDate);
 
-                result =(PkixCertPathValidatorResult) cpv.Validate(cp, param);
+                result = cpv.Validate(cp, param);
                 policyTree = result.PolicyTree;
                 subjectPublicKey = result.SubjectPublicKey;
 
diff --git a/crypto/test/src/test/CertTest.cs b/crypto/test/src/test/CertTest.cs
index 5fc23d861..0e1cf1d70 100644
--- a/crypto/test/src/test/CertTest.cs
+++ b/crypto/test/src/test/CertTest.cs
@@ -1137,7 +1137,7 @@ namespace Org.BouncyCastle.Tests
             //
             // distinguished name table.
             //
-            IList ord = new ArrayList();
+            var ord = new List<DerObjectIdentifier>();
             ord.Add(X509Name.C);
             ord.Add(X509Name.O);
             ord.Add(X509Name.L);
@@ -1215,8 +1215,8 @@ namespace Org.BouncyCastle.Tests
                 Fail("error generating cert - key usage wrong.");
             }
 
-            IList l = cert.GetExtendedKeyUsage();
-            if (!l[0].Equals(KeyPurposeID.AnyExtendedKeyUsage.Id))
+            var ekus = cert.GetExtendedKeyUsage();
+            if (ekus.Count < 1 || !KeyPurposeID.AnyExtendedKeyUsage.Equals(ekus[0]))
             {
                 Fail("failed extended key usage test");
             }
@@ -1291,7 +1291,7 @@ namespace Org.BouncyCastle.Tests
             //
             // distinguished name table.
             //
-            IList ord = new ArrayList();
+            var ord = new List<DerObjectIdentifier>();
             ord.Add(X509Name.C);
             ord.Add(X509Name.O);
             ord.Add(X509Name.L);
@@ -1312,7 +1312,7 @@ namespace Org.BouncyCastle.Tests
             //
             // create the certificate - version 3
             //
-            X509V3CertificateGenerator  certGen = new X509V3CertificateGenerator();
+            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
 
             certGen.SetSerialNumber(BigInteger.One);
             certGen.SetIssuerDN(new X509Name(ord, values));
@@ -1967,9 +1967,7 @@ namespace Org.BouncyCastle.Tests
                 Fail("crl not returned!");
             }
 
-//			ICollection col = cFact.generateCRLs(new ByteArrayInputStream(newCrl.getEncoded()));
-            ICollection col = new X509CrlParser().ReadCrls(newCrl.GetEncoded());
-
+            var col = new X509CrlParser().ReadCrls(newCrl.GetEncoded());
             if (col.Count != 1)
             {
                 Fail("wrong number of CRLs found in collection");
@@ -2090,7 +2088,7 @@ namespace Org.BouncyCastle.Tests
             //
             // distinguished name table.
             //
-            IList ord = new ArrayList();
+            var ord = new List<DerObjectIdentifier>();
             ord.Add(X509Name.C);
             ord.Add(X509Name.O);
             ord.Add(X509Name.L);
@@ -2230,15 +2228,13 @@ namespace Org.BouncyCastle.Tests
             {
                 Fail("PEM crl not read");
             }
-            ArrayList col = new ArrayList(
-                new X509CertificateParser().ReadCertificates(Encoding.ASCII.GetBytes(PemData.CERTIFICATE_2)));
-            if (col.Count != 1 || !col.Contains(cert))
+            var certList = new X509CertificateParser().ReadCertificates(Encoding.ASCII.GetBytes(PemData.CERTIFICATE_2));
+            if (certList.Count != 1 || !certList.Contains(cert))
             {
                 Fail("PEM cert collection not right");
             }
-            col = new ArrayList(
-                new X509CrlParser().ReadCrls(Encoding.ASCII.GetBytes(PemData.CRL_2)));
-            if (col.Count != 1 || !col.Contains(crl))
+            var crlList = new X509CrlParser().ReadCrls(Encoding.ASCII.GetBytes(PemData.CRL_2));
+            if (crlList.Count != 1 || !crlList.Contains(crl))
             {
                 Fail("PEM crl collection not right");
             }
@@ -2279,13 +2275,13 @@ namespace Org.BouncyCastle.Tests
             {
                 Fail("PKCS7 crl not read");
             }
-            ArrayList col = new ArrayList(certParser.ReadCertificates(info.GetEncoded()));
-            if (col.Count != 1 || !col.Contains(cert))
+            var certList = certParser.ReadCertificates(info.GetEncoded());
+            if (certList.Count != 1 || !certList.Contains(cert))
             {
                 Fail("PKCS7 cert collection not right");
             }
-            col = new ArrayList(crlParser.ReadCrls(info.GetEncoded()));
-            if (col.Count != 1 || !col.Contains(crl))
+            var crlList = crlParser.ReadCrls(info.GetEncoded());
+            if (crlList.Count != 1 || !crlList.Contains(crl))
             {
                 Fail("PKCS7 crl collection not right");
             }
@@ -2327,8 +2323,8 @@ namespace Org.BouncyCastle.Tests
             //
             // sample message
             //
-            ICollection certCol = certParser.ReadCertificates(pkcs7CrlProblem);
-            ICollection crlCol = crlParser.ReadCrls(pkcs7CrlProblem);
+            var certCol = certParser.ReadCertificates(pkcs7CrlProblem);
+            var crlCol = crlParser.ReadCrls(pkcs7CrlProblem);
 
             if (crlCol.Count != 0)
             {
@@ -2352,7 +2348,7 @@ namespace Org.BouncyCastle.Tests
             //
             // distinguished name table.
             //
-            IList ord = new ArrayList();
+            var ord = new List<DerObjectIdentifier>();
             ord.Add(X509Name.C);
             ord.Add(X509Name.O);
             ord.Add(X509Name.L);
@@ -2474,7 +2470,7 @@ namespace Org.BouncyCastle.Tests
         {
             X509CertificateParser fact = new X509CertificateParser();
 
-            ICollection certs1 = fact.ReadCertificates(GetTestDataAsStream("cert_chain.data"));
+            var certs1 = fact.ReadCertificates(GetTestDataAsStream("cert_chain.data"));
             IsTrue("certs wrong <cr><nl>", 2 == certs1.Count);
 
             MemoryStream input = new MemoryStream(Streams.ReadAll(GetTestDataAsStream("cert_chain.data")), false);
@@ -2501,10 +2497,10 @@ namespace Org.BouncyCastle.Tests
         {
             X509CrlParser crlParser = new X509CrlParser();
 
-            ICollection crls = crlParser.ReadCrls(GetTestDataAsStream("cert_chain.data"));
+            var crls = crlParser.ReadCrls(GetTestDataAsStream("cert_chain.data"));
             IsTrue("multi crl", crls.Count == 0);
 
-            X509Crl crl = crlParser.ReadCrl(GetTestDataAsStream("cert_chain.data"));
+            var crl = crlParser.ReadCrl(GetTestDataAsStream("cert_chain.data"));
             IsTrue("single crl", crl == null);
         }
 
@@ -2512,7 +2508,7 @@ namespace Org.BouncyCastle.Tests
         {
             X509CertificateParser fact = new X509CertificateParser();
 
-            ICollection certs1 = fact.ReadCertificates(GetTestDataAsStream("cert_chain_nl.data"));
+            var certs1 = fact.ReadCertificates(GetTestDataAsStream("cert_chain_nl.data"));
             IsTrue("certs wrong <nl>", 2 == certs1.Count);
 
             MemoryStream input = new MemoryStream(Streams.ReadAll(GetTestDataAsStream("cert_chain_nl.data")), false);