SecurityUtils.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / SecurityUtils.cs / 4 / SecurityUtils.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.ServiceModel.Security 
{
    using Microsoft.Win32; 
    using System.ServiceModel; 
    using System.Diagnostics;
    using System.Text; 
    using System.Threading;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    using System.ServiceModel.Diagnostics; 
    using System.Security;
    using System.Security.Permissions; 
    using System.Security.Principal; 
    using System.Security.Cryptography.X509Certificates;
    using System.IdentityModel.Claims; 
    using System.IdentityModel.Policy;
    using System.IdentityModel.Selectors;
    using System.IdentityModel.Tokens;
    using System.ServiceModel.Security.Tokens; 
    using System.Xml;
    using System.Runtime.Serialization; 
    using System.Collections; 
    using System.Collections.ObjectModel;
    using System.Collections.Generic; 
    using System.Security.Cryptography;
    using System.DirectoryServices.ActiveDirectory;
    using System.Runtime.InteropServices;
    using System.ComponentModel; 
    using System.Globalization;
    using System.IO; 
    using System.Net; 
    using System.Net.Security;
    using System.ServiceModel.Dispatcher; 

    using DictionaryManager = System.IdentityModel.DictionaryManager;
    using SspiWrapper = System.IdentityModel.SspiWrapper;
    using CredentialUse = System.IdentityModel.CredentialUse; 
    using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials;
    using AuthIdentityEx = System.IdentityModel.AuthIdentityEx; 
 
    static class StoreLocationHelper
    { 
        internal static bool IsDefined(StoreLocation value)
        {
            return (value == StoreLocation.CurrentUser
                || value == StoreLocation.LocalMachine); 
        }
    } 
 
    static class ProtectionLevelHelper
    { 
        internal static bool IsDefined(ProtectionLevel value)
        {
            return (value == ProtectionLevel.None
                || value == ProtectionLevel.Sign 
                || value == ProtectionLevel.EncryptAndSign);
        } 
 
        internal static void Validate(ProtectionLevel value)
        { 
            if (!IsDefined(value))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("value", (int)value,
                    typeof(ProtectionLevel))); 
            }
        } 
 
        internal static bool IsStronger(ProtectionLevel v1, ProtectionLevel v2)
        { 
            return ((v1 == ProtectionLevel.EncryptAndSign && v2 != ProtectionLevel.EncryptAndSign)
                    || (v1 == ProtectionLevel.Sign && v2 == ProtectionLevel.None));
        }
 
        internal static bool IsStrongerOrEqual(ProtectionLevel v1, ProtectionLevel v2)
        { 
            return (v1 == ProtectionLevel.EncryptAndSign 
                    || (v1 == ProtectionLevel.Sign && v2 != ProtectionLevel.EncryptAndSign));
        } 

        internal static ProtectionLevel Max(ProtectionLevel v1, ProtectionLevel v2)
        {
            return IsStronger(v1, v2) ? v1 : v2; 
        }
 
        internal static int GetOrdinal(Nullable p) 
        {
            if (p.HasValue) 
            {
                switch ((ProtectionLevel)p)
                {
                    default: 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("p", (int)p,
                        typeof(ProtectionLevel))); 
                    case ProtectionLevel.None: 
                        return 2;
                    case ProtectionLevel.Sign: 
                        return 3;
                    case ProtectionLevel.EncryptAndSign:
                        return 4;
                } 
            }
            else 
                return 1; 
        }
    } 

    static class TokenImpersonationLevelHelper
    {
        internal static bool IsDefined(TokenImpersonationLevel value) 
        {
            return (value == TokenImpersonationLevel.None 
                || value == TokenImpersonationLevel.Anonymous 
                || value == TokenImpersonationLevel.Identification
                || value == TokenImpersonationLevel.Impersonation 
                || value == TokenImpersonationLevel.Delegation);
        }

        internal static void Validate(TokenImpersonationLevel value) 
        {
            if (!IsDefined(value)) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("value", (int)value,
                    typeof(TokenImpersonationLevel))); 
            }
        }

        static TokenImpersonationLevel[] TokenImpersonationLevelOrder = new TokenImpersonationLevel[] 
            {
                TokenImpersonationLevel.None, 
                TokenImpersonationLevel.Anonymous, 
                TokenImpersonationLevel.Identification,
                TokenImpersonationLevel.Impersonation, 
                TokenImpersonationLevel.Delegation
            };

        internal static string ToString(TokenImpersonationLevel impersonationLevel) 
        {
            if (impersonationLevel == TokenImpersonationLevel.Identification) 
            { 
                return "identification";
            } 
            else if (impersonationLevel == TokenImpersonationLevel.None)
            {
                return "none";
            } 
            else if (impersonationLevel == TokenImpersonationLevel.Anonymous)
            { 
                return "anonymous"; 
            }
            else if (impersonationLevel == TokenImpersonationLevel.Impersonation) 
            {
                return "impersonation";
            }
            else if (impersonationLevel == TokenImpersonationLevel.Delegation) 
            {
                return "delegation"; 
            } 

            DiagnosticUtility.DebugAssert("unknown token impersonation level"); 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("impersonationLevel", (int)impersonationLevel,
            typeof(TokenImpersonationLevel)));
        }
 
        internal static bool IsGreaterOrEqual(TokenImpersonationLevel x, TokenImpersonationLevel y)
        { 
            TokenImpersonationLevelHelper.Validate(x); 
            TokenImpersonationLevelHelper.Validate(y);
 
            if (x == y)
                return true;

            int px = 0; 
            int py = 0;
            for (int i = 0; i < TokenImpersonationLevelOrder.Length; i++) 
            { 
                if (x == TokenImpersonationLevelOrder[i])
                    px = i; 
                if (y == TokenImpersonationLevelOrder[i])
                    py = i;
            }
 
            return (px > py);
        } 
 
        internal static int Compare(TokenImpersonationLevel x, TokenImpersonationLevel y)
        { 
            int result = 0;

            if (x != y)
            { 
                switch (x)
                { 
                    case TokenImpersonationLevel.Identification: 
                        result = -1;
                        break; 
                    case TokenImpersonationLevel.Impersonation:
                        switch (y)
                        {
                            case TokenImpersonationLevel.Identification: 
                                result = 1;
                                break; 
                            case TokenImpersonationLevel.Delegation: 
                                result = -1;
                                break; 
                            default:
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("y", (int)y,
                                    typeof(TokenImpersonationLevel)));
 
                        }
                        break; 
                    case TokenImpersonationLevel.Delegation: 
                        result = 1;
                        break; 
                    default:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("x", (int)x,
                            typeof(TokenImpersonationLevel)));
 
                }
            } 
 
            return result;
        } 
    }

    internal class ServiceModelDictionaryManager
    { 
        static DictionaryManager dictionaryManager;
 
        public static DictionaryManager Instance 
        {
            get 
            {
                if (dictionaryManager == null)
                    dictionaryManager = new DictionaryManager(BinaryMessageEncoderFactory.XmlDictionary);
 
                return dictionaryManager;
            } 
        } 
    }
 
    static class SecurityUtils
    {
        public const string Principal = "Principal";
        public const string Identities = "Identities"; 
        static bool computedDomain;
        static string currentDomain; 
        static byte[] combinedHashLabel; 
        static int fipsAlgorithmPolicy = -1;
        static IIdentity anonymousIdentity; 
        static NetworkCredential dummyNetworkCredential;
        static object dummyNetworkCredentialLock = new object();
        static X509SecurityTokenAuthenticator nonValidatingX509Authenticator;
        static SecurityIdentifier administratorsSid; 
        const int WindowsServerMajorNumber = 5;
        const int WindowsServerMinorNumber = 2; 
        const int XPMajorNumber = 5; 
        const int XPMinorNumber = 1;
        const string ServicePack1 = "Service Pack 1"; 
        const string ServicePack2 = "Service Pack 2";
        volatile static bool shouldValidateSslCipherStrength;
        volatile static bool isSslValidationRequirementDetermined = false;
        static readonly int MinimumSslCipherStrength = 128; 

        internal static bool IsOsGreaterThanXP() 
        { 
            return ((Environment.OSVersion.Version.Major >= SecurityUtils.XPMajorNumber && Environment.OSVersion.Version.Minor > SecurityUtils.XPMinorNumber) ||
                    Environment.OSVersion.Version.Major > SecurityUtils.XPMajorNumber); 
        }

        internal static X509SecurityTokenAuthenticator NonValidatingX509Authenticator
        { 
            get
            { 
                if (nonValidatingX509Authenticator == null) 
                {
                    nonValidatingX509Authenticator = new X509SecurityTokenAuthenticator(X509CertificateValidator.None); 
                }
                return nonValidatingX509Authenticator;
            }
        } 

        public static SecurityIdentifier AdministratorsSid 
        { 
            get
            { 
                if (administratorsSid == null)
                    administratorsSid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
                return administratorsSid;
            } 
        }
 
        internal static IIdentity AnonymousIdentity 
        {
            get 
            {
                if (anonymousIdentity == null)
                {
                    anonymousIdentity = SecurityUtils.CreateIdentity(String.Empty); 
                }
                return anonymousIdentity; 
            } 
        }
 
        public static DateTime MaxUtcDateTime
        {
            get
            { 
                // + and -  TimeSpan.TicksPerDay is to compensate the DateTime.ParseExact (to localtime) overflow.
                return new DateTime(DateTime.MaxValue.Ticks - TimeSpan.TicksPerDay, DateTimeKind.Utc); 
            } 
        }
 
        public static DateTime MinUtcDateTime
        {
            get
            { 
                // + and -  TimeSpan.TicksPerDay is to compensate the DateTime.ParseExact (to localtime) overflow.
                return new DateTime(DateTime.MinValue.Ticks + TimeSpan.TicksPerDay, DateTimeKind.Utc); 
            } 
        }
 
        internal static IIdentity CreateIdentity(string name, string authenticationType)
        {
            return new GenericIdentity(name, authenticationType);
        } 

        internal static IIdentity CreateIdentity(string name) 
        { 
            return new GenericIdentity(name);
        } 

        internal static EndpointIdentity CreateWindowsIdentity()
        {
            return CreateWindowsIdentity(false); 
        }
 
        internal static EndpointIdentity CreateWindowsIdentity(NetworkCredential serverCredential) 
        {
            if (serverCredential != null && !NetworkCredentialHelper.IsDefault(serverCredential)) 
            {
                string upn;
                if (serverCredential.Domain != null && serverCredential.Domain.Length > 0)
                { 
                    upn = serverCredential.UserName + "@" + serverCredential.Domain;
                } 
                else 
                {
                    upn = serverCredential.UserName; 
                }
                return EndpointIdentity.CreateUpnIdentity(upn);
            }
            else 
            {
                return SecurityUtils.CreateWindowsIdentity(); 
            } 
        }
 
        static bool IsSystemAccount(WindowsIdentity self)
        {
            SecurityIdentifier sid = self.User;
            if (sid == null) 
            {
                return false; 
            } 
            return (sid.IsWellKnown(WellKnownSidType.LocalSystemSid)
                    || sid.IsWellKnown(WellKnownSidType.NetworkServiceSid) 
                    || sid.IsWellKnown(WellKnownSidType.LocalServiceSid));
        }

        internal static EndpointIdentity CreateWindowsIdentity(bool spnOnly) 
        {
            EndpointIdentity identity = null; 
            using (WindowsIdentity self = WindowsIdentity.GetCurrent()) 
            {
                bool isSystemAccount = IsSystemAccount(self); 
                if (spnOnly || isSystemAccount)
                {
                    identity = EndpointIdentity.CreateSpnIdentity(String.Format(CultureInfo.InvariantCulture, "host/{0}", DnsCache.MachineName));
                } 
                else
                { 
                    // Save windowsIdentity for delay lookup 
                    identity = new UpnEndpointIdentity(CloneWindowsIdentityIfNecessary(self));
                } 
            }

            return identity;
        } 

        ///  
        /// Critical - calls two critical methods: UnsafeGetWindowsIdentityToken and UnsafeCreateWindowsIdentityFromToken 
        /// Safe - "clone" operation is considered safe despite using WindowsIdentity IntPtr token
        ///        must not let IntPtr token leak in or out 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal static WindowsIdentity CloneWindowsIdentityIfNecessary(WindowsIdentity wid)
        { 
            if (wid != null)
            { 
                IntPtr token = UnsafeGetWindowsIdentityToken(wid); 
                if (token != IntPtr.Zero)
                { 
                    return UnsafeCreateWindowsIdentityFromToken(token);
                }
            }
            return wid; 
        }
 
        ///  
        /// Critical - elevates in order to return the WindowsIdentity.Token property
        ///            caller must protect return value 
        /// 
        [SecurityCritical]
        [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
        static IntPtr UnsafeGetWindowsIdentityToken(WindowsIdentity wid) 
        {
            return wid.Token; 
        } 

        ///  
        /// Critical - elevates in order to construct a WindowsIdentity instance from an IntPtr
        ///            caller must protect parameter return value
        /// 
        [SecurityCritical] 
        [SecurityPermission(SecurityAction.Assert, ControlPrincipal = true, UnmanagedCode = true)]
        static WindowsIdentity UnsafeCreateWindowsIdentityFromToken(IntPtr token) 
        { 
            return new WindowsIdentity(token);
        } 

        internal static bool AllowsImpersonation(WindowsIdentity windowsIdentity, TokenImpersonationLevel impersonationLevel)
        {
            if (windowsIdentity == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("windowsIdentity");
 
            TokenImpersonationLevelHelper.Validate(impersonationLevel); 

            if (impersonationLevel == TokenImpersonationLevel.Identification) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("impersonationLevel"));

            bool result = true;
 
            switch (windowsIdentity.ImpersonationLevel)
            { 
                case TokenImpersonationLevel.None: 
                case TokenImpersonationLevel.Anonymous:
                case TokenImpersonationLevel.Identification: 
                    result = false; break;
                case TokenImpersonationLevel.Impersonation:
                    if (impersonationLevel == TokenImpersonationLevel.Delegation)
                        result = false; 
                    break;
                case TokenImpersonationLevel.Delegation: 
                    break; 
                default:
                    result = false; 
                    break;
            }

            return result; 
        }
 
        internal static byte[] CombinedHashLabel 
        {
            get 
            {
                if (combinedHashLabel == null)
                    combinedHashLabel = Encoding.UTF8.GetBytes(TrustApr2004Strings.CombinedHashLabel);
                return combinedHashLabel; 
            }
        } 
 
        internal static T GetSecurityKey(SecurityToken token)
            where T : SecurityKey 
        {
            T result = null;
            if (token.SecurityKeys != null)
            { 
                for (int i = 0; i < token.SecurityKeys.Count; ++i)
                { 
                    T temp = (token.SecurityKeys[i] as T); 
                    if (temp != null)
                    { 
                        if (result != null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.MultipleMatchingCryptosFound, typeof(T).ToString())));
                        } 
                        else
                        { 
                            result = temp; 
                        }
                    } 
                }
            }
            return result;
        } 

        internal static bool HasSymmetricSecurityKey(SecurityToken token) 
        { 
            return GetSecurityKey(token) != null;
        } 

        internal static void EnsureExpectedSymmetricMatch(SecurityToken t1, SecurityToken t2, Message message)
        {
            // nulls are not mismatches 
            if (t1 == null || t2 == null || ReferenceEquals(t1, t2))
            { 
                return; 
            }
            // check for interop flexibility 
            SymmetricSecurityKey c1 = SecurityUtils.GetSecurityKey(t1);
            SymmetricSecurityKey c2 = SecurityUtils.GetSecurityKey(t2);
            if (c1 == null || c2 == null || !CryptoHelper.IsEqual(c1.GetSymmetricKey(), c2.GetSymmetricKey()))
            { 
                throw System.ServiceModel.Diagnostics.TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenNotExpectedInSecurityHeader, t2)), message);
            } 
        } 

        internal static SymmetricAlgorithm GetSymmetricAlgorithm(string algorithm, SecurityToken token) 
        {
            SymmetricSecurityKey securityKey = SecurityUtils.GetSecurityKey(token);
            if (securityKey != null && securityKey.IsSupportedAlgorithm(algorithm))
            { 
                return securityKey.GetSymmetricAlgorithm(algorithm);
            } 
            else 
            {
                return null; 
            }
        }

        internal static KeyedHashAlgorithm GetKeyedHashAlgorithm(string algorithm, SecurityToken token) 
        {
            SymmetricSecurityKey securityKey = SecurityUtils.GetSecurityKey(token); 
            if (securityKey != null && securityKey.IsSupportedAlgorithm(algorithm)) 
            {
                return securityKey.GetKeyedHashAlgorithm(algorithm); 
            }
            else
            {
                return null; 
            }
        } 
 
        internal static ReadOnlyCollection CreateSymmetricSecurityKeys(byte[] key)
        { 
            List temp = new List(1);
            temp.Add(new InMemorySymmetricSecurityKey(key));
            return temp.AsReadOnly();
        } 

        internal static byte[] DecryptKey(SecurityToken unwrappingToken, string encryptionMethod, byte[] wrappedKey, out SecurityKey unwrappingSecurityKey) 
        { 
            unwrappingSecurityKey = null;
            if (unwrappingToken.SecurityKeys != null) 
            {
                for (int i = 0; i < unwrappingToken.SecurityKeys.Count; ++i)
                {
                    if (unwrappingToken.SecurityKeys[i].IsSupportedAlgorithm(encryptionMethod)) 
                    {
                        unwrappingSecurityKey = unwrappingToken.SecurityKeys[i]; 
                        break; 
                    }
                } 
            }
            if (unwrappingSecurityKey == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.CannotFindMatchingCrypto, encryptionMethod))); 
            }
            return unwrappingSecurityKey.DecryptKey(encryptionMethod, wrappedKey); 
        } 

        internal static byte[] EncryptKey(SecurityToken wrappingToken, string encryptionMethod, byte[] keyToWrap) 
        {
            SecurityKey wrappingSecurityKey = null;
            if (wrappingToken.SecurityKeys != null)
            { 
                for (int i = 0; i < wrappingToken.SecurityKeys.Count; ++i)
                { 
                    if (wrappingToken.SecurityKeys[i].IsSupportedAlgorithm(encryptionMethod)) 
                    {
                        wrappingSecurityKey = wrappingToken.SecurityKeys[i]; 
                        break;
                    }
                }
            } 
            if (wrappingSecurityKey == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.CannotFindMatchingCrypto, encryptionMethod)); 
            }
            return wrappingSecurityKey.EncryptKey(encryptionMethod, keyToWrap); 
        }

        internal static byte[] ReadContentAsBase64(XmlDictionaryReader reader, long maxBufferSize)
        { 
            if (reader == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 
 
            // Code cloned from System.Xml.XmlDictionaryReder.
            byte[][] buffers = new byte[32][]; 
            byte[] buffer;
            // Its best to read in buffers that are a multiple of 3 so we don't break base64 boundaries when converting text
            int count = 384;
            int bufferCount = 0; 
            int totalRead = 0;
            while (true) 
            { 
                buffer = new byte[count];
                buffers[bufferCount++] = buffer; 
                int read = 0;
                while (read < buffer.Length)
                {
                    int actual = reader.ReadContentAsBase64(buffer, read, buffer.Length - read); 
                    if (actual == 0)
                        break; 
                    read += actual; 
                }
                if (totalRead > maxBufferSize - read) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QuotaExceededException(SR.GetString(SR.BufferQuotaExceededReadingBase64, maxBufferSize)));
                totalRead += read;
                if (read < buffer.Length)
                    break; 
                count = count * 2;
            } 
            buffer = new byte[totalRead]; 
            int offset = 0;
            for (int i = 0; i < bufferCount - 1; i++) 
            {
                Buffer.BlockCopy(buffers[i], 0, buffer, offset, buffers[i].Length);
                offset += buffers[i].Length;
            } 
            Buffer.BlockCopy(buffers[bufferCount - 1], 0, buffer, offset, totalRead - offset);
            return buffer; 
        } 

        internal static byte[] GenerateDerivedKey(SecurityToken tokenToDerive, string derivationAlgorithm, byte[] label, byte[] nonce, 
            int keySize, int offset)
        {
            SymmetricSecurityKey symmetricSecurityKey = SecurityUtils.GetSecurityKey(tokenToDerive);
            if (symmetricSecurityKey == null || !symmetricSecurityKey.IsSupportedAlgorithm(derivationAlgorithm)) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.CannotFindMatchingCrypto, derivationAlgorithm))); 
            } 
            return symmetricSecurityKey.GenerateDerivedKey(derivationAlgorithm, label, nonce, keySize, offset);
        } 

        internal static string GetSpnFromIdentity(EndpointIdentity identity, EndpointAddress target)
        {
            bool foundSpn = false; 
            string spn = null;
            if (identity != null) 
            { 
                if (ClaimTypes.Spn.Equals(identity.IdentityClaim.ClaimType))
                { 
                    spn = (string)identity.IdentityClaim.Resource;
                    foundSpn = true;
                }
                else if (ClaimTypes.Upn.Equals(identity.IdentityClaim.ClaimType)) 
                {
                    spn = (string)identity.IdentityClaim.Resource; 
                    foundSpn = true; 
                }
                else if (ClaimTypes.Dns.Equals(identity.IdentityClaim.ClaimType)) 
                {
                    spn = String.Format(CultureInfo.InvariantCulture, "host/{0}", (string)identity.IdentityClaim.Resource);
                    foundSpn = true;
                } 
            }
            if (!foundSpn) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.CannotDetermineSPNBasedOnAddress, target)));
            } 
            return spn;
        }

        internal static string GetSpnFromTarget(EndpointAddress target) 
        {
            if (target == null) 
            { 
                DiagnosticUtility.DebugAssert("target should not be null - expecting an EndpointAddress");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            }

            return string.Format(CultureInfo.InvariantCulture, "host/{0}", target.Uri.DnsSafeHost);
        } 

        internal static bool IsSupportedAlgorithm(string algorithm, SecurityToken token) 
        { 
            if (token.SecurityKeys == null)
            { 
                return false;
            }
            for (int i = 0; i < token.SecurityKeys.Count; ++i)
            { 
                if (token.SecurityKeys[i].IsSupportedAlgorithm(algorithm))
                { 
                    return true; 
                }
            } 
            return false;
        }

        internal static Claim GetPrimaryIdentityClaim(ReadOnlyCollection authorizationPolicies) 
        {
            return GetPrimaryIdentityClaim(AuthorizationContext.CreateDefaultAuthorizationContext(authorizationPolicies)); 
        } 

        internal static Claim GetPrimaryIdentityClaim(AuthorizationContext authContext) 
        {
            if (authContext != null)
            {
                for (int i = 0; i < authContext.ClaimSets.Count; ++i) 
                {
                    ClaimSet claimSet = authContext.ClaimSets[i]; 
                    foreach (Claim claim in claimSet.FindClaims(null, Rights.Identity)) 
                    {
                        return claim; 
                    }
                }
            }
            return null; 
        }
 
        internal static int GetServiceAddressAndViaHash(EndpointAddress sr) 
        {
            if (sr == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sr");
            }
            return sr.GetHashCode(); 
        }
 
        internal static string GenerateId() 
        {
            return SecurityUniqueId.Create().Value; 
        }

        internal static string GenerateIdWithPrefix(string prefix)
        { 
            return SecurityUniqueId.Create(prefix).Value;
        } 
 
        internal static UniqueId GenerateUniqueId()
        { 
            return new UniqueId();
        }

        internal static string GetPrimaryDomain() 
        {
            using (WindowsIdentity wid = WindowsIdentity.GetCurrent()) 
            { 
                return GetPrimaryDomain(IsSystemAccount(wid));
            } 
        }

        internal static string GetPrimaryDomain(bool isSystemAccount)
        { 
            if (computedDomain == false)
            { 
                try 
                {
                    if (isSystemAccount) 
                    {
                        currentDomain = Domain.GetComputerDomain().Name;
                    }
                    else 
                    {
                        currentDomain = Domain.GetCurrentDomain().Name; 
                    } 
                }
#pragma warning suppress 56500 // covered by FxCOP 
                catch (Exception e)
                {
                    if (Diagnostics.ExceptionUtility.IsFatal(e))
                    { 
                        throw;
                    } 
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Warning); 
                }
                finally 
                {
                    computedDomain = true;
                }
            } 
            return currentDomain;
        } 
 
        internal static void EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate)
        { 
            if (certificate == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificate");
            } 
            bool canDoKeyExchange = false;
            Exception innerException = null; 
            if (certificate.HasPrivateKey) 
            {
                try 
                {
                    RSACryptoServiceProvider rsa = (certificate.PrivateKey as RSACryptoServiceProvider);
                    if (rsa != null && rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange)
                    { 
                        canDoKeyExchange = true;
                    } 
                } 
                // exceptions can be due to ACLs on the key etc
                catch (System.Security.SecurityException e) 
                {
                    innerException = e;
                }
                catch (CryptographicException e) 
                {
                    innerException = e; 
                } 
            }
            if (!canDoKeyExchange) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SslServerCertMustDoKeyExchange, certificate.SubjectName.Name), innerException));
            }
        } 

        internal static string GetCertificateId(X509Certificate2 certificate) 
        { 
            StringBuilder str = new StringBuilder(256);
            AppendCertificateIdentityName(str, certificate); 
            return str.ToString();
        }

        internal static ReadOnlyCollection CreatePrincipalNameAuthorizationPolicies(string principalName) 
        {
            if (principalName == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("principalName"); 

            Claim identityClaim; 
            Claim primaryPrincipal;
            if (principalName.Contains("@") || principalName.Contains(@"\"))
            {
                identityClaim = new Claim(ClaimTypes.Upn, principalName, Rights.Identity); 
                primaryPrincipal = Claim.CreateUpnClaim(principalName);
            } 
            else 
            {
                identityClaim = new Claim(ClaimTypes.Spn, principalName, Rights.Identity); 
                primaryPrincipal = Claim.CreateSpnClaim(principalName);
            }

            List claims = new List(2); 
            claims.Add(identityClaim);
            claims.Add(primaryPrincipal); 
 
            List policies = new List(1);
            policies.Add(new UnconditionalPolicy(SecurityUtils.CreateIdentity(principalName), new DefaultClaimSet(ClaimSet.Anonymous, claims))); 
            return policies.AsReadOnly();
        }

        internal static string GetIdentityNamesFromPolicies(IList authPolicies) 
        {
            return GetIdentityNamesFromContext(AuthorizationContext.CreateDefaultAuthorizationContext(authPolicies)); 
        } 

        internal static string GetIdentityNamesFromContext(AuthorizationContext authContext) 
        {
            if (authContext == null)
                return String.Empty;
 
            StringBuilder str = new StringBuilder(256);
            for (int i = 0; i < authContext.ClaimSets.Count; ++i) 
            { 
                ClaimSet claimSet = authContext.ClaimSets[i];
 
                // Windows
                WindowsClaimSet windows = claimSet as WindowsClaimSet;
                if (windows != null)
                { 
                    if (str.Length > 0)
                        str.Append(", "); 
 
                    AppendIdentityName(str, windows.WindowsIdentity);
                } 
                else
                {
                    // X509
                    X509CertificateClaimSet x509 = claimSet as X509CertificateClaimSet; 
                    if (x509 != null)
                    { 
                        if (str.Length > 0) 
                            str.Append(", ");
 
                        AppendCertificateIdentityName(str, x509.X509Certificate);
                    }
                }
            } 

            if (str.Length <= 0) 
            { 
                List identities = null;
                object obj; 
                if (authContext.Properties.TryGetValue(SecurityUtils.Identities, out obj))
                {
                    identities = obj as List;
                } 
                if (identities != null)
                { 
                    for (int i = 0; i < identities.Count; ++i) 
                    {
                        IIdentity identity = identities[i]; 
                        if (identity != null)
                        {
                            if (str.Length > 0)
                                str.Append(", "); 

                            AppendIdentityName(str, identity); 
                        } 
                    }
                } 
            }
            return str.Length <= 0 ? String.Empty : str.ToString();
        }
 
        internal static void AppendCertificateIdentityName(StringBuilder str, X509Certificate2 certificate)
        { 
            string value = certificate.SubjectName.Name; 
            if (String.IsNullOrEmpty(value))
            { 
                value = certificate.GetNameInfo(X509NameType.DnsName, false);
                if (String.IsNullOrEmpty(value))
                {
                    value = certificate.GetNameInfo(X509NameType.SimpleName, false); 
                    if (String.IsNullOrEmpty(value))
                    { 
                        value = certificate.GetNameInfo(X509NameType.EmailName, false); 
                        if (String.IsNullOrEmpty(value))
                        { 
                            value = certificate.GetNameInfo(X509NameType.UpnName, false);
                        }
                    }
                } 
            }
            // Same format as X509Identity 
            str.Append(String.IsNullOrEmpty(value) ? "" : value); 
            str.Append("; ");
            str.Append(certificate.Thumbprint); 
        }

        internal static void AppendIdentityName(StringBuilder str, IIdentity identity)
        { 
            string name = null;
            try 
            { 
                name = identity.Name;
            } 
#pragma warning suppress 56500
            catch (Exception e)
            {
                if (DiagnosticUtility.IsFatal(e)) 
                    throw;
                // suppress exception, this is just info. 
            } 

            str.Append(String.IsNullOrEmpty(name) ? "" : name); 

            WindowsIdentity windows = identity as WindowsIdentity;
            if (windows != null)
            { 
                if (windows.User != null)
                { 
                    str.Append("; "); 
                    str.Append(windows.User.ToString());
                } 
            }
            else
            {
                WindowsSidIdentity sid = identity as WindowsSidIdentity; 
                if (sid != null)
                { 
                    str.Append("; "); 
                    str.Append(sid.SecurityIdentifier.ToString());
                } 
            }
        }

        ///  
        /// Critical - Calls critical methods UnsafeGetDomain, UnsafeGetUserName and UnsafeGetPassword.
        ///  
        [SecurityCritical] 
        internal static string AppendWindowsAuthenticationInfo(string inputString, NetworkCredential credential,
            AuthenticationLevel authenticationLevel, TokenImpersonationLevel impersonationLevel) 
        {
            const string delimiter = "\0"; // nonprintable characters are invalid for SSPI Domain/UserName/Password

            if (IsDefaultNetworkCredential(credential)) 
            {
                using (WindowsIdentity self = WindowsIdentity.GetCurrent()) 
                { 
                    SecurityIdentifier sid = self.User;
                    return string.Concat(inputString, delimiter, 
                        sid.Value, delimiter,
                        AuthenticationLevelHelper.ToString(authenticationLevel), delimiter,
                        TokenImpersonationLevelHelper.ToString(impersonationLevel));
                } 
            }
            else 
            { 
                return string.Concat(inputString, delimiter,
                    NetworkCredentialHelper.UnsafeGetDomain(credential), delimiter, 
                    NetworkCredentialHelper.UnsafeGetUsername(credential), delimiter,
                    NetworkCredentialHelper.UnsafeGetPassword(credential), delimiter,
                    AuthenticationLevelHelper.ToString(authenticationLevel), delimiter,
                    TokenImpersonationLevelHelper.ToString(impersonationLevel)); 
            }
        } 
 
        internal static string GetIdentityName(IIdentity identity)
        { 
            StringBuilder str = new StringBuilder(256);
            AppendIdentityName(str, identity);
            return str.ToString();
        } 

        // Federal Information Processing Standards Publications 
        // at http://www.itl.nist.gov/fipspubs/geninfo.htm 
        // Note: this is copied from System.IdentityModel.SecurityUtils.RequiresFipsCompliance.
        internal static bool RequiresFipsCompliance 
        {
            /// 
            /// Critical - Calls an UnsafeNativeMethod and a Critical method (GetFipsAlgorithmPolicyKeyFromRegistry)
            /// Safe - processes the return and just returns a bool, which is safe 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get 
            {
                if (fipsAlgorithmPolicy == -1) 
                {
                    if (OSEnvironmentHelper.IsVistaOrGreater)
                    {
                        bool fipsEnabled; 
#pragma warning suppress 56523 // TODO: evaluate PRESharp Warning here
                        bool readPolicy = (UnsafeNativeMethods.ERROR_SUCCESS == UnsafeNativeMethods.BCryptGetFipsAlgorithmMode(out fipsEnabled)); 
 
                        if (readPolicy && fipsEnabled)
                            fipsAlgorithmPolicy = 1; 
                        else
                            fipsAlgorithmPolicy = 0;
                    }
                    else 
                    {
                        fipsAlgorithmPolicy = GetFipsAlgorithmPolicyKeyFromRegistry(); 
                        if (fipsAlgorithmPolicy != 1) 
                            fipsAlgorithmPolicy = 0;
                    } 
                }
                return fipsAlgorithmPolicy == 1;
            }
        } 

        const string fipsPolicyRegistryKey = @"System\CurrentControlSet\Control\Lsa"; 
 
        /// 
        /// Critical - Asserts to get a value from the registry 
        /// 
        [SecurityCritical]
        [RegistryPermission(SecurityAction.Assert, Read = @"HKEY_LOCAL_MACHINE\" + fipsPolicyRegistryKey)]
        static int GetFipsAlgorithmPolicyKeyFromRegistry() 
        {
            int fipsAlgorithmPolicy = -1; 
            using (RegistryKey fipsAlgorithmPolicyKey = Registry.LocalMachine.OpenSubKey(fipsPolicyRegistryKey, false)) 
            {
                if (fipsAlgorithmPolicyKey != null) 
                {
                    object data = fipsAlgorithmPolicyKey.GetValue("FIPSAlgorithmPolicy");
                    if (data != null)
                        fipsAlgorithmPolicy = (int)data; 
                }
            } 
            return fipsAlgorithmPolicy; 
        }
 
        internal static void ThrowIfNegotiationFault(Message message, EndpointAddress target)
        {
            if (message.IsFault)
            { 
                MessageFault fault = MessageFault.CreateFault(message, TransportDefaults.MaxSecurityFaultSize);
                Exception faultException = new FaultException(fault, message.Headers.Action); 
                if (fault.Code != null && fault.Code.IsReceiverFault && fault.Code.SubCode != null) 
                {
                    FaultCode subCode = fault.Code.SubCode; 
                    if (subCode.Name == DotNetSecurityStrings.SecurityServerTooBusyFault && subCode.Namespace == DotNetSecurityStrings.Namespace)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ServerTooBusyException(SR.GetString(SR.SecurityServerTooBusy, target), faultException));
                    } 
                    else if (subCode.Name == AddressingStrings.EndpointUnavailable && subCode.Namespace == message.Version.Addressing.Namespace)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new EndpointNotFoundException(SR.GetString(SR.SecurityEndpointNotFound, target), faultException)); 
                    }
                } 
                throw TraceUtility.ThrowHelperError(faultException, message);
            }
        }
 
        internal static bool IsSecurityFault(MessageFault fault, SecurityStandardsManager standardsManager)
        { 
            if (fault.Code.IsSenderFault) 
            {
                FaultCode subCode = fault.Code.SubCode; 
                if (subCode != null)
                {
                    return (subCode.Namespace == standardsManager.SecurityVersion.HeaderNamespace.Value
                        || subCode.Namespace == standardsManager.SecureConversationDriver.Namespace.Value 
                        || subCode.Namespace == standardsManager.TrustDriver.Namespace.Value
                        || subCode.Namespace == DotNetSecurityStrings.Namespace); 
                } 
            }
            return false; 
        }

        internal static Exception CreateSecurityFaultException(Message unverifiedMessage)
        { 
            MessageFault fault = MessageFault.CreateFault(unverifiedMessage, TransportDefaults.MaxSecurityFaultSize);
            return CreateSecurityFaultException(fault); 
        } 

        internal static Exception CreateSecurityFaultException(MessageFault fault) 
        {
            FaultException faultException = FaultException.CreateFault(fault, typeof(string), typeof(object));
            return new MessageSecurityException(SR.GetString(SR.UnsecuredMessageFaultReceived), faultException);
        } 

        internal static MessageFault CreateSecurityContextNotFoundFault(SecurityStandardsManager standardsManager, string action) 
        { 
            SecureConversationDriver scDriver = standardsManager.SecureConversationDriver;
            FaultCode subCode = new FaultCode(scDriver.BadContextTokenFaultCode.Value, scDriver.Namespace.Value); 
            FaultReason reason;
            if (action != null)
            {
                reason = new FaultReason(SR.GetString(SR.BadContextTokenOrActionFaultReason, action), CultureInfo.CurrentCulture); 
            }
            else 
            { 
                reason = new FaultReason(SR.GetString(SR.BadContextTokenFaultReason), CultureInfo.CurrentCulture);
            } 
            FaultCode senderCode = FaultCode.CreateSenderFaultCode(subCode);
            return MessageFault.CreateFault(senderCode, reason);
        }
 
        internal static MessageFault CreateSecurityMessageFault(Exception e, SecurityStandardsManager standardsManager)
        { 
            bool isSecurityError = false; 
            bool isTokenValidationError = false;
            bool isGenericTokenError = false; 
            FaultException faultException = null;
            while (e != null)
            {
                if (e is SecurityTokenValidationException) 
                {
                    if (e is SecurityContextTokenValidationException) 
                    { 
                        return CreateSecurityContextNotFoundFault(SecurityStandardsManager.DefaultInstance, null);
                    } 
                    isSecurityError = true;
                    isTokenValidationError = true;
                    break;
                } 
                else if (e is SecurityTokenException)
                { 
                    isSecurityError = true; 
                    isGenericTokenError = true;
                    break; 
                }
                else if (e is MessageSecurityException)
                {
                    MessageSecurityException ms = (MessageSecurityException)e; 
                    if (ms.Fault != null)
                    { 
                        return ms.Fault; 
                    }
                    isSecurityError = true; 
                }
                else if (e is FaultException)
                {
                    faultException = (FaultException)e; 
                    break;
                } 
                e = e.InnerException; 
            }
            if (!isSecurityError && faultException == null) 
            {
                return null;
            }
            FaultCode subCode; 
            FaultReason reason;
            SecurityVersion wss = standardsManager.SecurityVersion; 
            if (isTokenValidationError) 
            {
                subCode = new FaultCode(wss.FailedAuthenticationFaultCode.Value, wss.HeaderNamespace.Value); 
                reason = new FaultReason(SR.GetString(SR.FailedAuthenticationFaultReason), CultureInfo.CurrentCulture);
            }
            else if (isGenericTokenError)
            { 
                subCode = new FaultCode(wss.InvalidSecurityTokenFaultCode.Value, wss.HeaderNamespace.Value);
                reason = new FaultReason(SR.GetString(SR.InvalidSecurityTokenFaultReason), CultureInfo.CurrentCulture); 
            } 
            else if (faultException != null)
            { 
                // Only support Code and Reason.  No detail or action customization.
                return MessageFault.CreateFault(faultException.Code, faultException.Reason);
            }
            else 
            {
                subCode = new FaultCode(wss.InvalidSecurityFaultCode.Value, wss.HeaderNamespace.Value); 
                reason = new FaultReason(SR.GetString(SR.InvalidSecurityFaultReason), CultureInfo.CurrentCulture); 
            }
            FaultCode senderCode = FaultCode.CreateSenderFaultCode(subCode); 
            return MessageFault.CreateFault(senderCode, reason);
        }

        internal static bool IsCompositeDuplexBinding(BindingContext context) 
        {
            return ((context.Binding.Elements.Find() != null) 
                    || (context.Binding.Elements.Find() != null)); 
        }
 
        // The method checks TransportToken, ProtectionToken and all SupportingTokens to find a
        // UserNameSecurityToken. If found, it sets the password of the UserNameSecurityToken to null.
        // Custom UserNameSecurityToken are skipped.
        internal static void ErasePasswordInUsernameTokenIfPresent(SecurityMessageProperty messageProperty) 
        {
            if (messageProperty == null) 
            { 
                // Nothing to fix.
                return; 
            }

            if (messageProperty.TransportToken != null)
            { 
                UserNameSecurityToken token = messageProperty.TransportToken.SecurityToken as UserNameSecurityToken;
                if ((token != null) && !messageProperty.TransportToken.SecurityToken.GetType().IsSubclassOf(typeof(UserNameSecurityToken))) 
                { 
                    messageProperty.TransportToken = new SecurityTokenSpecification(new UserNameSecurityToken(token.UserName, null, token.Id), messageProperty.TransportToken.SecurityTokenPolicies);
                } 
            }

            if (messageProperty.ProtectionToken != null)
            { 
                UserNameSecurityToken token = messageProperty.ProtectionToken.SecurityToken as UserNameSecurityToken;
                if ((token != null) && !messageProperty.ProtectionToken.SecurityToken.GetType().IsSubclassOf(typeof(UserNameSecurityToken))) 
                { 
                    messageProperty.ProtectionToken = new SecurityTokenSpecification(new UserNameSecurityToken(token.UserName, null, token.Id), messageProperty.ProtectionToken.SecurityTokenPolicies);
                } 
            }

            if (messageProperty.HasIncomingSupportingTokens)
            { 
                for (int i = 0; i < messageProperty.IncomingSupportingTokens.Count; ++i)
                { 
                    SupportingTokenSpecification supportingTokenSpecification = messageProperty.IncomingSupportingTokens[i]; 
                    UserNameSecurityToken token = supportingTokenSpecification.SecurityToken as UserNameSecurityToken;
                    if ((token != null) && !supportingTokenSpecification.SecurityToken.GetType().IsSubclassOf(typeof(UserNameSecurityToken))) 
                    {
                        messageProperty.IncomingSupportingTokens[i] = new SupportingTokenSpecification(new UserNameSecurityToken(token.UserName, null, token.Id), supportingTokenSpecification.SecurityTokenPolicies, supportingTokenSpecification.SecurityTokenAttachmentMode, supportingTokenSpecification.SecurityTokenParameters);
                    }
                } 
            }
        } 
 
        // work-around to Windows SE Bug 141614
        ///  
        ///  Critical - Uses unsafe critical method UnsafeGetPassword to access the credential password without a Demand
        ///  Safe - only uses the password to construct a cloned NetworkCredential instance, does not leak password value
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal static void FixNetworkCredential(ref NetworkCredential credential)
        { 
            if (credential == null) 
            {
                return; 
            }
            string username = NetworkCredentialHelper.UnsafeGetUsername(credential);
            string domain = NetworkCredentialHelper.UnsafeGetDomain(credential);
            if (!string.IsNullOrEmpty(username) && string.IsNullOrEmpty(domain)) 
            {
                // do the splitting only if there is exactly 1 \ or exactly 1 @ 
                string[] partsWithSlashDelimiter = username.Split('\\'); 
                string[] partsWithAtDelimiter = username.Split('@');
                if (partsWithSlashDelimiter.Length == 2 && partsWithAtDelimiter.Length == 1) 
                {
                    if (!string.IsNullOrEmpty(partsWithSlashDelimiter[0]) && !string.IsNullOrEmpty(partsWithSlashDelimiter[1]))
                    {
                        credential = new NetworkCredential(partsWithSlashDelimiter[1], NetworkCredentialHelper.UnsafeGetPassword(credential), partsWithSlashDelimiter[0]); 
                    }
                } 
                else if (partsWithSlashDelimiter.Length == 1 && partsWithAtDelimiter.Length == 2) 
                {
                    if (!string.IsNullOrEmpty(partsWithAtDelimiter[0]) && !string.IsNullOrEmpty(partsWithAtDelimiter[1])) 
                    {
                        credential = new NetworkCredential(partsWithAtDelimiter[0], NetworkCredentialHelper.UnsafeGetPassword(credential), partsWithAtDelimiter[1]);
                    }
                } 
            }
        } 
 
        // WORKAROUND, [....], VSWhidbey 561276: The first NetworkCredential must be created in a lock.
        internal static void PrepareNetworkCredential() 
        {
            if (dummyNetworkCredential == null)
            {
                PrepareNetworkCredentialWorker(); 
            }
        } 
 
        // Since this takes a lock, it probably won't be inlined, but the typical case will be.
        static void PrepareNetworkCredentialWorker() 
        {
            lock (dummyNetworkCredentialLock)
            {
                dummyNetworkCredential = new NetworkCredential("dummy", "dummy"); 
            }
        } 
 
        // This is the workaround, Since store.Certificates returns a full collection
        // of certs in store.  These are holding native resources. 
        internal static void ResetAllCertificates(X509Certificate2Collection certificates)
        {
            if (certificates != null)
            { 
                for (int i = 0; i < certificates.Count; ++i)
                { 
                    certificates[i].Reset(); 
                }
            } 
        }

        internal static bool IsDefaultNetworkCredential(NetworkCredential credential)
        { 
            return NetworkCredentialHelper.IsDefault(credential);
        } 
 
        internal static void OpenTokenProviderIfRequired(SecurityTokenProvider tokenProvider, TimeSpan timeout)
        { 
            OpenCommunicationObject(tokenProvider as ICommunicationObject, timeout);
        }

        internal static IAsyncResult BeginOpenTokenProviderIfRequired(SecurityTokenProvider tokenProvider, TimeSpan timeout, 
            AsyncCallback callback, object state)
        { 
            return new OpenCommunicationObjectAsyncResult(tokenProvider, timeout, callback, state); 
        }
 
        internal static void EndOpenTokenProviderIfRequired(IAsyncResult result)
        {
            OpenCommunicationObjectAsyncResult.End(result);
        } 

        internal static IAsyncResult BeginCloseTokenProviderIfRequired(SecurityTokenProvider tokenProvider, TimeSpan timeout, 
            AsyncCallback callback, object state) 
        {
            return new CloseCommunicationObjectAsyncResult(tokenProvider, timeout, callback, state); 
        }

        internal static void EndCloseTokenProviderIfRequired(IAsyncResult result)
        { 
            CloseCommunicationObjectAsyncResult.End(result);
        } 
 
        internal static void CloseTokenProviderIfRequired(SecurityTokenProvider tokenProvider, TimeSpan timeout)
        { 
            CloseCommunicationObject(tokenProvider, false, timeout);
        }

        internal static void CloseTokenProviderIfRequired(SecurityTokenProvider tokenProvider, bool aborted, TimeSpan timeout) 
        {
            CloseCommunicationObject(tokenProvider, aborted, timeout); 
        } 

        internal static void AbortTokenProviderIfRequired(SecurityTokenProvider tokenProvider) 
        {
            CloseCommunicationObject(tokenProvider, true, TimeSpan.Zero);
        }
 
        internal static void OpenTokenAuthenticatorIfRequired(SecurityTokenAuthenticator tokenAuthenticator, TimeSpan timeout)
        { 
            OpenCommunicationObject(tokenAuthenticator as ICommunicationObject, timeout); 
        }
 
        internal static void CloseTokenAuthenticatorIfRequired(SecurityTokenAuthenticator tokenAuthenticator, TimeSpan timeout)
        {
            CloseTokenAuthenticatorIfRequired(tokenAuthenticator, false, timeout);
        } 

        internal static void CloseTokenAuthenticatorIfRequired(SecurityTokenAuthenticator tokenAuthenticator, bool aborted, TimeSpan timeout) 
        { 
            CloseCommunicationObject(tokenAuthenticator, aborted, timeout);
        } 

        internal static IAsyncResult BeginOpenTokenAuthenticatorIfRequired(SecurityTokenAuthenticator tokenAuthenticator, TimeSpan timeout,
            AsyncCallback callback, object state)
        { 
            return new OpenCommunicationObjectAsyncResult(tokenAuthenticator, timeout, callback, state);
        } 
 
        internal static void EndOpenTokenAuthenticatorIfRequired(IAsyncResult result)
        { 
            OpenCommunicationObjectAsyncResult.End(result);
        }

        internal static IAsyncResult BeginCloseTokenAuthenticatorIfRequired(SecurityTokenAuthenticator tokenAuthenticator, TimeSpan timeout, 
            AsyncCallback callback, object state)
        { 
            return new CloseCommunicationObjectAsyncResult(tokenAuthenticator, timeout, callback, state); 
        }
 
        internal static void EndCloseTokenAuthenticatorIfRequired(IAsyncResult result)
        {
            CloseCommunicationObjectAsyncResult.End(result);
        } 

        internal static void AbortTokenAuthenticatorIfRequired(SecurityTokenAuthenticator tokenAuthenticator) 
        { 
            CloseCommunicationObject(tokenAuthenticator, true, TimeSpan.Zero);
        } 

        static void OpenCommunicationObject(ICommunicationObject obj, TimeSpan timeout)
        {
            if (obj != null) 
                obj.Open(timeout);
        } 
 
        static void CloseCommunicationObject(Object obj, bool aborted, TimeSpan timeout)
        { 
            if (obj != null)
            {
                ICommunicationObject co = obj as ICommunicationObject;
                if (co != null) 
                {
                    if (aborted) 
                    { 
                        try
                        { 
                            co.Abort();
                        }
                        catch (CommunicationException e)
                        { 
                            if (DiagnosticUtility.ShouldTraceInformation)
                            { 
                                DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); 
                            }
                        } 
                    }
                    else
                    {
                        co.Close(timeout); 
                    }
                } 
                else if (obj is IDisposable) 
                {
                    ((IDisposable)obj).Dispose(); 
                }
            }
        }
 
        class OpenCommunicationObjectAsyncResult : AsyncResult
        { 
            ICommunicationObject communicationObject; 
            static AsyncCallback onOpen;
 
            public OpenCommunicationObjectAsyncResult(object obj, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state)
            {
                this.communicationObject = obj as ICommunicationObject; 

                bool completeSelf = false; 
                if (this.communicationObject == null) 
                {
                    completeSelf = true; 
                }
                else
                {
                    if (onOpen == null) 
                    {
                        onOpen = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnOpen)); 
                    } 

                    IAsyncResult result = this.communicationObject.BeginOpen(timeout, onOpen, this); 
                    if (result.CompletedSynchronously)
                    {
                        this.communicationObject.EndOpen(result);
                        completeSelf = true; 
                    }
                } 
 
                if (completeSelf)
                { 
                    base.Complete(true);
                }
            }
 
            public static void End(IAsyncResult result)
            { 
                AsyncResult.End(result); 
            }
 
            static void OnOpen(IAsyncResult result)
            {
                if (result.CompletedSynchronously)
                { 
                    return;
                } 
 
                OpenCommunicationObjectAsyncResult thisPtr =
                    (OpenCommunicationObjectAsyncResult)result.AsyncState; 

                Exception completionException = null;
                try
                { 
                    thisPtr.communicationObject.EndOpen(result);
                } 
#pragma warning suppress 56500 // [....], transferring exception to another thread 
                catch (Exception e)
                { 
                    if (DiagnosticUtility.IsFatal(e))
                    {
                        throw;
                    } 

                    completionException = e; 
                } 
                thisPtr.Complete(false, completionException);
            } 
        }

        class CloseCommunicationObjectAsyncResult : AsyncResult
        { 
            ICommunicationObject communicationObject;
            static AsyncCallback onClose; 
 
            public CloseCommunicationObjectAsyncResult(object obj, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state) 
            {
                this.communicationObject = obj as ICommunicationObject;

                bool completeSelf = false; 
                if (this.communicationObject == null)
                { 
                    IDisposable disposable = obj as IDisposable; 
                    if (disposable != null)
                    { 
                        disposable.Dispose();
                    }
                    completeSelf = true;
                } 
                else
                { 
                    if (onClose == null) 
                    {
                        onClose = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnClose)); 
                    }

                    IAsyncResult result = this.communicationObject.BeginClose(timeout, onClose, this);
                    if (result.CompletedSynchronously) 
                    {
                        this.communicationObject.EndClose(result); 
                        completeSelf = true; 
                    }
                } 

                if (completeSelf)
                {
                    base.Complete(true); 
                }
            } 
 
            public static void End(IAsyncResult result)
            { 
                AsyncResult.End(result);
            }

            static void OnClose(IAsyncResult result) 
            {
                if (result.CompletedSynchronously) 
                { 
                    return;
                } 

                CloseCommunicationObjectAsyncResult thisPtr =
                    (CloseCommunicationObjectAsyncResult)result.AsyncState;
 
                Exception completionException = null;
                try 
                { 
                    thisPtr.communicationObject.EndClose(result);
                } 
#pragma warning suppress 56500 // [....], transferring exception to another thread
                catch (Exception e)
                {
                    if (DiagnosticUtility.IsFatal(e)) 
                    {
                        throw; 
                    } 

                    completionException = e; 
                }
                thisPtr.Complete(false, completionException);
            }
        } 

        internal static void MatchRstWithEndpointFilter(Message rst, IMessageFilterTable endpointFilterTable, Uri listenUri) 
        { 
            if (endpointFilterTable == null)
            { 
                return;
            }
            Collection result = new Collection();
            if (!endpointFilterTable.GetMatchingValues(rst, result)) 
            {
                throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.RequestSecurityTokenDoesNotMatchEndpointFilters, listenUri)), rst); 
            } 
        }
 
        // match the RST with the endpoint filters in case there is at least 1 asymmetric signature in the message
        internal static bool ShouldMatchRstWithEndpointFilter(SecurityBindingElement sbe)
        {
            foreach (SecurityTokenParameters parameters in new SecurityTokenParametersEnumerable(sbe, true)) 
            {
                if (parameters.HasAsymmetricKey) 
                { 
                    return true;
                } 
            }
            return false;
        }
 
        internal static SecurityStandardsManager CreateSecurityStandardsManager(MessageSecurityVersion securityVersion, SecurityTokenManager tokenManager)
        { 
            SecurityTokenSerializer tokenSerializer = tokenManager.CreateSecurityTokenSerializer(securityVersion.SecurityTokenVersion); 
            return new SecurityStandardsManager(securityVersion, tokenSerializer);
        } 

        internal static SecurityStandardsManager CreateSecurityStandardsManager(SecurityTokenRequirement requirement, SecurityTokenManager tokenManager)
        {
            MessageSecurityTokenVersion securityVersion = (MessageSecurityTokenVersion)requirement.GetProperty(ServiceModelSecurityTokenRequirement.MessageSecurityVersionProperty); 
            if (securityVersion == MessageSecurityTokenVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005BasicSecurityProfile10)
                return CreateSecurityStandardsManager(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, tokenManager); 
            else if (securityVersion == MessageSecurityTokenVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005) 
                return CreateSecurityStandardsManager(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11, tokenManager);
            else if (securityVersion == MessageSecurityTokenVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005BasicSecurityProfile10) 
                return CreateSecurityStandardsManager(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, tokenManager);
            else if (securityVersion == MessageSecurityTokenVersion.WSSecurity10WSTrust13WSSecureConversation13BasicSecurityProfile10)
                return CreateSecurityStandardsManager(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10, tokenManager);
            else if (securityVersion == MessageSecurityTokenVersion.WSSecurity11WSTrust13WSSecureConversation13) 
                return CreateSecurityStandardsManager(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12, tokenManager);
            else if (securityVersion == MessageSecurityTokenVersion.WSSecurity11WSTrust13WSSecureConversation13BasicSecurityProfile10) 
                return CreateSecurityStandardsManager(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10, tokenManager); 
            else
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
        }

        internal static SecurityStandardsManager CreateSecurityStandardsManager(MessageSecurityVersion securityVersion, SecurityTokenSerializer securityTokenSerializer)
        { 
            if (securityVersion == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("securityVersion")); 
            }
            if (securityTokenSerializer == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("securityTokenSerializer");
            }
            return new SecurityStandardsManager(securityVersion, securityTokenSerializer); 
        }
 
        static bool TryCreateIdentity(ClaimSet claimSet, string claimType, out EndpointIdentity identity) 
        {
            identity = null; 
            foreach (Claim claim in claimSet.FindClaims(claimType, null))
            {
                identity = EndpointIdentity.CreateIdentity(claim);
                return true; 
            }
            return false; 
        } 

        internal static EndpointIdentity GetServiceCertificateIdentity(X509Certificate2 certificate) 
        {
            using (X509CertificateClaimSet claimSet = new X509CertificateClaimSet(certificate))
            {
                EndpointIdentity identity; 
                if (!TryCreateIdentity(claimSet, ClaimTypes.Dns, out identity))
                { 
                    TryCreateIdentity(claimSet, ClaimTypes.Rsa, out identity); 
                }
                return identity; 
            }
        }

        ///  
        ///  Critical - Uses unsafe critical method UnsafeGetPassword to access the credential password without a Demand
        ///  Safe - only uses the password to construct a new NetworkCredential which will then protect access; 
        ///         password does not leak from this method 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal static NetworkCredential GetNetworkCredentialsCopy(NetworkCredential networkCredential)
        {
            NetworkCredential result;
            if (networkCredential != null && !NetworkCredentialHelper.IsDefault(networkCredential)) 
            {
                result = new NetworkCredential(NetworkCredentialHelper.UnsafeGetUsername(networkCredential), NetworkCredentialHelper.UnsafeGetPassword(networkCredential), NetworkCredentialHelper.UnsafeGetDomain(networkCredential)); 
            } 
            else
            { 
                result = networkCredential;
            }
            return result;
        } 

        internal static NetworkCredential GetNetworkCredentialOrDefault(NetworkCredential credential) 
        { 
            // because of VSW 564452, we dont use CredentialCache.DefaultNetworkCredentials in our OM. Instead we
            // use an empty NetworkCredential to denote the default credentials 
            if (NetworkCredentialHelper.IsNullOrEmpty(credential))
            {
                // FYI: this will fail with SecurityException in PT due to Demand for EnvironmentPermission.
                // Typically a PT app should not have access to DefaultNetworkCredentials. If there is a valid reason, 
                // see UnsafeGetDefaultNetworkCredentials.
                return CredentialCache.DefaultNetworkCredentials; 
            } 
            else
            { 
                return credential;
            }
        }
 
        static class NetworkCredentialHelper
        { 
            ///  
            ///  Critical - Uses unsafe critical methods UnsafeGetUsername, UnsafeGetPassword, and UnsafeGetDomain
            ///             to access the credential details without a Demand 
            ///  Safe - only uses the protected values to test for null/empty.  does not leak.
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            static internal bool IsNullOrEmpty(NetworkCredential credential) 
            {
                return credential == null || 
                        ( 
                            String.IsNullOrEmpty(UnsafeGetUsername(credential)) &&
                            String.IsNullOrEmpty(UnsafeGetDomain(credential)) && 
                            String.IsNullOrEmpty(UnsafeGetPassword(credential))
                        );
            }
 
            /// 
            ///  Critical - Uses unsafe critical method UnsafeGetDefaultNetworkCredentials to access the default network credentials without a Demand 
            ///  Safe - only uses the default credentials to test for equality and uses the system credential's .Equals, not the caller's. 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            static internal bool IsDefault(NetworkCredential credential)
            {
                return UnsafeGetDefaultNetworkCredentials().Equals(credential);
            } 

            ///  
            ///  Critical - Asserts SecurityPermission(UnmanagedCode) in order to get the NetworkCredential password 
            ///             this is used for example to test for empty/null or to construct a cloned NetworkCredential.
            ///             callers absolutely must not leak the return value 
            /// 
            [SecurityCritical]
            [EnvironmentPermission(SecurityAction.Assert, Read = "USERNAME")]
            static internal string UnsafeGetUsername(NetworkCredential credential) 
            {
                return credential.UserName; 
            } 

            ///  
            ///  Critical - Asserts SecurityPermission(UnmanagedCode) in order to get the NetworkCredential password
            ///             this is used for example to test for empty/null or to construct a cloned NetworkCredential.
            ///             callers absolutely must not leak the return value
            ///  
            [SecurityCritical]
            [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)] 
            static internal string UnsafeGetPassword(NetworkCredential credential) 
            {
                return credential.Password; 
            }

            /// 
            ///  Critical - Asserts SecurityPermission(UnmanagedCode) in order to get the NetworkCredential password 
            ///             this is used for example to test for empty/null or to construct a cloned NetworkCredential.
            ///             callers absolutely must not leak the return value 
            ///  
            [SecurityCritical]
            [EnvironmentPermission(SecurityAction.Assert, Read = "USERDOMAIN")] 
            static internal string UnsafeGetDomain(NetworkCredential credential)
            {
                return credential.Domain;
            } 

            ///  
            ///  Critical - Asserts EnvironmentPermission(Read="USERNAME") in order to get the DefaultNetworkCredentials in PT 
            ///             this is used for example to test for instance equality with a specific NetworkCredential
            ///             callers absolutely must not leak the return value 
            /// 
            [SecurityCritical]
            [EnvironmentPermission(SecurityAction.Assert, Read = "USERNAME")]
            static NetworkCredential UnsafeGetDefaultNetworkCredentials() 
            {
                return CredentialCache.DefaultNetworkCredentials; 
            } 
        }
 
        internal static SafeFreeCredentials GetCredentialsHandle(string package, NetworkCredential credential, bool isServer, params string[] additionalPackages)
        {
            SafeFreeCredentials credentialsHandle;
            CredentialUse credentialUse = isServer ? CredentialUse.Inbound : CredentialUse.Outbound; 
            if (credential == null || NetworkCredentialHelper.IsDefault(credential))
            { 
                AuthIdentityEx authIdentity = new AuthIdentityEx(null, null, null, additionalPackages); 
                credentialsHandle = SspiWrapper.AcquireCredentialsHandle(package, credentialUse, ref authIdentity);
            } 
            else
            {
                SecurityUtils.FixNetworkCredential(ref credential);
 
                // we're not using DefaultCredentials, we need a
                // AuthIdentity struct to contain credentials 
                AuthIdentityEx authIdentity = new AuthIdentityEx(credential.UserName, credential.Password, credential.Domain); 
                credentialsHandle = SspiWrapper.AcquireCredentialsHandle(package, credentialUse, ref authIdentity);
            } 
            return credentialsHandle;
        }

        internal static SafeFreeCredentials GetCredentialsHandle(Binding binding, KeyedByTypeCollection behaviors) 
        {
            ClientCredentials clientCredentials = (behaviors == null) ? null : behaviors.Find(); 
            return GetCredentialsHandle(binding, clientCredentials); 
        }
 
        internal static SafeFreeCredentials GetCredentialsHandle(Binding binding, ClientCredentials clientCredentials)
        {
            SecurityBindingElement sbe = (binding == null) ? null : binding.CreateBindingElements().Find();
            return GetCredentialsHandle(sbe, clientCredentials); 
        }
 
        internal static SafeFreeCredentials GetCredentialsHandle(SecurityBindingElement sbe, BindingContext context) 
        {
            ClientCredentials clientCredentials = (context == null) ? null : context.BindingParameters.Find(); 
            return GetCredentialsHandle(sbe, clientCredentials);
        }

        internal static SafeFreeCredentials GetCredentialsHandle(SecurityBindingElement sbe, ClientCredentials clientCredentials) 
        {
            if (sbe == null) 
            { 
                return null;
            } 

            bool isSspi = false;
            bool isKerberos = false;
            foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(sbe, true)) 
            {
                if (stp is SecureConversationSecurityTokenParameters) 
                { 
                    SafeFreeCredentials result = GetCredentialsHandle(((SecureConversationSecurityTokenParameters)stp).BootstrapSecurityBindingElement, clientCredentials);
                    if (result != null) 
                    {
                        return result;
                    }
                    continue; 
                }
                else if (stp is IssuedSecurityTokenParameters) 
                { 
                    SafeFreeCredentials result = GetCredentialsHandle(((IssuedSecurityTokenParameters)stp).IssuerBinding, clientCredentials);
                    if (result != null) 
                    {
                        return result;
                    }
                    continue; 
                }
                else if (stp is SspiSecurityTokenParameters) 
                { 
                    isSspi = true;
                    break; 
                }
                else if (stp is KerberosSecurityTokenParameters)
                {
                    isKerberos = true; 
                    break;
                } 
            } 
            if (!isSspi && !isKerberos)
            { 
                return null;
            }

            NetworkCredential credential = null; 
            if (clientCredentials != null)
            { 
                credential = SecurityUtils.GetNetworkCredentialOrDefault(clientCredentials.Windows.ClientCredential); 
            }
 
            if (isKerberos)
            {
                return SecurityUtils.GetCredentialsHandle("Kerberos", credential, false);
            } 
            // if OS is less that Vista cannot use !NTLM, Windows SE 142400
            else if (clientCredentials != null && !clientCredentials.Windows.AllowNtlm ) 
            { 
                if ( SecurityUtils.IsOsGreaterThanXP() )
                { 
                    return SecurityUtils.GetCredentialsHandle("Negotiate", credential, false, "!NTLM");
                }
                else
                { 
                    return SecurityUtils.GetCredentialsHandle("Kerberos", credential, false);
                } 
            } 
            return SecurityUtils.GetCredentialsHandle("Negotiate", credential, false);
        } 

        internal static byte[] CloneBuffer(byte[] buffer)
        {
            byte[] copy = DiagnosticUtility.Utility.AllocateByteArray(buffer.Length); 
            Buffer.BlockCopy(buffer, 0, copy, 0, buffer.Length);
            return copy; 
        } 

        internal static X509Certificate2 GetCertificateFromStore(StoreName storeName, StoreLocation storeLocation, 
            X509FindType findType, object findValue, EndpointAddress target)
        {
            X509Certificate2 certificate = GetCertificateFromStoreCore(storeName, storeLocation, findType, findValue, target, true);
            if (certificate == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CannotFindCert, storeName, storeLocation, findType, findValue)));
 
            return certificate; 
        }
 
        internal static bool TryGetCertificateFromStore(StoreName storeName, StoreLocation storeLocation,
            X509FindType findType, object findValue, EndpointAddress target, out X509Certificate2 certificate)
        {
            certificate = GetCertificateFromStoreCore(storeName, storeLocation, findType, findValue, target, false); 
            return (certificate != null);
        } 
 
        static X509Certificate2 GetCertificateFromStoreCore(StoreName storeName, StoreLocation storeLocation,
            X509FindType findType, object findValue, EndpointAddress target, bool throwIfMultipleOrNoMatch) 
        {
            if (findValue == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("findValue"); 
            }
            X509CertificateStore store = new X509CertificateStore(storeName, storeLocation); 
            X509Certificate2Collection certs = null; 
            try
            { 
                store.Open(OpenFlags.ReadOnly);
                certs = store.Find(findType, findValue, false);
                if (certs.Count == 1)
                { 
                    return new X509Certificate2(certs[0]);
                } 
                if (throwIfMultipleOrNoMatch) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateCertificateLoadException( 
                        storeName, storeLocation, findType, findValue, target, certs.Count));
                }
                else
                { 
                    return null;
                } 
            } 
            finally
            { 
                SecurityUtils.ResetAllCertificates(certs);
                store.Close();
            }
        } 

        static Exception CreateCertificateLoadException(StoreName storeName, StoreLocation storeLocation, 
            X509FindType findType, object findValue, EndpointAddress target, int certCount) 
        {
            if (certCount == 0) 
            {
                if (target == null)
                {
                    return new InvalidOperationException(SR.GetString(SR.CannotFindCert, storeName, storeLocation, findType, findValue)); 
                }
                else 
                { 
                    return new InvalidOperationException(SR.GetString(SR.CannotFindCertForTarget, storeName, storeLocation, findType, findValue, target));
                } 
            }
            else
            {
                if (target == null) 
                {
                    return new InvalidOperationException(SR.GetString(SR.FoundMultipleCerts, storeName, storeLocation, findType, findValue)); 
                } 
                else
                { 
                    return new InvalidOperationException(SR.GetString(SR.FoundMultipleCertsForTarget, storeName, storeLocation, findType, findValue, target));
                }
            }
        } 

        public static SecurityBindingElement GetIssuerSecurityBindingElement(ServiceModelSecurityTokenRequirement requirement) 
        { 
            SecurityBindingElement bindingElement = requirement.SecureConversationSecurityBindingElement;
            if (bindingElement != null) 
            {
                return bindingElement;
            }
 
            Binding binding = requirement.IssuerBinding;
            if (binding == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.IssuerBindingNotPresentInTokenRequirement, requirement));
            } 
            BindingElementCollection bindingElements = binding.CreateBindingElements();
            return bindingElements.Find();
        }
 
        public static int GetMaxNegotiationBufferSize(BindingContext bindingContext)
        { 
            TransportBindingElement transport = bindingContext.RemainingBindingElements.Find(); 
            DiagnosticUtility.DebugAssert(transport != null, "TransportBindingElement is null!");
            int maxNegoMessageSize; 
            if (transport is ConnectionOrientedTransportBindingElement)
            {
                maxNegoMessageSize = ((ConnectionOrientedTransportBindingElement)transport).MaxBufferSize;
            } 
            else if (transport is HttpTransportBindingElement)
            { 
                maxNegoMessageSize = ((HttpTransportBindingElement)transport).MaxBufferSize; 
            }
            else 
            {
                maxNegoMessageSize = TransportDefaults.MaxBufferSize;
            }
            return maxNegoMessageSize; 
        }
 
        public static bool TryCreateKeyFromIntrinsicKeyClause(SecurityKeyIdentifierClause keyIdentifierClause, SecurityTokenResolver resolver, out SecurityKey key) 
        {
            key = null; 
            if (keyIdentifierClause.CanCreateKey)
            {
                key = keyIdentifierClause.CreateKey();
                return true; 
            }
            if (keyIdentifierClause is EncryptedKeyIdentifierClause) 
            { 
                EncryptedKeyIdentifierClause keyClause = (EncryptedKeyIdentifierClause)keyIdentifierClause;
                // PreSharp Bug: Parameter 'keyClause' to this public method must be validated: A null-dereference can occur here. 
#pragma warning suppress 56506 // keyClause will not be null due to the if condition above.
                for (int i = 0; i < keyClause.EncryptingKeyIdentifier.Count; i++)
                {
                    SecurityKey unwrappingSecurityKey = null; 
                    if (resolver.TryResolveSecurityKey(keyClause.EncryptingKeyIdentifier[i], out unwrappingSecurityKey))
                    { 
                        byte[] wrappedKey = keyClause.GetEncryptedKey(); 
                        string wrappingAlgorithm = keyClause.EncryptionMethod;
                        byte[] unwrappedKey = unwrappingSecurityKey.DecryptKey(wrappingAlgorithm, wrappedKey); 
                        key = new InMemorySymmetricSecurityKey(unwrappedKey, false);
                        return true;
                    }
                } 
            }
            return false; 
        } 

        public static WrappedKeySecurityToken CreateTokenFromEncryptedKeyClause(EncryptedKeyIdentifierClause keyClause, SecurityToken unwrappingToken) 
        {
            SecurityKeyIdentifier wrappingTokenReference = keyClause.EncryptingKeyIdentifier;
            byte[] wrappedKey = keyClause.GetEncryptedKey();
            SecurityKey unwrappingSecurityKey = unwrappingToken.SecurityKeys[0]; 
            string wrappingAlgorithm = keyClause.EncryptionMethod;
            byte[] unwrappedKey = unwrappingSecurityKey.DecryptKey(wrappingAlgorithm, wrappedKey); 
            return new WrappedKeySecurityToken(SecurityUtils.GenerateId(), unwrappedKey, wrappingAlgorithm, 
                unwrappingToken, wrappingTokenReference, wrappedKey, unwrappingSecurityKey
                    ); 
        }

        public static void ValidateAnonymityConstraint(WindowsIdentity identity, bool allowUnauthenticatedCallers)
        { 
            if (!allowUnauthenticatedCallers && identity.User.IsWellKnown(WellKnownSidType.AnonymousSid))
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning( 
                    new SecurityTokenValidationException(SR.GetString(SR.AnonymousLogonsAreNotAllowed)));
            } 
        }

        static bool ComputeSslCipherStrengthRequirementFlag()
        { 
            // validate only for  XP versions < XP SP3 and windows server versions < Win2K3 SP2
            if ((Environment.OSVersion.Version.Major > WindowsServerMajorNumber) 
                || (Environment.OSVersion.Version.Major == WindowsServerMajorNumber && Environment.OSVersion.Version.Minor > WindowsServerMinorNumber)) 
            {
                return false; 
            }
            // version <= Win2K3
            if (Environment.OSVersion.Version.Major == XPMajorNumber && Environment.OSVersion.Version.Minor == XPMinorNumber)
            { 
                if ((Environment.OSVersion.ServicePack == string.Empty) || String.Equals(Environment.OSVersion.ServicePack, ServicePack1, StringComparison.OrdinalIgnoreCase) || String.Equals(Environment.OSVersion.ServicePack, ServicePack2, StringComparison.OrdinalIgnoreCase))
                { 
                    return true; 
                }
                else 
                {
                    // the OS is XP SP3 or higher
                    return false;
                } 
            }
            else if (Environment.OSVersion.Version.Major == WindowsServerMajorNumber && Environment.OSVersion.Version.Minor == WindowsServerMinorNumber) 
            { 
                if (Environment.OSVersion.ServicePack == string.Empty || String.Equals(Environment.OSVersion.ServicePack, ServicePack1, StringComparison.OrdinalIgnoreCase))
                { 
                    return true;
                }
                else
                { 
                    // the OS is Win2K3 SP2 or higher
                    return false; 
                } 
            }
            else 
            {
                // this is <= XP. We should never get here but if we do validate SSL strength
                return true;
            } 
        }
 
        public static bool ShouldValidateSslCipherStrength() 
        {
            if (!isSslValidationRequirementDetermined) 
            {
                shouldValidateSslCipherStrength = ComputeSslCipherStrengthRequirementFlag();
                Thread.MemoryBarrier();
                isSslValidationRequirementDetermined = true; 
            }
            return shouldValidateSslCipherStrength; 
        } 

        public static void ValidateSslCipherStrength(int keySizeInBits) 
        {
            if (ShouldValidateSslCipherStrength() && keySizeInBits < MinimumSslCipherStrength)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.SslCipherKeyTooSmall, keySizeInBits, MinimumSslCipherStrength))); 
            }
        } 
 
        public static bool TryCreateX509CertificateFromRawData(byte[] rawData, out X509Certificate2 certificate)
        { 
            certificate = (rawData == null || rawData.Length == 0) ? null : new X509Certificate2(rawData);
            return certificate != null && certificate.Handle != IntPtr.Zero;
        }
 
        internal static string GetKeyDerivationAlgorithm(SecureConversationVersion version)
        { 
            string derivationAlgorithm = null; 
            if (version == SecureConversationVersion.WSSecureConversationFeb2005)
            { 
                derivationAlgorithm = SecurityAlgorithms.Psha1KeyDerivation;
            }
            else if (version == SecureConversationVersion.WSSecureConversation13)
            { 
                derivationAlgorithm = SecurityAlgorithms.Psha1KeyDerivationDec2005;
            } 
            else 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
            }

            return derivationAlgorithm;
        } 

    } 
 
    struct SecurityUniqueId
    { 
        static long nextId = 0;
        static string commonPrefix = "uuid-" + Guid.NewGuid().ToString() + "-";

        long id; 
        string prefix;
        string val; 
 
        SecurityUniqueId(string prefix, long id)
        { 
            this.id = id;
            this.prefix = prefix;
            this.val = null;
        } 

        public static SecurityUniqueId Create() 
        { 
            return SecurityUniqueId.Create(commonPrefix);
        } 

        public static SecurityUniqueId Create(string prefix)
        {
            return new SecurityUniqueId(prefix, Interlocked.Increment(ref nextId)); 
        }
 
        public string Value 
        {
            get 
            {
                if (this.val == null)
                    this.val = this.prefix + this.id.ToString(CultureInfo.InvariantCulture);
 
                return this.val;
            } 
        } 
    }
 
    static class EmptyReadOnlyCollection
    {
        public static ReadOnlyCollection Instance = new ReadOnlyCollection(new List());
    } 

    class OperationWithTimeoutAsyncResult : TraceAsyncResult 
    { 
        static readonly WaitCallback scheduledCallback = new WaitCallback(OnScheduled);
        TimeoutHelper timeoutHelper; 
        OperationWithTimeoutCallback operationWithTimeout;

        public OperationWithTimeoutAsyncResult(OperationWithTimeoutCallback operationWithTimeout, TimeSpan timeout, AsyncCallback callback, object state)
            : base(callback, state) 
        {
            this.operationWithTimeout = operationWithTimeout; 
            this.timeoutHelper = new TimeoutHelper(timeout); 
            IOThreadScheduler.ScheduleCallback(scheduledCallback, this);
        } 

        static void OnScheduled(object state)
        {
            OperationWithTimeoutAsyncResult thisResult = (OperationWithTimeoutAsyncResult)state; 
            Exception completionException = null;
            try 
            { 
                using (thisResult.CallbackActivity == null ? null : ServiceModelActivity.BoundOperation(thisResult.CallbackActivity))
                { 
                    thisResult.operationWithTimeout(thisResult.timeoutHelper.RemainingTime());
                }
            }
#pragma warning suppress 56500 // covered by FxCOP 
            catch (Exception e)
            { 
                if (Diagnostics.ExceptionUtility.IsFatal(e)) 
                    throw;
 
                completionException = e;
            }
            thisResult.Complete(false, completionException);
        } 

        public static void End(IAsyncResult result) 
        { 
            AsyncResult.End(result);
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK