internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType, bool signData)
        {
            byte[] buffer8;
            try
            {
                byte[] buffer4;
                EnsureConfig();
                if (!fEncrypt && signData)
                {
                    if ((start != 0) || (length != buf.Length))
                    {
                        byte[] dst = new byte[length];
                        Buffer.BlockCopy(buf, start, dst, 0, length);
                        buf = dst;
                        start = 0;
                    }
                    buf = GetUnHashedData(buf);
                    if (buf == null)
                    {
                        throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data"));
                    }
                    length = buf.Length;
                }
                if (useLegacyMode)
                {
                    useLegacyMode = _UsingCustomEncryption;
                }
                MemoryStream stream = new MemoryStream();
                ICryptoTransform transform = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode);
                CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write);
                bool flag = signData || ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1));
                if (fEncrypt && flag)
                {
                    int ivLength = useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption;
                    byte[] data = null;
                    switch (ivType)
                    {
                        case IVType.Random:
                            data = new byte[ivLength];
                            RandomNumberGenerator.GetBytes(data);
                            break;

                        case IVType.Hash:
                            data = GetIVHash(buf, ivLength);
                            break;
                    }
                    stream2.Write(data, 0, data.Length);
                }
                stream2.Write(buf, start, length);
                if (fEncrypt && (modifier != null))
                {
                    stream2.Write(modifier, 0, modifier.Length);
                }
                stream2.FlushFinalBlock();
                byte[] src = stream.ToArray();
                stream2.Close();
                ReturnCryptoTransform(fEncrypt, transform, useValidationSymAlgo, useLegacyMode);
                if (!fEncrypt && flag)
                {
                    int srcOffset = useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption;
                    int count = src.Length - srcOffset;
                    if (count < 0)
                    {
                        throw new Exception();
                    }
                    buffer4 = new byte[count];
                    Buffer.BlockCopy(src, srcOffset, buffer4, 0, count);
                }
                else
                {
                    buffer4 = src;
                }
                if ((!fEncrypt && (modifier != null)) && (modifier.Length > 0))
                {
                    bool flag2 = false;
                    for (int i = 0; i < modifier.Length; i++)
                    {
                        if (buffer4[(buffer4.Length - modifier.Length) + i] != modifier[i])
                        {
                            flag2 = true;
                        }
                    }
                    if (flag2)
                    {
                        throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data"));
                    }
                    byte[] buffer5 = new byte[buffer4.Length - modifier.Length];
                    Buffer.BlockCopy(buffer4, 0, buffer5, 0, buffer5.Length);
                    buffer4 = buffer5;
                }
                if (fEncrypt && signData)
                {
                    byte[] buffer6 = HashData(buffer4, null, 0, buffer4.Length);
                    byte[] buffer7 = new byte[buffer4.Length + buffer6.Length];
                    Buffer.BlockCopy(buffer4, 0, buffer7, 0, buffer4.Length);
                    Buffer.BlockCopy(buffer6, 0, buffer7, buffer4.Length, buffer6.Length);
                    buffer4 = buffer7;
                }
                buffer8 = buffer4;
            }
            catch
            {
                throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data"));
            }
            return buffer8;
        }
        internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length,
                                                    bool useValidationSymAlgo, bool useLegacyMode, IVType ivType, bool signData)
        {
            /* This algorithm is used to perform encryption or decryption of a buffer, along with optional signing (for encryption)
             * or signature verification (for decryption). Possible operation modes are:
             * 
             * ENCRYPT + SIGN DATA (fEncrypt = true, signData = true)
             * Input: buf represents plaintext to encrypt, modifier represents data to be appended to buf (but isn't part of the plaintext itself)
             * Output: E(iv + buf + modifier) + HMAC(E(iv + buf + modifier))
             * 
             * ONLY ENCRYPT DATA (fEncrypt = true, signData = false)
             * Input: buf represents plaintext to encrypt, modifier represents data to be appended to buf (but isn't part of the plaintext itself)
             * Output: E(iv + buf + modifier)
             * 
             * VERIFY + DECRYPT DATA (fEncrypt = false, signData = true)
             * Input: buf represents ciphertext to decrypt, modifier represents data to be removed from the end of the plaintext (since it's not really plaintext data)
             * Input (buf): E(iv + m + modifier) + HMAC(E(iv + m + modifier))
             * Output: m
             * 
             * ONLY DECRYPT DATA (fEncrypt = false, signData = false)
             * Input: buf represents ciphertext to decrypt, modifier represents data to be removed from the end of the plaintext (since it's not really plaintext data)
             * Input (buf): E(iv + plaintext + modifier)
             * Output: m
             * 
             * The 'iv' in the above descriptions isn't an actual IV. Rather, if ivType = IVType.Random, we'll prepend random bytes ('iv')
             * to the plaintext before feeding it to the crypto algorithms. Introducing randomness early in the algorithm prevents users
             * from inspecting two ciphertexts to see if the plaintexts are related. If ivType = IVType.None, then 'iv' is simply
             * an empty string. If ivType = IVType.Hash, we use a non-keyed hash of the plaintext.
             * 
             * The 'modifier' in the above descriptions is a piece of metadata that should be encrypted along with the plaintext but
             * which isn't actually part of the plaintext itself. It can be used for storing things like the user name for whom this
             * plaintext was generated, the page that generated the plaintext, etc. On decryption, the modifier parameter is compared
             * against the modifier stored in the crypto stream, and it is stripped from the message before the plaintext is returned.
             * 
             * In all cases, if something goes wrong (e.g. invalid padding, invalid signature, invalid modifier, etc.), a generic exception is thrown.
             */

            try {
                EnsureConfig();

                if (!fEncrypt && signData) {
                    if (start != 0 || length != buf.Length) {
                        // These transformations assume that we're operating on buf in its entirety and
                        // not on any subset of buf, so we'll just replace buf with the particular subset
                        // we're interested in.
                        byte[] bTemp = new byte[length];
                        Buffer.BlockCopy(buf, start, bTemp, 0, length);
                        buf = bTemp;
                        start = 0;
                    }

                    // buf actually contains E(iv + m + modifier) + HMAC(E(iv + m + modifier)), so we need to verify and strip off the signature
                    buf = GetUnHashedData(buf);
                    // At this point, buf contains only E(iv + m + modifier) if the signature check succeeded.

                    if (buf == null) {
                        // signature verification failed
                        throw new HttpException(SR.GetString(SR.Unable_to_validate_data));
                    }

                    // need to fix up again since GetUnhashedData() returned a different array
                    length = buf.Length;
                }

                if (useLegacyMode)
                    useLegacyMode = _UsingCustomEncryption; // only use legacy mode for custom algorithms

                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                ICryptoTransform cryptoTransform = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode);
                CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write);

                // DevDiv Bugs 137864: Add IV to beginning of data to be encrypted.
                // IVType.None is used by MembershipProvider which requires compatibility even in SP2 mode (and will set signData = false).
                // MSRC 10405: If signData is set to true, we must generate an IV.
                bool createIV = signData || ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1));

                if (fEncrypt && createIV)
                {
                    int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption);
                    byte[] iv = null;

                    switch (ivType) {
                        case IVType.Hash:
                            // iv := H(buf)
                            iv = GetIVHash(buf, ivLength);
                            break;

                        case IVType.Random:
                            // iv := [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();

                // At this point:
                // If fEncrypt = true (encrypting), paddedData := Enc(iv + buf + modifier)
                // If fEncrypt = false (decrypting), paddedData := iv + plaintext + modifier

                byte[] bData;
                cs.Close();

                // In ASP.NET 2.0, we pool ICryptoTransform objects, and this returns that ICryptoTransform
                // to the pool. In ASP.NET 4.0, this just disposes of the ICryptoTransform object.
                ReturnCryptoTransform(fEncrypt, cryptoTransform, useValidationSymAlgo, useLegacyMode);

                // DevDiv Bugs 137864: Strip IV from beginning of unencrypted data
                if (!fEncrypt && createIV)
                {
                    // strip off the first bytes that were random bits
                    int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption);
                    int bDataLength = paddedData.Length - ivLength;
                    if (bDataLength < 0) {
                        throw new HttpException(SR.GetString(SR.Unable_to_validate_data));
                    }

                    bData = new byte[bDataLength];
                    Buffer.BlockCopy(paddedData, ivLength, bData, 0, bDataLength);
                }
                else
                {
                    bData = paddedData;
                }

                // At this point:
                // If fEncrypt = true (encrypting), bData := Enc(iv + buf + modifier)
                // If fEncrypt = false (decrypting), bData := plaintext + modifier

                if (!fEncrypt && modifier != null && modifier.Length > 0)
                {
                    // MSRC 10405: Crypto board suggests blinding where signature failed
                    // to prevent timing attacks.
                    bool modifierCheckFailed = false;
                    for(int iter=0; iter<modifier.Length; iter++)
                        if (bData[bData.Length - modifier.Length + iter] != modifier[iter])
                            modifierCheckFailed = true;
                    if (modifierCheckFailed) {
                        throw new HttpException(SR.GetString(SR.Unable_to_validate_data));
                    }

                    byte[] bData2 = new byte[bData.Length - modifier.Length];
                    Buffer.BlockCopy(bData, 0, bData2, 0, bData2.Length);
                    bData = bData2;
                }

                // At this point:
                // If fEncrypt = true (encrypting), bData := Enc(iv + buf + modifier)
                // If fEncrypt = false (decrypting), bData := plaintext

                if (fEncrypt && signData) {
                    byte[] hmac = HashData(bData, null, 0, bData.Length);
                    byte[] bData2 = new byte[bData.Length + hmac.Length];

                    Buffer.BlockCopy(bData, 0, bData2, 0, bData.Length);
                    Buffer.BlockCopy(hmac, 0, bData2, bData.Length, hmac.Length);
                    bData = bData2;
                }

                // At this point:
                // If fEncrypt = true (encrypting), bData := Enc(iv + buf + modifier) + HMAC(Enc(iv + buf + modifier))
                // If fEncrypt = false (decrypting), bData := plaintext

                // And we're done
                return bData;
            } catch {
                // It's important that we don't propagate the original exception here as we don't want a production
                // server which has unintentionally left YSODs enabled to leak cryptographic information.
                throw new HttpException(SR.GetString(SR.Unable_to_validate_data));
            }
        }
 internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType)
 {
     return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, !AppSettings.UseLegacyEncryption);
 }
        internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType, bool signData)
        {
            byte[] buffer8;
            try
            {
                byte[] buffer4;
                EnsureConfig();
                if (!fEncrypt && signData)
                {
                    if ((start != 0) || (length != buf.Length))
                    {
                        byte[] dst = new byte[length];
                        Buffer.BlockCopy(buf, start, dst, 0, length);
                        buf   = dst;
                        start = 0;
                    }
                    buf = GetUnHashedData(buf);
                    if (buf == null)
                    {
                        throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data"));
                    }
                    length = buf.Length;
                }
                if (useLegacyMode)
                {
                    useLegacyMode = _UsingCustomEncryption;
                }
                MemoryStream     stream    = new MemoryStream();
                ICryptoTransform transform = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode);
                CryptoStream     stream2   = new CryptoStream(stream, transform, CryptoStreamMode.Write);
                bool             flag      = signData || ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1));
                if (fEncrypt && flag)
                {
                    int    ivLength = useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption;
                    byte[] data     = null;
                    switch (ivType)
                    {
                    case IVType.Random:
                        data = new byte[ivLength];
                        RandomNumberGenerator.GetBytes(data);
                        break;

                    case IVType.Hash:
                        data = GetIVHash(buf, ivLength);
                        break;
                    }
                    stream2.Write(data, 0, data.Length);
                }
                stream2.Write(buf, start, length);
                if (fEncrypt && (modifier != null))
                {
                    stream2.Write(modifier, 0, modifier.Length);
                }
                stream2.FlushFinalBlock();
                byte[] src = stream.ToArray();
                stream2.Close();
                ReturnCryptoTransform(fEncrypt, transform, useValidationSymAlgo, useLegacyMode);
                if (!fEncrypt && flag)
                {
                    int srcOffset = useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption;
                    int count     = src.Length - srcOffset;
                    if (count < 0)
                    {
                        throw new Exception();
                    }
                    buffer4 = new byte[count];
                    Buffer.BlockCopy(src, srcOffset, buffer4, 0, count);
                }
                else
                {
                    buffer4 = src;
                }
                if ((!fEncrypt && (modifier != null)) && (modifier.Length > 0))
                {
                    bool flag2 = false;
                    for (int i = 0; i < modifier.Length; i++)
                    {
                        if (buffer4[(buffer4.Length - modifier.Length) + i] != modifier[i])
                        {
                            flag2 = true;
                        }
                    }
                    if (flag2)
                    {
                        throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data"));
                    }
                    byte[] buffer5 = new byte[buffer4.Length - modifier.Length];
                    Buffer.BlockCopy(buffer4, 0, buffer5, 0, buffer5.Length);
                    buffer4 = buffer5;
                }
                if (fEncrypt && signData)
                {
                    byte[] buffer6 = HashData(buffer4, null, 0, buffer4.Length);
                    byte[] buffer7 = new byte[buffer4.Length + buffer6.Length];
                    Buffer.BlockCopy(buffer4, 0, buffer7, 0, buffer4.Length);
                    Buffer.BlockCopy(buffer6, 0, buffer7, buffer4.Length, buffer6.Length);
                    buffer4 = buffer7;
                }
                buffer8 = buffer4;
            }
            catch
            {
                throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data"));
            }
            return(buffer8);
        }
        internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length,
                                                    bool useValidationSymAlgo, bool useLegacyMode, IVType ivType)
        {
            // MSRC 10405: Encryption is not sufficient to prevent a malicious user from tampering with the data, and the result of decryption can
            // be used to discover information about the plaintext (such as via a padding or decryption oracle). We must sign anything that we
            // encrypt to ensure that end users can't abuse our encryption routines.

            // the new encrypt-then-sign behavior for everything EXCEPT Membership / MachineKey. We need to make it very clear that setting this
            // to 'false' is a Very Bad Thing(tm).
            return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, !AppSettings.UseLegacyEncryption);
        }
Beispiel #6
0
    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 < modifier.Length; iter++)
            {
                if (bData[bData.Length - modifier.Length + iter] != modifier[iter])
                {
                    throw new HttpException(SR.GetString(SR.Unable_to_validate_data));
                }
            }
            byte[] bData2 = new byte[bData.Length - modifier.Length];
            Buffer.BlockCopy(bData, 0, bData2, 0, bData2.Length);
            bData = bData2;
        }
        return(bData);
    }
 internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType)
 {
     return(EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, !AppSettings.UseLegacyEncryption));
 }
 public static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType, bool signData)
 {
     return EncryptOrDecryptDataFunc(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, signData);
 }
 internal static string EncryptStringWithIV(string s, IVType ivType)
 {
     byte[] bytes = Encoding.UTF8.GetBytes(s);
     return HttpServerUtility.UrlTokenEncode(MachineKeySection.EncryptOrDecryptData(true, bytes, null, 0, bytes.Length, false, false, ivType));
 }
 internal static string DecryptStringWithIV(string s, IVType ivType)
 {
     if (s == null)
     {
         return null;
     }
     byte[] buf = HttpServerUtility.UrlTokenDecode(s);
     if (buf != null)
     {
         buf = MachineKeySection.EncryptOrDecryptData(false, buf, null, 0, buf.Length, false, false, ivType);
     }
     if (buf == null)
     {
         throw new HttpException(System.Web.SR.GetString("ViewState_InvalidViewState"));
     }
     return Encoding.UTF8.GetString(buf);
 }
Beispiel #11
0
 public Variable(IVType value)
 {
     _value = value;
 }
Beispiel #12
0
		public Variable(IVType value)
		{ _value = value; }