Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / Configuration / MachineKeySection.cs / 1586730 / MachineKeySection.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.Configuration { using System; using System.Xml; using System.Configuration; using System.Collections.Specialized; using System.Collections; using System.IO; using System.Text; using System.Security.Cryptography; using System.Web.Util; using System.Globalization; using System.Web.Hosting; using System.Runtime.InteropServices; using System.ComponentModel; using System.Security.Permissions; /**/ public sealed class MachineKeySection : ConfigurationSection { // If the default validation algorithm changes, be sure to update the _HashSize and _AutoGenValidationKeySize fields also. internal const string DefaultValidationAlgorithm = "HMACSHA256"; internal const MachineKeyValidation DefaultValidation = MachineKeyValidation.SHA1; private static ConfigurationPropertyCollection _properties; private static readonly ConfigurationProperty _propValidationKey = new ConfigurationProperty("validationKey", typeof(string), "AutoGenerate,IsolateApps", StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propDecryptionKey = new ConfigurationProperty("decryptionKey", typeof(string),"AutoGenerate,IsolateApps",StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propDecryption = new ConfigurationProperty("decryption", typeof(string), "Auto", StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propValidation = new ConfigurationProperty("validation", typeof(string), DefaultValidationAlgorithm, StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propCompatibilityMode = new ConfigurationProperty("compatibilityMode", typeof(MachineKeyCompatibilityMode), MachineKeyCompatibilityMode.Framework20SP1, null, null, ConfigurationPropertyOptions.None); static object s_initLock = new object(); static MachineKeySection s_config; static MachineKeyCompatibilityMode s_compatMode; private static RNGCryptoServiceProvider s_randomNumberGenerator; private static SymmetricAlgorithm s_oSymAlgoDecryption; private static SymmetricAlgorithm s_oSymAlgoValidation; private static byte[] s_validationKey; private static byte[] s_inner = null; private static byte[] s_outer = null; internal static bool IsDecryptionKeyAutogenerated { get { EnsureConfig(); return s_config.AutogenKey; } } private bool _AutogenKey; internal bool AutogenKey { get { RuntimeDataInitialize(); return _AutogenKey; } } private byte[] _ValidationKey; private byte[] _DecryptionKey; private bool DataInitialized = false; private static bool _CustomValidationTypeIsKeyed; private static string _CustomValidationName; private static int _IVLengthDecryption = 64; private static int _IVLengthValidation = 64; private static int _HashSize = HMACSHA256_HASH_SIZE; private static int _AutoGenValidationKeySize = HMACSHA256_KEY_SIZE; private static int _AutoGenDecryptionKeySize = 24; private static bool _UseHMACSHA = true; private static bool _UsingCustomEncryption = false; private static SymmetricAlgorithm s_oSymAlgoLegacy; private const int MD5_KEY_SIZE = 64; private const int MD5_HASH_SIZE = 16; private const int SHA1_KEY_SIZE = 64; private const int HMACSHA256_KEY_SIZE = 64; private const int HMACSHA384_KEY_SIZE = 128; private const int HMACSHA512_KEY_SIZE = 128; private const int SHA1_HASH_SIZE = 20; private const int HMACSHA256_HASH_SIZE = 32; private const int HMACSHA384_HASH_SIZE = 48; private const int HMACSHA512_HASH_SIZE = 64; private const string ALGO_PREFIX = "alg:"; internal byte[] ValidationKeyInternal { get { RuntimeDataInitialize(); return (byte[])_ValidationKey.Clone(); } } internal byte[] DecryptionKeyInternal { get { RuntimeDataInitialize(); return (byte[])_DecryptionKey.Clone(); } } internal static int HashSize { get { s_config.RuntimeDataInitialize(); return _HashSize; } } internal static int ValidationKeySize { get { s_config.RuntimeDataInitialize(); return _AutoGenValidationKeySize; } } static MachineKeySection() { // Property initialization _properties = new ConfigurationPropertyCollection(); _properties.Add(_propValidationKey); _properties.Add(_propDecryptionKey); _properties.Add(_propValidation); _properties.Add(_propDecryption); _properties.Add(_propCompatibilityMode); } public MachineKeySection() { } internal static MachineKeyCompatibilityMode CompatMode { get { EnsureConfig(); return s_compatMode; } } protected override ConfigurationPropertyCollection Properties { get { return _properties; } } [ConfigurationProperty("validationKey", DefaultValue = "AutoGenerate,IsolateApps")] [TypeConverter(typeof(WhiteSpaceTrimStringConverter))] [StringValidator(MinLength = 1)] public string ValidationKey { get { return (string)base[_propValidationKey]; } set { base[_propValidationKey] = value; } } [ConfigurationProperty("decryptionKey", DefaultValue = "AutoGenerate,IsolateApps")] [TypeConverter(typeof(WhiteSpaceTrimStringConverter))] [StringValidator(MinLength = 1)] public string DecryptionKey { get { return (string)base[_propDecryptionKey]; } set { base[_propDecryptionKey] = value; } } [ConfigurationProperty("decryption", DefaultValue = "Auto")] [TypeConverter(typeof(WhiteSpaceTrimStringConverter))] [StringValidator(MinLength = 1)] public string Decryption { get { string s = base[_propDecryption] as string; if (s == null) return "Auto"; if (s != "Auto" && s != "AES" && s != "3DES" && s != "DES" && !s.StartsWith(ALGO_PREFIX, StringComparison.Ordinal)) throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); return s; } set { if (value != "AES" && value != "3DES" && value != "Auto" && value != "DES" && !value.StartsWith(ALGO_PREFIX, StringComparison.Ordinal)) throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); base[_propDecryption] = value; } } private bool _validationIsCached; private string _cachedValidation; private MachineKeyValidation _cachedValidationEnum; [ConfigurationProperty("validation", DefaultValue = DefaultValidationAlgorithm)] [TypeConverter(typeof(WhiteSpaceTrimStringConverter))] [StringValidator(MinLength = 1)] public string ValidationAlgorithm { get { if (!_validationIsCached) CacheValidation(); return _cachedValidation; } set { if (_validationIsCached && value == _cachedValidation) return; if (value == null) value = DefaultValidationAlgorithm; _cachedValidationEnum = MachineKeyValidationConverter.ConvertToEnum(value); _cachedValidation = value; base[_propValidation] = value; _validationIsCached = true; } } private void CacheValidation() { _cachedValidation = (string)base[_propValidation]; if (_cachedValidation == null) _cachedValidation = DefaultValidationAlgorithm; _cachedValidationEnum = MachineKeyValidationConverter.ConvertToEnum(_cachedValidation); _validationIsCached = true; } public MachineKeyValidation Validation { get { if (_validationIsCached == false) CacheValidation(); return _cachedValidationEnum; } set { if (_validationIsCached && value == _cachedValidationEnum) return; _cachedValidation = MachineKeyValidationConverter.ConvertFromEnum(value); _cachedValidationEnum = value; base[_propValidation] = _cachedValidation; _validationIsCached = true; } } [ConfigurationProperty("compatibilityMode", DefaultValue = MachineKeyCompatibilityMode.Framework20SP1)] public MachineKeyCompatibilityMode CompatibilityMode { get { return (MachineKeyCompatibilityMode)base[_propCompatibilityMode]; } set { base[_propCompatibilityMode] = value; } } protected override void Reset(ConfigurationElement parentElement) { MachineKeySection parent = parentElement as MachineKeySection; base.Reset(parentElement); // copy the privates from the parent. if (parent != null) { // _ValidationKey = parent.ValidationKeyInternal; // _DecryptionKey = parent.DecryptionKeyInternal; // _AutogenKey = parent.AutogenKey; } } private void RuntimeDataInitialize() { if (DataInitialized == false) { byte [] bKeysRandom = null; bool fNonHttpApp = false; string strKey = ValidationKey; string appName = HttpRuntime.AppDomainAppVirtualPath; InitValidationAndEncyptionSizes(); if( appName == null ) { #if !FEATURE_PAL // FEATURE_PAL does not enable cryptography // FEATURE_PAL appName = System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName; if( ValidationKey.Contains( "AutoGenerate" ) || DecryptionKey.Contains( "AutoGenerate" ) ) { fNonHttpApp = true; bKeysRandom = new byte[ _AutoGenValidationKeySize + _AutoGenDecryptionKeySize ]; // Gernerate random keys RandomNumberGenerator.GetBytes(bKeysRandom); } #endif // !FEATURE_PAL } bool fAppSpecific = StringUtil.StringEndsWith(strKey, ",IsolateApps"); if (fAppSpecific) { strKey = strKey.Substring(0, strKey.Length - ",IsolateApps".Length); } if (strKey == "AutoGenerate") { // case sensitive _ValidationKey = new byte[_AutoGenValidationKeySize]; if( fNonHttpApp ) { Buffer.BlockCopy( bKeysRandom, 0, _ValidationKey, 0, _AutoGenValidationKeySize); } else { Buffer.BlockCopy(HttpRuntime.s_autogenKeys, 0, _ValidationKey, 0, _AutoGenValidationKeySize); } } else { if (strKey.Length < 40 || (strKey.Length & 0x1) == 1) throw new ConfigurationErrorsException(SR.GetString(SR.Unable_to_get_cookie_authentication_validation_key, strKey.Length.ToString(CultureInfo.InvariantCulture)), ElementInformation.Properties["validationKey"].Source, ElementInformation.Properties["validationKey"].LineNumber); _ValidationKey = HexStringToByteArray(strKey); if (_ValidationKey == null) throw new ConfigurationErrorsException(SR.GetString(SR.Invalid_validation_key), ElementInformation.Properties["validationKey"].Source, ElementInformation.Properties["validationKey"].LineNumber); } if (fAppSpecific) { int dwCode = StringComparer.InvariantCultureIgnoreCase.GetHashCode( appName ); _ValidationKey[0] = (byte)(dwCode & 0xff); _ValidationKey[1] = (byte)((dwCode & 0xff00) >> 8); _ValidationKey[2] = (byte)((dwCode & 0xff0000) >> 16); _ValidationKey[3] = (byte)((dwCode & 0xff000000) >> 24); } strKey = DecryptionKey; fAppSpecific = StringUtil.StringEndsWith(strKey, ",IsolateApps"); if (fAppSpecific) { strKey = strKey.Substring(0, strKey.Length - ",IsolateApps".Length); } if (strKey == "AutoGenerate") { // case sensitive _DecryptionKey = new byte[_AutoGenDecryptionKeySize]; if( fNonHttpApp ) { Buffer.BlockCopy( bKeysRandom, _AutoGenValidationKeySize, _DecryptionKey, 0, _AutoGenDecryptionKeySize); } else { Buffer.BlockCopy(HttpRuntime.s_autogenKeys, _AutoGenValidationKeySize, _DecryptionKey, 0, _AutoGenDecryptionKeySize); } _AutogenKey = true; } else { _AutogenKey = false; if ((strKey.Length & 1) != 0) throw new ConfigurationErrorsException(SR.GetString(SR.Invalid_decryption_key), ElementInformation.Properties["decryptionKey"].Source, ElementInformation.Properties["decryptionKey"].LineNumber); _DecryptionKey = HexStringToByteArray(strKey); if (_DecryptionKey == null) throw new ConfigurationErrorsException(SR.GetString(SR.Invalid_decryption_key), ElementInformation.Properties["decryptionKey"].Source, ElementInformation.Properties["decryptionKey"].LineNumber); } if (fAppSpecific) { int dwCode = StringComparer.InvariantCultureIgnoreCase.GetHashCode(appName); _DecryptionKey[0] = (byte)(dwCode & 0xff); _DecryptionKey[1] = (byte)((dwCode & 0xff00) >> 8); _DecryptionKey[2] = (byte)((dwCode & 0xff0000) >> 16); _DecryptionKey[3] = (byte)((dwCode & 0xff000000) >> 24); } DataInitialized = true; } } internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length) { // DevDiv Bugs 137864: IVType.Hash is the default for compatibility reasons. It allows the result to be // consistent across multiple calls with the same data. This was the behavior when there was no padding. return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, false, false, IVType.Hash); } internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo) { // DevDiv Bugs 137864: IVType.Hash is the default for compatibility reasons. It allows the result to be // consistent across multiple calls with the same data. This was the behavior when there was no padding. return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, false, IVType.Hash); } internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType) { EnsureConfig(); if (useLegacyMode) useLegacyMode = _UsingCustomEncryption; // only use legacy mode for custom algorithms System.IO.MemoryStream ms = new System.IO.MemoryStream(); ICryptoTransform oDesEnc = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode); CryptoStream cs = new CryptoStream(ms, oDesEnc, CryptoStreamMode.Write); // DevDiv Bugs 137864: Add Random or Hashed IV to beginning of data to be encrypted. // IVType.None is used by MembershipProvider which requires compatibility even in SP2 mode. bool createIV = ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1)); if (fEncrypt && createIV) { byte[] iv = null; int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); switch (ivType) { case IVType.Hash: iv = GetIVHash(buf, ivLength); break; case IVType.Random: iv = new byte[ivLength]; RandomNumberGenerator.GetBytes(iv); break; } Debug.Assert(iv != null, "Invalid value for IVType: " + ivType.ToString("G")); cs.Write(iv, 0, iv.Length); } cs.Write(buf, start, length); if (fEncrypt && modifier != null) { cs.Write(modifier, 0, modifier.Length); } cs.FlushFinalBlock(); byte[] paddedData = ms.ToArray(); byte[] bData; cs.Close(); ReturnCryptoTransform(fEncrypt, oDesEnc, useValidationSymAlgo, useLegacyMode); // DevDiv Bugs 137864: Strip Random or Hashed IV from beginning of unencrypted data if (!fEncrypt && createIV) { // strip off the first bytes that were either random bits or a hash of the original data // either way it is always equal to the key length int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); int bDataLength = paddedData.Length - ivLength; // valid if the data is long enough to have included the padding if (bDataLength >= 0) { bData = new byte[bDataLength]; // copy from the padded data to non-padded buffer bData. // dont bother with copy if the data is entirely the padding if (bDataLength > 0) { Buffer.BlockCopy(paddedData, ivLength, bData, 0, bDataLength); } } else { // data is not padded because it is not long enough bData = paddedData; } } else { bData = paddedData; } if (!fEncrypt && modifier != null && modifier.Length > 0) { for(int iter=0; iter _AutoGenValidationKeySize) { key = new byte[_HashSize]; int hr = UnsafeNativeMethods.GetSHA1Hash(validationKey, validationKey.Length, key, key.Length); Marshal.ThrowExceptionForHR(hr); } if (inner == null) inner = new byte[_AutoGenValidationKeySize]; if (outer == null) outer = new byte[_AutoGenValidationKeySize]; int i; for (i = 0; i < _AutoGenValidationKeySize; i++) { inner[i] = 0x36; outer[i] = 0x5C; } for (i=0; i < validationKey.Length; i++) { inner[i] ^= validationKey[i]; outer[i] ^= validationKey[i]; } } private static byte[] GetHMACSHA1Hash(byte[] buf, byte[] modifier, int start, int length) { if (start < 0 || start > buf.Length) throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "start")); if (length < 0 || buf == null || (start + length) > buf.Length) throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "length")); byte[] hash = new byte[_HashSize]; int hr = UnsafeNativeMethods.GetHMACSHA1Hash(buf, start, length, modifier, (modifier == null) ? 0 : modifier.Length, s_inner, s_inner.Length, s_outer, s_outer.Length, hash, hash.Length); if (hr == 0) return hash; _UseHMACSHA = false; return null; } internal static string HashAndBase64EncodeString(string s) { byte[] ab; byte[] hash; string result; ab = Encoding.Unicode.GetBytes(s); hash = HashData(ab, null, 0, ab.Length); result = Convert.ToBase64String(hash); return result; } static internal void DestroyByteArray(byte[] buf) { if (buf == null || buf.Length < 1) return; for (int iter = 0; iter < buf.Length; iter++) buf[iter] = (byte)0; } internal void DestroyKeys() { MachineKeySection.DestroyByteArray(_ValidationKey); MachineKeySection.DestroyByteArray(_DecryptionKey); } static char[] s_acharval; static unsafe internal String ByteArrayToHexString(byte[] buf, int iLen) { char[] acharval = s_acharval; if (acharval == null) { acharval = new char[16]; for (int i = acharval.Length; --i >= 0; ) { if (i < 10) { acharval[i] = (char)('0' + i); } else { acharval[i] = (char)('A' + (i - 10)); } } s_acharval = acharval; } if (buf == null) return null; if (iLen == 0) iLen = buf.Length; char[] chars = new char[iLen * 2]; fixed (char* fc = chars, fcharval = acharval) { fixed (byte* fb = buf) { char* pc; byte* pb; pc = fc; pb = fb; while (--iLen >= 0) { *pc++ = fcharval[(*pb & 0xf0) >> 4]; *pc++ = fcharval[*pb & 0x0f]; pb++; } } } return new String(chars); } static void EnsureConfig() { if (s_config == null) { lock (s_initLock) { if (s_config == null) { MachineKeySection config = RuntimeConfig.GetAppConfig().MachineKey; config.ConfigureEncryptionObject(); s_config = config; s_compatMode = config.CompatibilityMode; } } } } // NOTE: When encoding the data, this method *may* return the same reference to the input "buf" parameter // with the hash appended in the end if there's enough space. The "length" parameter would also be // appropriately adjusted in those cases. This is an optimization to prevent unnecessary copying of // buffers. internal static byte[] GetEncodedData(byte[] buf, byte[] modifier, int start, ref int length) { EnsureConfig(); byte[] bHash = HashData(buf, modifier, start, length); byte[] returnBuffer; if (buf.Length - start - length >= bHash.Length) { // Append hash to end of buffer if there's space Buffer.BlockCopy(bHash, 0, buf, start + length, bHash.Length); returnBuffer = buf; } else { returnBuffer = new byte[length + bHash.Length]; Buffer.BlockCopy(buf, start, returnBuffer, 0, length); Buffer.BlockCopy(bHash, 0, returnBuffer, length, bHash.Length); start = 0; } length += bHash.Length; if (s_config.Validation == MachineKeyValidation.TripleDES || s_config.Validation == MachineKeyValidation.AES) { returnBuffer = EncryptOrDecryptData(true, returnBuffer, modifier, start, length, true); length = returnBuffer.Length; } return returnBuffer; } // NOTE: When decoding the data, this method *may* return the same reference to the input "buf" parameter // with the "dataLength" parameter containing the actual length of the data in the "buf" (i.e. length of actual // data is (total length of data - hash length)). This is an optimization to prevent unnecessary copying of buffers. internal static byte[] GetDecodedData(byte[] buf, byte[] modifier, int start, int length, ref int dataLength) { EnsureConfig(); if (s_config.Validation == MachineKeyValidation.TripleDES || s_config.Validation == MachineKeyValidation.AES) { buf = EncryptOrDecryptData(false, buf, modifier, start, length, true); if (buf == null || buf.Length < _HashSize) throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); length = buf.Length; start = 0; } if (length < _HashSize || start < 0 || start >= length) throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); byte[] bHash = HashData(buf, modifier, start, length - _HashSize); for (int iter = 0; iter < bHash.Length; iter++) if (bHash[iter] != buf[start + length - _HashSize + iter]) throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); dataLength = length - _HashSize; return buf; } internal static byte[] HashData(byte[] buf, byte[] modifier, int start, int length) { EnsureConfig(); if (s_config.Validation == MachineKeyValidation.MD5) return HashDataUsingNonKeyedAlgorithm(null, buf, modifier, start, length, s_validationKey); if (_UseHMACSHA) { byte [] hash = GetHMACSHA1Hash(buf, modifier, start, length); if (hash != null) return hash; } if (_CustomValidationTypeIsKeyed) { return HashDataUsingKeyedAlgorithm(KeyedHashAlgorithm.Create(_CustomValidationName), buf, modifier, start, length, s_validationKey); } else { return HashDataUsingNonKeyedAlgorithm(HashAlgorithm.Create(_CustomValidationName), buf, modifier, start, length, s_validationKey); } } private void ConfigureEncryptionObject() { using (new ApplicationImpersonationContext()) { s_validationKey = ValidationKeyInternal; byte[] dKey = DecryptionKeyInternal; if (_UseHMACSHA) SetInnerOuterKeys(s_validationKey, ref s_inner, ref s_outer); DestroyKeys(); switch (Decryption) { case "3DES": s_oSymAlgoDecryption = new TripleDESCryptoServiceProvider(); break; case "DES": s_oSymAlgoDecryption = new DESCryptoServiceProvider(); break; case "AES": s_oSymAlgoDecryption = GetAESAlgorithm(); break; case "Auto": if (dKey.Length == 8) { s_oSymAlgoDecryption = new DESCryptoServiceProvider(); } else { s_oSymAlgoDecryption = GetAESAlgorithm(); } break; } if (s_oSymAlgoDecryption == null) // Shouldn't happen! InitValidationAndEncyptionSizes(); switch(Validation) { case MachineKeyValidation.TripleDES: if (dKey.Length == 8) { s_oSymAlgoValidation = new DESCryptoServiceProvider(); } else { s_oSymAlgoValidation = new TripleDESCryptoServiceProvider(); } break; case MachineKeyValidation.AES: s_oSymAlgoValidation = GetAESAlgorithm(); break; } if (s_oSymAlgoValidation != null) { SetKeyOnSymAlgorithm(s_oSymAlgoValidation, dKey); _IVLengthValidation = RoundupNumBitsToNumBytes(s_oSymAlgoValidation.KeySize); } SetKeyOnSymAlgorithm(s_oSymAlgoDecryption, dKey); _IVLengthDecryption = RoundupNumBitsToNumBytes(s_oSymAlgoDecryption.KeySize); InitLegacyEncAlgorithm(dKey); DestroyByteArray(dKey); } } private void SetKeyOnSymAlgorithm(SymmetricAlgorithm symAlgo, byte[] dKey) { try { if (dKey.Length > 8 && symAlgo is DESCryptoServiceProvider) { byte[] bTemp = new byte[8]; Buffer.BlockCopy(dKey, 0, bTemp, 0, 8); symAlgo.Key = bTemp; DestroyByteArray(bTemp); } else { symAlgo.Key = dKey; } symAlgo.GenerateIV(); symAlgo.IV = new byte[symAlgo.IV.Length]; } catch (Exception e) { throw new ConfigurationErrorsException(SR.GetString(SR.Bad_machine_key, e.Message), ElementInformation.Properties["decryptionKey"].Source, ElementInformation.Properties["decryptionKey"].LineNumber); } } private static ICryptoTransform GetCryptoTransform(bool fEncrypt, bool useValidationSymAlgo, bool legacyMode) { SymmetricAlgorithm algo = (legacyMode ? s_oSymAlgoLegacy : (useValidationSymAlgo ? s_oSymAlgoValidation : s_oSymAlgoDecryption)); lock(algo) return (fEncrypt ? algo.CreateEncryptor() : algo.CreateDecryptor()); } private static void ReturnCryptoTransform(bool fEncrypt, ICryptoTransform ct, bool useValidationSymAlgo, bool legacyMode) { ct.Dispose(); } static byte[] s_ahexval; static internal byte[] HexStringToByteArray(String str) { if (((uint)str.Length & 0x1) == 0x1) // must be 2 nibbles per byte { return null; } byte[] ahexval = s_ahexval; // initialize a table for faster lookups if (ahexval == null) { ahexval = new byte['f' + 1]; for (int i = ahexval.Length; --i >= 0; ) { if ('0' <= i && i <= '9') { ahexval[i] = (byte)(i - '0'); } else if ('a' <= i && i <= 'f') { ahexval[i] = (byte)(i - 'a' + 10); } else if ('A' <= i && i <= 'F') { ahexval[i] = (byte)(i - 'A' + 10); } } s_ahexval = ahexval; } byte[] result = new byte[str.Length / 2]; int istr = 0, ir = 0; int n = result.Length; while (--n >= 0) { int c1, c2; try { c1 = ahexval[str[istr++]]; } catch (ArgumentNullException) { c1 = 0; return null;// Inavlid char } catch (ArgumentException) { c1 = 0; return null;// Inavlid char } catch (IndexOutOfRangeException) { c1 = 0; return null;// Inavlid char } try { c2 = ahexval[str[istr++]]; } catch (ArgumentNullException) { c2 = 0; return null;// Inavlid char } catch (ArgumentException) { c2 = 0; return null;// Inavlid char } catch (IndexOutOfRangeException) { c2 = 0; return null;// Inavlid char } result[ir++] = (byte)((c1 << 4) + c2); } return result; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// private void InitValidationAndEncyptionSizes() { _CustomValidationName = ValidationAlgorithm; _CustomValidationTypeIsKeyed = true; switch(ValidationAlgorithm) { case "AES": case "3DES": _UseHMACSHA = true; _HashSize = SHA1_HASH_SIZE; _AutoGenValidationKeySize = SHA1_KEY_SIZE; break; case "SHA1": _UseHMACSHA = true; _HashSize = SHA1_HASH_SIZE; _AutoGenValidationKeySize = SHA1_KEY_SIZE; break; case "MD5": _CustomValidationTypeIsKeyed = false; _UseHMACSHA = false; _HashSize = MD5_HASH_SIZE; _AutoGenValidationKeySize = MD5_KEY_SIZE; break; case "HMACSHA256": _UseHMACSHA = true; _HashSize = HMACSHA256_HASH_SIZE; _AutoGenValidationKeySize = HMACSHA256_KEY_SIZE; break; case "HMACSHA384": _UseHMACSHA = true; _HashSize = HMACSHA384_HASH_SIZE; _AutoGenValidationKeySize = HMACSHA384_KEY_SIZE; break; case "HMACSHA512": _UseHMACSHA = true; _HashSize = HMACSHA512_HASH_SIZE; _AutoGenValidationKeySize = HMACSHA512_KEY_SIZE; break; default: _UseHMACSHA = false; if (!_CustomValidationName.StartsWith(ALGO_PREFIX, StringComparison.Ordinal)) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_validation_enum), ElementInformation.Properties["validation"].Source, ElementInformation.Properties["validation"].LineNumber); } _CustomValidationName = _CustomValidationName.Substring(ALGO_PREFIX.Length); HashAlgorithm alg = null; try { _CustomValidationTypeIsKeyed = false; alg = HashAlgorithm.Create(_CustomValidationName); } catch (Exception e) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_validation_enum), e, ElementInformation.Properties["validation"].Source, ElementInformation.Properties["validation"].LineNumber); } if (alg == null) throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_validation_enum), ElementInformation.Properties["validation"].Source, ElementInformation.Properties["validation"].LineNumber); _AutoGenValidationKeySize = 0; _HashSize = 0; _CustomValidationTypeIsKeyed = (alg is KeyedHashAlgorithm); if (!_CustomValidationTypeIsKeyed) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_validation_enum), ElementInformation.Properties["validation"].Source, ElementInformation.Properties["validation"].LineNumber); } try { _HashSize = RoundupNumBitsToNumBytes(alg.HashSize); if (_CustomValidationTypeIsKeyed) _AutoGenValidationKeySize = ((KeyedHashAlgorithm) alg).Key.Length; if (_AutoGenValidationKeySize < 1) _AutoGenValidationKeySize = RoundupNumBitsToNumBytes(alg.InputBlockSize); if (_AutoGenValidationKeySize < 1) _AutoGenValidationKeySize = RoundupNumBitsToNumBytes(alg.OutputBlockSize); } catch {} if (_HashSize < 1 || _AutoGenValidationKeySize < 1) { // If we didn't get the hash-size or key-size, perform a hash and get the sizes byte [] buf = new byte[10]; byte [] buf2 = new byte[512]; RandomNumberGenerator.GetBytes(buf); RandomNumberGenerator.GetBytes(buf2); byte [] bHash = alg.ComputeHash(buf); _HashSize = bHash.Length; if (_AutoGenValidationKeySize < 1) { if (_CustomValidationTypeIsKeyed) _AutoGenValidationKeySize = ((KeyedHashAlgorithm) alg).Key.Length; else _AutoGenValidationKeySize = RoundupNumBitsToNumBytes(alg.InputBlockSize); } alg.Clear(); } if (_HashSize < 1) _HashSize = HMACSHA512_HASH_SIZE; if (_AutoGenValidationKeySize < 1) _AutoGenValidationKeySize = HMACSHA512_KEY_SIZE; break; } _AutoGenDecryptionKeySize = 0; switch(Decryption) { case "AES": _AutoGenDecryptionKeySize = 24; break; case "3DES": _AutoGenDecryptionKeySize = 24; break; case "Auto": _AutoGenDecryptionKeySize = 24; break; case "DES": if (ValidationAlgorithm == "AES" || ValidationAlgorithm == "3DES") _AutoGenDecryptionKeySize = 24; else _AutoGenDecryptionKeySize = 8; break; default: _UsingCustomEncryption = true; if (!Decryption.StartsWith(ALGO_PREFIX, StringComparison.Ordinal)) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); } try { s_oSymAlgoDecryption = SymmetricAlgorithm.Create(Decryption.Substring(ALGO_PREFIX.Length)); } catch(Exception e) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), e, ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); } if (s_oSymAlgoDecryption == null) throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); _AutoGenDecryptionKeySize = RoundupNumBitsToNumBytes(s_oSymAlgoDecryption.KeySize); break; } } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal static int RoundupNumBitsToNumBytes(int numBits) { if (numBits < 0) return 0; return (numBits / 8) + (((numBits & 7) != 0) ? 1 : 0); } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// private static byte[] HashDataUsingNonKeyedAlgorithm(HashAlgorithm hashAlgo, byte[] buf, byte[] modifier, int start, int length, byte[] validationKey) { int totalLength = length + validationKey.Length + ((modifier != null) ? modifier.Length : 0); byte [] bAll = new byte[totalLength]; Buffer.BlockCopy(buf, start, bAll, 0, length); if (modifier != null) { Buffer.BlockCopy(modifier, 0, bAll, length, modifier.Length); } Buffer.BlockCopy(validationKey, 0, bAll, length, validationKey.Length); if (hashAlgo != null) { return hashAlgo.ComputeHash(bAll); } else { byte[] newHash = new byte[MD5_HASH_SIZE]; int hr = UnsafeNativeMethods.GetSHA1Hash(bAll, bAll.Length, newHash, newHash.Length); Marshal.ThrowExceptionForHR(hr); return newHash; } } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// private static byte[] HashDataUsingKeyedAlgorithm(KeyedHashAlgorithm hashAlgo, byte[] buf, byte[] modifier, int start, int length, byte[] validationKey) { int totalLength = length + ((modifier != null) ? modifier.Length : 0); byte [] bAll = new byte[totalLength]; Buffer.BlockCopy(buf, start, bAll, 0, length); if (modifier != null) { Buffer.BlockCopy(modifier, 0, bAll, length, modifier.Length); } hashAlgo.Key = validationKey; return hashAlgo.ComputeHash(bAll); } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal static byte[] GetUnHashedData(byte[] bufHashed) { if (!VerifyHashedData(bufHashed)) return null; byte[] buf2 = new byte[bufHashed.Length - _HashSize]; Buffer.BlockCopy(bufHashed, 0, buf2, 0, buf2.Length); return buf2; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal static bool VerifyHashedData(byte[] bufHashed) { EnsureConfig(); ////////////////////////////////////////////////////////////////////// // Step 1: Get the MAC: Last 20 bytes if (bufHashed.Length <= _HashSize) return false; byte[] bMac = HashData(bufHashed, null, 0, bufHashed.Length - _HashSize); ////////////////////////////////////////////////////////////////////// // Step 2: Make sure the MAC is correct if (bMac == null || bMac.Length != _HashSize) return false; int lastPos = bufHashed.Length - _HashSize; for (int iter = 0; iter < _HashSize; iter++) if (bMac[iter] != bufHashed[lastPos + iter]) return false; return true; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal static SymmetricAlgorithm GetAESAlgorithm() { //try { // return new AesCng(); //} catch {} try { return new RijndaelManaged(); } catch { } return new AesCryptoServiceProvider(); } internal static bool UsingCustomEncryption { get { EnsureConfig(); return _UsingCustomEncryption; } } private static void InitLegacyEncAlgorithm(byte [] dKey) { if (!_UsingCustomEncryption) return; s_oSymAlgoLegacy = GetAESAlgorithm(); try { s_oSymAlgoLegacy.Key = dKey; } catch { if (dKey.Length <= 24) throw; byte [] buf = new byte[24]; Buffer.BlockCopy(dKey, 0, buf, 0, buf.Length); dKey = buf; s_oSymAlgoLegacy.Key = dKey; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.Configuration { using System; using System.Xml; using System.Configuration; using System.Collections.Specialized; using System.Collections; using System.IO; using System.Text; using System.Security.Cryptography; using System.Web.Util; using System.Globalization; using System.Web.Hosting; using System.Runtime.InteropServices; using System.ComponentModel; using System.Security.Permissions; /**/ public sealed class MachineKeySection : ConfigurationSection { // If the default validation algorithm changes, be sure to update the _HashSize and _AutoGenValidationKeySize fields also. internal const string DefaultValidationAlgorithm = "HMACSHA256"; internal const MachineKeyValidation DefaultValidation = MachineKeyValidation.SHA1; private static ConfigurationPropertyCollection _properties; private static readonly ConfigurationProperty _propValidationKey = new ConfigurationProperty("validationKey", typeof(string), "AutoGenerate,IsolateApps", StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propDecryptionKey = new ConfigurationProperty("decryptionKey", typeof(string),"AutoGenerate,IsolateApps",StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propDecryption = new ConfigurationProperty("decryption", typeof(string), "Auto", StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propValidation = new ConfigurationProperty("validation", typeof(string), DefaultValidationAlgorithm, StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propCompatibilityMode = new ConfigurationProperty("compatibilityMode", typeof(MachineKeyCompatibilityMode), MachineKeyCompatibilityMode.Framework20SP1, null, null, ConfigurationPropertyOptions.None); static object s_initLock = new object(); static MachineKeySection s_config; static MachineKeyCompatibilityMode s_compatMode; private static RNGCryptoServiceProvider s_randomNumberGenerator; private static SymmetricAlgorithm s_oSymAlgoDecryption; private static SymmetricAlgorithm s_oSymAlgoValidation; private static byte[] s_validationKey; private static byte[] s_inner = null; private static byte[] s_outer = null; internal static bool IsDecryptionKeyAutogenerated { get { EnsureConfig(); return s_config.AutogenKey; } } private bool _AutogenKey; internal bool AutogenKey { get { RuntimeDataInitialize(); return _AutogenKey; } } private byte[] _ValidationKey; private byte[] _DecryptionKey; private bool DataInitialized = false; private static bool _CustomValidationTypeIsKeyed; private static string _CustomValidationName; private static int _IVLengthDecryption = 64; private static int _IVLengthValidation = 64; private static int _HashSize = HMACSHA256_HASH_SIZE; private static int _AutoGenValidationKeySize = HMACSHA256_KEY_SIZE; private static int _AutoGenDecryptionKeySize = 24; private static bool _UseHMACSHA = true; private static bool _UsingCustomEncryption = false; private static SymmetricAlgorithm s_oSymAlgoLegacy; private const int MD5_KEY_SIZE = 64; private const int MD5_HASH_SIZE = 16; private const int SHA1_KEY_SIZE = 64; private const int HMACSHA256_KEY_SIZE = 64; private const int HMACSHA384_KEY_SIZE = 128; private const int HMACSHA512_KEY_SIZE = 128; private const int SHA1_HASH_SIZE = 20; private const int HMACSHA256_HASH_SIZE = 32; private const int HMACSHA384_HASH_SIZE = 48; private const int HMACSHA512_HASH_SIZE = 64; private const string ALGO_PREFIX = "alg:"; internal byte[] ValidationKeyInternal { get { RuntimeDataInitialize(); return (byte[])_ValidationKey.Clone(); } } internal byte[] DecryptionKeyInternal { get { RuntimeDataInitialize(); return (byte[])_DecryptionKey.Clone(); } } internal static int HashSize { get { s_config.RuntimeDataInitialize(); return _HashSize; } } internal static int ValidationKeySize { get { s_config.RuntimeDataInitialize(); return _AutoGenValidationKeySize; } } static MachineKeySection() { // Property initialization _properties = new ConfigurationPropertyCollection(); _properties.Add(_propValidationKey); _properties.Add(_propDecryptionKey); _properties.Add(_propValidation); _properties.Add(_propDecryption); _properties.Add(_propCompatibilityMode); } public MachineKeySection() { } internal static MachineKeyCompatibilityMode CompatMode { get { EnsureConfig(); return s_compatMode; } } protected override ConfigurationPropertyCollection Properties { get { return _properties; } } [ConfigurationProperty("validationKey", DefaultValue = "AutoGenerate,IsolateApps")] [TypeConverter(typeof(WhiteSpaceTrimStringConverter))] [StringValidator(MinLength = 1)] public string ValidationKey { get { return (string)base[_propValidationKey]; } set { base[_propValidationKey] = value; } } [ConfigurationProperty("decryptionKey", DefaultValue = "AutoGenerate,IsolateApps")] [TypeConverter(typeof(WhiteSpaceTrimStringConverter))] [StringValidator(MinLength = 1)] public string DecryptionKey { get { return (string)base[_propDecryptionKey]; } set { base[_propDecryptionKey] = value; } } [ConfigurationProperty("decryption", DefaultValue = "Auto")] [TypeConverter(typeof(WhiteSpaceTrimStringConverter))] [StringValidator(MinLength = 1)] public string Decryption { get { string s = base[_propDecryption] as string; if (s == null) return "Auto"; if (s != "Auto" && s != "AES" && s != "3DES" && s != "DES" && !s.StartsWith(ALGO_PREFIX, StringComparison.Ordinal)) throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); return s; } set { if (value != "AES" && value != "3DES" && value != "Auto" && value != "DES" && !value.StartsWith(ALGO_PREFIX, StringComparison.Ordinal)) throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); base[_propDecryption] = value; } } private bool _validationIsCached; private string _cachedValidation; private MachineKeyValidation _cachedValidationEnum; [ConfigurationProperty("validation", DefaultValue = DefaultValidationAlgorithm)] [TypeConverter(typeof(WhiteSpaceTrimStringConverter))] [StringValidator(MinLength = 1)] public string ValidationAlgorithm { get { if (!_validationIsCached) CacheValidation(); return _cachedValidation; } set { if (_validationIsCached && value == _cachedValidation) return; if (value == null) value = DefaultValidationAlgorithm; _cachedValidationEnum = MachineKeyValidationConverter.ConvertToEnum(value); _cachedValidation = value; base[_propValidation] = value; _validationIsCached = true; } } private void CacheValidation() { _cachedValidation = (string)base[_propValidation]; if (_cachedValidation == null) _cachedValidation = DefaultValidationAlgorithm; _cachedValidationEnum = MachineKeyValidationConverter.ConvertToEnum(_cachedValidation); _validationIsCached = true; } public MachineKeyValidation Validation { get { if (_validationIsCached == false) CacheValidation(); return _cachedValidationEnum; } set { if (_validationIsCached && value == _cachedValidationEnum) return; _cachedValidation = MachineKeyValidationConverter.ConvertFromEnum(value); _cachedValidationEnum = value; base[_propValidation] = _cachedValidation; _validationIsCached = true; } } [ConfigurationProperty("compatibilityMode", DefaultValue = MachineKeyCompatibilityMode.Framework20SP1)] public MachineKeyCompatibilityMode CompatibilityMode { get { return (MachineKeyCompatibilityMode)base[_propCompatibilityMode]; } set { base[_propCompatibilityMode] = value; } } protected override void Reset(ConfigurationElement parentElement) { MachineKeySection parent = parentElement as MachineKeySection; base.Reset(parentElement); // copy the privates from the parent. if (parent != null) { // _ValidationKey = parent.ValidationKeyInternal; // _DecryptionKey = parent.DecryptionKeyInternal; // _AutogenKey = parent.AutogenKey; } } private void RuntimeDataInitialize() { if (DataInitialized == false) { byte [] bKeysRandom = null; bool fNonHttpApp = false; string strKey = ValidationKey; string appName = HttpRuntime.AppDomainAppVirtualPath; InitValidationAndEncyptionSizes(); if( appName == null ) { #if !FEATURE_PAL // FEATURE_PAL does not enable cryptography // FEATURE_PAL appName = System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName; if( ValidationKey.Contains( "AutoGenerate" ) || DecryptionKey.Contains( "AutoGenerate" ) ) { fNonHttpApp = true; bKeysRandom = new byte[ _AutoGenValidationKeySize + _AutoGenDecryptionKeySize ]; // Gernerate random keys RandomNumberGenerator.GetBytes(bKeysRandom); } #endif // !FEATURE_PAL } bool fAppSpecific = StringUtil.StringEndsWith(strKey, ",IsolateApps"); if (fAppSpecific) { strKey = strKey.Substring(0, strKey.Length - ",IsolateApps".Length); } if (strKey == "AutoGenerate") { // case sensitive _ValidationKey = new byte[_AutoGenValidationKeySize]; if( fNonHttpApp ) { Buffer.BlockCopy( bKeysRandom, 0, _ValidationKey, 0, _AutoGenValidationKeySize); } else { Buffer.BlockCopy(HttpRuntime.s_autogenKeys, 0, _ValidationKey, 0, _AutoGenValidationKeySize); } } else { if (strKey.Length < 40 || (strKey.Length & 0x1) == 1) throw new ConfigurationErrorsException(SR.GetString(SR.Unable_to_get_cookie_authentication_validation_key, strKey.Length.ToString(CultureInfo.InvariantCulture)), ElementInformation.Properties["validationKey"].Source, ElementInformation.Properties["validationKey"].LineNumber); _ValidationKey = HexStringToByteArray(strKey); if (_ValidationKey == null) throw new ConfigurationErrorsException(SR.GetString(SR.Invalid_validation_key), ElementInformation.Properties["validationKey"].Source, ElementInformation.Properties["validationKey"].LineNumber); } if (fAppSpecific) { int dwCode = StringComparer.InvariantCultureIgnoreCase.GetHashCode( appName ); _ValidationKey[0] = (byte)(dwCode & 0xff); _ValidationKey[1] = (byte)((dwCode & 0xff00) >> 8); _ValidationKey[2] = (byte)((dwCode & 0xff0000) >> 16); _ValidationKey[3] = (byte)((dwCode & 0xff000000) >> 24); } strKey = DecryptionKey; fAppSpecific = StringUtil.StringEndsWith(strKey, ",IsolateApps"); if (fAppSpecific) { strKey = strKey.Substring(0, strKey.Length - ",IsolateApps".Length); } if (strKey == "AutoGenerate") { // case sensitive _DecryptionKey = new byte[_AutoGenDecryptionKeySize]; if( fNonHttpApp ) { Buffer.BlockCopy( bKeysRandom, _AutoGenValidationKeySize, _DecryptionKey, 0, _AutoGenDecryptionKeySize); } else { Buffer.BlockCopy(HttpRuntime.s_autogenKeys, _AutoGenValidationKeySize, _DecryptionKey, 0, _AutoGenDecryptionKeySize); } _AutogenKey = true; } else { _AutogenKey = false; if ((strKey.Length & 1) != 0) throw new ConfigurationErrorsException(SR.GetString(SR.Invalid_decryption_key), ElementInformation.Properties["decryptionKey"].Source, ElementInformation.Properties["decryptionKey"].LineNumber); _DecryptionKey = HexStringToByteArray(strKey); if (_DecryptionKey == null) throw new ConfigurationErrorsException(SR.GetString(SR.Invalid_decryption_key), ElementInformation.Properties["decryptionKey"].Source, ElementInformation.Properties["decryptionKey"].LineNumber); } if (fAppSpecific) { int dwCode = StringComparer.InvariantCultureIgnoreCase.GetHashCode(appName); _DecryptionKey[0] = (byte)(dwCode & 0xff); _DecryptionKey[1] = (byte)((dwCode & 0xff00) >> 8); _DecryptionKey[2] = (byte)((dwCode & 0xff0000) >> 16); _DecryptionKey[3] = (byte)((dwCode & 0xff000000) >> 24); } DataInitialized = true; } } internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length) { // DevDiv Bugs 137864: IVType.Hash is the default for compatibility reasons. It allows the result to be // consistent across multiple calls with the same data. This was the behavior when there was no padding. return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, false, false, IVType.Hash); } internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo) { // DevDiv Bugs 137864: IVType.Hash is the default for compatibility reasons. It allows the result to be // consistent across multiple calls with the same data. This was the behavior when there was no padding. return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, false, IVType.Hash); } internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType) { EnsureConfig(); if (useLegacyMode) useLegacyMode = _UsingCustomEncryption; // only use legacy mode for custom algorithms System.IO.MemoryStream ms = new System.IO.MemoryStream(); ICryptoTransform oDesEnc = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode); CryptoStream cs = new CryptoStream(ms, oDesEnc, CryptoStreamMode.Write); // DevDiv Bugs 137864: Add Random or Hashed IV to beginning of data to be encrypted. // IVType.None is used by MembershipProvider which requires compatibility even in SP2 mode. bool createIV = ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1)); if (fEncrypt && createIV) { byte[] iv = null; int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); switch (ivType) { case IVType.Hash: iv = GetIVHash(buf, ivLength); break; case IVType.Random: iv = new byte[ivLength]; RandomNumberGenerator.GetBytes(iv); break; } Debug.Assert(iv != null, "Invalid value for IVType: " + ivType.ToString("G")); cs.Write(iv, 0, iv.Length); } cs.Write(buf, start, length); if (fEncrypt && modifier != null) { cs.Write(modifier, 0, modifier.Length); } cs.FlushFinalBlock(); byte[] paddedData = ms.ToArray(); byte[] bData; cs.Close(); ReturnCryptoTransform(fEncrypt, oDesEnc, useValidationSymAlgo, useLegacyMode); // DevDiv Bugs 137864: Strip Random or Hashed IV from beginning of unencrypted data if (!fEncrypt && createIV) { // strip off the first bytes that were either random bits or a hash of the original data // either way it is always equal to the key length int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); int bDataLength = paddedData.Length - ivLength; // valid if the data is long enough to have included the padding if (bDataLength >= 0) { bData = new byte[bDataLength]; // copy from the padded data to non-padded buffer bData. // dont bother with copy if the data is entirely the padding if (bDataLength > 0) { Buffer.BlockCopy(paddedData, ivLength, bData, 0, bDataLength); } } else { // data is not padded because it is not long enough bData = paddedData; } } else { bData = paddedData; } if (!fEncrypt && modifier != null && modifier.Length > 0) { for(int iter=0; iter _AutoGenValidationKeySize) { key = new byte[_HashSize]; int hr = UnsafeNativeMethods.GetSHA1Hash(validationKey, validationKey.Length, key, key.Length); Marshal.ThrowExceptionForHR(hr); } if (inner == null) inner = new byte[_AutoGenValidationKeySize]; if (outer == null) outer = new byte[_AutoGenValidationKeySize]; int i; for (i = 0; i < _AutoGenValidationKeySize; i++) { inner[i] = 0x36; outer[i] = 0x5C; } for (i=0; i < validationKey.Length; i++) { inner[i] ^= validationKey[i]; outer[i] ^= validationKey[i]; } } private static byte[] GetHMACSHA1Hash(byte[] buf, byte[] modifier, int start, int length) { if (start < 0 || start > buf.Length) throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "start")); if (length < 0 || buf == null || (start + length) > buf.Length) throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "length")); byte[] hash = new byte[_HashSize]; int hr = UnsafeNativeMethods.GetHMACSHA1Hash(buf, start, length, modifier, (modifier == null) ? 0 : modifier.Length, s_inner, s_inner.Length, s_outer, s_outer.Length, hash, hash.Length); if (hr == 0) return hash; _UseHMACSHA = false; return null; } internal static string HashAndBase64EncodeString(string s) { byte[] ab; byte[] hash; string result; ab = Encoding.Unicode.GetBytes(s); hash = HashData(ab, null, 0, ab.Length); result = Convert.ToBase64String(hash); return result; } static internal void DestroyByteArray(byte[] buf) { if (buf == null || buf.Length < 1) return; for (int iter = 0; iter < buf.Length; iter++) buf[iter] = (byte)0; } internal void DestroyKeys() { MachineKeySection.DestroyByteArray(_ValidationKey); MachineKeySection.DestroyByteArray(_DecryptionKey); } static char[] s_acharval; static unsafe internal String ByteArrayToHexString(byte[] buf, int iLen) { char[] acharval = s_acharval; if (acharval == null) { acharval = new char[16]; for (int i = acharval.Length; --i >= 0; ) { if (i < 10) { acharval[i] = (char)('0' + i); } else { acharval[i] = (char)('A' + (i - 10)); } } s_acharval = acharval; } if (buf == null) return null; if (iLen == 0) iLen = buf.Length; char[] chars = new char[iLen * 2]; fixed (char* fc = chars, fcharval = acharval) { fixed (byte* fb = buf) { char* pc; byte* pb; pc = fc; pb = fb; while (--iLen >= 0) { *pc++ = fcharval[(*pb & 0xf0) >> 4]; *pc++ = fcharval[*pb & 0x0f]; pb++; } } } return new String(chars); } static void EnsureConfig() { if (s_config == null) { lock (s_initLock) { if (s_config == null) { MachineKeySection config = RuntimeConfig.GetAppConfig().MachineKey; config.ConfigureEncryptionObject(); s_config = config; s_compatMode = config.CompatibilityMode; } } } } // NOTE: When encoding the data, this method *may* return the same reference to the input "buf" parameter // with the hash appended in the end if there's enough space. The "length" parameter would also be // appropriately adjusted in those cases. This is an optimization to prevent unnecessary copying of // buffers. internal static byte[] GetEncodedData(byte[] buf, byte[] modifier, int start, ref int length) { EnsureConfig(); byte[] bHash = HashData(buf, modifier, start, length); byte[] returnBuffer; if (buf.Length - start - length >= bHash.Length) { // Append hash to end of buffer if there's space Buffer.BlockCopy(bHash, 0, buf, start + length, bHash.Length); returnBuffer = buf; } else { returnBuffer = new byte[length + bHash.Length]; Buffer.BlockCopy(buf, start, returnBuffer, 0, length); Buffer.BlockCopy(bHash, 0, returnBuffer, length, bHash.Length); start = 0; } length += bHash.Length; if (s_config.Validation == MachineKeyValidation.TripleDES || s_config.Validation == MachineKeyValidation.AES) { returnBuffer = EncryptOrDecryptData(true, returnBuffer, modifier, start, length, true); length = returnBuffer.Length; } return returnBuffer; } // NOTE: When decoding the data, this method *may* return the same reference to the input "buf" parameter // with the "dataLength" parameter containing the actual length of the data in the "buf" (i.e. length of actual // data is (total length of data - hash length)). This is an optimization to prevent unnecessary copying of buffers. internal static byte[] GetDecodedData(byte[] buf, byte[] modifier, int start, int length, ref int dataLength) { EnsureConfig(); if (s_config.Validation == MachineKeyValidation.TripleDES || s_config.Validation == MachineKeyValidation.AES) { buf = EncryptOrDecryptData(false, buf, modifier, start, length, true); if (buf == null || buf.Length < _HashSize) throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); length = buf.Length; start = 0; } if (length < _HashSize || start < 0 || start >= length) throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); byte[] bHash = HashData(buf, modifier, start, length - _HashSize); for (int iter = 0; iter < bHash.Length; iter++) if (bHash[iter] != buf[start + length - _HashSize + iter]) throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); dataLength = length - _HashSize; return buf; } internal static byte[] HashData(byte[] buf, byte[] modifier, int start, int length) { EnsureConfig(); if (s_config.Validation == MachineKeyValidation.MD5) return HashDataUsingNonKeyedAlgorithm(null, buf, modifier, start, length, s_validationKey); if (_UseHMACSHA) { byte [] hash = GetHMACSHA1Hash(buf, modifier, start, length); if (hash != null) return hash; } if (_CustomValidationTypeIsKeyed) { return HashDataUsingKeyedAlgorithm(KeyedHashAlgorithm.Create(_CustomValidationName), buf, modifier, start, length, s_validationKey); } else { return HashDataUsingNonKeyedAlgorithm(HashAlgorithm.Create(_CustomValidationName), buf, modifier, start, length, s_validationKey); } } private void ConfigureEncryptionObject() { using (new ApplicationImpersonationContext()) { s_validationKey = ValidationKeyInternal; byte[] dKey = DecryptionKeyInternal; if (_UseHMACSHA) SetInnerOuterKeys(s_validationKey, ref s_inner, ref s_outer); DestroyKeys(); switch (Decryption) { case "3DES": s_oSymAlgoDecryption = new TripleDESCryptoServiceProvider(); break; case "DES": s_oSymAlgoDecryption = new DESCryptoServiceProvider(); break; case "AES": s_oSymAlgoDecryption = GetAESAlgorithm(); break; case "Auto": if (dKey.Length == 8) { s_oSymAlgoDecryption = new DESCryptoServiceProvider(); } else { s_oSymAlgoDecryption = GetAESAlgorithm(); } break; } if (s_oSymAlgoDecryption == null) // Shouldn't happen! InitValidationAndEncyptionSizes(); switch(Validation) { case MachineKeyValidation.TripleDES: if (dKey.Length == 8) { s_oSymAlgoValidation = new DESCryptoServiceProvider(); } else { s_oSymAlgoValidation = new TripleDESCryptoServiceProvider(); } break; case MachineKeyValidation.AES: s_oSymAlgoValidation = GetAESAlgorithm(); break; } if (s_oSymAlgoValidation != null) { SetKeyOnSymAlgorithm(s_oSymAlgoValidation, dKey); _IVLengthValidation = RoundupNumBitsToNumBytes(s_oSymAlgoValidation.KeySize); } SetKeyOnSymAlgorithm(s_oSymAlgoDecryption, dKey); _IVLengthDecryption = RoundupNumBitsToNumBytes(s_oSymAlgoDecryption.KeySize); InitLegacyEncAlgorithm(dKey); DestroyByteArray(dKey); } } private void SetKeyOnSymAlgorithm(SymmetricAlgorithm symAlgo, byte[] dKey) { try { if (dKey.Length > 8 && symAlgo is DESCryptoServiceProvider) { byte[] bTemp = new byte[8]; Buffer.BlockCopy(dKey, 0, bTemp, 0, 8); symAlgo.Key = bTemp; DestroyByteArray(bTemp); } else { symAlgo.Key = dKey; } symAlgo.GenerateIV(); symAlgo.IV = new byte[symAlgo.IV.Length]; } catch (Exception e) { throw new ConfigurationErrorsException(SR.GetString(SR.Bad_machine_key, e.Message), ElementInformation.Properties["decryptionKey"].Source, ElementInformation.Properties["decryptionKey"].LineNumber); } } private static ICryptoTransform GetCryptoTransform(bool fEncrypt, bool useValidationSymAlgo, bool legacyMode) { SymmetricAlgorithm algo = (legacyMode ? s_oSymAlgoLegacy : (useValidationSymAlgo ? s_oSymAlgoValidation : s_oSymAlgoDecryption)); lock(algo) return (fEncrypt ? algo.CreateEncryptor() : algo.CreateDecryptor()); } private static void ReturnCryptoTransform(bool fEncrypt, ICryptoTransform ct, bool useValidationSymAlgo, bool legacyMode) { ct.Dispose(); } static byte[] s_ahexval; static internal byte[] HexStringToByteArray(String str) { if (((uint)str.Length & 0x1) == 0x1) // must be 2 nibbles per byte { return null; } byte[] ahexval = s_ahexval; // initialize a table for faster lookups if (ahexval == null) { ahexval = new byte['f' + 1]; for (int i = ahexval.Length; --i >= 0; ) { if ('0' <= i && i <= '9') { ahexval[i] = (byte)(i - '0'); } else if ('a' <= i && i <= 'f') { ahexval[i] = (byte)(i - 'a' + 10); } else if ('A' <= i && i <= 'F') { ahexval[i] = (byte)(i - 'A' + 10); } } s_ahexval = ahexval; } byte[] result = new byte[str.Length / 2]; int istr = 0, ir = 0; int n = result.Length; while (--n >= 0) { int c1, c2; try { c1 = ahexval[str[istr++]]; } catch (ArgumentNullException) { c1 = 0; return null;// Inavlid char } catch (ArgumentException) { c1 = 0; return null;// Inavlid char } catch (IndexOutOfRangeException) { c1 = 0; return null;// Inavlid char } try { c2 = ahexval[str[istr++]]; } catch (ArgumentNullException) { c2 = 0; return null;// Inavlid char } catch (ArgumentException) { c2 = 0; return null;// Inavlid char } catch (IndexOutOfRangeException) { c2 = 0; return null;// Inavlid char } result[ir++] = (byte)((c1 << 4) + c2); } return result; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// private void InitValidationAndEncyptionSizes() { _CustomValidationName = ValidationAlgorithm; _CustomValidationTypeIsKeyed = true; switch(ValidationAlgorithm) { case "AES": case "3DES": _UseHMACSHA = true; _HashSize = SHA1_HASH_SIZE; _AutoGenValidationKeySize = SHA1_KEY_SIZE; break; case "SHA1": _UseHMACSHA = true; _HashSize = SHA1_HASH_SIZE; _AutoGenValidationKeySize = SHA1_KEY_SIZE; break; case "MD5": _CustomValidationTypeIsKeyed = false; _UseHMACSHA = false; _HashSize = MD5_HASH_SIZE; _AutoGenValidationKeySize = MD5_KEY_SIZE; break; case "HMACSHA256": _UseHMACSHA = true; _HashSize = HMACSHA256_HASH_SIZE; _AutoGenValidationKeySize = HMACSHA256_KEY_SIZE; break; case "HMACSHA384": _UseHMACSHA = true; _HashSize = HMACSHA384_HASH_SIZE; _AutoGenValidationKeySize = HMACSHA384_KEY_SIZE; break; case "HMACSHA512": _UseHMACSHA = true; _HashSize = HMACSHA512_HASH_SIZE; _AutoGenValidationKeySize = HMACSHA512_KEY_SIZE; break; default: _UseHMACSHA = false; if (!_CustomValidationName.StartsWith(ALGO_PREFIX, StringComparison.Ordinal)) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_validation_enum), ElementInformation.Properties["validation"].Source, ElementInformation.Properties["validation"].LineNumber); } _CustomValidationName = _CustomValidationName.Substring(ALGO_PREFIX.Length); HashAlgorithm alg = null; try { _CustomValidationTypeIsKeyed = false; alg = HashAlgorithm.Create(_CustomValidationName); } catch (Exception e) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_validation_enum), e, ElementInformation.Properties["validation"].Source, ElementInformation.Properties["validation"].LineNumber); } if (alg == null) throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_validation_enum), ElementInformation.Properties["validation"].Source, ElementInformation.Properties["validation"].LineNumber); _AutoGenValidationKeySize = 0; _HashSize = 0; _CustomValidationTypeIsKeyed = (alg is KeyedHashAlgorithm); if (!_CustomValidationTypeIsKeyed) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_validation_enum), ElementInformation.Properties["validation"].Source, ElementInformation.Properties["validation"].LineNumber); } try { _HashSize = RoundupNumBitsToNumBytes(alg.HashSize); if (_CustomValidationTypeIsKeyed) _AutoGenValidationKeySize = ((KeyedHashAlgorithm) alg).Key.Length; if (_AutoGenValidationKeySize < 1) _AutoGenValidationKeySize = RoundupNumBitsToNumBytes(alg.InputBlockSize); if (_AutoGenValidationKeySize < 1) _AutoGenValidationKeySize = RoundupNumBitsToNumBytes(alg.OutputBlockSize); } catch {} if (_HashSize < 1 || _AutoGenValidationKeySize < 1) { // If we didn't get the hash-size or key-size, perform a hash and get the sizes byte [] buf = new byte[10]; byte [] buf2 = new byte[512]; RandomNumberGenerator.GetBytes(buf); RandomNumberGenerator.GetBytes(buf2); byte [] bHash = alg.ComputeHash(buf); _HashSize = bHash.Length; if (_AutoGenValidationKeySize < 1) { if (_CustomValidationTypeIsKeyed) _AutoGenValidationKeySize = ((KeyedHashAlgorithm) alg).Key.Length; else _AutoGenValidationKeySize = RoundupNumBitsToNumBytes(alg.InputBlockSize); } alg.Clear(); } if (_HashSize < 1) _HashSize = HMACSHA512_HASH_SIZE; if (_AutoGenValidationKeySize < 1) _AutoGenValidationKeySize = HMACSHA512_KEY_SIZE; break; } _AutoGenDecryptionKeySize = 0; switch(Decryption) { case "AES": _AutoGenDecryptionKeySize = 24; break; case "3DES": _AutoGenDecryptionKeySize = 24; break; case "Auto": _AutoGenDecryptionKeySize = 24; break; case "DES": if (ValidationAlgorithm == "AES" || ValidationAlgorithm == "3DES") _AutoGenDecryptionKeySize = 24; else _AutoGenDecryptionKeySize = 8; break; default: _UsingCustomEncryption = true; if (!Decryption.StartsWith(ALGO_PREFIX, StringComparison.Ordinal)) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); } try { s_oSymAlgoDecryption = SymmetricAlgorithm.Create(Decryption.Substring(ALGO_PREFIX.Length)); } catch(Exception e) { throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), e, ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); } if (s_oSymAlgoDecryption == null) throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); _AutoGenDecryptionKeySize = RoundupNumBitsToNumBytes(s_oSymAlgoDecryption.KeySize); break; } } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal static int RoundupNumBitsToNumBytes(int numBits) { if (numBits < 0) return 0; return (numBits / 8) + (((numBits & 7) != 0) ? 1 : 0); } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// private static byte[] HashDataUsingNonKeyedAlgorithm(HashAlgorithm hashAlgo, byte[] buf, byte[] modifier, int start, int length, byte[] validationKey) { int totalLength = length + validationKey.Length + ((modifier != null) ? modifier.Length : 0); byte [] bAll = new byte[totalLength]; Buffer.BlockCopy(buf, start, bAll, 0, length); if (modifier != null) { Buffer.BlockCopy(modifier, 0, bAll, length, modifier.Length); } Buffer.BlockCopy(validationKey, 0, bAll, length, validationKey.Length); if (hashAlgo != null) { return hashAlgo.ComputeHash(bAll); } else { byte[] newHash = new byte[MD5_HASH_SIZE]; int hr = UnsafeNativeMethods.GetSHA1Hash(bAll, bAll.Length, newHash, newHash.Length); Marshal.ThrowExceptionForHR(hr); return newHash; } } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// private static byte[] HashDataUsingKeyedAlgorithm(KeyedHashAlgorithm hashAlgo, byte[] buf, byte[] modifier, int start, int length, byte[] validationKey) { int totalLength = length + ((modifier != null) ? modifier.Length : 0); byte [] bAll = new byte[totalLength]; Buffer.BlockCopy(buf, start, bAll, 0, length); if (modifier != null) { Buffer.BlockCopy(modifier, 0, bAll, length, modifier.Length); } hashAlgo.Key = validationKey; return hashAlgo.ComputeHash(bAll); } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal static byte[] GetUnHashedData(byte[] bufHashed) { if (!VerifyHashedData(bufHashed)) return null; byte[] buf2 = new byte[bufHashed.Length - _HashSize]; Buffer.BlockCopy(bufHashed, 0, buf2, 0, buf2.Length); return buf2; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal static bool VerifyHashedData(byte[] bufHashed) { EnsureConfig(); ////////////////////////////////////////////////////////////////////// // Step 1: Get the MAC: Last 20 bytes if (bufHashed.Length <= _HashSize) return false; byte[] bMac = HashData(bufHashed, null, 0, bufHashed.Length - _HashSize); ////////////////////////////////////////////////////////////////////// // Step 2: Make sure the MAC is correct if (bMac == null || bMac.Length != _HashSize) return false; int lastPos = bufHashed.Length - _HashSize; for (int iter = 0; iter < _HashSize; iter++) if (bMac[iter] != bufHashed[lastPos + iter]) return false; return true; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal static SymmetricAlgorithm GetAESAlgorithm() { //try { // return new AesCng(); //} catch {} try { return new RijndaelManaged(); } catch { } return new AesCryptoServiceProvider(); } internal static bool UsingCustomEncryption { get { EnsureConfig(); return _UsingCustomEncryption; } } private static void InitLegacyEncAlgorithm(byte [] dKey) { if (!_UsingCustomEncryption) return; s_oSymAlgoLegacy = GetAESAlgorithm(); try { s_oSymAlgoLegacy.Key = dKey; } catch { if (dKey.Length <= 24) throw; byte [] buf = new byte[24]; Buffer.BlockCopy(dKey, 0, buf, 0, buf.Length); dKey = buf; s_oSymAlgoLegacy.Key = dKey; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NonParentingControl.cs
- InfoCardProofToken.cs
- Message.cs
- Literal.cs
- AsyncStreamReader.cs
- figurelength.cs
- SessionIDManager.cs
- ControlOperationInvoker.cs
- ErrorHandlingReceiver.cs
- messageonlyhwndwrapper.cs
- SqlRowUpdatedEvent.cs
- RedistVersionInfo.cs
- ContractMapping.cs
- MemberHolder.cs
- TextureBrush.cs
- TableStyle.cs
- HTTPNotFoundHandler.cs
- DataSourceSelectArguments.cs
- LocalizableAttribute.cs
- CapabilitiesState.cs
- HttpFileCollection.cs
- RootBuilder.cs
- WindowHelperService.cs
- HandlerWithFactory.cs
- SiteMapNodeItemEventArgs.cs
- GradientBrush.cs
- UnsafeNativeMethods.cs
- EncoderFallback.cs
- MethodImplAttribute.cs
- storepermission.cs
- SqlDeflator.cs
- FeatureSupport.cs
- DataPagerCommandEventArgs.cs
- configsystem.cs
- manifestimages.cs
- Socket.cs
- ActionMessageFilter.cs
- CollectionViewGroupInternal.cs
- MenuItemCollection.cs
- DoubleCollectionConverter.cs
- SystemIcmpV6Statistics.cs
- InputScopeNameConverter.cs
- TriggerAction.cs
- DictionaryEntry.cs
- SmtpCommands.cs
- TextTreeText.cs
- JoinElimination.cs
- PreloadedPackages.cs
- DocumentViewerConstants.cs
- BuildResult.cs
- AutomationElement.cs
- BindingExpression.cs
- HttpServerUtilityWrapper.cs
- QueryStringConverter.cs
- XamlSerializer.cs
- Span.cs
- GetImportFileNameRequest.cs
- RotateTransform3D.cs
- CodeParameterDeclarationExpressionCollection.cs
- ReferenceAssemblyAttribute.cs
- PatternMatchRules.cs
- EmulateRecognizeCompletedEventArgs.cs
- TrackingMemoryStreamFactory.cs
- AssemblyAttributes.cs
- AssemblyCollection.cs
- MouseGestureConverter.cs
- ExtentJoinTreeNode.cs
- TypeDelegator.cs
- ForeignConstraint.cs
- Drawing.cs
- HelpProvider.cs
- SiteMapDataSourceDesigner.cs
- Int32Converter.cs
- GeometryDrawing.cs
- CookieProtection.cs
- HostProtectionPermission.cs
- XsdCachingReader.cs
- PieceNameHelper.cs
- FileLogRecordHeader.cs
- CompilerWrapper.cs
- WebEvents.cs
- HybridCollection.cs
- BindingValueChangedEventArgs.cs
- LogStream.cs
- PropertyGeneratedEventArgs.cs
- ProviderConnectionPointCollection.cs
- DoubleAnimation.cs
- FileStream.cs
- DivideByZeroException.cs
- FormViewInsertEventArgs.cs
- SqlProcedureAttribute.cs
- UndoManager.cs
- MailHeaderInfo.cs
- AssemblyNameProxy.cs
- ScriptDescriptor.cs
- InvalidWMPVersionException.cs
- ConstructorArgumentAttribute.cs
- ReachIDocumentPaginatorSerializerAsync.cs
- BuildManagerHost.cs
- PeerNameRecord.cs