We need you! We're working hard on the next version of Developer Fusion -
Let us know what you think we should be up to!
- namespace System.Net.Security
- {
-
- using System.Net;
- using System.Security.Cryptography.X509Certificates;
- using System.Collections;
-
- static internal class SslSessionsCache
- {
-
- private const int c_CheckExpiredModulo = 32;
- private static Hashtable s_CachedCreds = new Hashtable(32);
-
-
-
-
- private struct SslCredKey
- {
- private static readonly byte[] s_EmptyArray = new byte[0];
-
- private byte[] _CertThumbPrint;
- private SchProtocols _AllowedProtocols;
- private int _HashCode;
-
-
-
-
-
- internal SslCredKey(byte[] thumbPrint, SchProtocols allowedProtocols)
- {
- _CertThumbPrint = thumbPrint == null ? s_EmptyArray : thumbPrint;
- _HashCode = 0;
- if (thumbPrint != null) {
- _HashCode ^= _CertThumbPrint[0];
- if (1 < _CertThumbPrint.Length)
- _HashCode ^= (_CertThumbPrint[1] << 8);
- if (2 < _CertThumbPrint.Length)
- _HashCode ^= (_CertThumbPrint[2] << 16);
- if (3 < _CertThumbPrint.Length)
- _HashCode ^= (_CertThumbPrint[3] << 24);
- }
- _AllowedProtocols = allowedProtocols;
- _HashCode ^= (int)_AllowedProtocols;
- }
-
- public override int GetHashCode()
- {
- return _HashCode;
- }
-
- public static bool operator ==(SslCredKey sslCredKey1, SslCredKey sslCredKey2)
- {
- if ((object)sslCredKey1 == (object)sslCredKey2) {
- return true;
- }
- if ((object)sslCredKey1 == null || (object)sslCredKey2 == null) {
- return false;
- }
- return sslCredKey1.Equals(sslCredKey2);
- }
-
- public static bool operator !=(SslCredKey sslCredKey1, SslCredKey sslCredKey2)
- {
- if ((object)sslCredKey1 == (object)sslCredKey2) {
- return false;
- }
- if ((object)sslCredKey1 == null || (object)sslCredKey2 == null) {
- return true;
- }
- return !sslCredKey1.Equals(sslCredKey2);
- }
-
- public override bool Equals(object y)
- {
- SslCredKey she = (SslCredKey)y;
-
- if (_CertThumbPrint.Length != she._CertThumbPrint.Length)
- return false;
-
- if (_HashCode != she._HashCode)
- return false;
-
- for (int i = 0; i < _CertThumbPrint.Length; ++i)
- if (_CertThumbPrint[i] != she._CertThumbPrint[i])
- return false;
-
- return true;
- }
- }
-
-
-
-
-
-
-
-
-
-
- static internal SafeFreeCredentials TryCachedCredential(byte[] thumbPrint, SchProtocols allowedProtocols)
- {
- if (s_CachedCreds.Count == 0) {
- GlobalLog.Print("TryCachedCredential() Not Found, Current Cache Count = " + s_CachedCreds.Count);
- return null;
- }
-
- object key = new SslCredKey(thumbPrint, allowedProtocols);
-
- SafeCredentialReference cached = s_CachedCreds[key] as SafeCredentialReference;
-
- if (cached == null || cached.IsClosed || cached._Target.IsInvalid) {
- GlobalLog.Print("TryCachedCredential() Not Found, Current Cache Count = " + s_CachedCreds.Count);
- return null;
- }
-
- GlobalLog.Print("TryCachedCredential() Found a cached Handle = " + cached._Target.ToString());
-
- return cached._Target;
- }
-
-
-
-
-
- static internal void CacheCredential(SafeFreeCredentials creds, byte[] thumbPrint, SchProtocols allowedProtocols)
- {
- GlobalLog.Assert(creds != null, "CacheCredential|creds == null");
- if (creds.IsInvalid) {
- GlobalLog.Print("CacheCredential() Refused to cache an Invalid Handle = " + creds.ToString() + ", Current Cache Count = " + s_CachedCreds.Count);
- return;
- }
-
- object key = new SslCredKey(thumbPrint, allowedProtocols);
-
- SafeCredentialReference cached = s_CachedCreds[key] as SafeCredentialReference;
-
- if (cached == null || cached.IsClosed || cached._Target.IsInvalid) {
- lock (s_CachedCreds) {
- cached = s_CachedCreds[key] as SafeCredentialReference;
-
- if (cached == null || cached.IsClosed) {
- cached = SafeCredentialReference.CreateReference(creds);
-
- if (cached == null) {
-
- return;
- }
-
- s_CachedCreds[key] = cached;
- GlobalLog.Print("CacheCredential() Caching New Handle = " + creds.ToString() + ", Current Cache Count = " + s_CachedCreds.Count);
-
-
-
-
-
-
-
-
-
-
-
- if ((s_CachedCreds.Count % c_CheckExpiredModulo) == 0) {
- DictionaryEntry[] toRemoveAttempt = new DictionaryEntry[s_CachedCreds.Count];
- s_CachedCreds.CopyTo(toRemoveAttempt, 0);
-
- for (int i = 0; i < toRemoveAttempt.Length; ++i) {
- cached = toRemoveAttempt[i].Value as SafeCredentialReference;
-
- if (cached != null) {
- creds = cached._Target;
- cached.Close();
-
- if (!creds.IsClosed && !creds.IsInvalid && (cached = SafeCredentialReference.CreateReference(creds)) != null)
- s_CachedCreds[toRemoveAttempt[i].Key] = cached;
- else
- s_CachedCreds.Remove(toRemoveAttempt[i].Key);
- }
- }
- GlobalLog.Print("Scavenged cache, New Cache Count = " + s_CachedCreds.Count);
- }
- }
- else {
- GlobalLog.Print("CacheCredential() (locked retry) Found already cached Handle = " + cached._Target.ToString());
- }
- }
- }
- else {
- GlobalLog.Print("CacheCredential() Ignoring incoming handle = " + creds.ToString() + " since found already cached Handle = " + cached._Target.ToString());
- }
- }
- }
- }