/// <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()); } }
/// <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)); } } }
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); } } }
// 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); }
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(); } } } } }