summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-06-28 20:49:58 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-06-28 20:49:58 +0700
commitdc5029c8650432ae04df78d2ead06a8349176b74 (patch)
tree306f232f9cf53762ccb427225dee958313b884fd /crypto/src
parentGenerics migration in Ocsp, OpenPgp (diff)
downloadBouncyCastle.NET-ed25519-dc5029c8650432ae04df78d2ead06a8349176b74.tar.xz
Generics migration in Tls
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/tls/AbstractTlsClient.cs74
-rw-r--r--crypto/src/tls/AbstractTlsServer.cs35
-rw-r--r--crypto/src/tls/Certificate.cs19
-rw-r--r--crypto/src/tls/CertificateEntry.cs8
-rw-r--r--crypto/src/tls/CertificateRequest.cs51
-rw-r--r--crypto/src/tls/CertificateStatus.cs27
-rw-r--r--crypto/src/tls/CertificateUrl.cs10
-rw-r--r--crypto/src/tls/ClientHello.cs10
-rw-r--r--crypto/src/tls/DefaultTlsDHGroupVerifier.cs11
-rw-r--r--crypto/src/tls/DefaultTlsSrpConfigVerifier.cs11
-rw-r--r--crypto/src/tls/DeferredHash.cs18
-rw-r--r--crypto/src/tls/DtlsClientProtocol.cs16
-rw-r--r--crypto/src/tls/DtlsProtocol.cs9
-rw-r--r--crypto/src/tls/DtlsReassembler.cs6
-rw-r--r--crypto/src/tls/DtlsReliableHandshake.cs29
-rw-r--r--crypto/src/tls/DtlsServerProtocol.cs10
-rw-r--r--crypto/src/tls/OcspStatusRequest.cs11
-rw-r--r--crypto/src/tls/OfferedPsks.cs18
-rw-r--r--crypto/src/tls/ProtocolVersion.cs11
-rw-r--r--crypto/src/tls/SecurityParameters.cs22
-rw-r--r--crypto/src/tls/ServerHello.cs12
-rw-r--r--crypto/src/tls/ServerNameList.cs10
-rw-r--r--crypto/src/tls/SessionParameters.cs6
-rw-r--r--crypto/src/tls/SrpTlsClient.cs8
-rw-r--r--crypto/src/tls/SrpTlsServer.cs4
-rw-r--r--crypto/src/tls/TlsClient.cs14
-rw-r--r--crypto/src/tls/TlsClientProtocol.cs29
-rw-r--r--crypto/src/tls/TlsExtensionsUtilities.cs275
-rw-r--r--crypto/src/tls/TlsProtocol.cs74
-rw-r--r--crypto/src/tls/TlsServer.cs14
-rw-r--r--crypto/src/tls/TlsServerProtocol.cs22
-rw-r--r--crypto/src/tls/TlsSrpUtilities.cs6
-rw-r--r--crypto/src/tls/TlsSrtpUtilities.cs6
-rw-r--r--crypto/src/tls/TlsUtilities.cs265
-rw-r--r--crypto/src/tls/crypto/TlsCrypto.cs4
-rw-r--r--crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs4
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs4
37 files changed, 574 insertions, 589 deletions
diff --git a/crypto/src/tls/AbstractTlsClient.cs b/crypto/src/tls/AbstractTlsClient.cs
index d5e1925a8..cf4e1d565 100644
--- a/crypto/src/tls/AbstractTlsClient.cs
+++ b/crypto/src/tls/AbstractTlsClient.cs
@@ -1,7 +1,8 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
+using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Tls.Crypto;
 using Org.BouncyCastle.Utilities;
 
@@ -15,9 +16,9 @@ namespace Org.BouncyCastle.Tls
         protected ProtocolVersion[] m_protocolVersions;
         protected int[] m_cipherSuites;
 
-        protected IList m_supportedGroups;
-        protected IList m_supportedSignatureAlgorithms;
-        protected IList m_supportedSignatureAlgorithmsCert;
+        protected IList<int> m_supportedGroups;
+        protected IList<SignatureAndHashAlgorithm> m_supportedSignatureAlgorithms;
+        protected IList<SignatureAndHashAlgorithm> m_supportedSignatureAlgorithmsCert;
 
         protected AbstractTlsClient(TlsCrypto crypto)
             : base(crypto)
@@ -52,14 +53,14 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        protected virtual IList GetNamedGroupRoles()
+        protected virtual IList<int> GetNamedGroupRoles()
         {
-            IList namedGroupRoles = TlsUtilities.GetNamedGroupRoles(GetCipherSuites());
-            IList sigAlgs = m_supportedSignatureAlgorithms, sigAlgsCert = m_supportedSignatureAlgorithmsCert;
+            var namedGroupRoles = TlsUtilities.GetNamedGroupRoles(GetCipherSuites());
+            var sigAlgs = m_supportedSignatureAlgorithms;
+            var sigAlgsCert = m_supportedSignatureAlgorithmsCert;
 
-            if ((null == sigAlgs || TlsUtilities.ContainsAnySignatureAlgorithm(sigAlgs, SignatureAlgorithm.ecdsa))
-                || (null != sigAlgsCert
-                    && TlsUtilities.ContainsAnySignatureAlgorithm(sigAlgsCert, SignatureAlgorithm.ecdsa)))
+            if ((null == sigAlgs || TlsUtilities.ContainsAnySignatureAlgorithm(sigAlgs, SignatureAlgorithm.ecdsa)) ||
+                (null != sigAlgsCert && TlsUtilities.ContainsAnySignatureAlgorithm(sigAlgsCert, SignatureAlgorithm.ecdsa)))
             {
                 TlsUtilities.AddToSet(namedGroupRoles, NamedGroupRole.ecdsa);
             }
@@ -68,7 +69,8 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        protected virtual void CheckForUnexpectedServerExtension(IDictionary serverExtensions, int extensionType)
+        protected virtual void CheckForUnexpectedServerExtension(IDictionary<int, byte[]> serverExtensions,
+            int extensionType)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(serverExtensions, extensionType);
             if (extensionData != null && !AllowUnexpectedServerExtension(extensionType, extensionData))
@@ -97,12 +99,12 @@ namespace Org.BouncyCastle.Tls
             return new DefaultTlsSrpConfigVerifier();
         }
 
-        protected virtual IList GetCertificateAuthorities()
+        protected virtual IList<X509Name> GetCertificateAuthorities()
         {
             return null;
         }
 
-        protected virtual IList GetProtocolNames()
+        protected virtual IList<ProtocolName> GetProtocolNames()
         {
             return null;
         }
@@ -113,12 +115,12 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <returns>an <see cref="IList"/> of <see cref="CertificateStatusRequestItemV2"/> (or null).</returns>
-        protected virtual IList GetMultiCertStatusRequest()
+        protected virtual IList<CertificateStatusRequestItemV2> GetMultiCertStatusRequest()
         {
             return null;
         }
 
-        protected virtual IList GetSniServerNames()
+        protected virtual IList<ServerName> GetSniServerNames()
         {
             return null;
         }
@@ -130,10 +132,10 @@ namespace Org.BouncyCastle.Tls
         /// algorithms.</param>
         /// <returns>an <see cref="IList"/> of <see cref="Int32"/>. See <see cref="NamedGroup"/> for group constants.
         /// </returns>
-        protected virtual IList GetSupportedGroups(IList namedGroupRoles)
+        protected virtual IList<int> GetSupportedGroups(IList<int> namedGroupRoles)
         {
             TlsCrypto crypto = Crypto;
-            IList supportedGroups = Platform.CreateArrayList();
+            var supportedGroups = new List<int>();
 
             if (namedGroupRoles.Contains(NamedGroupRole.ecdh))
             {
@@ -157,17 +159,17 @@ namespace Org.BouncyCastle.Tls
             return supportedGroups;
         }
 
-        protected virtual IList GetSupportedSignatureAlgorithms()
+        protected virtual IList<SignatureAndHashAlgorithm> GetSupportedSignatureAlgorithms()
         {
             return TlsUtilities.GetDefaultSupportedSignatureAlgorithms(m_context);
         }
 
-        protected virtual IList GetSupportedSignatureAlgorithmsCert()
+        protected virtual IList<SignatureAndHashAlgorithm> GetSupportedSignatureAlgorithmsCert()
         {
             return null;
         }
 
-        protected virtual IList GetTrustedCAIndication()
+        protected virtual IList<TrustedAuthority> GetTrustedCAIndication()
         {
             return null;
         }
@@ -205,7 +207,7 @@ namespace Org.BouncyCastle.Tls
             return null;
         }
 
-        public virtual IList GetExternalPsks()
+        public virtual IList<TlsPskExternal> GetExternalPsks()
         {
             return null;
         }
@@ -221,9 +223,9 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public virtual IDictionary GetClientExtensions()
+        public virtual IDictionary<int, byte[]> GetClientExtensions()
         {
-            IDictionary clientExtensions = Platform.CreateHashtable();
+            var clientExtensions = new Dictionary<int, byte[]>();
 
             bool offeringTlsV13Plus = false;
             bool offeringPreTlsV13 = false;
@@ -242,13 +244,13 @@ namespace Org.BouncyCastle.Tls
                 }
             }
 
-            IList protocolNames = GetProtocolNames();
+            var protocolNames = GetProtocolNames();
             if (protocolNames != null)
             {
                 TlsExtensionsUtilities.AddAlpnExtensionClient(clientExtensions, protocolNames);
             }
 
-            IList sniServerNames = GetSniServerNames();
+            var sniServerNames = GetSniServerNames();
             if (sniServerNames != null)
             {
                 TlsExtensionsUtilities.AddServerNameExtensionClient(clientExtensions, sniServerNames);
@@ -262,7 +264,7 @@ namespace Org.BouncyCastle.Tls
 
             if (offeringTlsV13Plus)
             {
-                IList certificateAuthorities = GetCertificateAuthorities();
+                var certificateAuthorities = GetCertificateAuthorities();
                 if (certificateAuthorities != null)
                 {
                     TlsExtensionsUtilities.AddCertificateAuthoritiesExtension(clientExtensions, certificateAuthorities);
@@ -274,13 +276,13 @@ namespace Org.BouncyCastle.Tls
                 // TODO Shouldn't add if no offered cipher suite uses a block cipher?
                 TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions);
 
-                IList statusRequestV2 = GetMultiCertStatusRequest();
+                var statusRequestV2 = GetMultiCertStatusRequest();
                 if (statusRequestV2 != null)
                 {
                     TlsExtensionsUtilities.AddStatusRequestV2Extension(clientExtensions, statusRequestV2);
                 }
 
-                IList trustedCAKeys = GetTrustedCAIndication();
+                var trustedCAKeys = GetTrustedCAIndication();
                 if (trustedCAKeys != null)
                 {
                     TlsExtensionsUtilities.AddTrustedCAKeysExtensionClient(clientExtensions, trustedCAKeys);
@@ -295,7 +297,7 @@ namespace Org.BouncyCastle.Tls
              */
             if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion))
             {
-                IList supportedSigAlgs = GetSupportedSignatureAlgorithms();
+                var supportedSigAlgs = GetSupportedSignatureAlgorithms();
                 if (null != supportedSigAlgs && supportedSigAlgs.Count > 0)
                 {
                     this.m_supportedSignatureAlgorithms = supportedSigAlgs;
@@ -303,7 +305,7 @@ namespace Org.BouncyCastle.Tls
                     TlsExtensionsUtilities.AddSignatureAlgorithmsExtension(clientExtensions, supportedSigAlgs);
                 }
 
-                IList supportedSigAlgsCert = GetSupportedSignatureAlgorithmsCert();
+                var supportedSigAlgsCert = GetSupportedSignatureAlgorithmsCert();
                 if (null != supportedSigAlgsCert && supportedSigAlgsCert.Count > 0)
                 {
                     this.m_supportedSignatureAlgorithmsCert = supportedSigAlgsCert;
@@ -312,9 +314,9 @@ namespace Org.BouncyCastle.Tls
                 }
             }
 
-            IList namedGroupRoles = GetNamedGroupRoles();
+            var namedGroupRoles = GetNamedGroupRoles();
 
-            IList supportedGroups = GetSupportedGroups(namedGroupRoles);
+            var supportedGroups = GetSupportedGroups(namedGroupRoles);
             if (supportedGroups != null && supportedGroups.Count > 0)
             {
                 this.m_supportedGroups = supportedGroups;
@@ -335,7 +337,7 @@ namespace Org.BouncyCastle.Tls
             return clientExtensions;
         }
 
-        public virtual IList GetEarlyKeyShareGroups()
+        public virtual IList<int> GetEarlyKeyShareGroups()
         {
             /*
              * RFC 8446 4.2.8. Each KeyShareEntry value MUST correspond to a group offered in the
@@ -379,7 +381,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public virtual void ProcessServerExtensions(IDictionary serverExtensions)
+        public virtual void ProcessServerExtensions(IDictionary<int, byte[]> serverExtensions)
         {
             if (null == serverExtensions)
                 return;
@@ -423,7 +425,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public virtual void ProcessServerSupplementalData(IList serverSupplementalData)
+        public virtual void ProcessServerSupplementalData(IList<SupplementalDataEntry> serverSupplementalData)
         {
             if (serverSupplementalData != null)
                 throw new TlsFatalAlert(AlertDescription.unexpected_message);
@@ -432,7 +434,7 @@ namespace Org.BouncyCastle.Tls
         public abstract TlsAuthentication GetAuthentication();
 
         /// <exception cref="IOException"/>
-        public virtual IList GetClientSupplementalData()
+        public virtual IList<SupplementalDataEntry> GetClientSupplementalData()
         {
             return null;
         }
diff --git a/crypto/src/tls/AbstractTlsServer.cs b/crypto/src/tls/AbstractTlsServer.cs
index f12233326..a41bc4710 100644
--- a/crypto/src/tls/AbstractTlsServer.cs
+++ b/crypto/src/tls/AbstractTlsServer.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -16,21 +16,21 @@ namespace Org.BouncyCastle.Tls
         protected int[] m_cipherSuites;
 
         protected int[] m_offeredCipherSuites;
-        protected IDictionary m_clientExtensions;
+        protected IDictionary<int, byte[]> m_clientExtensions;
 
         protected bool m_encryptThenMACOffered;
         protected short m_maxFragmentLengthOffered;
         protected bool m_truncatedHMacOffered;
         protected bool m_clientSentECPointFormats;
         protected CertificateStatusRequest m_certificateStatusRequest;
-        protected IList m_statusRequestV2;
-        protected IList m_trustedCAKeys;
+        protected IList<CertificateStatusRequestItemV2> m_statusRequestV2;
+        protected IList<TrustedAuthority> m_trustedCAKeys;
 
         protected int m_selectedCipherSuite;
-        protected IList m_clientProtocolNames;
+        protected IList<ProtocolName> m_clientProtocolNames;
         protected ProtocolName m_selectedProtocolName;
 
-        protected readonly IDictionary m_serverExtensions = Platform.CreateHashtable();
+        protected readonly IDictionary<int, byte[]> m_serverExtensions = new Dictionary<int, byte[]>();
 
         public AbstractTlsServer(TlsCrypto crypto)
             : base(crypto)
@@ -99,13 +99,13 @@ namespace Org.BouncyCastle.Tls
             return maxBits;
         }
 
-        protected virtual IList GetProtocolNames()
+        protected virtual IList<ProtocolName> GetProtocolNames()
         {
             return null;
         }
 
         protected virtual bool IsSelectableCipherSuite(int cipherSuite, int availCurveBits, int availFiniteFieldBits,
-            IList sigAlgs)
+            IList<short> sigAlgs)
         {
             // TODO[tls13] The version check should be separated out (eventually select ciphersuite before version)
             return TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, m_context.ServerVersion)
@@ -180,7 +180,7 @@ namespace Org.BouncyCastle.Tls
 
         protected virtual ProtocolName SelectProtocolName()
         {
-            IList serverProtocolNames = GetProtocolNames();
+            IList<ProtocolName> serverProtocolNames = GetProtocolNames();
             if (null == serverProtocolNames || serverProtocolNames.Count < 1)
                 return null;
 
@@ -191,7 +191,8 @@ namespace Org.BouncyCastle.Tls
             return result;
         }
 
-        protected virtual ProtocolName SelectProtocolName(IList clientProtocolNames, IList serverProtocolNames)
+        protected virtual ProtocolName SelectProtocolName(IList<ProtocolName> clientProtocolNames,
+            IList<ProtocolName> serverProtocolNames)
         {
             foreach (ProtocolName serverProtocolName in serverProtocolNames)
             {
@@ -250,7 +251,7 @@ namespace Org.BouncyCastle.Tls
             return null;
         }
 
-        public virtual TlsPskExternal GetExternalPsk(IList identities)
+        public virtual TlsPskExternal GetExternalPsk(IList<PskIdentity> identities)
         {
             return null;
         }
@@ -302,7 +303,7 @@ namespace Org.BouncyCastle.Tls
             this.m_offeredCipherSuites = offeredCipherSuites;
         }
 
-        public virtual void ProcessClientExtensions(IDictionary clientExtensions)
+        public virtual void ProcessClientExtensions(IDictionary<int, byte[]> clientExtensions)
         {
             this.m_clientExtensions = clientExtensions;
 
@@ -382,7 +383,7 @@ namespace Org.BouncyCastle.Tls
                  * somewhat inelegant but is a compromise designed to minimize changes to the original
                  * cipher suite design.
                  */
-                IList sigAlgs = TlsUtilities.GetUsableSignatureAlgorithms(securityParameters.ClientSigAlgs);
+                var sigAlgs = TlsUtilities.GetUsableSignatureAlgorithms(securityParameters.ClientSigAlgs);
 
                 /*
                  * RFC 4429 5.1. A server that receives a ClientHello containing one or both of these
@@ -412,7 +413,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         // IDictionary is (Int32 -> byte[])
-        public virtual IDictionary GetServerExtensions()
+        public virtual IDictionary<int, byte[]> GetServerExtensions()
         {
             bool isTlsV13 = TlsUtilities.IsTlsV13(m_context);
 
@@ -493,7 +494,7 @@ namespace Org.BouncyCastle.Tls
             return m_serverExtensions;
         }
 
-        public virtual void GetServerExtensionsForConnection(IDictionary serverExtensions)
+        public virtual void GetServerExtensionsForConnection(IDictionary<int, byte[]> serverExtensions)
         {
             if (!ShouldSelectProtocolNameEarly())
             {
@@ -518,7 +519,7 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public virtual IList GetServerSupplementalData()
+        public virtual IList<SupplementalDataEntry> GetServerSupplementalData()
         {
             return null;
         }
@@ -559,7 +560,7 @@ namespace Org.BouncyCastle.Tls
             return TlsEccUtilities.CreateNamedECConfig(m_context, namedGroup);
         }
 
-        public virtual void ProcessClientSupplementalData(IList clientSupplementalData)
+        public virtual void ProcessClientSupplementalData(IList<SupplementalDataEntry> clientSupplementalData)
         {
             if (clientSupplementalData != null)
                 throw new TlsFatalAlert(AlertDescription.unexpected_message);
diff --git a/crypto/src/tls/Certificate.cs b/crypto/src/tls/Certificate.cs
index fef35fc1e..c7f08b2aa 100644
--- a/crypto/src/tls/Certificate.cs
+++ b/crypto/src/tls/Certificate.cs
@@ -1,9 +1,8 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Tls
 {
@@ -137,8 +136,8 @@ namespace Org.BouncyCastle.Tls
             }
 
             int count = m_certificateEntryList.Length;
-            IList certEncodings = Platform.CreateArrayList(count);
-            IList extEncodings = isTlsV13 ? Platform.CreateArrayList(count) : null;
+            var certEncodings = new List<byte[]>(count);
+            var extEncodings = isTlsV13 ? new List<byte[]>(count) : null;
 
             long totalLength = 0;
             for (int i = 0; i < count; ++i)
@@ -158,7 +157,7 @@ namespace Org.BouncyCastle.Tls
 
                 if (isTlsV13)
                 {
-                    IDictionary extensions = entry.Extensions;
+                    var extensions = entry.Extensions;
                     byte[] extEncoding = (null == extensions)
                         ?   TlsUtilities.EmptyBytes
                         :   TlsProtocol.WriteExtensionsData(extensions);
@@ -174,13 +173,11 @@ namespace Org.BouncyCastle.Tls
 
             for (int i = 0; i < count; ++i)
             {
-                byte[] certEncoding = (byte[])certEncodings[i];
-                TlsUtilities.WriteOpaque24(certEncoding, messageOutput);
+                TlsUtilities.WriteOpaque24(certEncodings[i], messageOutput);
 
                 if (isTlsV13)
                 {
-                    byte[] extEncoding = (byte[])extEncodings[i];
-                    TlsUtilities.WriteOpaque16(extEncoding, messageOutput);
+                    TlsUtilities.WriteOpaque16(extEncodings[i], messageOutput);
                 }
             }
         }
@@ -219,7 +216,7 @@ namespace Org.BouncyCastle.Tls
             TlsCrypto crypto = context.Crypto;
             int maxChainLength = System.Math.Max(1, options.MaxChainLength);
 
-            IList certificate_list = Platform.CreateArrayList();
+            var certificate_list = new List<CertificateEntry>();
             while (buf.Position < buf.Length)
             {
                 if (certificate_list.Count >= maxChainLength)
@@ -236,7 +233,7 @@ namespace Org.BouncyCastle.Tls
                     CalculateEndPointHash(context, cert, derEncoding, endPointHashOutput);
                 }
 
-                IDictionary extensions = null;
+                IDictionary<int, byte[]> extensions = null;
                 if (isTlsV13)
                 {
                     byte[] extEncoding = TlsUtilities.ReadOpaque16(buf);
diff --git a/crypto/src/tls/CertificateEntry.cs b/crypto/src/tls/CertificateEntry.cs
index b88677536..78bc4d3b9 100644
--- a/crypto/src/tls/CertificateEntry.cs
+++ b/crypto/src/tls/CertificateEntry.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Tls.Crypto;
 
@@ -8,9 +8,9 @@ namespace Org.BouncyCastle.Tls
     public sealed class CertificateEntry
     {
         private readonly TlsCertificate m_certificate;
-        private readonly IDictionary m_extensions;
+        private readonly IDictionary<int, byte[]> m_extensions;
 
-        public CertificateEntry(TlsCertificate certificate, IDictionary extensions)
+        public CertificateEntry(TlsCertificate certificate, IDictionary<int, byte[]> extensions)
         {
             if (null == certificate)
                 throw new ArgumentNullException("certificate");
@@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Tls
             get { return m_certificate; }
         }
 
-        public IDictionary Extensions
+        public IDictionary<int, byte[]> Extensions
         {
             get { return m_extensions; }
         }
diff --git a/crypto/src/tls/CertificateRequest.cs b/crypto/src/tls/CertificateRequest.cs
index 8005731f4..d2bbe57c1 100644
--- a/crypto/src/tls/CertificateRequest.cs
+++ b/crypto/src/tls/CertificateRequest.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
@@ -37,8 +37,8 @@ namespace Org.BouncyCastle.Tls
     public sealed class CertificateRequest
     {
         /// <exception cref="IOException"/>
-        private static IList CheckSupportedSignatureAlgorithms(IList supportedSignatureAlgorithms,
-            short alertDescription)
+        private static IList<SignatureAndHashAlgorithm> CheckSupportedSignatureAlgorithms(
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms, short alertDescription)
         {
             if (null == supportedSignatureAlgorithms)
                 throw new TlsFatalAlert(alertDescription, "'signature_algorithms' is required");
@@ -48,25 +48,26 @@ namespace Org.BouncyCastle.Tls
 
         private readonly byte[] m_certificateRequestContext;
         private readonly short[] m_certificateTypes;
-        private readonly IList m_supportedSignatureAlgorithms;
-        private readonly IList m_supportedSignatureAlgorithmsCert;
-        private readonly IList m_certificateAuthorities;
+        private readonly IList<SignatureAndHashAlgorithm> m_supportedSignatureAlgorithms;
+        private readonly IList<SignatureAndHashAlgorithm> m_supportedSignatureAlgorithmsCert;
+        private readonly IList<X509Name> m_certificateAuthorities;
 
         /// <param name="certificateTypes">see <see cref="ClientCertificateType"/> for valid constants.</param>
         /// <param name="supportedSignatureAlgorithms"></param>
         /// <param name="certificateAuthorities">an <see cref="IList"/> of <see cref="X509Name"/>.</param>
-        public CertificateRequest(short[] certificateTypes, IList supportedSignatureAlgorithms,
-            IList certificateAuthorities)
+        public CertificateRequest(short[] certificateTypes,
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms, IList<X509Name> certificateAuthorities)
             : this(null, certificateTypes, supportedSignatureAlgorithms, null, certificateAuthorities)
         {
         }
 
         // TODO[tls13] Prefer to manage the certificateRequestContext internally only? 
         /// <exception cref="IOException"/>
-        public CertificateRequest(byte[] certificateRequestContext, IList supportedSignatureAlgorithms,
-            IList supportedSignatureAlgorithmsCert, IList certificateAuthorities)
+        public CertificateRequest(byte[] certificateRequestContext,
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms,
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithmsCert, IList<X509Name> certificateAuthorities)
             : this(certificateRequestContext, null,
-                 CheckSupportedSignatureAlgorithms(supportedSignatureAlgorithms, AlertDescription.internal_error),
+                CheckSupportedSignatureAlgorithms(supportedSignatureAlgorithms, AlertDescription.internal_error),
                 supportedSignatureAlgorithmsCert, certificateAuthorities)
         {
             /*
@@ -77,7 +78,8 @@ namespace Org.BouncyCastle.Tls
         }
 
         private CertificateRequest(byte[] certificateRequestContext, short[] certificateTypes,
-            IList supportedSignatureAlgorithms, IList supportedSignatureAlgorithmsCert, IList certificateAuthorities)
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms,
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithmsCert, IList<X509Name> certificateAuthorities)
         {
             if (null != certificateRequestContext && !TlsUtilities.IsValidUint8(certificateRequestContext.Length))
                 throw new ArgumentException("cannot be longer than 255", "certificateRequestContext");
@@ -108,20 +110,20 @@ namespace Org.BouncyCastle.Tls
 
         /// <returns>an <see cref="IList"/> of <see cref="SignatureAndHashAlgorithm"/> (or null before TLS 1.2).
         /// </returns>
-        public IList SupportedSignatureAlgorithms
+        public IList<SignatureAndHashAlgorithm> SupportedSignatureAlgorithms
         {
             get { return m_supportedSignatureAlgorithms; }
         }
 
         /// <returns>an optional <see cref="IList"/> of <see cref="SignatureAndHashAlgorithm"/>. May be non-null from
         /// TLS 1.3 onwards.</returns>
-        public IList SupportedSignatureAlgorithmsCert
+        public IList<SignatureAndHashAlgorithm> SupportedSignatureAlgorithmsCert
         {
             get { return m_supportedSignatureAlgorithmsCert; }
         }
 
         /// <returns>an <see cref="IList"/> of <see cref="X509Name"/>.</returns>
-        public IList CertificateAuthorities
+        public IList<X509Name> CertificateAuthorities
         {
             get { return m_certificateAuthorities; }
         }
@@ -153,7 +155,7 @@ namespace Org.BouncyCastle.Tls
             {
                 TlsUtilities.WriteOpaque8(m_certificateRequestContext, output);
 
-                IDictionary extensions = Platform.CreateHashtable();
+                var extensions = new Dictionary<int, byte[]>();
                 TlsExtensionsUtilities.AddSignatureAlgorithmsExtension(extensions, m_supportedSignatureAlgorithms);
 
                 if (null != m_supportedSignatureAlgorithmsCert)
@@ -187,7 +189,7 @@ namespace Org.BouncyCastle.Tls
             }
             else
             {
-                IList derEncodings = Platform.CreateArrayList(m_certificateAuthorities.Count);
+                var derEncodings = new List<byte[]>(m_certificateAuthorities.Count);
 
                 int totalLength = 0;
                 foreach (X509Name certificateAuthority in m_certificateAuthorities)
@@ -229,15 +231,14 @@ namespace Org.BouncyCastle.Tls
 
                 byte[] extEncoding = TlsUtilities.ReadOpaque16(input);
 
-                IDictionary extensions = TlsProtocol.ReadExtensionsData13(HandshakeType.certificate_request,
-                    extEncoding);
+                var extensions = TlsProtocol.ReadExtensionsData13(HandshakeType.certificate_request, extEncoding);
 
-                IList supportedSignatureAlgorithms13 = CheckSupportedSignatureAlgorithms(
+                var supportedSignatureAlgorithms13 = CheckSupportedSignatureAlgorithms(
                     TlsExtensionsUtilities.GetSignatureAlgorithmsExtension(extensions),
                     AlertDescription.missing_extension);
-                IList supportedSignatureAlgorithmsCert13 = TlsExtensionsUtilities
+                var supportedSignatureAlgorithmsCert13 = TlsExtensionsUtilities
                     .GetSignatureAlgorithmsCertExtension(extensions);
-                IList certificateAuthorities13 = TlsExtensionsUtilities.GetCertificateAuthoritiesExtension(extensions);
+                var certificateAuthorities13 = TlsExtensionsUtilities.GetCertificateAuthoritiesExtension(extensions);
 
                 return new CertificateRequest(certificateRequestContext, supportedSignatureAlgorithms13,
                     supportedSignatureAlgorithmsCert13, certificateAuthorities13);
@@ -247,18 +248,18 @@ namespace Org.BouncyCastle.Tls
 
             short[] certificateTypes = TlsUtilities.ReadUint8ArrayWithUint8Length(input, 1);
 
-            IList supportedSignatureAlgorithms = null;
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms = null;
             if (isTLSv12)
             {
                 supportedSignatureAlgorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(input);
             }
 
-            IList certificateAuthorities = null;
+            IList<X509Name> certificateAuthorities = null;
             {
                 byte[] certAuthData = TlsUtilities.ReadOpaque16(input);
                 if (certAuthData.Length > 0)
                 {
-                    certificateAuthorities = Platform.CreateArrayList();
+                    certificateAuthorities = new List<X509Name>();
                     MemoryStream bis = new MemoryStream(certAuthData, false);
                     do
                     {
diff --git a/crypto/src/tls/CertificateStatus.cs b/crypto/src/tls/CertificateStatus.cs
index 11c4d4571..51f488fd6 100644
--- a/crypto/src/tls/CertificateStatus.cs
+++ b/crypto/src/tls/CertificateStatus.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
@@ -44,14 +44,14 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <summary>an <see cref="IList"/> of (possibly null) <see cref="Asn1.Ocsp.OcspResponse"/>.</summary>
-        public IList OcspResponseList
+        public IList<OcspResponse> OcspResponseList
         {
             get
             {
                 if (!IsCorrectType(CertificateStatusType.ocsp_multi, m_response))
                     throw new InvalidOperationException("'response' is not an OCSPResponseList");
 
-                return (IList)m_response;
+                return (IList<OcspResponse>)m_response;
             }
         }
 
@@ -73,10 +73,10 @@ namespace Org.BouncyCastle.Tls
             }
             case CertificateStatusType.ocsp_multi:
             {
-                IList ocspResponseList = (IList)m_response;
+                var ocspResponseList = (IList<OcspResponse>)m_response;
                 int count = ocspResponseList.Count;
 
-                IList derEncodings = Platform.CreateArrayList(count);
+                var derEncodings = new List<byte[]>(count);
                 long totalLength = 0;
                 foreach (OcspResponse ocspResponse in ocspResponseList)
                 {
@@ -147,7 +147,7 @@ namespace Org.BouncyCastle.Tls
                 byte[] ocsp_response_list = TlsUtilities.ReadOpaque24(input, 1);
                 MemoryStream buf = new MemoryStream(ocsp_response_list, false);
 
-                IList ocspResponseList = Platform.CreateArrayList();
+                var ocspResponseList = new List<OcspResponse>();
                 while (buf.Position < buf.Length)
                 {
                     if (ocspResponseList.Count >= certificateCount)
@@ -191,20 +191,7 @@ namespace Org.BouncyCastle.Tls
 
         private static bool IsOcspResponseList(object response)
         {
-            if (!(response is IList))
-                return false;
-
-            IList v = (IList)response;
-            int count = v.Count;
-            if (count < 1)
-                return false;
-
-            foreach (object e in v)
-            {
-                if (null != e && !(e is OcspResponse))
-                    return false;
-            }
-            return true;
+            return response is IList<OcspResponse> v && v.Count > 0;
         }
 
         /// <exception cref="IOException"/>
diff --git a/crypto/src/tls/CertificateUrl.cs b/crypto/src/tls/CertificateUrl.cs
index d2445772a..6629e67f9 100644
--- a/crypto/src/tls/CertificateUrl.cs
+++ b/crypto/src/tls/CertificateUrl.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Utilities;
@@ -11,11 +11,11 @@ namespace Org.BouncyCastle.Tls
     public sealed class CertificateUrl
     {
         private readonly short m_type;
-        private readonly IList m_urlAndHashList;
+        private readonly IList<UrlAndHash> m_urlAndHashList;
 
         /// <param name="type">see <see cref="CertChainType"/> for valid constants.</param>
         /// <param name="urlAndHashList">an <see cref="IList"/> of <see cref="UrlAndHash"/>.</param>
-        public CertificateUrl(short type, IList urlAndHashList)
+        public CertificateUrl(short type, IList<UrlAndHash> urlAndHashList)
         {
             if (!CertChainType.IsValid(type))
                 throw new ArgumentException("not a valid CertChainType value", "type");
@@ -36,7 +36,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <returns>an <see cref="IList"/> of <see cref="UrlAndHash"/>.</returns>
-        public IList UrlAndHashList
+        public IList<UrlAndHash> UrlAndHashList
         {
             get { return m_urlAndHashList; }
         }
@@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Tls
 
             MemoryStream buf = new MemoryStream(urlAndHashListData, false);
 
-            IList url_and_hash_list = Platform.CreateArrayList();
+            var url_and_hash_list = new List<UrlAndHash>();
             while (buf.Position < buf.Length)
             {
                 UrlAndHash url_and_hash = UrlAndHash.Parse(context, buf);
diff --git a/crypto/src/tls/ClientHello.cs b/crypto/src/tls/ClientHello.cs
index 7f1018e89..14e8b4cde 100644
--- a/crypto/src/tls/ClientHello.cs
+++ b/crypto/src/tls/ClientHello.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Utilities;
@@ -14,11 +14,11 @@ namespace Org.BouncyCastle.Tls
         private readonly byte[] m_sessionID;
         private readonly byte[] m_cookie;
         private readonly int[] m_cipherSuites;
-        private readonly IDictionary m_extensions;
+        private readonly IDictionary<int, byte[]> m_extensions;
         private readonly int m_bindersSize;
 
         public ClientHello(ProtocolVersion version, byte[] random, byte[] sessionID, byte[] cookie,
-            int[] cipherSuites, IDictionary extensions, int bindersSize)
+            int[] cipherSuites, IDictionary<int, byte[]> extensions, int bindersSize)
         {
             this.m_version = version;
             this.m_random = random;
@@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Tls
             get { return m_cookie; }
         }
 
-        public IDictionary Extensions
+        public IDictionary<int, byte[]> Extensions
         {
             get { return m_extensions; }
         }
@@ -161,7 +161,7 @@ namespace Org.BouncyCastle.Tls
              * NOTE: Can't use TlsProtocol.ReadExtensions directly because TeeInputStream a) won't have
              * 'Length' or 'Position' properties in the FIPS provider, b) isn't a MemoryStream.
              */
-            IDictionary extensions = null;
+            IDictionary<int, byte[]> extensions = null;
             if (messageInput.Position < messageInput.Length)
             {
                 byte[] extBytes = TlsUtilities.ReadOpaque16(input);
diff --git a/crypto/src/tls/DefaultTlsDHGroupVerifier.cs b/crypto/src/tls/DefaultTlsDHGroupVerifier.cs
index 8b9cf2e0f..9aa3a23b4 100644
--- a/crypto/src/tls/DefaultTlsDHGroupVerifier.cs
+++ b/crypto/src/tls/DefaultTlsDHGroupVerifier.cs
@@ -1,9 +1,8 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Tls.Crypto;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Tls
 {
@@ -12,7 +11,7 @@ namespace Org.BouncyCastle.Tls
     {
         public static readonly int DefaultMinimumPrimeBits = 2048;
 
-        private static readonly IList DefaultGroups = Platform.CreateArrayList();
+        private static readonly List<DHGroup> DefaultGroups = new List<DHGroup>();
 
         private static void AddDefaultGroup(DHGroup dhGroup)
         {
@@ -41,7 +40,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         // IList is (DHGroup)
-        protected readonly IList m_groups;
+        protected readonly IList<DHGroup> m_groups;
         protected readonly int m_minimumPrimeBits;
 
         /// <summary>Accept named groups and various standard DH groups with 'P' at least
@@ -63,9 +62,9 @@ namespace Org.BouncyCastle.Tls
         /// </summary>
         /// <param name="groups">a <see cref="IList">list</see> of acceptable <see cref="DHGroup"/>s.</param>
         /// <param name="minimumPrimeBits">the minimum bitlength of 'P'.</param>
-        public DefaultTlsDHGroupVerifier(IList groups, int minimumPrimeBits)
+        public DefaultTlsDHGroupVerifier(IList<DHGroup> groups, int minimumPrimeBits)
         {
-            this.m_groups = Platform.CreateArrayList(groups);
+            this.m_groups = new List<DHGroup>(groups);
             this.m_minimumPrimeBits = minimumPrimeBits;
         }
 
diff --git a/crypto/src/tls/DefaultTlsSrpConfigVerifier.cs b/crypto/src/tls/DefaultTlsSrpConfigVerifier.cs
index 781249829..30b107ed2 100644
--- a/crypto/src/tls/DefaultTlsSrpConfigVerifier.cs
+++ b/crypto/src/tls/DefaultTlsSrpConfigVerifier.cs
@@ -1,16 +1,15 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Tls.Crypto;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Tls
 {
     public class DefaultTlsSrpConfigVerifier
         : TlsSrpConfigVerifier
     {
-        private static readonly IList DefaultGroups = Platform.CreateArrayList();
+        private static readonly List<Srp6Group> DefaultGroups = new List<Srp6Group>();
 
         static DefaultTlsSrpConfigVerifier()
         {
@@ -24,7 +23,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         // IList is (SRP6Group)
-        protected readonly IList m_groups;
+        protected readonly IList<Srp6Group> m_groups;
 
         /// <summary>Accept only the group parameters specified in RFC 5054 Appendix A.</summary>
         public DefaultTlsSrpConfigVerifier()
@@ -34,9 +33,9 @@ namespace Org.BouncyCastle.Tls
 
         /// <summary>Specify a custom set of acceptable group parameters.</summary>
         /// <param name="groups">an <see cref="IList"/> of acceptable <see cref="Srp6Group"/>.</param>
-        public DefaultTlsSrpConfigVerifier(IList groups)
+        public DefaultTlsSrpConfigVerifier(IList<Srp6Group> groups)
         {
-            this.m_groups = Platform.CreateArrayList(groups);
+            this.m_groups = new List<Srp6Group>(groups);
         }
 
         public virtual bool Accept(TlsSrpConfig srpConfig)
diff --git a/crypto/src/tls/DeferredHash.cs b/crypto/src/tls/DeferredHash.cs
index ac66c8f0c..82f7899a5 100644
--- a/crypto/src/tls/DeferredHash.cs
+++ b/crypto/src/tls/DeferredHash.cs
@@ -1,9 +1,8 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Tls
 {
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Tls
         private readonly TlsContext m_context;
 
         private DigestInputBuffer m_buf;
-        private IDictionary m_hashes;
+        private IDictionary<int, TlsHash> m_hashes;
         private bool m_forceBuffering;
         private bool m_sealed;
 
@@ -24,7 +23,7 @@ namespace Org.BouncyCastle.Tls
         {
             this.m_context = context;
             this.m_buf = new DigestInputBuffer();
-            this.m_hashes = Platform.CreateHashtable();
+            this.m_hashes = new Dictionary<int, TlsHash>();
             this.m_forceBuffering = false;
             this.m_sealed = false;
         }
@@ -91,7 +90,7 @@ namespace Org.BouncyCastle.Tls
         {
             SecurityParameters securityParameters = m_context.SecurityParameters;
 
-            IDictionary newHashes = Platform.CreateHashtable();
+            IDictionary<int, TlsHash> newHashes = new Dictionary<int, TlsHash>();
             switch (securityParameters.PrfAlgorithm)
             {
             case PrfAlgorithm.ssl_prf_legacy:
@@ -148,8 +147,7 @@ namespace Org.BouncyCastle.Tls
 
         public byte[] GetFinalHash(int cryptoHashAlgorithm)
         {
-            TlsHash hash = (TlsHash)m_hashes[cryptoHashAlgorithm];
-            if (hash == null)
+            if (!m_hashes.TryGetValue(cryptoHashAlgorithm, out var hash))
                 throw new InvalidOperationException("CryptoHashAlgorithm." + cryptoHashAlgorithm
                     + " is not being tracked");
 
@@ -217,7 +215,7 @@ namespace Org.BouncyCastle.Tls
 
         private void CheckTrackingHash(int cryptoHashAlgorithm)
         {
-            if (!m_hashes.Contains(cryptoHashAlgorithm))
+            if (!m_hashes.ContainsKey(cryptoHashAlgorithm))
             {
                 TlsHash hash = m_context.Crypto.CreateHash(cryptoHashAlgorithm);
                 m_hashes[cryptoHashAlgorithm] = hash;
@@ -226,10 +224,10 @@ namespace Org.BouncyCastle.Tls
 
         private TlsHash CloneHash(int cryptoHashAlgorithm)
         {
-            return ((TlsHash)m_hashes[cryptoHashAlgorithm]).CloneHash();
+            return m_hashes[cryptoHashAlgorithm].CloneHash();
         }
 
-        private void CloneHash(IDictionary newHashes, int cryptoHashAlgorithm)
+        private void CloneHash(IDictionary<int, TlsHash> newHashes, int cryptoHashAlgorithm)
         {
             TlsHash hash = CloneHash(cryptoHashAlgorithm);
             if (m_buf != null)
diff --git a/crypto/src/tls/DtlsClientProtocol.cs b/crypto/src/tls/DtlsClientProtocol.cs
index fd71a07ed..3e3aab662 100644
--- a/crypto/src/tls/DtlsClientProtocol.cs
+++ b/crypto/src/tls/DtlsClientProtocol.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -307,7 +307,7 @@ namespace Org.BouncyCastle.Tls
                 state.keyExchange.ProcessClientCredentials(clientAuthCredentials);                    
             }
 
-            IList clientSupplementalData = state.client.GetClientSupplementalData();
+            var clientSupplementalData = state.client.GetClientSupplementalData();
             if (clientSupplementalData != null)
             {
                 byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData);
@@ -838,8 +838,8 @@ namespace Org.BouncyCastle.Tls
 
 
 
-            IDictionary sessionClientExtensions = state.clientExtensions,
-                sessionServerExtensions = state.serverExtensions;
+            var sessionClientExtensions = state.clientExtensions;
+            var sessionServerExtensions = state.serverExtensions;
 
             if (state.resumedSession)
             {
@@ -914,7 +914,7 @@ namespace Org.BouncyCastle.Tls
         protected virtual void ProcessServerSupplementalData(ClientHandshakeState state, byte[] body)
         {
             MemoryStream buf = new MemoryStream(body, false);
-            IList serverSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf);
+            var serverSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf);
             state.client.ProcessServerSupplementalData(serverSupplementalData);
         }
 
@@ -970,11 +970,11 @@ namespace Org.BouncyCastle.Tls
             internal TlsSecret sessionMasterSecret = null;
             internal SessionParameters.Builder sessionParametersBuilder = null;
             internal int[] offeredCipherSuites = null;
-            internal IDictionary clientExtensions = null;
-            internal IDictionary serverExtensions = null;
+            internal IDictionary<int, byte[]> clientExtensions = null;
+            internal IDictionary<int, byte[]> serverExtensions = null;
             internal bool resumedSession = false;
             internal bool expectSessionTicket = false;
-            internal IDictionary clientAgreements = null;
+            internal IDictionary<int, TlsAgreement> clientAgreements = null;
             internal TlsKeyExchange keyExchange = null;
             internal TlsAuthentication authentication = null;
             internal CertificateStatus certificateStatus = null;
diff --git a/crypto/src/tls/DtlsProtocol.cs b/crypto/src/tls/DtlsProtocol.cs
index f0f42f968..3d72bca9f 100644
--- a/crypto/src/tls/DtlsProtocol.cs
+++ b/crypto/src/tls/DtlsProtocol.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Utilities;
@@ -39,8 +39,9 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static short EvaluateMaxFragmentLengthExtension(bool resumedSession, IDictionary clientExtensions,
-            IDictionary serverExtensions, short alertDescription)
+        internal static short EvaluateMaxFragmentLengthExtension(bool resumedSession,
+            IDictionary<int, byte[]> clientExtensions, IDictionary<int, byte[]> serverExtensions,
+            short alertDescription)
         {
             short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions);
             if (maxFragmentLength >= 0)
@@ -64,7 +65,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static byte[] GenerateSupplementalData(IList supplementalData)
+        internal static byte[] GenerateSupplementalData(IList<SupplementalDataEntry> supplementalData)
         {
             MemoryStream buf = new MemoryStream();
             TlsProtocol.WriteSupplementalData(buf, supplementalData);
diff --git a/crypto/src/tls/DtlsReassembler.cs b/crypto/src/tls/DtlsReassembler.cs
index 964c8eb84..f53295eb1 100644
--- a/crypto/src/tls/DtlsReassembler.cs
+++ b/crypto/src/tls/DtlsReassembler.cs
@@ -1,7 +1,5 @@
 using System;
-using System.Collections;
-
-using Org.BouncyCastle.Utilities;
+using System.Collections.Generic;
 
 namespace Org.BouncyCastle.Tls
 {
@@ -10,7 +8,7 @@ namespace Org.BouncyCastle.Tls
         private readonly short m_msg_type;
         private readonly byte[] m_body;
 
-        private readonly IList m_missing = Platform.CreateArrayList();
+        private readonly List<Range> m_missing = new List<Range>();
 
         internal DtlsReassembler(short msg_type, int length)
         {
diff --git a/crypto/src/tls/DtlsReliableHandshake.cs b/crypto/src/tls/DtlsReliableHandshake.cs
index 7581e4766..1d35cf2ce 100644
--- a/crypto/src/tls/DtlsReliableHandshake.cs
+++ b/crypto/src/tls/DtlsReliableHandshake.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Utilities;
@@ -82,9 +82,9 @@ namespace Org.BouncyCastle.Tls
 
         private TlsHandshakeHash m_handshakeHash;
 
-        private IDictionary m_currentInboundFlight = Platform.CreateHashtable();
-        private IDictionary m_previousInboundFlight = null;
-        private IList m_outboundFlight = Platform.CreateArrayList();
+        private IDictionary<int, DtlsReassembler> m_currentInboundFlight = new Dictionary<int, DtlsReassembler>();
+        private IDictionary<int, DtlsReassembler> m_previousInboundFlight = null;
+        private IList<Message> m_outboundFlight = new List<Message>();
 
         private int m_resendMillis = -1;
         private Timeout m_resendTimeout = null;
@@ -124,9 +124,9 @@ namespace Org.BouncyCastle.Tls
 
         internal void ResetAfterHelloVerifyRequestClient()
         {
-            this.m_currentInboundFlight = Platform.CreateHashtable();
+            this.m_currentInboundFlight = new Dictionary<int, DtlsReassembler>();
             this.m_previousInboundFlight = null;
-            this.m_outboundFlight = Platform.CreateArrayList();
+            this.m_outboundFlight = new List<Message>();
 
             this.m_resendMillis = -1;
             this.m_resendTimeout = null;
@@ -280,8 +280,7 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         private Message GetPendingMessage()
         {
-            DtlsReassembler next = (DtlsReassembler)m_currentInboundFlight[m_next_receive_seq];
-            if (next != null)
+            if (m_currentInboundFlight.TryGetValue(m_next_receive_seq, out var next))
             {
                 byte[] body = next.GetBodyIfComplete();
                 if (body != null)
@@ -303,7 +302,7 @@ namespace Org.BouncyCastle.Tls
                 m_resendMillis = INITIAL_RESEND_MILLIS;
                 m_resendTimeout = new Timeout(m_resendMillis, currentTimeMillis);
 
-                PrepareInboundFlight(Platform.CreateHashtable());
+                PrepareInboundFlight(new Dictionary<int, DtlsReassembler>());
             }
 
             byte[] buf = null;
@@ -349,7 +348,7 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        private void PrepareInboundFlight(IDictionary nextFlight)
+        private void PrepareInboundFlight(IDictionary<int, DtlsReassembler> nextFlight)
         {
             ResetAll(m_currentInboundFlight);
             m_previousInboundFlight = m_currentInboundFlight;
@@ -395,8 +394,7 @@ namespace Org.BouncyCastle.Tls
                 }
                 else if (message_seq >= m_next_receive_seq)
                 {
-                    DtlsReassembler reassembler = (DtlsReassembler)m_currentInboundFlight[message_seq];
-                    if (reassembler == null)
+                    if (!m_currentInboundFlight.TryGetValue(message_seq, out var reassembler))
                     {
                         reassembler = new DtlsReassembler(msg_type, length);
                         m_currentInboundFlight[message_seq] = reassembler;
@@ -412,8 +410,7 @@ namespace Org.BouncyCastle.Tls
                      * retransmit our last flight
                      */
 
-                    DtlsReassembler reassembler = (DtlsReassembler)m_previousInboundFlight[message_seq];
-                    if (reassembler != null)
+                    if (m_previousInboundFlight.TryGetValue(message_seq, out var reassembler))
                     {
                         reassembler.ContributeFragment(msg_type, length, buf, off + MESSAGE_HEADER_LENGTH,
                             fragment_offset, fragment_length);
@@ -485,7 +482,7 @@ namespace Org.BouncyCastle.Tls
             fragment.SendToRecordLayer(m_recordLayer);
         }
 
-        private static bool CheckAll(IDictionary inboundFlight)
+        private static bool CheckAll(IDictionary<int, DtlsReassembler> inboundFlight)
         {
             foreach (DtlsReassembler r in inboundFlight.Values)
             {
@@ -495,7 +492,7 @@ namespace Org.BouncyCastle.Tls
             return true;
         }
 
-        private static void ResetAll(IDictionary inboundFlight)
+        private static void ResetAll(IDictionary<int, DtlsReassembler> inboundFlight)
         {
             foreach (DtlsReassembler r in inboundFlight.Values)
             {
diff --git a/crypto/src/tls/DtlsServerProtocol.cs b/crypto/src/tls/DtlsServerProtocol.cs
index b01c6e34f..51e013290 100644
--- a/crypto/src/tls/DtlsServerProtocol.cs
+++ b/crypto/src/tls/DtlsServerProtocol.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -147,7 +147,7 @@ namespace Org.BouncyCastle.Tls
 
             handshake.HandshakeHash.NotifyPrfDetermined();
 
-            IList serverSupplementalData = state.server.GetServerSupplementalData();
+            var serverSupplementalData = state.server.GetServerSupplementalData();
             if (serverSupplementalData != null)
             {
                 byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData);
@@ -829,7 +829,7 @@ namespace Org.BouncyCastle.Tls
         protected virtual void ProcessClientSupplementalData(ServerHandshakeState state, byte[] body)
         {
             MemoryStream buf = new MemoryStream(body, false);
-            IList clientSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf);
+            var clientSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf);
             state.server.ProcessClientSupplementalData(clientSupplementalData);
         }
 
@@ -853,8 +853,8 @@ namespace Org.BouncyCastle.Tls
             internal TlsSecret sessionMasterSecret = null;
             internal SessionParameters.Builder sessionParametersBuilder = null;
             internal int[] offeredCipherSuites = null;
-            internal IDictionary clientExtensions = null;
-            internal IDictionary serverExtensions = null;
+            internal IDictionary<int, byte[]> clientExtensions = null;
+            internal IDictionary<int, byte[]> serverExtensions = null;
             internal bool offeredExtendedMasterSecret = false;
             internal bool resumedSession = false;
             internal bool expectSessionTicket = false;
diff --git a/crypto/src/tls/OcspStatusRequest.cs b/crypto/src/tls/OcspStatusRequest.cs
index 8679022ec..00728f64e 100644
--- a/crypto/src/tls/OcspStatusRequest.cs
+++ b/crypto/src/tls/OcspStatusRequest.cs
@@ -1,11 +1,10 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Ocsp;
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
 namespace Org.BouncyCastle.Tls
@@ -13,7 +12,7 @@ namespace Org.BouncyCastle.Tls
     /// <summary>RFC 3546 3.6</summary>
     public sealed class OcspStatusRequest
     {
-        private readonly IList m_responderIDList;
+        private readonly IList<ResponderID> m_responderIDList;
         private readonly X509Extensions m_requestExtensions;
 
         /// <param name="responderIDList">an <see cref="IList"/> of <see cref="ResponderID"/>, specifying the list of
@@ -21,14 +20,14 @@ namespace Org.BouncyCastle.Tls
         /// the server - e.g., by prior arrangement.</param>
         /// <param name="requestExtensions">OCSP request extensions. A null value means that there are no extensions.
         /// </param>
-        public OcspStatusRequest(IList responderIDList, X509Extensions requestExtensions)
+        public OcspStatusRequest(IList<ResponderID> responderIDList, X509Extensions requestExtensions)
         {
             this.m_responderIDList = responderIDList;
             this.m_requestExtensions = requestExtensions;
         }
 
         /// <returns>an <see cref="IList"/> of <see cref="ResponderID"/>.</returns>
-        public IList ResponderIDList
+        public IList<ResponderID> ResponderIDList
         {
             get { return m_responderIDList; }
         }
@@ -80,7 +79,7 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         public static OcspStatusRequest Parse(Stream input)
         {
-            IList responderIDList = Platform.CreateArrayList();
+            var responderIDList = new List<ResponderID>();
             {
                 byte[] data = TlsUtilities.ReadOpaque16(input);
                 if (data.Length > 0)
diff --git a/crypto/src/tls/OfferedPsks.cs b/crypto/src/tls/OfferedPsks.cs
index 1cc8a2a68..d2860fff6 100644
--- a/crypto/src/tls/OfferedPsks.cs
+++ b/crypto/src/tls/OfferedPsks.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -42,16 +42,16 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        private readonly IList m_identities;
-        private readonly IList m_binders;
+        private readonly IList<PskIdentity> m_identities;
+        private readonly IList<byte[]> m_binders;
         private readonly int m_bindersSize;
 
-        public OfferedPsks(IList identities)
+        public OfferedPsks(IList<PskIdentity> identities)
             : this(identities, null, -1)
         {
         }
 
-        private OfferedPsks(IList identities, IList binders, int bindersSize)
+        private OfferedPsks(IList<PskIdentity> identities, IList<byte[]> binders, int bindersSize)
         {
             if (null == identities || identities.Count < 1)
                 throw new ArgumentException("cannot be null or empty", "identities");
@@ -65,7 +65,7 @@ namespace Org.BouncyCastle.Tls
             this.m_bindersSize = bindersSize;
         }
 
-        public IList Binders
+        public IList<byte[]> Binders
         {
             get { return m_binders; }
         }
@@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Tls
             get { return m_bindersSize; }
         }
 
-        public IList Identities
+        public IList<PskIdentity> Identities
         {
             get { return m_identities; }
         }
@@ -186,7 +186,7 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         public static OfferedPsks Parse(Stream input)
         {
-            IList identities = Platform.CreateArrayList();
+            var identities = new List<PskIdentity>();
             {
                 int totalLengthIdentities = TlsUtilities.ReadUint16(input);
                 if (totalLengthIdentities < 7)
@@ -202,7 +202,7 @@ namespace Org.BouncyCastle.Tls
                 while (buf.Position < buf.Length);
             }
 
-            IList binders = Platform.CreateArrayList();
+            var binders = new List<byte[]>();
             int totalLengthBinders = TlsUtilities.ReadUint16(input);
             {
                 if (totalLengthBinders < 33)
diff --git a/crypto/src/tls/ProtocolVersion.cs b/crypto/src/tls/ProtocolVersion.cs
index f516aed2a..e9c08e8cd 100644
--- a/crypto/src/tls/ProtocolVersion.cs
+++ b/crypto/src/tls/ProtocolVersion.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities;
 
@@ -169,7 +169,7 @@ namespace Org.BouncyCastle.Tls
             if (!IsEqualOrLaterVersionOf(min))
                 throw new ArgumentException("must be an equal or earlier version of this one", "min");
 
-            IList result = Platform.CreateArrayList();
+            var result = new List<ProtocolVersion>();
             result.Add(this);
 
             ProtocolVersion current = this;
@@ -179,12 +179,7 @@ namespace Org.BouncyCastle.Tls
                 result.Add(current);
             }
 
-            ProtocolVersion[] versions = new ProtocolVersion[result.Count];
-            for (int i = 0; i < result.Count; ++i)
-            {
-                versions[i] = (ProtocolVersion)result[i];
-            }
-            return versions;
+            return result.ToArray();
         }
 
         public int FullVersion
diff --git a/crypto/src/tls/SecurityParameters.cs b/crypto/src/tls/SecurityParameters.cs
index 548e4a4ca..0681401eb 100644
--- a/crypto/src/tls/SecurityParameters.cs
+++ b/crypto/src/tls/SecurityParameters.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Tls.Crypto;
 
@@ -39,12 +39,12 @@ namespace Org.BouncyCastle.Tls
         internal ProtocolName m_applicationProtocol = null;
         internal bool m_applicationProtocolSet = false;
         internal short[] m_clientCertTypes = null;
-        internal IList m_clientServerNames = null;
-        internal IList m_clientSigAlgs = null;
-        internal IList m_clientSigAlgsCert = null;
+        internal IList<ServerName> m_clientServerNames = null;
+        internal IList<SignatureAndHashAlgorithm> m_clientSigAlgs = null;
+        internal IList<SignatureAndHashAlgorithm> m_clientSigAlgsCert = null;
         internal int[] m_clientSupportedGroups = null;
-        internal IList m_serverSigAlgs = null;
-        internal IList m_serverSigAlgsCert = null;
+        internal IList<SignatureAndHashAlgorithm> m_serverSigAlgs = null;
+        internal IList<SignatureAndHashAlgorithm> m_serverSigAlgsCert = null;
         internal int[] m_serverSupportedGroups = null;
         internal int m_keyExchangeAlgorithm = -1;
         internal Certificate m_localCertificate = null;
@@ -109,17 +109,17 @@ namespace Org.BouncyCastle.Tls
             get { return m_clientRandom; }
         }
 
-        public IList ClientServerNames
+        public IList<ServerName> ClientServerNames
         {
             get { return m_clientServerNames; }
         }
 
-        public IList ClientSigAlgs
+        public IList<SignatureAndHashAlgorithm> ClientSigAlgs
         {
             get { return m_clientSigAlgs; }
         }
 
-        public IList ClientSigAlgsCert
+        public IList<SignatureAndHashAlgorithm> ClientSigAlgsCert
         {
             get { return m_clientSigAlgsCert; }
         }
@@ -249,12 +249,12 @@ namespace Org.BouncyCastle.Tls
             get { return m_serverRandom; }
         }
 
-        public IList ServerSigAlgs
+        public IList<SignatureAndHashAlgorithm> ServerSigAlgs
         {
             get { return m_serverSigAlgs; }
         }
 
-        public IList ServerSigAlgsCert
+        public IList<SignatureAndHashAlgorithm> ServerSigAlgsCert
         {
             get { return m_serverSigAlgsCert; }
         }
diff --git a/crypto/src/tls/ServerHello.cs b/crypto/src/tls/ServerHello.cs
index 15cc09032..ca206e1fc 100644
--- a/crypto/src/tls/ServerHello.cs
+++ b/crypto/src/tls/ServerHello.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Utilities;
@@ -16,15 +16,15 @@ namespace Org.BouncyCastle.Tls
         private readonly byte[] m_random;
         private readonly byte[] m_sessionID;
         private readonly int m_cipherSuite;
-        private readonly IDictionary m_extensions;
+        private readonly IDictionary<int, byte[]> m_extensions;
 
-        public ServerHello(byte[] sessionID, int cipherSuite, IDictionary extensions)
+        public ServerHello(byte[] sessionID, int cipherSuite, IDictionary<int, byte[]> extensions)
             : this(ProtocolVersion.TLSv12, Arrays.Clone(HelloRetryRequestMagic), sessionID, cipherSuite, extensions)
         {
         }
 
         public ServerHello(ProtocolVersion version, byte[] random, byte[] sessionID, int cipherSuite,
-            IDictionary extensions)
+            IDictionary<int, byte[]> extensions)
         {
             this.m_version = version;
             this.m_random = random;
@@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Tls
             get { return m_cipherSuite; }
         }
 
-        public IDictionary Extensions
+        public IDictionary<int, byte[]> Extensions
         {
             get { return m_extensions; }
         }
@@ -100,7 +100,7 @@ namespace Org.BouncyCastle.Tls
             if (CompressionMethod.cls_null != compressionMethod)
                 throw new TlsFatalAlert(AlertDescription.illegal_parameter);
 
-            IDictionary extensions = TlsProtocol.ReadExtensions(input);
+            var extensions = TlsProtocol.ReadExtensions(input);
 
             return new ServerHello(version, random, sessionID, cipherSuite, extensions);
         }
diff --git a/crypto/src/tls/ServerNameList.cs b/crypto/src/tls/ServerNameList.cs
index 915e94390..358e82a67 100644
--- a/crypto/src/tls/ServerNameList.cs
+++ b/crypto/src/tls/ServerNameList.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Utilities;
@@ -9,10 +9,10 @@ namespace Org.BouncyCastle.Tls
 {
     public sealed class ServerNameList
     {
-        private readonly IList m_serverNameList;
+        private readonly IList<ServerName> m_serverNameList;
 
         /// <param name="serverNameList">an <see cref="IList"/> of <see cref="ServerName"/>.</param>
-        public ServerNameList(IList serverNameList)
+        public ServerNameList(IList<ServerName> serverNameList)
         {
             if (null == serverNameList)
                 throw new ArgumentNullException("serverNameList");
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <returns>an <see cref="IList"/> of <see cref="ServerName"/>.</returns>
-        public IList ServerNames
+        public IList<ServerName> ServerNames
         {
             get { return m_serverNameList; }
         }
@@ -60,7 +60,7 @@ namespace Org.BouncyCastle.Tls
             MemoryStream buf = new MemoryStream(data, false);
 
             short[] nameTypesSeen = TlsUtilities.EmptyShorts;
-            IList server_name_list = Platform.CreateArrayList();
+            var server_name_list = new List<ServerName>();
             while (buf.Position < buf.Length)
             {
                 ServerName entry = ServerName.Parse(buf);
diff --git a/crypto/src/tls/SessionParameters.cs b/crypto/src/tls/SessionParameters.cs
index 9a62e351c..1472c7907 100644
--- a/crypto/src/tls/SessionParameters.cs
+++ b/crypto/src/tls/SessionParameters.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -82,7 +82,7 @@ namespace Org.BouncyCastle.Tls
             }
 
             /// <exception cref="IOException"/>
-            public Builder SetServerExtensions(IDictionary serverExtensions)
+            public Builder SetServerExtensions(IDictionary<int, byte[]> serverExtensions)
             {
                 if (serverExtensions == null || serverExtensions.Count < 1)
                 {
@@ -179,7 +179,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public IDictionary ReadServerExtensions()
+        public IDictionary<int, byte[]> ReadServerExtensions()
         {
             if (m_encodedServerExtensions == null)
                 return null;
diff --git a/crypto/src/tls/SrpTlsClient.cs b/crypto/src/tls/SrpTlsClient.cs
index f6f6472bc..cd78dc887 100644
--- a/crypto/src/tls/SrpTlsClient.cs
+++ b/crypto/src/tls/SrpTlsClient.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -44,16 +44,16 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public override IDictionary GetClientExtensions()
+        public override IDictionary<int, byte[]> GetClientExtensions()
         {
-            IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(
+            var clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(
                 base.GetClientExtensions());
             TlsSrpUtilities.AddSrpExtension(clientExtensions, m_srpIdentity.GetSrpIdentity());
             return clientExtensions;
         }
 
         /// <exception cref="IOException"/>
-        public override void ProcessServerExtensions(IDictionary serverExtensions)
+        public override void ProcessServerExtensions(IDictionary<int, byte[]> serverExtensions)
         {
             if (!TlsUtilities.HasExpectedEmptyExtensionData(serverExtensions, ExtensionType.srp,
                 AlertDescription.illegal_parameter))
diff --git a/crypto/src/tls/SrpTlsServer.cs b/crypto/src/tls/SrpTlsServer.cs
index 1e2f09e03..63d41ede2 100644
--- a/crypto/src/tls/SrpTlsServer.cs
+++ b/crypto/src/tls/SrpTlsServer.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Tls
             return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites);
         }
 
-        public override void ProcessClientExtensions(IDictionary clientExtensions)
+        public override void ProcessClientExtensions(IDictionary<int, byte[]> clientExtensions)
         {
             base.ProcessClientExtensions(clientExtensions);
 
diff --git a/crypto/src/tls/TlsClient.cs b/crypto/src/tls/TlsClient.cs
index 66bb3bc86..368161c32 100644
--- a/crypto/src/tls/TlsClient.cs
+++ b/crypto/src/tls/TlsClient.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 namespace Org.BouncyCastle.Tls
@@ -22,13 +22,13 @@ namespace Org.BouncyCastle.Tls
         /// <remarks>This will only be called when TLS 1.3 or higher is amongst the offered protocol versions.</remarks>
         /// <returns>an <see cref="IList"/> of <see cref="TlsPskExternal"/> instances, or null if none should be
         /// offered.</returns>
-        IList GetExternalPsks();
+        IList<TlsPskExternal> GetExternalPsks();
 
         bool IsFallback();
 
         /// <returns>(Int32 -> byte[])</returns>
         /// <exception cref="IOException"/>
-        IDictionary GetClientExtensions();
+        IDictionary<int, byte[]> GetClientExtensions();
 
         /// <summary>If this client is offering TLS 1.3 or higher, this method may be called to determine for which
         /// groups a key share should be included in the initial ClientHello.</summary>
@@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Tls
         /// </remarks>
         /// <returns>an <see cref="IList"/> of <see cref="NamedGroup">named group</see> values, possibly empty or null.
         /// </returns>
-        IList GetEarlyKeyShareGroups();
+        IList<int> GetEarlyKeyShareGroups();
 
         /// <exception cref="IOException"/>
         void NotifyServerVersion(ProtocolVersion selectedVersion);
@@ -72,11 +72,11 @@ namespace Org.BouncyCastle.Tls
         /// </remarks>
         /// <param name="serverExtensions">(Int32 -> byte[])</param>
         /// <exception cref="IOException"/>
-        void ProcessServerExtensions(IDictionary serverExtensions);
+        void ProcessServerExtensions(IDictionary<int, byte[]> serverExtensions);
 
         /// <param name="serverSupplementalData">(SupplementalDataEntry)</param>
         /// <exception cref="IOException"/>
-        void ProcessServerSupplementalData(IList serverSupplementalData);
+        void ProcessServerSupplementalData(IList<SupplementalDataEntry> serverSupplementalData);
 
         /// <exception cref="IOException"/>
         TlsPskIdentity GetPskIdentity();
@@ -95,7 +95,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <returns>(SupplementalDataEntry)</returns>
         /// <exception cref="IOException"/>
-        IList GetClientSupplementalData();
+        IList<SupplementalDataEntry> GetClientSupplementalData();
 
         /// <summary>RFC 5077 3.3. NewSessionTicket Handshake Message</summary>
         /// <remarks>
diff --git a/crypto/src/tls/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs
index 399d8c9b8..d750c5e2c 100644
--- a/crypto/src/tls/TlsClientProtocol.cs
+++ b/crypto/src/tls/TlsClientProtocol.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Tls
         protected TlsClient m_tlsClient = null;
         internal TlsClientContextImpl m_tlsClientContext = null;
 
-        protected IDictionary m_clientAgreements = null;
+        protected IDictionary<int, TlsAgreement> m_clientAgreements = null;
         internal OfferedPsks.BindersConfig m_clientBinders = null;
         protected ClientHello m_clientHello = null;
         protected TlsKeyExchange m_keyExchange = null;
@@ -580,7 +580,7 @@ namespace Org.BouncyCastle.Tls
                         m_keyExchange.ProcessClientCredentials(clientAuthCredentials);                    
                     }
 
-                    IList clientSupplementalData = m_tlsClient.GetClientSupplementalData();
+                    var clientSupplementalData = m_tlsClient.GetClientSupplementalData();
                     if (clientSupplementalData != null)
                     {
                         SendSupplementalDataMessage(clientSupplementalData);
@@ -769,7 +769,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        protected virtual void HandleSupplementalData(IList serverSupplementalData)
+        protected virtual void HandleSupplementalData(IList<SupplementalDataEntry> serverSupplementalData)
         {
             m_tlsClient.ProcessServerSupplementalData(serverSupplementalData);
             this.m_connectionState = CS_SERVER_SUPPLEMENTAL_DATA;
@@ -803,7 +803,7 @@ namespace Org.BouncyCastle.Tls
                 throw new TlsFatalAlert(AlertDescription.illegal_parameter);
             }
 
-            IDictionary extensions = helloRetryRequest.Extensions;
+            var extensions = helloRetryRequest.Extensions;
             if (null == extensions)
                 throw new TlsFatalAlert(AlertDescription.illegal_parameter);
 
@@ -899,7 +899,7 @@ namespace Org.BouncyCastle.Tls
                 throw new TlsFatalAlert(AlertDescription.illegal_parameter);
             }
 
-            IDictionary extensions = serverHello.Extensions;
+            var extensions = serverHello.Extensions;
             if (null == extensions)
                 throw new TlsFatalAlert(AlertDescription.illegal_parameter);
 
@@ -953,7 +953,8 @@ namespace Org.BouncyCastle.Tls
              * 
              * OCSP information is carried in an extension for a CertificateEntry.
              */
-            securityParameters.m_statusRequestVersion = m_clientExtensions.Contains(ExtensionType.status_request) ? 1 : 0;
+            securityParameters.m_statusRequestVersion =
+                m_clientExtensions.ContainsKey(ExtensionType.status_request) ? 1 : 0;
 
             TlsSecret pskEarlySecret = null;
             {
@@ -1045,7 +1046,7 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         protected virtual void ProcessServerHello(ServerHello serverHello)
         {
-            IDictionary serverHelloExtensions = serverHello.Extensions;
+            var serverHelloExtensions = serverHello.Extensions;
 
             ProtocolVersion legacy_version = serverHello.Version;
             ProtocolVersion supported_version = TlsExtensionsUtilities.GetSupportedVersionsExtensionServer(
@@ -1256,7 +1257,8 @@ namespace Org.BouncyCastle.Tls
                 m_serverExtensions);
             securityParameters.m_applicationProtocolSet = true;
 
-            IDictionary sessionClientExtensions = m_clientExtensions, sessionServerExtensions = m_serverExtensions;
+            var sessionClientExtensions = m_clientExtensions;
+            var sessionServerExtensions = m_serverExtensions;
             if (m_resumedSession)
             {
                 if (securityParameters.CipherSuite != m_sessionParameters.CipherSuite
@@ -1393,7 +1395,8 @@ namespace Org.BouncyCastle.Tls
                 m_serverExtensions);
             securityParameters.m_applicationProtocolSet = true;
 
-            IDictionary sessionClientExtensions = m_clientExtensions, sessionServerExtensions = m_serverExtensions;
+            var sessionClientExtensions = m_clientExtensions;
+            var sessionServerExtensions = m_serverExtensions;
             if (m_resumedSession)
             {
                 if (securityParameters.CipherSuite != m_sessionParameters.CipherSuite
@@ -1417,8 +1420,8 @@ namespace Org.BouncyCastle.Tls
              * 
              * OCSP information is carried in an extension for a CertificateEntry.
              */
-            securityParameters.m_statusRequestVersion = m_clientExtensions.Contains(ExtensionType.status_request)
-                ? 1 : 0;
+            securityParameters.m_statusRequestVersion =
+                m_clientExtensions.ContainsKey(ExtensionType.status_request) ? 1 : 0;
 
             this.m_expectSessionTicket = false;
 
@@ -1524,7 +1527,7 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         protected virtual void Send13ClientHelloRetry()
         {
-            IDictionary clientHelloExtensions = m_clientHello.Extensions;
+            var clientHelloExtensions = m_clientHello.Extensions;
 
             clientHelloExtensions.Remove(ExtensionType.cookie);
             clientHelloExtensions.Remove(ExtensionType.early_data);
diff --git a/crypto/src/tls/TlsExtensionsUtilities.cs b/crypto/src/tls/TlsExtensionsUtilities.cs
index e1db93016..9ffdcfe40 100644
--- a/crypto/src/tls/TlsExtensionsUtilities.cs
+++ b/crypto/src/tls/TlsExtensionsUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Asn1;
@@ -8,516 +8,543 @@ using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Tls
 {
-    public abstract class TlsExtensionsUtilities
+    public static class TlsExtensionsUtilities
     {
-        public static IDictionary EnsureExtensionsInitialised(IDictionary extensions)
+        public static IDictionary<int, byte[]> EnsureExtensionsInitialised(IDictionary<int, byte[]> extensions)
         {
-            return extensions == null ? Platform.CreateHashtable() : extensions;
+            return extensions == null ? new Dictionary<int, byte[]>() : extensions;
         }
 
         /// <param name="extensions">(Int32 -> byte[])</param>
         /// <param name="protocolNameList">an <see cref="IList"/> of <see cref="ProtocolName"/>.</param>
         /// <exception cref="IOException"/>
-        public static void AddAlpnExtensionClient(IDictionary extensions, IList protocolNameList)
+        public static void AddAlpnExtensionClient(IDictionary<int, byte[]> extensions,
+            IList<ProtocolName> protocolNameList)
         {
-            extensions[ExtensionType.application_layer_protocol_negotiation] = CreateAlpnExtensionClient(protocolNameList);
+            extensions[ExtensionType.application_layer_protocol_negotiation] =
+                CreateAlpnExtensionClient(protocolNameList);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddAlpnExtensionServer(IDictionary extensions, ProtocolName protocolName)
+        public static void AddAlpnExtensionServer(IDictionary<int, byte[]> extensions, ProtocolName protocolName)
         {
             extensions[ExtensionType.application_layer_protocol_negotiation] = CreateAlpnExtensionServer(protocolName);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddCertificateAuthoritiesExtension(IDictionary extensions, IList authorities)
+        public static void AddCertificateAuthoritiesExtension(IDictionary<int, byte[]> extensions,
+            IList<X509Name> authorities)
         {
             extensions[ExtensionType.certificate_authorities] = CreateCertificateAuthoritiesExtension(authorities);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddClientCertificateTypeExtensionClient(IDictionary extensions, short[] certificateTypes)
+        public static void AddClientCertificateTypeExtensionClient(IDictionary<int, byte[]> extensions,
+            short[] certificateTypes)
         {
             extensions[ExtensionType.client_certificate_type] = CreateCertificateTypeExtensionClient(certificateTypes);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddClientCertificateTypeExtensionServer(IDictionary extensions, short certificateType)
+        public static void AddClientCertificateTypeExtensionServer(IDictionary<int, byte[]> extensions,
+            short certificateType)
         {
             extensions[ExtensionType.client_certificate_type] = CreateCertificateTypeExtensionServer(certificateType);
         }
 
-        public static void AddClientCertificateUrlExtension(IDictionary extensions)
+        public static void AddClientCertificateUrlExtension(IDictionary<int, byte[]> extensions)
         {
             extensions[ExtensionType.client_certificate_url] = CreateClientCertificateUrlExtension();
         }
 
         /// <exception cref="IOException"/>
-        public static void AddCompressCertificateExtension(IDictionary extensions, int[] algorithms)
+        public static void AddCompressCertificateExtension(IDictionary<int, byte[]> extensions, int[] algorithms)
         {
             extensions[ExtensionType.compress_certificate] = CreateCompressCertificateExtension(algorithms);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddCookieExtension(IDictionary extensions, byte[] cookie)
+        public static void AddCookieExtension(IDictionary<int, byte[]> extensions, byte[] cookie)
         {
             extensions[ExtensionType.cookie] = CreateCookieExtension(cookie);
         }
 
-        public static void AddEarlyDataIndication(IDictionary extensions)
+        public static void AddEarlyDataIndication(IDictionary<int, byte[]> extensions)
         {
             extensions[ExtensionType.early_data] = CreateEarlyDataIndication();
         }
 
         /// <exception cref="IOException"/>
-        public static void AddEarlyDataMaxSize(IDictionary extensions, long maxSize)
+        public static void AddEarlyDataMaxSize(IDictionary<int, byte[]> extensions, long maxSize)
         {
             extensions[ExtensionType.early_data] = CreateEarlyDataMaxSize(maxSize);
         }
 
-        public static void AddEmptyExtensionData(IDictionary extensions, Int32 extType)
+        public static void AddEmptyExtensionData(IDictionary<int, byte[]> extensions, int extType)
         {
             extensions[extType] = CreateEmptyExtensionData();
         }
 
-        public static void AddEncryptThenMacExtension(IDictionary extensions)
+        public static void AddEncryptThenMacExtension(IDictionary<int, byte[]> extensions)
         {
             extensions[ExtensionType.encrypt_then_mac] = CreateEncryptThenMacExtension();
         }
 
-        public static void AddExtendedMasterSecretExtension(IDictionary extensions)
+        public static void AddExtendedMasterSecretExtension(IDictionary<int, byte[]> extensions)
         {
             extensions[ExtensionType.extended_master_secret] = CreateExtendedMasterSecretExtension();
         }
 
         /// <exception cref="IOException"/>
-        public static void AddHeartbeatExtension(IDictionary extensions, HeartbeatExtension heartbeatExtension)
+        public static void AddHeartbeatExtension(IDictionary<int, byte[]> extensions,
+            HeartbeatExtension heartbeatExtension)
         {
             extensions[ExtensionType.heartbeat] = CreateHeartbeatExtension(heartbeatExtension);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddKeyShareClientHello(IDictionary extensions, IList clientShares)
+        public static void AddKeyShareClientHello(IDictionary<int, byte[]> extensions,
+            IList<KeyShareEntry> clientShares)
         {
             extensions[ExtensionType.key_share] = CreateKeyShareClientHello(clientShares);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddKeyShareHelloRetryRequest(IDictionary extensions, int namedGroup)
+        public static void AddKeyShareHelloRetryRequest(IDictionary<int, byte[]> extensions, int namedGroup)
         {
             extensions[ExtensionType.key_share] = CreateKeyShareHelloRetryRequest(namedGroup);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddKeyShareServerHello(IDictionary extensions, KeyShareEntry serverShare)
+        public static void AddKeyShareServerHello(IDictionary<int, byte[]> extensions, KeyShareEntry serverShare)
         {
             extensions[ExtensionType.key_share] = CreateKeyShareServerHello(serverShare);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddMaxFragmentLengthExtension(IDictionary extensions, short maxFragmentLength)
+        public static void AddMaxFragmentLengthExtension(IDictionary<int, byte[]> extensions, short maxFragmentLength)
         {
             extensions[ExtensionType.max_fragment_length] = CreateMaxFragmentLengthExtension(maxFragmentLength);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddOidFiltersExtension(IDictionary extensions, IDictionary filters)
+        public static void AddOidFiltersExtension(IDictionary<int, byte[]> extensions,
+            IDictionary<DerObjectIdentifier, byte[]> filters)
         {
             extensions[ExtensionType.oid_filters] = CreateOidFiltersExtension(filters);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddPaddingExtension(IDictionary extensions, int dataLength)
+        public static void AddPaddingExtension(IDictionary<int, byte[]> extensions, int dataLength)
         {
             extensions[ExtensionType.padding] = CreatePaddingExtension(dataLength);
         }
 
-        public static void AddPostHandshakeAuthExtension(IDictionary extensions)
+        public static void AddPostHandshakeAuthExtension(IDictionary<int, byte[]> extensions)
         {
             extensions[ExtensionType.post_handshake_auth] = CreatePostHandshakeAuthExtension();
         }
 
         /// <exception cref="IOException"/>
-        public static void AddPreSharedKeyClientHello(IDictionary extensions, OfferedPsks offeredPsks)
+        public static void AddPreSharedKeyClientHello(IDictionary<int, byte[]> extensions, OfferedPsks offeredPsks)
         {
             extensions[ExtensionType.pre_shared_key] = CreatePreSharedKeyClientHello(offeredPsks);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddPreSharedKeyServerHello(IDictionary extensions, int selectedIdentity)
+        public static void AddPreSharedKeyServerHello(IDictionary<int, byte[]> extensions, int selectedIdentity)
         {
             extensions[ExtensionType.pre_shared_key] = CreatePreSharedKeyServerHello(selectedIdentity);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddPskKeyExchangeModesExtension(IDictionary extensions, short[] modes)
+        public static void AddPskKeyExchangeModesExtension(IDictionary<int, byte[]> extensions, short[] modes)
         {
             extensions[ExtensionType.psk_key_exchange_modes] = CreatePskKeyExchangeModesExtension(modes);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddRecordSizeLimitExtension(IDictionary extensions, int recordSizeLimit)
+        public static void AddRecordSizeLimitExtension(IDictionary<int, byte[]> extensions, int recordSizeLimit)
         {
             extensions[ExtensionType.record_size_limit] = CreateRecordSizeLimitExtension(recordSizeLimit);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddServerCertificateTypeExtensionClient(IDictionary extensions, short[] certificateTypes)
+        public static void AddServerCertificateTypeExtensionClient(IDictionary<int, byte[]> extensions,
+            short[] certificateTypes)
         {
             extensions[ExtensionType.server_certificate_type] = CreateCertificateTypeExtensionClient(certificateTypes);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddServerCertificateTypeExtensionServer(IDictionary extensions, short certificateType)
+        public static void AddServerCertificateTypeExtensionServer(IDictionary<int, byte[]> extensions,
+            short certificateType)
         {
             extensions[ExtensionType.server_certificate_type] = CreateCertificateTypeExtensionServer(certificateType);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddServerNameExtensionClient(IDictionary extensions, IList serverNameList)
+        public static void AddServerNameExtensionClient(IDictionary<int, byte[]> extensions,
+            IList<ServerName> serverNameList)
         {
             extensions[ExtensionType.server_name] = CreateServerNameExtensionClient(serverNameList);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddServerNameExtensionServer(IDictionary extensions)
+        public static void AddServerNameExtensionServer(IDictionary<int, byte[]> extensions)
         {
             extensions[ExtensionType.server_name] = CreateServerNameExtensionServer();
         }
 
         /// <exception cref="IOException"/>
-        public static void AddSignatureAlgorithmsExtension(IDictionary extensions, IList supportedSignatureAlgorithms)
+        public static void AddSignatureAlgorithmsExtension(IDictionary<int, byte[]> extensions,
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms)
         {
-            extensions[ExtensionType.signature_algorithms] = CreateSignatureAlgorithmsExtension(supportedSignatureAlgorithms);
+            extensions[ExtensionType.signature_algorithms] =
+                CreateSignatureAlgorithmsExtension(supportedSignatureAlgorithms);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddSignatureAlgorithmsCertExtension(IDictionary extensions, IList supportedSignatureAlgorithms)
+        public static void AddSignatureAlgorithmsCertExtension(IDictionary<int, byte[]> extensions,
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms)
         {
-            extensions[ExtensionType.signature_algorithms_cert] = CreateSignatureAlgorithmsCertExtension(supportedSignatureAlgorithms);
+            extensions[ExtensionType.signature_algorithms_cert] =
+                CreateSignatureAlgorithmsCertExtension(supportedSignatureAlgorithms);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddStatusRequestExtension(IDictionary extensions, CertificateStatusRequest statusRequest)
+        public static void AddStatusRequestExtension(IDictionary<int, byte[]> extensions,
+            CertificateStatusRequest statusRequest)
         {
             extensions[ExtensionType.status_request] = CreateStatusRequestExtension(statusRequest);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddStatusRequestV2Extension(IDictionary extensions, IList statusRequestV2)
+        public static void AddStatusRequestV2Extension(IDictionary<int, byte[]> extensions,
+            IList<CertificateStatusRequestItemV2> statusRequestV2)
         {
             extensions[ExtensionType.status_request_v2] = CreateStatusRequestV2Extension(statusRequestV2);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddSupportedGroupsExtension(IDictionary extensions, IList namedGroups)
+        public static void AddSupportedGroupsExtension(IDictionary<int, byte[]> extensions, IList<int> namedGroups)
         {
             extensions[ExtensionType.supported_groups] = CreateSupportedGroupsExtension(namedGroups);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddSupportedPointFormatsExtension(IDictionary extensions, short[] ecPointFormats)
+        public static void AddSupportedPointFormatsExtension(IDictionary<int, byte[]> extensions,
+            short[] ecPointFormats)
         {
             extensions[ExtensionType.ec_point_formats] = CreateSupportedPointFormatsExtension(ecPointFormats);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddSupportedVersionsExtensionClient(IDictionary extensions, ProtocolVersion[] versions)
+        public static void AddSupportedVersionsExtensionClient(IDictionary<int, byte[]> extensions,
+            ProtocolVersion[] versions)
         {
             extensions[ExtensionType.supported_versions] = CreateSupportedVersionsExtensionClient(versions);
         }
 
         /// <exception cref="IOException"/>
-        public static void AddSupportedVersionsExtensionServer(IDictionary extensions, ProtocolVersion selectedVersion)
+        public static void AddSupportedVersionsExtensionServer(IDictionary<int, byte[]> extensions,
+            ProtocolVersion selectedVersion)
         {
             extensions[ExtensionType.supported_versions] = CreateSupportedVersionsExtensionServer(selectedVersion);
         }
 
-        public static void AddTruncatedHmacExtension(IDictionary extensions)
+        public static void AddTruncatedHmacExtension(IDictionary<int, byte[]> extensions)
         {
             extensions[ExtensionType.truncated_hmac] = CreateTruncatedHmacExtension();
         }
 
         /// <exception cref="IOException"/>
-        public static void AddTrustedCAKeysExtensionClient(IDictionary extensions, IList trustedAuthoritiesList)
+        public static void AddTrustedCAKeysExtensionClient(IDictionary<int, byte[]> extensions,
+            IList<TrustedAuthority> trustedAuthoritiesList)
         {
             extensions[ExtensionType.trusted_ca_keys] = CreateTrustedCAKeysExtensionClient(trustedAuthoritiesList);
         }
 
-        public static void AddTrustedCAKeysExtensionServer(IDictionary extensions)
+        public static void AddTrustedCAKeysExtensionServer(IDictionary<int, byte[]> extensions)
         {
             extensions[ExtensionType.trusted_ca_keys] = CreateTrustedCAKeysExtensionServer();
         }
 
         /// <returns>an <see cref="IList"/> of <see cref="ProtocolName"/>.</returns>
         /// <exception cref="IOException"/>
-        public static IList GetAlpnExtensionClient(IDictionary extensions)
+        public static IList<ProtocolName> GetAlpnExtensionClient(IDictionary<int, byte[]> extensions)
         {
-            byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.application_layer_protocol_negotiation);
+            byte[] extensionData = TlsUtilities.GetExtensionData(extensions,
+                ExtensionType.application_layer_protocol_negotiation);
             return extensionData == null ? null : ReadAlpnExtensionClient(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static ProtocolName GetAlpnExtensionServer(IDictionary extensions)
+        public static ProtocolName GetAlpnExtensionServer(IDictionary<int, byte[]> extensions)
         {
-            byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.application_layer_protocol_negotiation);
+            byte[] extensionData = TlsUtilities.GetExtensionData(extensions,
+                ExtensionType.application_layer_protocol_negotiation);
             return extensionData == null ? null : ReadAlpnExtensionServer(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static IList GetCertificateAuthoritiesExtension(IDictionary extensions)
+        public static IList<X509Name> GetCertificateAuthoritiesExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.certificate_authorities);
             return extensionData == null ? null : ReadCertificateAuthoritiesExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static short[] GetClientCertificateTypeExtensionClient(IDictionary extensions)
+        public static short[] GetClientCertificateTypeExtensionClient(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_type);
             return extensionData == null ? null : ReadCertificateTypeExtensionClient(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static short GetClientCertificateTypeExtensionServer(IDictionary extensions)
+        public static short GetClientCertificateTypeExtensionServer(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_type);
             return extensionData == null ? (short)-1 : ReadCertificateTypeExtensionServer(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static int[] GetCompressCertificateExtension(IDictionary extensions)
+        public static int[] GetCompressCertificateExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.compress_certificate);
             return extensionData == null ? null : ReadCompressCertificateExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] GetCookieExtension(IDictionary extensions)
+        public static byte[] GetCookieExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.cookie);
             return extensionData == null ? null : ReadCookieExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static long GetEarlyDataMaxSize(IDictionary extensions)
+        public static long GetEarlyDataMaxSize(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.early_data);
             return extensionData == null ? -1L : ReadEarlyDataMaxSize(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static HeartbeatExtension GetHeartbeatExtension(IDictionary extensions)
+        public static HeartbeatExtension GetHeartbeatExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.heartbeat);
             return extensionData == null ? null : ReadHeartbeatExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static IList GetKeyShareClientHello(IDictionary extensions)
+        public static IList<KeyShareEntry> GetKeyShareClientHello(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.key_share);
             return extensionData == null ? null : ReadKeyShareClientHello(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static int GetKeyShareHelloRetryRequest(IDictionary extensions)
+        public static int GetKeyShareHelloRetryRequest(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.key_share);
             return extensionData == null ? -1 : ReadKeyShareHelloRetryRequest(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static KeyShareEntry GetKeyShareServerHello(IDictionary extensions)
+        public static KeyShareEntry GetKeyShareServerHello(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.key_share);
             return extensionData == null ? null : ReadKeyShareServerHello(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static short GetMaxFragmentLengthExtension(IDictionary extensions)
+        public static short GetMaxFragmentLengthExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.max_fragment_length);
             return extensionData == null ? (short)-1 : ReadMaxFragmentLengthExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static IDictionary GetOidFiltersExtension(IDictionary extensions)
+        public static IDictionary<DerObjectIdentifier, byte[]> GetOidFiltersExtension(
+            IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.oid_filters);
             return extensionData == null ? null : ReadOidFiltersExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static int GetPaddingExtension(IDictionary extensions)
+        public static int GetPaddingExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.padding);
             return extensionData == null ? -1 : ReadPaddingExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static OfferedPsks GetPreSharedKeyClientHello(IDictionary extensions)
+        public static OfferedPsks GetPreSharedKeyClientHello(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.pre_shared_key);
             return extensionData == null ? null : ReadPreSharedKeyClientHello(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static int GetPreSharedKeyServerHello(IDictionary extensions)
+        public static int GetPreSharedKeyServerHello(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.pre_shared_key);
             return extensionData == null ? -1 : ReadPreSharedKeyServerHello(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static short[] GetPskKeyExchangeModesExtension(IDictionary extensions)
+        public static short[] GetPskKeyExchangeModesExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.psk_key_exchange_modes);
             return extensionData == null ? null : ReadPskKeyExchangeModesExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static int GetRecordSizeLimitExtension(IDictionary extensions)
+        public static int GetRecordSizeLimitExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.record_size_limit);
             return extensionData == null ? -1 : ReadRecordSizeLimitExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static short[] GetServerCertificateTypeExtensionClient(IDictionary extensions)
+        public static short[] GetServerCertificateTypeExtensionClient(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_certificate_type);
             return extensionData == null ? null : ReadCertificateTypeExtensionClient(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static short GetServerCertificateTypeExtensionServer(IDictionary extensions)
+        public static short GetServerCertificateTypeExtensionServer(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_certificate_type);
             return extensionData == null ? (short)-1 : ReadCertificateTypeExtensionServer(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static IList GetServerNameExtensionClient(IDictionary extensions)
+        public static IList<ServerName> GetServerNameExtensionClient(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_name);
             return extensionData == null ? null : ReadServerNameExtensionClient(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static IList GetSignatureAlgorithmsExtension(IDictionary extensions)
+        public static IList<SignatureAndHashAlgorithm> GetSignatureAlgorithmsExtension(
+            IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.signature_algorithms);
             return extensionData == null ? null : ReadSignatureAlgorithmsExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static IList GetSignatureAlgorithmsCertExtension(IDictionary extensions)
+        public static IList<SignatureAndHashAlgorithm> GetSignatureAlgorithmsCertExtension(
+            IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.signature_algorithms_cert);
             return extensionData == null ? null : ReadSignatureAlgorithmsCertExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static CertificateStatusRequest GetStatusRequestExtension(IDictionary extensions)
+        public static CertificateStatusRequest GetStatusRequestExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.status_request);
             return extensionData == null ? null : ReadStatusRequestExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static IList GetStatusRequestV2Extension(IDictionary extensions)
+        public static IList<CertificateStatusRequestItemV2> GetStatusRequestV2Extension(
+            IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.status_request_v2);
             return extensionData == null ? null : ReadStatusRequestV2Extension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static int[] GetSupportedGroupsExtension(IDictionary extensions)
+        public static int[] GetSupportedGroupsExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.supported_groups);
             return extensionData == null ? null : ReadSupportedGroupsExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static short[] GetSupportedPointFormatsExtension(IDictionary extensions)
+        public static short[] GetSupportedPointFormatsExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.ec_point_formats);
             return extensionData == null ? null : ReadSupportedPointFormatsExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static ProtocolVersion[] GetSupportedVersionsExtensionClient(IDictionary extensions)
+        public static ProtocolVersion[] GetSupportedVersionsExtensionClient(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.supported_versions);
             return extensionData == null ? null : ReadSupportedVersionsExtensionClient(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static ProtocolVersion GetSupportedVersionsExtensionServer(IDictionary extensions)
+        public static ProtocolVersion GetSupportedVersionsExtensionServer(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.supported_versions);
             return extensionData == null ? null : ReadSupportedVersionsExtensionServer(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static IList GetTrustedCAKeysExtensionClient(IDictionary extensions)
+        public static IList<TrustedAuthority> GetTrustedCAKeysExtensionClient(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.trusted_ca_keys);
             return extensionData == null ? null : ReadTrustedCAKeysExtensionClient(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static bool HasClientCertificateUrlExtension(IDictionary extensions)
+        public static bool HasClientCertificateUrlExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_url);
             return extensionData == null ? false : ReadClientCertificateUrlExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static bool HasEarlyDataIndication(IDictionary extensions)
+        public static bool HasEarlyDataIndication(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.early_data);
             return extensionData == null ? false : ReadEarlyDataIndication(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static bool HasEncryptThenMacExtension(IDictionary extensions)
+        public static bool HasEncryptThenMacExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.encrypt_then_mac);
             return extensionData == null ? false : ReadEncryptThenMacExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static bool HasExtendedMasterSecretExtension(IDictionary extensions)
+        public static bool HasExtendedMasterSecretExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.extended_master_secret);
             return extensionData == null ? false : ReadExtendedMasterSecretExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static bool HasServerNameExtensionServer(IDictionary extensions)
+        public static bool HasServerNameExtensionServer(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_name);
             return extensionData == null ? false : ReadServerNameExtensionServer(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static bool HasPostHandshakeAuthExtension(IDictionary extensions)
+        public static bool HasPostHandshakeAuthExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.post_handshake_auth);
             return extensionData == null ? false : ReadPostHandshakeAuthExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static bool HasTruncatedHmacExtension(IDictionary extensions)
+        public static bool HasTruncatedHmacExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.truncated_hmac);
             return extensionData == null ? false : ReadTruncatedHmacExtension(extensionData);
         }
 
         /// <exception cref="IOException"/>
-        public static bool HasTrustedCAKeysExtensionServer(IDictionary extensions)
+        public static bool HasTrustedCAKeysExtensionServer(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.trusted_ca_keys);
             return extensionData == null ? false : ReadTrustedCAKeysExtensionServer(extensionData);
@@ -525,7 +552,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <param name="protocolNameList">an <see cref="IList"/> of <see cref="ProtocolName"/>.</param>
         /// <exception cref="IOException"/>
-        public static byte[] CreateAlpnExtensionClient(IList protocolNameList)
+        public static byte[] CreateAlpnExtensionClient(IList<ProtocolName> protocolNameList)
         {
             if (protocolNameList == null || protocolNameList.Count < 1)
                 throw new TlsFatalAlert(AlertDescription.internal_error);
@@ -546,14 +573,14 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         public static byte[] CreateAlpnExtensionServer(ProtocolName protocolName)
         {
-            IList protocol_name_list = Platform.CreateArrayList();
+            var protocol_name_list = new List<ProtocolName>();
             protocol_name_list.Add(protocolName);
 
             return CreateAlpnExtensionClient(protocol_name_list);
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateCertificateAuthoritiesExtension(IList authorities)
+        public static byte[] CreateCertificateAuthoritiesExtension(IList<X509Name> authorities)
         {
             if (null == authorities || authorities.Count < 1)
                 throw new TlsFatalAlert(AlertDescription.internal_error);
@@ -652,7 +679,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateKeyShareClientHello(IList clientShares)
+        public static byte[] CreateKeyShareClientHello(IList<KeyShareEntry> clientShares)
         {
             if (clientShares == null || clientShares.Count < 1)
                 return TlsUtilities.EncodeUint16(0);
@@ -698,7 +725,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateOidFiltersExtension(IDictionary filters)
+        public static byte[] CreateOidFiltersExtension(IDictionary<DerObjectIdentifier, byte[]> filters)
         {
             MemoryStream buf = new MemoryStream();
 
@@ -707,9 +734,11 @@ namespace Org.BouncyCastle.Tls
 
             if (null != filters)
             {
-                foreach (DerObjectIdentifier certificateExtensionOid in filters.Keys)
+                //foreach (DerObjectIdentifier certificateExtensionOid in filters.Keys)
+                foreach (var filter in filters)
                 {
-                    byte[] certificateExtensionValues = (byte[])filters[certificateExtensionOid];
+                    var certificateExtensionOid = filter.Key;
+                    var certificateExtensionValues = filter.Value;
 
                     if (null == certificateExtensionOid || null == certificateExtensionValues)
                         throw new TlsFatalAlert(AlertDescription.internal_error);
@@ -774,7 +803,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateServerNameExtensionClient(IList serverNameList)
+        public static byte[] CreateServerNameExtensionClient(IList<ServerName> serverNameList)
         {
             if (serverNameList == null)
                 throw new TlsFatalAlert(AlertDescription.internal_error);
@@ -792,7 +821,8 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateSignatureAlgorithmsExtension(IList supportedSignatureAlgorithms)
+        public static byte[] CreateSignatureAlgorithmsExtension(
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms)
         {
             MemoryStream buf = new MemoryStream();
 
@@ -802,7 +832,8 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateSignatureAlgorithmsCertExtension(IList supportedSignatureAlgorithms)
+        public static byte[] CreateSignatureAlgorithmsCertExtension(
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms)
         {
             return CreateSignatureAlgorithmsExtension(supportedSignatureAlgorithms);
         }
@@ -821,7 +852,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateStatusRequestV2Extension(IList statusRequestV2)
+        public static byte[] CreateStatusRequestV2Extension(IList<CertificateStatusRequestItemV2> statusRequestV2)
         {
             if (statusRequestV2 == null || statusRequestV2.Count < 1)
                 throw new TlsFatalAlert(AlertDescription.internal_error);
@@ -840,7 +871,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateSupportedGroupsExtension(IList namedGroups)
+        public static byte[] CreateSupportedGroupsExtension(IList<int> namedGroups)
         {
             if (namedGroups == null || namedGroups.Count < 1)
                 throw new TlsFatalAlert(AlertDescription.internal_error);
@@ -849,7 +880,7 @@ namespace Org.BouncyCastle.Tls
             int[] values = new int[count];
             for (int i = 0; i < count; ++i)
             {
-                values[i] = (Int32)namedGroups[i];
+                values[i] = namedGroups[i];
             }
 
             return TlsUtilities.EncodeUint16ArrayWithUint16Length(values);
@@ -883,7 +914,7 @@ namespace Org.BouncyCastle.Tls
             TlsUtilities.WriteUint8(count * 2, data, 0);
             for (int i = 0; i < count; ++i)
             {
-                TlsUtilities.WriteVersion((ProtocolVersion)versions[i], data, 1 + i * 2);
+                TlsUtilities.WriteVersion(versions[i], data, 1 + i * 2);
             }
             return data;
         }
@@ -900,7 +931,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] CreateTrustedCAKeysExtensionClient(IList trustedAuthoritiesList)
+        public static byte[] CreateTrustedCAKeysExtensionClient(IList<TrustedAuthority> trustedAuthoritiesList)
         {
             MemoryStream buf = new MemoryStream();
 
@@ -937,7 +968,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <returns>an <see cref="IList"/> of <see cref="ProtocolName"/>.</returns>
         /// <exception cref="IOException"/>
-        public static IList ReadAlpnExtensionClient(byte[] extensionData)
+        public static IList<ProtocolName> ReadAlpnExtensionClient(byte[] extensionData)
         {
             if (extensionData == null)
                 throw new ArgumentNullException("extensionData");
@@ -948,7 +979,7 @@ namespace Org.BouncyCastle.Tls
             if (length != (extensionData.Length - 2))
                 throw new TlsFatalAlert(AlertDescription.decode_error);
 
-            IList protocol_name_list = Platform.CreateArrayList();
+            var protocol_name_list = new List<ProtocolName>();
             while (buf.Position < buf.Length)
             {
                 ProtocolName protocolName = ProtocolName.Parse(buf);
@@ -961,15 +992,15 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         public static ProtocolName ReadAlpnExtensionServer(byte[] extensionData)
         {
-            IList protocol_name_list = ReadAlpnExtensionClient(extensionData);
+            var protocol_name_list = ReadAlpnExtensionClient(extensionData);
             if (protocol_name_list.Count != 1)
                 throw new TlsFatalAlert(AlertDescription.decode_error);
 
-            return (ProtocolName)protocol_name_list[0];
+            return protocol_name_list[0];
         }
 
         /// <exception cref="IOException"/>
-        public static IList ReadCertificateAuthoritiesExtension(byte[] extensionData)
+        public static IList<X509Name> ReadCertificateAuthoritiesExtension(byte[] extensionData)
         {
             if (extensionData == null)
                 throw new ArgumentNullException("extensionData");
@@ -982,7 +1013,7 @@ namespace Org.BouncyCastle.Tls
             if (length != (extensionData.Length - 2))
                 throw new TlsFatalAlert(AlertDescription.decode_error);
 
-            IList authorities = Platform.CreateArrayList();
+            var authorities = new List<X509Name>();
             while (buf.Position < buf.Length)
             {
                 byte[] derEncoding = TlsUtilities.ReadOpaque16(buf, 1);
@@ -1072,7 +1103,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static IList ReadKeyShareClientHello(byte[] extensionData)
+        public static IList<KeyShareEntry> ReadKeyShareClientHello(byte[] extensionData)
         {
             if (extensionData == null)
                 throw new ArgumentNullException("extensionData");
@@ -1090,7 +1121,7 @@ namespace Org.BouncyCastle.Tls
             if (length != (extensionData.Length - 2))
                 throw new TlsFatalAlert(AlertDescription.decode_error);
 
-            IList clientShares = Platform.CreateArrayList();
+            var clientShares = new List<KeyShareEntry>();
             while (buf.Position < buf.Length)
             {
                 KeyShareEntry clientShare = KeyShareEntry.Parse(buf);
@@ -1128,7 +1159,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static IDictionary ReadOidFiltersExtension(byte[] extensionData)
+        public static IDictionary<DerObjectIdentifier, byte[]> ReadOidFiltersExtension(byte[] extensionData)
         {
             if (extensionData == null)
                 throw new ArgumentNullException("extensionData");
@@ -1141,7 +1172,7 @@ namespace Org.BouncyCastle.Tls
             if (length != (extensionData.Length - 2))
                 throw new TlsFatalAlert(AlertDescription.decode_error);
 
-            IDictionary filters = Platform.CreateHashtable();
+            var filters = new Dictionary<DerObjectIdentifier, byte[]>();
             while (buf.Position < buf.Length)
             {
                 byte[] derEncoding = TlsUtilities.ReadOpaque8(buf, 1);
@@ -1149,7 +1180,7 @@ namespace Org.BouncyCastle.Tls
                 DerObjectIdentifier certificateExtensionOid = DerObjectIdentifier.GetInstance(asn1);
                 TlsUtilities.RequireDerEncoding(certificateExtensionOid, derEncoding);
 
-                if (filters.Contains(certificateExtensionOid))
+                if (filters.ContainsKey(certificateExtensionOid))
                     throw new TlsFatalAlert(AlertDescription.illegal_parameter);
 
                 byte[] certificateExtensionValues = TlsUtilities.ReadOpaque16(buf);
@@ -1219,7 +1250,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static IList ReadServerNameExtensionClient(byte[] extensionData)
+        public static IList<ServerName> ReadServerNameExtensionClient(byte[] extensionData)
         {
             if (extensionData == null)
                 throw new ArgumentNullException("extensionData");
@@ -1240,14 +1271,14 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static IList ReadSignatureAlgorithmsExtension(byte[] extensionData)
+        public static IList<SignatureAndHashAlgorithm> ReadSignatureAlgorithmsExtension(byte[] extensionData)
         {
             if (extensionData == null)
                 throw new ArgumentNullException("extensionData");
 
             MemoryStream buf = new MemoryStream(extensionData, false);
 
-            IList supported_signature_algorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(buf);
+            var supported_signature_algorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(buf);
 
             TlsProtocol.AssertEmpty(buf);
 
@@ -1255,7 +1286,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static IList ReadSignatureAlgorithmsCertExtension(byte[] extensionData)
+        public static IList<SignatureAndHashAlgorithm> ReadSignatureAlgorithmsCertExtension(byte[] extensionData)
         {
             return ReadSignatureAlgorithmsExtension(extensionData);
         }
@@ -1276,7 +1307,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static IList ReadStatusRequestV2Extension(byte[] extensionData)
+        public static IList<CertificateStatusRequestItemV2> ReadStatusRequestV2Extension(byte[] extensionData)
         {
             if (extensionData == null)
                 throw new ArgumentNullException("extensionData");
@@ -1289,7 +1320,7 @@ namespace Org.BouncyCastle.Tls
             if (length != (extensionData.Length - 2))
                 throw new TlsFatalAlert(AlertDescription.decode_error);
 
-            IList statusRequestV2 = Platform.CreateArrayList();
+            var statusRequestV2 = new List<CertificateStatusRequestItemV2>();
             while (buf.Position < buf.Length)
             {
                 CertificateStatusRequestItemV2 entry = CertificateStatusRequestItemV2.Parse(buf);
@@ -1371,7 +1402,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static IList ReadTrustedCAKeysExtensionClient(byte[] extensionData)
+        public static IList<TrustedAuthority> ReadTrustedCAKeysExtensionClient(byte[] extensionData)
         {
             if (extensionData == null)
                 throw new ArgumentNullException("extensionData");
@@ -1384,7 +1415,7 @@ namespace Org.BouncyCastle.Tls
             if (length != (extensionData.Length - 2))
                 throw new TlsFatalAlert(AlertDescription.decode_error);
 
-            IList trusted_authorities_list = Platform.CreateArrayList();
+            var trusted_authorities_list = new List<TrustedAuthority>();
             while (buf.Position < buf.Length)
             {
                 TrustedAuthority entry = TrustedAuthority.Parse(buf);
diff --git a/crypto/src/tls/TlsProtocol.cs b/crypto/src/tls/TlsProtocol.cs
index e442dd585..67ee5773b 100644
--- a/crypto/src/tls/TlsProtocol.cs
+++ b/crypto/src/tls/TlsProtocol.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -146,8 +146,8 @@ namespace Org.BouncyCastle.Tls
 
         protected byte[] m_retryCookie = null;
         protected int m_retryGroup = -1;
-        protected IDictionary m_clientExtensions = null;
-        protected IDictionary m_serverExtensions = null;
+        protected IDictionary<int, byte[]> m_clientExtensions = null;
+        protected IDictionary<int, byte[]> m_serverExtensions = null;
 
         protected short m_connectionState = CS_START;
         protected bool m_resumedSession = false;
@@ -1601,7 +1601,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        protected virtual void SendSupplementalDataMessage(IList supplementalData)
+        protected virtual void SendSupplementalDataMessage(IList<SupplementalDataEntry> supplementalData)
         {
             HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.supplemental_data);
             WriteSupplementalData(message, supplementalData);
@@ -1654,8 +1654,8 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        protected virtual short ProcessMaxFragmentLengthExtension(IDictionary clientExtensions,
-            IDictionary serverExtensions, short alertDescription)
+        protected virtual short ProcessMaxFragmentLengthExtension(IDictionary<int, byte[]> clientExtensions,
+            IDictionary<int, byte[]> serverExtensions, short alertDescription)
         {
             short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions);
             if (maxFragmentLength >= 0)
@@ -1732,7 +1732,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static IDictionary ReadExtensions(MemoryStream input)
+        internal static IDictionary<int, byte[]> ReadExtensions(MemoryStream input)
         {
             if (input.Position >= input.Length)
                 return null;
@@ -1745,10 +1745,10 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static IDictionary ReadExtensionsData(byte[] extBytes)
+        internal static IDictionary<int, byte[]> ReadExtensionsData(byte[] extBytes)
         {
             // Int32 -> byte[]
-            IDictionary extensions = Platform.CreateHashtable();
+            var extensions = new Dictionary<int, byte[]>();
 
             if (extBytes.Length > 0)
             {
@@ -1762,12 +1762,11 @@ namespace Org.BouncyCastle.Tls
                     /*
                      * RFC 3546 2.3 There MUST NOT be more than one extension of the same type.
                      */
-                    Int32 key = extension_type;
-                    if (extensions.Contains(key))
+                    if (extensions.ContainsKey(extension_type))
                         throw new TlsFatalAlert(AlertDescription.illegal_parameter,
                             "Repeated extension: " + ExtensionType.GetText(extension_type));
 
-                    extensions.Add(key, extension_data);
+                    extensions.Add(extension_type, extension_data);
                 }
                 while (buf.Position < buf.Length);
             }
@@ -1776,10 +1775,10 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static IDictionary ReadExtensionsData13(int handshakeType, byte[] extBytes)
+        internal static IDictionary<int, byte[]> ReadExtensionsData13(int handshakeType, byte[] extBytes)
         {
             // Int32 -> byte[]
-            IDictionary extensions = Platform.CreateHashtable();
+            var extensions = new Dictionary<int, byte[]>();
 
             if (extBytes.Length > 0)
             {
@@ -1800,12 +1799,11 @@ namespace Org.BouncyCastle.Tls
                     /*
                      * RFC 3546 2.3 There MUST NOT be more than one extension of the same type.
                      */
-                    Int32 key = extension_type;
-                    if (extensions.Contains(key))
+                    if (extensions.ContainsKey(extension_type))
                         throw new TlsFatalAlert(AlertDescription.illegal_parameter,
                             "Repeated extension: " + ExtensionType.GetText(extension_type));
 
-                    extensions.Add(key, extension_data);
+                    extensions.Add(extension_type, extension_data);
                 }
                 while (buf.Position < buf.Length);
             }
@@ -1814,7 +1812,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static IDictionary ReadExtensionsDataClientHello(byte[] extBytes)
+        internal static IDictionary<int, byte[]> ReadExtensionsDataClientHello(byte[] extBytes)
         {
             /*
              * TODO[tls13] We are currently allowing any extensions to appear in ClientHello. It is
@@ -1824,7 +1822,7 @@ namespace Org.BouncyCastle.Tls
              */
 
             // Int32 -> byte[]
-            IDictionary extensions = Platform.CreateHashtable();
+            var extensions = new Dictionary<int, byte[]>();
 
             if (extBytes.Length > 0)
             {
@@ -1841,12 +1839,11 @@ namespace Org.BouncyCastle.Tls
                     /*
                      * RFC 3546 2.3 There MUST NOT be more than one extension of the same type.
                      */
-                    Int32 key = extension_type;
-                    if (extensions.Contains(key))
+                    if (extensions.ContainsKey(extension_type))
                         throw new TlsFatalAlert(AlertDescription.illegal_parameter,
                             "Repeated extension: " + ExtensionType.GetText(extension_type));
 
-                    extensions.Add(key, extension_data);
+                    extensions.Add(extension_type, extension_data);
 
                     pre_shared_key_found |= (ExtensionType.pre_shared_key == extension_type);
                 }
@@ -1861,7 +1858,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static IList ReadSupplementalDataMessage(MemoryStream input)
+        internal static IList<SupplementalDataEntry> ReadSupplementalDataMessage(MemoryStream input)
         {
             byte[] supp_data = TlsUtilities.ReadOpaque24(input, 1);
 
@@ -1869,7 +1866,7 @@ namespace Org.BouncyCastle.Tls
 
             MemoryStream buf = new MemoryStream(supp_data, false);
 
-            IList supplementalData = Platform.CreateArrayList();
+            var supplementalData = new List<SupplementalDataEntry>();
 
             while (buf.Position < buf.Length)
             {
@@ -1883,13 +1880,13 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static void WriteExtensions(Stream output, IDictionary extensions)
+        internal static void WriteExtensions(Stream output, IDictionary<int, byte[]> extensions)
         {
             WriteExtensions(output, extensions, 0);
         }
 
         /// <exception cref="IOException"/>
-        internal static void WriteExtensions(Stream output, IDictionary extensions, int bindersSize)
+        internal static void WriteExtensions(Stream output, IDictionary<int, byte[]> extensions, int bindersSize)
         {
             if (null == extensions || extensions.Count < 1)
                 return;
@@ -1903,13 +1900,13 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static byte[] WriteExtensionsData(IDictionary extensions)
+        internal static byte[] WriteExtensionsData(IDictionary<int, byte[]> extensions)
         {
             return WriteExtensionsData(extensions, 0);
         }
 
         /// <exception cref="IOException"/>
-        internal static byte[] WriteExtensionsData(IDictionary extensions, int bindersSize)
+        internal static byte[] WriteExtensionsData(IDictionary<int, byte[]> extensions, int bindersSize)
         {
             MemoryStream buf = new MemoryStream();
             WriteExtensionsData(extensions, buf, bindersSize);
@@ -1917,13 +1914,13 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static void WriteExtensionsData(IDictionary extensions, MemoryStream buf)
+        internal static void WriteExtensionsData(IDictionary<int, byte[]> extensions, MemoryStream buf)
         {
             WriteExtensionsData(extensions, buf, 0);
         }
 
         /// <exception cref="IOException"/>
-        internal static void WriteExtensionsData(IDictionary extensions, MemoryStream buf, int bindersSize)
+        internal static void WriteExtensionsData(IDictionary<int, byte[]> extensions, MemoryStream buf, int bindersSize)
         {
             /*
              * NOTE: There are reports of servers that don't accept a zero-length extension as the last
@@ -1935,10 +1932,10 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static void WritePreSharedKeyExtension(MemoryStream buf, IDictionary extensions, int bindersSize)
+        internal static void WritePreSharedKeyExtension(MemoryStream buf, IDictionary<int, byte[]> extensions,
+            int bindersSize)
         {
-            byte[] extension_data = (byte[])extensions[ExtensionType.pre_shared_key];
-            if (null != extension_data)
+            if (extensions.TryGetValue(ExtensionType.pre_shared_key, out var extension_data))
             {
                 TlsUtilities.CheckUint16(ExtensionType.pre_shared_key);
                 TlsUtilities.WriteUint16(ExtensionType.pre_shared_key, buf);
@@ -1951,17 +1948,18 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static void WriteSelectedExtensions(Stream output, IDictionary extensions, bool selectEmpty)
+        internal static void WriteSelectedExtensions(Stream output, IDictionary<int, byte[]> extensions,
+            bool selectEmpty)
         {
-            foreach (Int32 key in extensions.Keys)
+            foreach (var extension in extensions)
             {
-                int extension_type = key;
+                int extension_type = extension.Key;
 
                 // NOTE: Must be last; handled by 'WritePreSharedKeyExtension'
                 if (ExtensionType.pre_shared_key == extension_type)
                     continue;
 
-                byte[] extension_data = (byte[])extensions[key];
+                byte[] extension_data = extension.Value;
 
                 if (selectEmpty == (extension_data.Length == 0))
                 {
@@ -1973,7 +1971,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static void WriteSupplementalData(Stream output, IList supplementalData)
+        internal static void WriteSupplementalData(Stream output, IList<SupplementalDataEntry> supplementalData)
         {
             MemoryStream buf = new MemoryStream();
 
diff --git a/crypto/src/tls/TlsServer.cs b/crypto/src/tls/TlsServer.cs
index fe88d7c43..9d8ae966d 100644
--- a/crypto/src/tls/TlsServer.cs
+++ b/crypto/src/tls/TlsServer.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Tls
         /// <param name="identities">an <see cref="IList"/> of <see cref="PskIdentity"/> instances.</param>
         /// <returns>The <see cref="TlsPskExternal"/> corresponding to the selected identity, or null to not select
         /// any.</returns>
-        TlsPskExternal GetExternalPsk(IList identities);
+        TlsPskExternal GetExternalPsk(IList<PskIdentity> identities);
 
         void NotifySession(TlsSession session);
 
@@ -47,7 +47,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <param name="clientExtensions">(Int32 -> byte[])</param>
         /// <exception cref="IOException"/>
-        void ProcessClientExtensions(IDictionary clientExtensions);
+        void ProcessClientExtensions(IDictionary<int, byte[]> clientExtensions);
 
         /// <exception cref="IOException"/>
         ProtocolVersion GetServerVersion();
@@ -60,15 +60,15 @@ namespace Org.BouncyCastle.Tls
 
         /// <returns>(Int32 -> byte[])</returns>
         /// <exception cref="IOException"/>
-        IDictionary GetServerExtensions();
+        IDictionary<int, byte[]> GetServerExtensions();
 
         /// <param name="serverExtensions">(Int32 -> byte[])</param>
         /// <exception cref="IOException"/>
-        void GetServerExtensionsForConnection(IDictionary serverExtensions);
+        void GetServerExtensionsForConnection(IDictionary<int, byte[]> serverExtensions);
 
         /// <returns>(SupplementalDataEntry)</returns>
         /// <exception cref="IOException"/>
-        IList GetServerSupplementalData();
+        IList<SupplementalDataEntry> GetServerSupplementalData();
 
         /// <summary>Return server credentials to use.</summary>
         /// <remarks>
@@ -107,7 +107,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <param name="clientSupplementalData">(SupplementalDataEntry)</param>
         /// <exception cref="IOException"/>
-        void ProcessClientSupplementalData(IList clientSupplementalData);
+        void ProcessClientSupplementalData(IList<SupplementalDataEntry> clientSupplementalData);
 
         /// <summary>Called by the protocol handler to report the client certificate, only if
         /// <see cref="GetCertificateRequest"/> returned non-null.</summary>
diff --git a/crypto/src/tls/TlsServerProtocol.cs b/crypto/src/tls/TlsServerProtocol.cs
index 88bc9d5fa..a222b998d 100644
--- a/crypto/src/tls/TlsServerProtocol.cs
+++ b/crypto/src/tls/TlsServerProtocol.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Tls.Crypto;
@@ -103,7 +103,7 @@ namespace Org.BouncyCastle.Tls
             SecurityParameters securityParameters = m_tlsServerContext.SecurityParameters;
             ProtocolVersion serverVersion = securityParameters.NegotiatedVersion;
 
-            IDictionary serverHelloExtensions = Platform.CreateHashtable();
+            var serverHelloExtensions = new Dictionary<int, byte[]>();
             TlsExtensionsUtilities.AddSupportedVersionsExtensionServer(serverHelloExtensions, serverVersion);
             if (m_retryGroup >= 0)
             {
@@ -129,7 +129,7 @@ namespace Org.BouncyCastle.Tls
 
             byte[] legacy_session_id = clientHello.SessionID;
 
-            IDictionary clientHelloExtensions = clientHello.Extensions;
+            var clientHelloExtensions = clientHello.Extensions;
             if (null == clientHelloExtensions)
                 throw new TlsFatalAlert(AlertDescription.missing_extension);
 
@@ -141,7 +141,7 @@ namespace Org.BouncyCastle.Tls
             OfferedPsks.SelectedConfig selectedPsk = TlsUtilities.SelectPreSharedKey(m_tlsServerContext, m_tlsServer,
                 clientHelloExtensions, clientHelloMessage, m_handshakeHash, afterHelloRetryRequest);
 
-            IList clientShares = TlsExtensionsUtilities.GetKeyShareClientHello(clientHelloExtensions);
+            var clientShares = TlsExtensionsUtilities.GetKeyShareClientHello(clientHelloExtensions);
             KeyShareEntry clientShare = null;
 
             if (afterHelloRetryRequest)
@@ -287,8 +287,8 @@ namespace Org.BouncyCastle.Tls
             }
 
 
-            IDictionary serverHelloExtensions = Platform.CreateHashtable();
-            IDictionary serverEncryptedExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(
+            var serverHelloExtensions = new Dictionary<int, byte[]>();
+            var serverEncryptedExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(
                 m_tlsServer.GetServerExtensions());
 
             m_tlsServer.GetServerExtensionsForConnection(serverEncryptedExtensions);
@@ -326,8 +326,8 @@ namespace Org.BouncyCastle.Tls
              * 
              * OCSP information is carried in an extension for a CertificateEntry.
              */
-            securityParameters.m_statusRequestVersion = clientHelloExtensions.Contains(ExtensionType.status_request)
-                ? 1 : 0;
+            securityParameters.m_statusRequestVersion =
+                clientHelloExtensions.ContainsKey(ExtensionType.status_request) ? 1 : 0;
 
             this.m_expectSessionTicket = false;
 
@@ -584,7 +584,7 @@ namespace Org.BouncyCastle.Tls
             m_tlsServerContext.SetRsaPreMasterSecretVersion(clientLegacyVersion);
 
             {
-                IDictionary sessionServerExtensions = m_resumedSession
+                var sessionServerExtensions = m_resumedSession
                     ?   m_sessionParameters.ReadServerExtensions()
                     :   m_tlsServer.GetServerExtensions();
 
@@ -944,7 +944,7 @@ namespace Org.BouncyCastle.Tls
                         break;
                     }
 
-                    IList serverSupplementalData = m_tlsServer.GetServerSupplementalData();
+                    var serverSupplementalData = m_tlsServer.GetServerSupplementalData();
                     if (serverSupplementalData != null)
                     {
                         SendSupplementalDataMessage(serverSupplementalData);
@@ -1383,7 +1383,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        protected virtual void Send13EncryptedExtensionsMessage(IDictionary serverExtensions)
+        protected virtual void Send13EncryptedExtensionsMessage(IDictionary<int, byte[]> serverExtensions)
         {
             // TODO[tls13] Avoid extra copy; use placeholder to write opaque-16 data directly to message buffer
 
diff --git a/crypto/src/tls/TlsSrpUtilities.cs b/crypto/src/tls/TlsSrpUtilities.cs
index c36a667ac..6b01ed512 100644
--- a/crypto/src/tls/TlsSrpUtilities.cs
+++ b/crypto/src/tls/TlsSrpUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Math;
@@ -10,13 +10,13 @@ namespace Org.BouncyCastle.Tls
     public abstract class TlsSrpUtilities
     {
         /// <exception cref="IOException"/>
-        public static void AddSrpExtension(IDictionary extensions, byte[] identity)
+        public static void AddSrpExtension(IDictionary<int, byte[]> extensions, byte[] identity)
         {
             extensions[ExtensionType.srp] = CreateSrpExtension(identity);
         }
 
         /// <exception cref="IOException"/>
-        public static byte[] GetSrpExtension(IDictionary extensions)
+        public static byte[] GetSrpExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.srp);
             return extensionData == null ? null : ReadSrpExtension(extensionData);
diff --git a/crypto/src/tls/TlsSrtpUtilities.cs b/crypto/src/tls/TlsSrtpUtilities.cs
index 72a9e774b..b7ceed260 100644
--- a/crypto/src/tls/TlsSrtpUtilities.cs
+++ b/crypto/src/tls/TlsSrtpUtilities.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 namespace Org.BouncyCastle.Tls
@@ -8,13 +8,13 @@ namespace Org.BouncyCastle.Tls
     public abstract class TlsSrtpUtilities
 {
         /// <exception cref="IOException"/>
-        public static void AddUseSrtpExtension(IDictionary extensions, UseSrtpData useSrtpData)
+        public static void AddUseSrtpExtension(IDictionary<int, byte[]> extensions, UseSrtpData useSrtpData)
         {
             extensions[ExtensionType.use_srtp] = CreateUseSrtpExtension(useSrtpData);
         }
 
         /// <exception cref="IOException"/>
-        public static UseSrtpData GetUseSrtpExtension(IDictionary extensions)
+        public static UseSrtpData GetUseSrtpExtension(IDictionary<int, byte[]> extensions)
         {
             byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.use_srtp);
             return extensionData == null ? null : ReadUseSrtpExtension(extensionData);
diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs
index 1e0b403c9..97895e8f2 100644
--- a/crypto/src/tls/TlsUtilities.cs
+++ b/crypto/src/tls/TlsUtilities.cs
@@ -1,9 +1,7 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
-#if !PORTABLE || DOTNET
 using System.Net.Sockets;
-#endif
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Bsi;
@@ -18,6 +16,7 @@ using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Tls.Crypto;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Date;
 using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.Utilities.IO;
@@ -29,24 +28,24 @@ namespace Org.BouncyCastle.Tls
         private static readonly byte[] DowngradeTlsV11 = Hex.DecodeStrict("444F574E47524400");
         private static readonly byte[] DowngradeTlsV12 = Hex.DecodeStrict("444F574E47524401");
 
-        private static readonly IDictionary CertSigAlgOids = CreateCertSigAlgOids();
-        private static readonly IList DefaultSupportedSigAlgs = CreateDefaultSupportedSigAlgs();
+        private static readonly IDictionary<string, SignatureAndHashAlgorithm> CertSigAlgOids = CreateCertSigAlgOids();
+        private static readonly IList<SignatureAndHashAlgorithm> DefaultSupportedSigAlgs = CreateDefaultSupportedSigAlgs();
 
-        private static void AddCertSigAlgOid(IDictionary d, DerObjectIdentifier oid,
+        private static void AddCertSigAlgOid(IDictionary<string, SignatureAndHashAlgorithm> d, DerObjectIdentifier oid,
             SignatureAndHashAlgorithm sigAndHash)
         {
             d[oid.Id] = sigAndHash;
         }
 
-        private static void AddCertSigAlgOid(IDictionary d, DerObjectIdentifier oid, short hashAlgorithm,
-            short signatureAlgorithm)
+        private static void AddCertSigAlgOid(IDictionary<string, SignatureAndHashAlgorithm> d, DerObjectIdentifier oid,
+            short hashAlgorithm, short signatureAlgorithm)
         {
             AddCertSigAlgOid(d, oid, SignatureAndHashAlgorithm.GetInstance(hashAlgorithm, signatureAlgorithm));
         }
 
-        private static IDictionary CreateCertSigAlgOids()
+        private static IDictionary<string, SignatureAndHashAlgorithm> CreateCertSigAlgOids()
         {
-            IDictionary d = Platform.CreateHashtable();
+            var d = new Dictionary<string, SignatureAndHashAlgorithm>();
 
             AddCertSigAlgOid(d, NistObjectIdentifiers.DsaWithSha224, HashAlgorithm.sha224, SignatureAlgorithm.dsa);
             AddCertSigAlgOid(d, NistObjectIdentifiers.DsaWithSha256, HashAlgorithm.sha256, SignatureAlgorithm.dsa);
@@ -97,9 +96,9 @@ namespace Org.BouncyCastle.Tls
             return d;
         }
 
-        private static IList CreateDefaultSupportedSigAlgs()
+        private static IList<SignatureAndHashAlgorithm> CreateDefaultSupportedSigAlgs()
         {
-            IList result = Platform.CreateArrayList();
+            var result = new List<SignatureAndHashAlgorithm>();
             result.Add(SignatureAndHashAlgorithm.ed25519);
             result.Add(SignatureAndHashAlgorithm.ed448);
             result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha256, SignatureAlgorithm.ecdsa));
@@ -970,7 +969,8 @@ namespace Org.BouncyCastle.Tls
             buf[offset + 1] = (byte)version.MinorVersion;
         }
 
-        public static void AddIfSupported(IList supportedAlgs, TlsCrypto crypto, SignatureAndHashAlgorithm alg)
+        public static void AddIfSupported(IList<SignatureAndHashAlgorithm> supportedAlgs, TlsCrypto crypto,
+            SignatureAndHashAlgorithm alg)
         {
             if (crypto.HasSignatureAndHashAlgorithm(alg))
             {
@@ -978,7 +978,7 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public static void AddIfSupported(IList supportedGroups, TlsCrypto crypto, int namedGroup)
+        public static void AddIfSupported(IList<int> supportedGroups, TlsCrypto crypto, int namedGroup)
         {
             if (crypto.HasNamedGroup(namedGroup))
             {
@@ -986,7 +986,7 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public static void AddIfSupported(IList supportedGroups, TlsCrypto crypto, int[] namedGroups)
+        public static void AddIfSupported(IList<int> supportedGroups, TlsCrypto crypto, int[] namedGroups)
         {
             for (int i = 0; i < namedGroups.Length; ++i)
             {
@@ -994,7 +994,7 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public static bool AddToSet(IList s, int i)
+        public static bool AddToSet<T>(IList<T> s, T i)
         {
             bool result = !s.Contains(i);
             if (result)
@@ -1004,17 +1004,17 @@ namespace Org.BouncyCastle.Tls
             return result;
         }
 
-        public static IList GetDefaultDssSignatureAlgorithms()
+        public static IList<SignatureAndHashAlgorithm> GetDefaultDssSignatureAlgorithms()
         {
             return GetDefaultSignatureAlgorithms(SignatureAlgorithm.dsa);
         }
 
-        public static IList GetDefaultECDsaSignatureAlgorithms()
+        public static IList<SignatureAndHashAlgorithm> GetDefaultECDsaSignatureAlgorithms()
         {
             return GetDefaultSignatureAlgorithms(SignatureAlgorithm.ecdsa);
         }
 
-        public static IList GetDefaultRsaSignatureAlgorithms()
+        public static IList<SignatureAndHashAlgorithm> GetDefaultRsaSignatureAlgorithms()
         {
             return GetDefaultSignatureAlgorithms(SignatureAlgorithm.rsa);
         }
@@ -1046,23 +1046,24 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public static IList GetDefaultSignatureAlgorithms(short signatureAlgorithm)
+        public static IList<SignatureAndHashAlgorithm> GetDefaultSignatureAlgorithms(short signatureAlgorithm)
         {
             SignatureAndHashAlgorithm sigAndHashAlg = GetDefaultSignatureAlgorithm(signatureAlgorithm);
 
-            return null == sigAndHashAlg ? Platform.CreateArrayList() : VectorOfOne(sigAndHashAlg);
+            return null == sigAndHashAlg ? new List<SignatureAndHashAlgorithm>() : VectorOfOne(sigAndHashAlg);
         }
 
-        public static IList GetDefaultSupportedSignatureAlgorithms(TlsContext context)
+        public static IList<SignatureAndHashAlgorithm> GetDefaultSupportedSignatureAlgorithms(TlsContext context)
         {
             return GetSupportedSignatureAlgorithms(context, DefaultSupportedSigAlgs);
         }
 
-        public static IList GetSupportedSignatureAlgorithms(TlsContext context, IList candidates)
+        public static IList<SignatureAndHashAlgorithm> GetSupportedSignatureAlgorithms(TlsContext context,
+            IList<SignatureAndHashAlgorithm> candidates)
         {
             TlsCrypto crypto = context.Crypto;
 
-            IList result = Platform.CreateArrayList(DefaultSupportedSigAlgs.Count);
+            var result = new List<SignatureAndHashAlgorithm>(candidates.Count);
             foreach (SignatureAndHashAlgorithm sigAndHashAlg in candidates)
             {
                 AddIfSupported(result, crypto, sigAndHashAlg);
@@ -1088,14 +1089,15 @@ namespace Org.BouncyCastle.Tls
             return signatureAndHashAlgorithm;
         }
 
-        public static byte[] GetExtensionData(IDictionary extensions, int extensionType)
+        public static byte[] GetExtensionData(IDictionary<int, byte[]> extensions, int extensionType)
         {
-            return extensions == null || !extensions.Contains(extensionType)
-                ? null
-                : (byte[])extensions[extensionType];
+            if (extensions == null || !extensions.TryGetValue(extensionType, out var extensionData))
+                return null;
+
+            return extensionData;
         }
 
-        public static bool HasExpectedEmptyExtensionData(IDictionary extensions, int extensionType,
+        public static bool HasExpectedEmptyExtensionData(IDictionary<int, byte[]> extensions, int extensionType,
             short alertDescription)
         {
             byte[] extension_data = GetExtensionData(extensions, extensionType);
@@ -1140,22 +1142,7 @@ namespace Org.BouncyCastle.Tls
             return false;
         }
 
-        public static bool IsNullOrEmpty(byte[] array)
-        {
-            return null == array || array.Length < 1;
-        }
-
-        public static bool IsNullOrEmpty(short[] array)
-        {
-            return null == array || array.Length < 1;
-        }
-
-        public static bool IsNullOrEmpty(int[] array)
-        {
-            return null == array || array.Length < 1;
-        }
-
-        public static bool IsNullOrEmpty(object[] array)
+        public static bool IsNullOrEmpty<T>(T[] array)
         {
             return null == array || array.Length < 1;
         }
@@ -1165,7 +1152,7 @@ namespace Org.BouncyCastle.Tls
             return null == s || s.Length < 1;
         }
 
-        public static bool IsNullOrEmpty(IList v)
+        public static bool IsNullOrEmpty<T>(IList<T> v)
         {
             return null == v || v.Count < 1;
         }
@@ -1275,9 +1262,9 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public static IList GetLegacySupportedSignatureAlgorithms()
+        public static IList<SignatureAndHashAlgorithm> GetLegacySupportedSignatureAlgorithms()
         {
-            IList result = Platform.CreateArrayList(3);
+            var result = new List<SignatureAndHashAlgorithm>(3);
             result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.dsa));
             result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.ecdsa));
             result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.rsa));
@@ -1285,10 +1272,12 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static void EncodeSupportedSignatureAlgorithms(IList supportedSignatureAlgorithms, Stream output)
+        public static void EncodeSupportedSignatureAlgorithms(
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms, Stream output)
         {
-            if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.Count < 1
-                || supportedSignatureAlgorithms.Count >= (1 << 15))
+            if (supportedSignatureAlgorithms == null ||
+                supportedSignatureAlgorithms.Count < 1 ||
+                supportedSignatureAlgorithms.Count >= (1 << 15))
             {
                 throw new ArgumentException("must have length from 1 to (2^15 - 1)", "supportedSignatureAlgorithms");
             }
@@ -1313,7 +1302,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static IList ParseSupportedSignatureAlgorithms(Stream input)
+        public static IList<SignatureAndHashAlgorithm> ParseSupportedSignatureAlgorithms(Stream input)
         {
             // supported_signature_algorithms
             int length = ReadUint16(input);
@@ -1321,7 +1310,7 @@ namespace Org.BouncyCastle.Tls
                 throw new TlsFatalAlert(AlertDescription.decode_error);
 
             int count = length / 2;
-            IList supportedSignatureAlgorithms = Platform.CreateArrayList(count);
+            var supportedSignatureAlgorithms = new List<SignatureAndHashAlgorithm>(count);
             for (int i = 0; i < count; ++i)
             {
                 SignatureAndHashAlgorithm sigAndHashAlg = SignatureAndHashAlgorithm.Parse(input);
@@ -1335,16 +1324,17 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms,
-            SignatureAndHashAlgorithm signatureAlgorithm)
+        public static void VerifySupportedSignatureAlgorithm(
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms, SignatureAndHashAlgorithm signatureAlgorithm)
         {
             VerifySupportedSignatureAlgorithm(supportedSignatureAlgorithms, signatureAlgorithm,
                 AlertDescription.illegal_parameter);
         }
 
         /// <exception cref="IOException"/>
-        internal static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms,
-            SignatureAndHashAlgorithm signatureAlgorithm, short alertDescription)
+        internal static void VerifySupportedSignatureAlgorithm(
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms, SignatureAndHashAlgorithm signatureAlgorithm,
+            short alertDescription)
         {
             if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.Count < 1
                 || supportedSignatureAlgorithms.Count >= (1 << 15))
@@ -1362,7 +1352,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static bool ContainsSignatureAlgorithm(IList supportedSignatureAlgorithms,
+        public static bool ContainsSignatureAlgorithm(IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms,
             SignatureAndHashAlgorithm signatureAlgorithm)
         {
             foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms)
@@ -1374,7 +1364,8 @@ namespace Org.BouncyCastle.Tls
             return false;
         }
 
-        public static bool ContainsAnySignatureAlgorithm(IList supportedSignatureAlgorithms, short signatureAlgorithm)
+        public static bool ContainsAnySignatureAlgorithm(IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms,
+            short signatureAlgorithm)
         {
             foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms)
             {
@@ -1464,9 +1455,9 @@ namespace Org.BouncyCastle.Tls
                 }
                 else
                 {
-                    if (CertSigAlgOids.Contains(sigAlgOid))
+                    if (CertSigAlgOids.TryGetValue(sigAlgOid, out var algorithm))
                     {
-                        hashAlgorithm = ((SignatureAndHashAlgorithm)CertSigAlgOids[sigAlgOid]).Hash;
+                        hashAlgorithm = algorithm.Hash;
                     }
                 }
             }
@@ -2271,7 +2262,7 @@ namespace Org.BouncyCastle.Tls
         {
             SecurityParameters securityParameters = serverContext.SecurityParameters;
 
-            IList supportedAlgorithms = securityParameters.ServerSigAlgs;
+            var supportedAlgorithms = securityParameters.ServerSigAlgs;
             TlsCertificate certificate = securityParameters.PeerCertificate.GetCertificateAt(0);
 
             Verify13CertificateVerify(supportedAlgorithms, "TLS 1.3, client CertificateVerify", handshakeHash,
@@ -2284,7 +2275,7 @@ namespace Org.BouncyCastle.Tls
         {
             SecurityParameters securityParameters = clientContext.SecurityParameters;
 
-            IList supportedAlgorithms = securityParameters.ClientSigAlgs;
+            var supportedAlgorithms = securityParameters.ClientSigAlgs;
             TlsCertificate certificate = securityParameters.PeerCertificate.GetCertificateAt(0);
 
             Verify13CertificateVerify(supportedAlgorithms, "TLS 1.3, server CertificateVerify", handshakeHash,
@@ -2292,8 +2283,9 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        private static void Verify13CertificateVerify(IList supportedAlgorithms, string contextString,
-            TlsHandshakeHash handshakeHash, TlsCertificate certificate, CertificateVerify certificateVerify)
+        private static void Verify13CertificateVerify(IList<SignatureAndHashAlgorithm> supportedAlgorithms,
+            string contextString, TlsHandshakeHash handshakeHash, TlsCertificate certificate,
+            CertificateVerify certificateVerify)
         {
             // Verify the CertificateVerify message contains a correct signature.
             bool verified;
@@ -2430,7 +2422,8 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash, IList supportedSignatureAlgorithms)
+        internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash,
+            IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms)
         {
             foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms)
             {
@@ -2459,9 +2452,9 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public static IList VectorOfOne(object obj)
+        public static IList<T> VectorOfOne<T>(T obj)
         {
-            IList v = Platform.CreateArrayList(1);
+            var v = new List<T>(1);
             v.Add(obj);
             return v;
         }
@@ -3203,9 +3196,9 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public static IList GetKeyExchangeAlgorithms(int[] cipherSuites)
+        public static IList<int> GetKeyExchangeAlgorithms(int[] cipherSuites)
         {
-            IList result = Platform.CreateArrayList();
+            var result = new List<int>();
             if (null != cipherSuites)
             {
                 for (int i = 0; i < cipherSuites.Length; ++i)
@@ -3723,14 +3716,14 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        public static IList GetNamedGroupRoles(int[] cipherSuites)
+        public static IList<int> GetNamedGroupRoles(int[] cipherSuites)
         {
             return GetNamedGroupRoles(GetKeyExchangeAlgorithms(cipherSuites));
         }
 
-        public static IList GetNamedGroupRoles(IList keyExchangeAlgorithms)
+        public static IList<int> GetNamedGroupRoles(IList<int> keyExchangeAlgorithms)
         {
-            IList result = Platform.CreateArrayList();
+            var result = new List<int>();
             foreach (int keyExchangeAlgorithm in keyExchangeAlgorithms)
             {
                 switch (keyExchangeAlgorithm)
@@ -3795,7 +3788,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <returns>Whether a server can select the specified cipher suite given the available signature algorithms
         /// for ServerKeyExchange.</returns>
-        public static bool IsValidCipherSuiteForSignatureAlgorithms(int cipherSuite, IList sigAlgs)
+        public static bool IsValidCipherSuiteForSignatureAlgorithms(int cipherSuite, IList<short> sigAlgs)
         {
             int keyExchangeAlgorithm = GetKeyExchangeAlgorithm(cipherSuite);
 
@@ -3832,11 +3825,11 @@ namespace Org.BouncyCastle.Tls
         }
 
         internal static bool IsValidKeyShareSelection(ProtocolVersion negotiatedVersion, int[] clientSupportedGroups,
-            IDictionary clientAgreements, int keyShareGroup)
+            IDictionary<int, TlsAgreement> clientAgreements, int keyShareGroup)
         {
             return null != clientSupportedGroups
                 && Arrays.Contains(clientSupportedGroups, keyShareGroup)
-                && !clientAgreements.Contains(keyShareGroup)
+                && !clientAgreements.ContainsKey(keyShareGroup)
                 && NamedGroup.CanBeNegotiated(keyShareGroup, negotiatedVersion);
         }
 
@@ -3910,20 +3903,19 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        public static SignatureAndHashAlgorithm ChooseSignatureAndHashAlgorithm(TlsContext context, IList sigHashAlgs,
-            short signatureAlgorithm)
+        public static SignatureAndHashAlgorithm ChooseSignatureAndHashAlgorithm(TlsContext context,
+            IList<SignatureAndHashAlgorithm> sigHashAlgs, short signatureAlgorithm)
         {
             return ChooseSignatureAndHashAlgorithm(context.ServerVersion, sigHashAlgs, signatureAlgorithm);
         }
 
         /// <exception cref="IOException"/>
         public static SignatureAndHashAlgorithm ChooseSignatureAndHashAlgorithm(ProtocolVersion negotiatedVersion,
-            IList sigHashAlgs, short signatureAlgorithm)
+            IList<SignatureAndHashAlgorithm> sigHashAlgs, short signatureAlgorithm)
         {
             if (!IsTlsV12(negotiatedVersion))
                 return null;
 
-
             if (sigHashAlgs == null)
             {
                 /*
@@ -3972,33 +3964,25 @@ namespace Org.BouncyCastle.Tls
             return result;
         }
 
-        public static IList GetUsableSignatureAlgorithms(IList sigHashAlgs)
+        public static IList<short> GetUsableSignatureAlgorithms(IList<SignatureAndHashAlgorithm> sigHashAlgs)
         {
             if (sigHashAlgs == null)
+                return new List<short>(){ SignatureAlgorithm.rsa, SignatureAlgorithm.dsa, SignatureAlgorithm.ecdsa };
+
+            var v = new List<short>();
+            foreach (SignatureAndHashAlgorithm sigHashAlg in sigHashAlgs)
             {
-                IList v = Platform.CreateArrayList(3);
-                v.Add(SignatureAlgorithm.rsa);
-                v.Add(SignatureAlgorithm.dsa);
-                v.Add(SignatureAlgorithm.ecdsa);
-                return v;
-            }
-            else
-            {
-                IList v = Platform.CreateArrayList();
-                foreach (SignatureAndHashAlgorithm sigHashAlg in sigHashAlgs)
+                if (sigHashAlg.Hash >= MinimumHashStrict)
                 {
-                    if (sigHashAlg.Hash >= MinimumHashStrict)
+                    short sigAlg = sigHashAlg.Signature;
+                    if (!v.Contains(sigAlg))
                     {
-                        short sigAlg = sigHashAlg.Signature;
-                        if (!v.Contains(sigAlg))
-                        {
-                            // TODO Check for crypto support before choosing (or pass in cached list?)
-                            v.Add(sigAlg);
-                        }
+                        // TODO Check for crypto support before choosing (or pass in cached list?)
+                        v.Add(sigAlg);
                     }
                 }
-                return v;
             }
+            return v;
         }
 
         public static int GetCommonCipherSuite13(ProtocolVersion negotiatedVersion, int[] peerCipherSuites,
@@ -4355,7 +4339,7 @@ namespace Org.BouncyCastle.Tls
         {
             SecurityParameters securityParameters = context.SecurityParameters;
             short[] clientCertTypes = securityParameters.ClientCertTypes;
-            IList serverSigAlgsCert = securityParameters.ServerSigAlgsCert;
+            var serverSigAlgsCert = securityParameters.ServerSigAlgsCert;
 
             int trustAnchorPos = clientCertPath.Length - 1;
             for (int i = 0; i < trustAnchorPos; ++i)
@@ -4405,8 +4389,8 @@ namespace Org.BouncyCastle.Tls
         private static void CheckSigAlgOfServerCerts(TlsContext context, TlsCertificate[] serverCertPath)
         {
             SecurityParameters securityParameters = context.SecurityParameters;
-            IList clientSigAlgsCert = securityParameters.ClientSigAlgsCert;
-            IList clientSigAlgs = securityParameters.ClientSigAlgs;
+            var clientSigAlgsCert = securityParameters.ClientSigAlgsCert;
+            var clientSigAlgs = securityParameters.ClientSigAlgs;
 
             /*
              * NOTE: For TLS 1.2, we'll check 'signature_algorithms' too (if it's distinct), since
@@ -4457,8 +4441,8 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        internal static void CheckTlsFeatures(Certificate serverCertificate, IDictionary clientExtensions,
-            IDictionary serverExtensions)
+        internal static void CheckTlsFeatures(Certificate serverCertificate, IDictionary<int, byte[]> clientExtensions,
+            IDictionary<int, byte[]> serverExtensions)
         {
             /*
              * RFC 7633 4.3.3. A client MUST treat a certificate with a TLS feature extension as an
@@ -4485,7 +4469,7 @@ namespace Org.BouncyCastle.Tls
                     {
                         int extensionType = tlsExtension.IntValueExact;
 
-                        if (clientExtensions.Contains(extensionType) && !serverExtensions.Contains(extensionType))
+                        if (clientExtensions.ContainsKey(extensionType) && !serverExtensions.ContainsKey(extensionType))
                             throw new TlsFatalAlert(AlertDescription.certificate_unknown);
                     }
                 }
@@ -4533,7 +4517,8 @@ namespace Org.BouncyCastle.Tls
 
         internal static void ProcessServerCertificate(TlsClientContext clientContext,
             CertificateStatus serverCertificateStatus, TlsKeyExchange keyExchange,
-            TlsAuthentication clientAuthentication, IDictionary clientExtensions, IDictionary serverExtensions)
+            TlsAuthentication clientAuthentication, IDictionary<int, byte[]> clientExtensions,
+            IDictionary<int, byte[]> serverExtensions)
         {
             SecurityParameters securityParameters = clientContext.SecurityParameters;
             bool isTlsV13 = IsTlsV13(securityParameters.NegotiatedVersion);
@@ -4569,12 +4554,7 @@ namespace Org.BouncyCastle.Tls
             if (null != sigAlgOid)
             {
                 if (!PkcsObjectIdentifiers.IdRsassaPss.Id.Equals(sigAlgOid))
-                {
-                    if (!CertSigAlgOids.Contains(sigAlgOid))
-                        return null;
-
-                    return (SignatureAndHashAlgorithm)CertSigAlgOids[sigAlgOid];
-                }
+                    return CollectionUtilities.GetValueOrNull(CertSigAlgOids, sigAlgOid);
 
                 RsassaPssParameters pssParams = RsassaPssParameters.GetInstance(subjectCert.GetSigAlgParams());
                 if (null != pssParams)
@@ -4871,8 +4851,8 @@ namespace Org.BouncyCastle.Tls
             return false;
         }
 
-        internal static IDictionary AddKeyShareToClientHello(TlsClientContext clientContext, TlsClient client,
-            IDictionary clientExtensions)
+        internal static IDictionary<int, TlsAgreement> AddKeyShareToClientHello(TlsClientContext clientContext,
+            TlsClient client, IDictionary<int, byte[]> clientExtensions)
         {
             /*
              * RFC 8446 9.2. If containing a "supported_groups" extension, it MUST also contain a
@@ -4880,15 +4860,15 @@ namespace Org.BouncyCastle.Tls
              * permitted.
              */
             if (!IsTlsV13(clientContext.ClientVersion)
-                || !clientExtensions.Contains(ExtensionType.supported_groups))
+                || !clientExtensions.ContainsKey(ExtensionType.supported_groups))
             {
                 return null;
             }
 
-            int[] supportedGroups = TlsExtensionsUtilities.GetSupportedGroupsExtension(clientExtensions);
-            IList keyShareGroups = client.GetEarlyKeyShareGroups();
-            IDictionary clientAgreements = Platform.CreateHashtable(3);
-            IList clientShares = Platform.CreateArrayList(2);
+            var supportedGroups = TlsExtensionsUtilities.GetSupportedGroupsExtension(clientExtensions);
+            var keyShareGroups = client.GetEarlyKeyShareGroups();
+            var clientAgreements = new Dictionary<int, TlsAgreement>(3);
+            var clientShares = new List<KeyShareEntry>(2);
 
             CollectKeyShares(clientContext.Crypto, supportedGroups, keyShareGroups, clientAgreements, clientShares);
 
@@ -4898,13 +4878,13 @@ namespace Org.BouncyCastle.Tls
             return clientAgreements;
         }
 
-        internal static IDictionary AddKeyShareToClientHelloRetry(TlsClientContext clientContext,
-            IDictionary clientExtensions, int keyShareGroup)
+        internal static IDictionary<int, TlsAgreement> AddKeyShareToClientHelloRetry(TlsClientContext clientContext,
+            IDictionary<int, byte[]> clientExtensions, int keyShareGroup)
         {
             int[] supportedGroups = new int[]{ keyShareGroup };
-            IList keyShareGroups = VectorOfOne(keyShareGroup);
-            IDictionary clientAgreements = Platform.CreateHashtable(1);
-            IList clientShares = Platform.CreateArrayList(1);
+            var keyShareGroups = VectorOfOne(keyShareGroup);
+            var clientAgreements = new Dictionary<int, TlsAgreement>(1);
+            var clientShares = new List<KeyShareEntry>(1);
 
             CollectKeyShares(clientContext.Crypto, supportedGroups, keyShareGroups, clientAgreements, clientShares);
 
@@ -4919,8 +4899,8 @@ namespace Org.BouncyCastle.Tls
             return clientAgreements;
         }
 
-        private static void CollectKeyShares(TlsCrypto crypto, int[] supportedGroups, IList keyShareGroups,
-            IDictionary clientAgreements, IList clientShares)
+        private static void CollectKeyShares(TlsCrypto crypto, int[] supportedGroups, IList<int> keyShareGroups,
+            IDictionary<int, TlsAgreement> clientAgreements, IList<KeyShareEntry> clientShares)
         {
             if (IsNullOrEmpty(supportedGroups))
                 return;
@@ -4933,7 +4913,7 @@ namespace Org.BouncyCastle.Tls
                 int supportedGroup = supportedGroups[i];
 
                 if (!keyShareGroups.Contains(supportedGroup)
-                    || clientAgreements.Contains(supportedGroup)
+                    || clientAgreements.ContainsKey(supportedGroup)
                     || !crypto.HasNamedGroup(supportedGroup))
                 {
                     continue;
@@ -4966,7 +4946,7 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        internal static KeyShareEntry SelectKeyShare(IList clientShares, int keyShareGroup)
+        internal static KeyShareEntry SelectKeyShare(IList<KeyShareEntry> clientShares, int keyShareGroup)
         {
             if (null != clientShares && 1 == clientShares.Count)
             {
@@ -4980,7 +4960,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         internal static KeyShareEntry SelectKeyShare(TlsCrypto crypto, ProtocolVersion negotiatedVersion,
-            IList clientShares, int[] clientSupportedGroups, int[] serverSupportedGroups)
+            IList<KeyShareEntry> clientShares, int[] clientSupportedGroups, int[] serverSupportedGroups)
         {
             if (null != clientShares && !IsNullOrEmpty(clientSupportedGroups) && !IsNullOrEmpty(serverSupportedGroups))
             {
@@ -5104,7 +5084,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         internal static void EstablishClientSigAlgs(SecurityParameters securityParameters,
-            IDictionary clientExtensions)
+            IDictionary<int, byte[]> clientExtensions)
         {
             securityParameters.m_clientSigAlgs = TlsExtensionsUtilities.GetSignatureAlgorithmsExtension(
                 clientExtensions);
@@ -5429,7 +5409,8 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <exception cref="IOException"/>
-        internal static void CheckExtensionData13(IDictionary extensions, int handshakeType, short alertDescription)
+        internal static void CheckExtensionData13(IDictionary<int, byte[]> extensions, int handshakeType,
+            short alertDescription)
         {
             foreach (int extensionType in extensions.Keys)
             {
@@ -5451,17 +5432,15 @@ namespace Org.BouncyCastle.Tls
             return preMasterSecret;
         }
 
-#if !PORTABLE || DOTNET
         public static bool IsTimeout(SocketException e)
         {
             return SocketError.TimedOut == e.SocketErrorCode;
         }
-#endif
 
         /// <exception cref="IOException"/>
-        internal static void AddPreSharedKeyToClientExtensions(TlsPsk[] psks, IDictionary clientExtensions)
+        internal static void AddPreSharedKeyToClientExtensions(TlsPsk[] psks, IDictionary<int, byte[]> clientExtensions)
         {
-            IList identities = Platform.CreateArrayList(psks.Length);
+            var identities = new List<PskIdentity>(psks.Length);
             for (int i = 0; i < psks.Length; ++i)
             {
                 TlsPsk psk = psks[i];
@@ -5475,7 +5454,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <exception cref="IOException"/>
         internal static OfferedPsks.BindersConfig AddPreSharedKeyToClientHello(TlsClientContext clientContext,
-            TlsClient client, IDictionary clientExtensions, int[] offeredCipherSuites)
+            TlsClient client, IDictionary<int, byte[]> clientExtensions, int[] offeredCipherSuites)
         {
             if (!IsTlsV13(clientContext.ClientVersion))
                 return null;
@@ -5501,13 +5480,13 @@ namespace Org.BouncyCastle.Tls
 
         /// <exception cref="IOException"/>
         internal static OfferedPsks.BindersConfig AddPreSharedKeyToClientHelloRetry(TlsClientContext clientContext,
-            OfferedPsks.BindersConfig clientBinders, IDictionary clientExtensions)
+            OfferedPsks.BindersConfig clientBinders, IDictionary<int, byte[]> clientExtensions)
         {
             SecurityParameters securityParameters = clientContext.SecurityParameters;
 
             int prfAlgorithm = GetPrfAlgorithm13(securityParameters.CipherSuite);
 
-            IList pskIndices = GetPskIndices(clientBinders.m_psks, prfAlgorithm);
+            var pskIndices = GetPskIndices(clientBinders.m_psks, prfAlgorithm);
             if (pskIndices.Count < 1)
                 return null;
 
@@ -5540,8 +5519,8 @@ namespace Org.BouncyCastle.Tls
         }
 
         internal static OfferedPsks.SelectedConfig SelectPreSharedKey(TlsServerContext serverContext, TlsServer server,
-            IDictionary clientHelloExtensions, HandshakeMessageInput clientHelloMessage, TlsHandshakeHash handshakeHash,
-            bool afterHelloRetryRequest)
+            IDictionary<int, byte[]> clientHelloExtensions, HandshakeMessageInput clientHelloMessage,
+            TlsHandshakeHash handshakeHash, bool afterHelloRetryRequest)
         {
             bool handshakeHashUpdated = false;
 
@@ -5633,7 +5612,7 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         internal static TlsPskExternal[] GetPskExternalsClient(TlsClient client, int[] offeredCipherSuites)
         {
-            IList externalPsks = client.GetExternalPsks();
+            var externalPsks = client.GetExternalPsks();
             if (IsNullOrEmpty(externalPsks))
                 return null;
 
@@ -5659,9 +5638,9 @@ namespace Org.BouncyCastle.Tls
             return result;
         }
 
-        internal static IList GetPskIndices(TlsPsk[] psks, int prfAlgorithm)
+        internal static IList<int> GetPskIndices(TlsPsk[] psks, int prfAlgorithm)
         {
-            IList v = Platform.CreateArrayList(psks.Length);
+            var v = new List<int>(psks.Length);
             for (int i = 0; i < psks.Length; ++i)
             {
                 if (psks[i].PrfAlgorithm == prfAlgorithm)
diff --git a/crypto/src/tls/crypto/TlsCrypto.cs b/crypto/src/tls/crypto/TlsCrypto.cs
index 27c5fb9e1..a99be8612 100644
--- a/crypto/src/tls/crypto/TlsCrypto.cs
+++ b/crypto/src/tls/crypto/TlsCrypto.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.IO;
 
 using Org.BouncyCastle.Math;
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Tls.Crypto
         /// <see cref="SignatureAndHashAlgorithm"/> values.</param>
         /// <returns>true if this instance would use a stream verifier for any of the passed in algorithms, otherwise
         /// false.</returns>
-        bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms);
+        bool HasAnyStreamVerifiers(IList<SignatureAndHashAlgorithm> signatureAndHashAlgorithms);
 
         /// <summary>Return true if this TlsCrypto would use a stream verifier for any of the passed in algorithms.
         /// </summary>
diff --git a/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs b/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs
index 87fe66dff..b2e1e7fe0 100644
--- a/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs
+++ b/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Security;
@@ -12,7 +12,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl
     public abstract class AbstractTlsCrypto
         : TlsCrypto
     {
-        public abstract bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms);
+        public abstract bool HasAnyStreamVerifiers(IList<SignatureAndHashAlgorithm> signatureAndHashAlgorithms);
 
         public abstract bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes);
 
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
index 38062829e..d6a41b86d 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Agreement.Srp;
@@ -153,7 +153,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
             return new BcTlsNonceGenerator(randomGenerator);
         }
 
-        public override bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms)
+        public override bool HasAnyStreamVerifiers(IList<SignatureAndHashAlgorithm> signatureAndHashAlgorithms)
         {
             foreach (SignatureAndHashAlgorithm algorithm in signatureAndHashAlgorithms)
             {