Example #1
0
        /// <summary>
        /// Encode the data.  The data is encrypted using the default encryption algorithm (AES-256),
        /// then the AES key is encrypted using RSA and the RSA public key is appended.
        /// </summary>
        /// <param name="value">The data to encode</param>
        /// <exception cref="ArgumentNullException">The argument 'value' is null.</exception>
        /// <exception cref="ArgumentException">The argument 'value' contains zero bytes.</exception>
        /// <exception cref="InvalidOperationException">The EncryptionKey is null.</exception>
        /// <returns>Encoded data</returns>
        public override byte[] Encode(byte[] value)
        {
            if (null == value)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
            }

            if (0 == value.Length)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.ID6044));
            }

            RSA encryptionKey = EncryptionKey;

            if (null == encryptionKey)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6043));
            }

            byte[] rsaHash;
            byte[] encryptedKeyAndIV;
            byte[] encryptedData;

            using (HashAlgorithm hash = CryptoHelper.CreateHashAlgorithm(_hashName))
            {
                rsaHash = hash.ComputeHash(Encoding.UTF8.GetBytes(encryptionKey.ToXmlString(false)));
            }

            using (SymmetricAlgorithm encryptionAlgorithm = CryptoHelper.NewDefaultEncryption())
            {
                encryptionAlgorithm.GenerateIV();
                encryptionAlgorithm.GenerateKey();

                using (ICryptoTransform encryptor = encryptionAlgorithm.CreateEncryptor())
                {
                    encryptedData = encryptor.TransformFinalBlock(value, 0, value.Length);
                }

                RSACryptoServiceProvider provider = encryptionKey as RSACryptoServiceProvider;

                if (provider == null)
                {
                    throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6041));
                }

                //
                // Concatenate the Key and IV in an attempt to avoid two minimum block lengths in the cookie
                //
                byte[] keyAndIV = new byte[encryptionAlgorithm.Key.Length + encryptionAlgorithm.IV.Length];
                Array.Copy(encryptionAlgorithm.Key, keyAndIV, encryptionAlgorithm.Key.Length);
                Array.Copy(encryptionAlgorithm.IV, 0, keyAndIV, encryptionAlgorithm.Key.Length, encryptionAlgorithm.IV.Length);

                encryptedKeyAndIV = provider.Encrypt(keyAndIV, true);
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write(rsaHash);
                    bw.Write(encryptedKeyAndIV.Length);
                    bw.Write(encryptedKeyAndIV);
                    bw.Write(encryptedData.Length);
                    bw.Write(encryptedData);
                    bw.Flush();
                }

                return(ms.ToArray());
            }
        }
Example #2
0
        /// <summary>
        /// Decrypts data using the provided RSA key(s) to decrypt an AES key, which decrypts the cookie.
        /// </summary>
        /// <param name="encoded">The encoded data</param>
        /// <returns>The decoded data</returns>
        /// <exception cref="ArgumentNullException">The argument 'encoded' is null.</exception>
        /// <exception cref="ArgumentException">The argument 'encoded' contains zero bytes.</exception>
        /// <exception cref="NotSupportedException">The platform does not support the requested algorithm.</exception>
        /// <exception cref="InvalidOperationException">There are no decryption keys or none of the keys match.</exception>
        public override byte[] Decode(byte[] encoded)
        {
            if (null == encoded)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encoded");
            }

            if (0 == encoded.Length)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("encoded", SR.GetString(SR.ID6045));
            }

            ReadOnlyCollection <RSA> decryptionKeys = DecryptionKeys;

            if (0 == decryptionKeys.Count)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6039));
            }

            byte[] encryptedKeyAndIV;
            byte[] encryptedData;
            byte[] rsaHash;
            RSA    rsaDecryptionKey = null;

            using (HashAlgorithm hash = CryptoHelper.CreateHashAlgorithm(_hashName))
            {
                int hashSizeInBytes = hash.HashSize / 8;
                using (BinaryReader br = new BinaryReader(new MemoryStream(encoded)))
                {
                    rsaHash = br.ReadBytes(hashSizeInBytes);
                    int encryptedKeyAndIVSize = br.ReadInt32();
                    if (encryptedKeyAndIVSize < 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1006, encryptedKeyAndIVSize)));
                    }
                    //
                    // Enforce upper limit on key size to prevent large buffer allocation in br.ReadBytes()
                    //

                    if (encryptedKeyAndIVSize > encoded.Length)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1007)));
                    }
                    encryptedKeyAndIV = br.ReadBytes(encryptedKeyAndIVSize);

                    int encryptedDataSize = br.ReadInt32();
                    if (encryptedDataSize < 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1008, encryptedDataSize)));
                    }
                    //
                    // Enforce upper limit on data size to prevent large buffer allocation in br.ReadBytes()
                    //
                    if (encryptedDataSize > encoded.Length)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1009)));
                    }

                    encryptedData = br.ReadBytes(encryptedDataSize);
                }

                //
                // Find the decryption key matching the one in XML
                //
                foreach (RSA key in decryptionKeys)
                {
                    byte[] hashedKey = hash.ComputeHash(Encoding.UTF8.GetBytes(key.ToXmlString(false)));
                    if (CryptoHelper.IsEqual(hashedKey, rsaHash))
                    {
                        rsaDecryptionKey = key;
                        break;
                    }
                }
            }

            if (rsaDecryptionKey == null)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6040));
            }

            RSACryptoServiceProvider rsaProvider = rsaDecryptionKey as RSACryptoServiceProvider;

            if (rsaProvider == null)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6041));
            }

            byte[] decryptedKeyAndIV = rsaProvider.Decrypt(encryptedKeyAndIV, true);

            using (SymmetricAlgorithm symmetricAlgorithm = CryptoHelper.NewDefaultEncryption())
            {
                byte[] decryptionKey = new byte[symmetricAlgorithm.KeySize / 8];

                //
                // Ensure there is sufficient length in the descrypted key and IV buffer for an IV.
                //
                if (decryptedKeyAndIV.Length < decryptionKey.Length)
                {
                    throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6047, decryptedKeyAndIV.Length, decryptionKey.Length));
                }

                byte[] decryptionIV = new byte[decryptedKeyAndIV.Length - decryptionKey.Length];

                //
                // Copy key into its own buffer.
                // The remaining bytes are the IV copy those into a buffer as well.
                //
                Array.Copy(decryptedKeyAndIV, decryptionKey, decryptionKey.Length);
                Array.Copy(decryptedKeyAndIV, decryptionKey.Length, decryptionIV, 0, decryptionIV.Length);

                using (ICryptoTransform decryptor = symmetricAlgorithm.CreateDecryptor(decryptionKey, decryptionIV))
                {
                    return(decryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length));
                }
            }
        }
Example #3
0
        public override string this[int index]
        {
            get
            {
                DiagnosticUtility.DebugAssert(index >= 0 && index < Count, "The index is out of range. It should be greater than or equal to 0 and less than" + Count.ToString());
                switch (index)
                {
                case 0: return(String0);

                case 1: return(String1);

                case 2: return(String2);

                case 3: return(String3);

                case 4: return(String4);

                case 5: return(String5);

                case 6: return(String6);

                case 7: return(String7);

                case 8: return(String8);

                case 9: return(String9);

                case 10: return(String10);

                case 11: return(String11);

                case 12: return(String12);

                case 13: return(String13);

                case 14: return(String14);

                case 15: return(String15);

                case 16: return(String16);

                case 17: return(String17);

                case 18: return(String18);

                case 19: return(String19);

                case 20: return(String20);

                case 21: return(String21);

                case 22: return(String22);

                case 23: return(String23);

                case 24: return(String24);

                case 25: return(String25);

                case 26: return(String26);

                case 27: return(String27);

                case 28: return(String28);

                case 29: return(String29);

                case 30: return(String30);

                case 31: return(String31);

                case 32: return(String32);

                case 33: return(String33);

                case 34: return(String34);

                case 35: return(String35);

                case 36: return(String36);

                case 37: return(String37);

                case 38: return(String38);

                case 39: return(String39);

                case 40: return(String40);

                case 41: return(String41);

                case 42: return(String42);

                case 43: return(String43);

                case 44: return(String44);

                case 45: return(String45);

                case 46: return(String46);

                case 47: return(String47);

                case 48: return(String48);

                case 49: return(String49);

                case 50: return(String50);

                case 51: return(String51);

                case 52: return(String52);

                case 53: return(String53);

                case 54: return(String54);

                case 55: return(String55);

                case 56: return(String56);

                case 57: return(String57);

                case 58: return(String58);

                case 59: return(String59);

                case 60: return(String60);

                case 61: return(String61);

                case 62: return(String62);

                case 63: return(String63);

                case 64: return(String64);

                case 65: return(String65);

                case 66: return(String66);

                case 67: return(String67);

                case 68: return(String68);

                case 69: return(String69);

                case 70: return(String70);

                case 71: return(String71);

                case 72: return(String72);

                case 73: return(String73);

                case 74: return(String74);

                case 75: return(String75);

                case 76: return(String76);

                case 77: return(String77);

                case 78: return(String78);

                case 79: return(String79);

                case 80: return(String80);

                case 81: return(String81);

                case 82: return(String82);

                case 83: return(String83);

                case 84: return(String84);

                case 85: return(String85);

                case 86: return(String86);

                case 87: return(String87);

                case 88: return(String88);

                case 89: return(String89);

                case 90: return(String90);

                case 91: return(String91);

                case 92: return(String92);

                case 93: return(String93);

                case 94: return(String94);

                case 95: return(String95);

                case 96: return(String96);

                case 97: return(String97);

                case 98: return(String98);

                case 99: return(String99);

                case 100: return(String100);

                case 101: return(String101);

                case 102: return(String102);

                case 103: return(String103);

                case 104: return(String104);

                case 105: return(String105);

                case 106: return(String106);

                case 107: return(String107);

                case 108: return(String108);

                case 109: return(String109);

                case 110: return(String110);

                case 111: return(String111);

                case 112: return(String112);

                case 113: return(String113);

                case 114: return(String114);

                case 115: return(String115);

                case 116: return(String116);

                case 117: return(String117);

                case 118: return(String118);

                case 119: return(String119);

                case 120: return(String120);

                case 121: return(String121);

                case 122: return(String122);

                case 123: return(String123);

                case 124: return(String124);

                case 125: return(String125);

                case 126: return(String126);

                case 127: return(String127);

                case 128: return(String128);

                case 129: return(String129);

                case 130: return(String130);

                case 131: return(String131);

                case 132: return(String132);

                case 133: return(String133);

                case 134: return(String134);

                case 135: return(String135);

                case 136: return(String136);

                case 137: return(String137);

                case 138: return(String138);

                case 139: return(String139);

                case 140: return(String140);

                case 141: return(String141);

                case 142: return(String142);

                case 143: return(String143);

                case 144: return(String144);

                case 145: return(String145);

                case 146: return(String146);

                case 147: return(String147);

                case 148: return(String148);

                case 149: return(String149);

                case 150: return(String150);

                case 151: return(String151);

                case 152: return(String152);

                case 153: return(String153);

                case 154: return(String154);

                case 155: return(String155);

                case 156: return(String156);

                case 157: return(String157);

                case 158: return(String158);

                case 159: return(String159);

                case 160: return(String160);

                case 161: return(String161);

                case 162: return(String162);

                case 163: return(String163);

                case 164: return(String164);

                case 165: return(String165);

                case 166: return(String166);

                case 167: return(String167);

                case 168: return(String168);

                case 169: return(String169);

                case 170: return(String170);

                case 171: return(String171);

                case 172: return(String172);

                case 173: return(String173);

                case 174: return(String174);

                case 175: return(String175);

                case 176: return(String176);

                case 177: return(String177);

                case 178: return(String178);

                case 179: return(String179);

                case 180: return(String180);

                case 181: return(String181);

                case 182: return(String182);

                case 183: return(String183);

                case 184: return(String184);

                case 185: return(String185);

                case 186: return(String186);

                case 187: return(String187);

                case 188: return(String188);

                case 189: return(String189);

                case 190: return(String190);

                case 191: return(String191);

                case 192: return(String192);

                case 193: return(String193);

                case 194: return(String194);

                case 195: return(String195);

                case 196: return(String196);

                case 197: return(String197);

                case 198: return(String198);

                case 199: return(String199);

                case 200: return(String200);

                case 201: return(String201);

                case 202: return(String202);

                case 203: return(String203);

                case 204: return(String204);

                case 205: return(String205);

                case 206: return(String206);

                case 207: return(String207);

                case 208: return(String208);

                case 209: return(String209);

                case 210: return(String210);

                case 211: return(String211);

                case 212: return(String212);

                case 213: return(String213);

                case 214: return(String214);

                case 215: return(String215);

                case 216: return(String216);

                case 217: return(String217);

                case 218: return(String218);

                case 219: return(String219);

                case 220: return(String220);

                case 221: return(String221);

                case 222: return(String222);

                case 223: return(String223);

                case 224: return(String224);

                case 225: return(String225);

                case 226: return(String226);

                case 227: return(String227);

                case 228: return(String228);

                case 229: return(String229);

                case 230: return(String230);

                case 231: return(String231);

                case 232: return(String232);

                case 233: return(String233);

                case 234: return(String234);

                case 235: return(String235);

                case 236: return(String236);

                case 237: return(String237);

                case 238: return(String238);

                case 239: return(String239);

                case 240: return(String240);

                case 241: return(String241);

                case 242: return(String242);

                case 243: return(String243);

                case 244: return(String244);

                case 245: return(String245);

                case 246: return(String246);

                case 247: return(String247);

                case 248: return(String248);

                case 249: return(String249);

                case 250: return(String250);

                case 251: return(String251);

                case 252: return(String252);

                case 253: return(String253);

                case 254: return(String254);

                case 255: return(String255);

                case 256: return(String256);

                case 257: return(String257);

                case 258: return(String258);

                case 259: return(String259);

                case 260: return(String260);

                case 261: return(String261);

                case 262: return(String262);

                case 263: return(String263);

                case 264: return(String264);

                case 265: return(String265);

                case 266: return(String266);

                case 267: return(String267);

                case 268: return(String268);

                case 269: return(String269);

                case 270: return(String270);

                case 271: return(String271);

                case 272: return(String272);

                case 273: return(String273);

                case 274: return(String274);

                case 275: return(String275);

                case 276: return(String276);

                case 277: return(String277);

                case 278: return(String278);

                default: return(null);
                }
            }
        }
Example #4
0
 // 0 is an Invalid Handle
 SafeKeyHandle(IntPtr handle)
     : base(true)
 {
     DiagnosticUtility.DebugAssert(handle == IntPtr.Zero, "SafeKeyHandle constructor can only be called with IntPtr.Zero.");
     SetHandle(handle);
 }
Example #5
0
        public static unsafe int EncryptDecryptHelper(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool encrypt, bool isGssBlob)
        {
            SecurityBufferDescriptor sdcInOut = new SecurityBufferDescriptor(input.Length);

            SecurityBufferStruct[] unmanagedBuffer = new SecurityBufferStruct[input.Length];
            byte[][] buffers = new byte[input.Length][];
            fixed(void *unmanagedBufferPtr = unmanagedBuffer)
            {
                sdcInOut.UnmanagedPointer = unmanagedBufferPtr;
                GCHandle[] pinnedBuffers = new GCHandle[input.Length];
                try
                {
                    for (int i = 0; i < input.Length; ++i)
                    {
                        SecurityBuffer iBuffer = input[i];
                        unmanagedBuffer[i].count = iBuffer.size;
                        unmanagedBuffer[i].type  = iBuffer.type;
                        if (iBuffer.token == null || iBuffer.token.Length == 0)
                        {
                            unmanagedBuffer[i].token = IntPtr.Zero;
                        }
                        else
                        {
                            pinnedBuffers[i]         = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned);
                            unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset);
                            buffers[i] = iBuffer.token;
                        }
                    }
                    int errorCode;
                    if (encrypt)
                    {
                        errorCode = SafeDeleteContext.EncryptMessage(context, sdcInOut, sequenceNumber);
                    }
                    else
                    {
                        errorCode = SafeDeleteContext.DecryptMessage(context, sdcInOut, sequenceNumber);
                    }
                    // Marshalling back returned sizes (do not marshal the "token" field)
                    for (int i = 0; i < input.Length; ++i)
                    {
                        SecurityBuffer iBuffer = input[i];
                        iBuffer.size = unmanagedBuffer[i].count;
                        iBuffer.type = unmanagedBuffer[i].type;
                        if (iBuffer.size == 0)
                        {
                            iBuffer.offset = 0;
                            iBuffer.token  = null;
                        }
                        else if (isGssBlob && !encrypt && iBuffer.type == BufferType.Data)
                        {
                            iBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(iBuffer.size);
                            Marshal.Copy(unmanagedBuffer[i].token, iBuffer.token, 0, iBuffer.size);
                        }
                        else
                        {
                            checked
                            {
                                // Find the buffer this is inside of.  Usually they all point inside buffer 0.
                                int j;
                                for (j = 0; j < input.Length; j++)
                                {
                                    if (buffers[j] == null)
                                    {
                                        continue;
                                    }

                                    byte *bufferAddress = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0);
                                    if ((byte *)unmanagedBuffer[i].token >= bufferAddress &&
                                        (byte *)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length)
                                    {
                                        iBuffer.offset = (int)((byte *)unmanagedBuffer[i].token - bufferAddress);
                                        iBuffer.token  = buffers[j];
                                        break;
                                    }
                                }

                                if (j >= input.Length)
                                {
                                    iBuffer.size   = 0;
                                    iBuffer.offset = 0;
                                    iBuffer.token  = null;
                                }
                                if (!(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length)))
                                {
                                    DiagnosticUtility.DebugAssert(SR.GetString(SR.SspiWrapperEncryptDecryptAssert1, iBuffer.offset));
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiWrapperEncryptDecryptAssert1, iBuffer.offset)));
                                }
                                if (!(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset)))
                                {
                                    DiagnosticUtility.DebugAssert(SR.GetString(SR.SspiWrapperEncryptDecryptAssert2, iBuffer.size));
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiWrapperEncryptDecryptAssert2, iBuffer.size)));
                                }
                            }
                        }
                    }
                    return(errorCode);
                }
                finally
                {
                    for (int i = 0; i < pinnedBuffers.Length; ++i)
                    {
                        if (pinnedBuffers[i].IsAllocated)
                        {
                            pinnedBuffers[i].Free();
                        }
                    }
                }
            }
        }