MachineKeySection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / Configuration / MachineKeySection.cs / 3 / 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;
 
    /*
             
         
    */
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public sealed class MachineKeySection : ConfigurationSection
    {
        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(MachineKeyValidation), MachineKeyValidation.SHA1, new MachineKeyValidationConverter(), null, ConfigurationPropertyOptions.None);
 
        private const int HASH_SIZE = 20;
        private const int BLOCK_SIZE = 64; 
 
        static object s_initLock = new object();
        static MachineKeySection s_config; 
        private static SymmetricAlgorithm s_oSymAlgoDecryption;
        private static Stack s_oEncryptorStackDecryption;
        private static Stack s_oDecryptorStackDecryption;
        private static SymmetricAlgorithm s_oSymAlgoValidation; 
        private static Stack s_oEncryptorStackValidation;
        private static Stack s_oDecryptorStackValidation; 
        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; 
 
        internal byte[] ValidationKeyInternal { get { RuntimeDataInitialize();  return (byte[])_ValidationKey.Clone(); } }
        internal byte[] DecryptionKeyInternal { get { RuntimeDataInitialize(); return (byte[])_DecryptionKey.Clone(); } } 

#if UNUSED
        static internal int ValidationKeyHashCode
        { 
            get
            { 
                EnsureConfig(); 
                return ByteArrayToHexString(s_validationKey, s_validationKey.Length).GetHashCode();
            } 
        }
#endif

 
        static MachineKeySection()
        { 
            // Property initialization 
            _properties = new ConfigurationPropertyCollection();
            _properties.Add(_propValidationKey); 
            _properties.Add(_propDecryptionKey);
            _properties.Add(_propValidation);
            _properties.Add(_propDecryption);
        } 

        public MachineKeySection() 
        { 
        }
 

        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")
                    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")
                    throw new ConfigurationErrorsException(SR.GetString(SR.Wrong_decryption_enum), ElementInformation.Properties["decryption"].Source, ElementInformation.Properties["decryption"].LineNumber); 
                base[_propDecryption] = value;
            }
        }
        private bool _validationIsCached; 
        private MachineKeyValidation _cachedValidation;
 
        [ConfigurationProperty("validation", DefaultValue = MachineKeyValidation.SHA1)] 
        [TypeConverter(typeof(MachineKeyValidationConverter ))]
        public MachineKeyValidation Validation 
        {
            get
            {
                if (_validationIsCached == false) { 
                    _cachedValidation = (MachineKeyValidation)base[_propValidation];
                    _validationIsCached = true; 
                } 
                return _cachedValidation;
            } 
            set
            {
                base[_propValidation] = value;
 
                _cachedValidation = value;
                _validationIsCached = true; 
            } 
        }
 
        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;
 
                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[ BLOCK_SIZE + 24 ];
 
                        RNGCryptoServiceProvider randgen = new RNGCryptoServiceProvider();

                        // Gernerate random keys
                        randgen.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[BLOCK_SIZE]; 

                    if( fNonHttpApp ) 
                    {
                        Buffer.BlockCopy( bKeysRandom, 0, _ValidationKey, 0, BLOCK_SIZE);
                    }
                    else 
                    {
                        Buffer.BlockCopy(HttpRuntime.s_autogenKeys, 0, _ValidationKey, 0, BLOCK_SIZE); 
                    } 
                }
                else 
                {
                    if (strKey.Length > 128 || strKey.Length < 40)
                        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[24]; 

                    if( fNonHttpApp )
                    {
                        Buffer.BlockCopy( bKeysRandom, BLOCK_SIZE, _DecryptionKey, 0, 24); 
                    }
                    else 
                    { 
                        Buffer.BlockCopy(HttpRuntime.s_autogenKeys, BLOCK_SIZE, _DecryptionKey, 0, 24);
                    } 

                    _AutogenKey = true;
                }
                else 
                {
                    _AutogenKey = false; 
                    if ((strKey.Length % 2) != 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)
        { 
            EnsureConfig();
            return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, false);
        }
 
        internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo)
        { 
            EnsureConfig(); 
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            ICryptoTransform oDesEnc = GetCryptoTransform(fEncrypt, useValidationSymAlgo); 
            CryptoStream cs = new CryptoStream(ms, oDesEnc, CryptoStreamMode.Write);

            cs.Write(buf, start, length);
            if (fEncrypt && modifier != null) 
            {
                cs.Write(modifier, 0, modifier.Length); 
            } 

            cs.FlushFinalBlock(); 
            byte[] bData = ms.ToArray();
            cs.Close();
            ReturnCryptoTransform(fEncrypt, oDesEnc, useValidationSymAlgo);
 
            if (!fEncrypt && modifier != null && modifier.Length > 0)
            { 
                for(int iter=0; iter= s_validationKey.Length) {
//                    Buffer.BlockCopy(s_validationKey, 0, buf, start + length, s_validationKey.Length);
//                    byte[] computedHash = md5.ComputeHash(buf, start, length + s_validationKey.Length); 
//
//                    // Cleanup validation key from buf 
//                    for (int i = (start + length); i < (start + length + s_validationKey.Length); i++) { 
//                        buf[i] = 0;
//                    } 
//
//                    return computedHash;
//                }
//            } 
            byte[] bAll = new byte[totalLength];
            Buffer.BlockCopy(buf, start, bAll, 0, length); 
            if (modifier != null) 
            {
                Buffer.BlockCopy(modifier, 0, bAll, length, modifier.Length); 
                length += modifier.Length;
            }
            Buffer.BlockCopy(s_validationKey, 0, bAll, length, s_validationKey.Length);
            return md5.ComputeHash(bAll); 
        }
 
        private static void SetInnerOuterKeys(byte[] validationKey) { 
            byte[] key = null;
            if (validationKey.Length > BLOCK_SIZE) { 
                key = new byte[HASH_SIZE];
                int hr = UnsafeNativeMethods.GetSHA1Hash(validationKey, validationKey.Length, key, key.Length);
                Marshal.ThrowExceptionForHR(hr);
            } 

            if (s_inner == null) 
                s_inner = new byte[BLOCK_SIZE]; 
            if (s_outer == null)
                s_outer = new byte[BLOCK_SIZE]; 

            int i;
            for (i=0; i < BLOCK_SIZE; i++) {
                s_inner[i] = 0x36; 
                s_outer[i] = 0x5C;
            } 
            for (i=0; i < validationKey.Length; i++) { 
                s_inner[i] ^= validationKey[i];
                s_outer[i] ^= validationKey[i]; 
            }
        }

        private static byte[] GetHMACSHA1Hash(byte[] buf, byte[] modifier, int start, int length) { 
            if (length < 0 || buf == null || length > buf.Length)
                throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "length")); 
            if (start < 0 || start >= length) 
                throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "start"));
            byte[] buffer = new byte[HASH_SIZE]; 
            int hr = UnsafeNativeMethods.GetHMACSHA1Hash(buf, start, length,
                                                         modifier, (modifier == null) ? 0 : modifier.Length,
                                                         s_inner, s_inner.Length, s_outer, s_outer.Length,
                                                         buffer, buffer.Length); 
            Marshal.ThrowExceptionForHR(hr);
            return buffer; 
        } 

        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; 
                    } 
                }
            } 
        }

        // 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 < HASH_SIZE) 
                    throw new HttpException(SR.GetString(SR.Unable_to_validate_data));
                length = buf.Length;
                start = 0;
            } 

            if (length < HASH_SIZE || start < 0 || start >= length) 
                throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); 
            byte[] bHash = HashData(buf, modifier, start, length - HASH_SIZE);
            for (int iter = 0; iter < bHash.Length; iter++) 
                if (bHash[iter] != buf[start + length - HASH_SIZE + iter])
                    throw new HttpException(SR.GetString(SR.Unable_to_validate_data));

            dataLength = length - HASH_SIZE; 
            return buf;
        } 
 
        internal static byte[] HashData(byte[] buf, byte[] modifier, int start, int length)
        { 
            EnsureConfig();
            byte[] hash = null;

            if (s_config.Validation == MachineKeyValidation.MD5) 
                hash = MD5HashForData(buf, modifier, start, length);
            else 
                hash = GetHMACSHA1Hash(buf, modifier, start, length); 
            // We need to pad the returning hash so that they all have an uniform size (makes it easier when we decode)
            // MD5 will return a 16 byte hash, whereas the default SHA1 returns 20, so we pad it with 4 zero bytes 
            System.Web.Util.Debug.Assert(hash.Length <= HASH_SIZE, "Hash size is greater than HASH_SIZE constant!");

            if (hash.Length < HASH_SIZE)
            { 
                byte[] tmp = new byte[HASH_SIZE];
                Buffer.BlockCopy(hash, 0, tmp, 0, hash.Length); 
                hash = tmp; 
            }
 
            return hash;
        }

        private void ConfigureEncryptionObject() 
        {
            using (new ApplicationImpersonationContext()) { 
                s_validationKey = ValidationKeyInternal; 
                byte[] dKey = DecryptionKeyInternal;
                SetInnerOuterKeys(s_validationKey); 
                DestroyKeys();
                switch (Decryption) {
                case "3DES":
                    s_oSymAlgoDecryption = new TripleDESCryptoServiceProvider(); 
                    break;
                case "DES": 
                    s_oSymAlgoDecryption = new DESCryptoServiceProvider(); 
                    break;
                case "AES": 
                    s_oSymAlgoDecryption = new RijndaelManaged();
                    break;
                default: // "Auto" case
                    if (dKey.Length == 8) { 
                        s_oSymAlgoDecryption = new DESCryptoServiceProvider();
                    } else { 
                        s_oSymAlgoDecryption = new RijndaelManaged(); 
                    }
                    break; 
                }
                switch(Validation)
                {
                case MachineKeyValidation.TripleDES: 
                    if (dKey.Length == 8) {
                        s_oSymAlgoValidation = new DESCryptoServiceProvider(); 
                    } else { 
                        s_oSymAlgoValidation = new TripleDESCryptoServiceProvider();
                    } 
                    break;
                case MachineKeyValidation.AES:
                    s_oSymAlgoValidation = new RijndaelManaged();
                    break; 
                }
                if (s_oSymAlgoValidation != null) { 
                    SetKeyOnSymAlgorithm(s_oSymAlgoValidation, dKey); 
                    s_oEncryptorStackValidation = new Stack();
                    s_oDecryptorStackValidation = new Stack(); 
                }
                SetKeyOnSymAlgorithm(s_oSymAlgoDecryption, dKey);
                s_oEncryptorStackDecryption = new Stack();
                s_oDecryptorStackDecryption = new Stack(); 
                DestroyByteArray(dKey);
            } 
        } 

        private void SetKeyOnSymAlgorithm(SymmetricAlgorithm symAlgo, byte[] dKey) 
        {
            try {
                if (dKey.Length == 24 && 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) 
        {
            Stack st;
            if (useValidationSymAlgo) {
                st = (fEncrypt ? s_oEncryptorStackValidation : s_oDecryptorStackValidation); 
            } else {
                st = (fEncrypt ? s_oEncryptorStackDecryption : s_oDecryptorStackDecryption); 
            } 

            lock (st) { 
                if (st.Count > 0)
                    return (ICryptoTransform)st.Pop();
            }
 
            if (useValidationSymAlgo) {
                lock (s_oSymAlgoValidation) { 
                    return (fEncrypt ? s_oSymAlgoValidation.CreateEncryptor() : s_oSymAlgoValidation.CreateDecryptor()); 
                }
            } else { 
                lock (s_oSymAlgoDecryption) {
                    return (fEncrypt ? s_oSymAlgoDecryption.CreateEncryptor() : s_oSymAlgoDecryption.CreateDecryptor());
                }
            } 
        }
 
        private static void ReturnCryptoTransform(bool fEncrypt, ICryptoTransform ct, bool useValidationSymAlgo) 
        {
            Stack st; 
            if (useValidationSymAlgo) {
                st = (fEncrypt ? s_oEncryptorStackValidation : s_oDecryptorStackValidation);
            } else {
                st = (fEncrypt ? s_oEncryptorStackDecryption : s_oDecryptorStackDecryption); 
            }
            lock (st) { 
                if (st.Count <= 100) 
                    st.Push(ct);
            } 
        }


 
        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;
        } 
    }
}
                        

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