/// <summary> /// Creates a new instance of a <see cref="CascadingSymmetricKey" /> using the specified buffer. /// </summary> /// <param name="buffer"> /// A binary representation of a <see cref="CascadingSymmetricKey" />. /// </param> /// <returns> /// A new instance of a <see cref="CascadingSymmetricKey" />. /// </returns> /// <exception cref="ArgumentException"> /// <paramref name="buffer" /> is invalid. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="buffer" /> is <see langword="null" />. /// </exception> public static CascadingSymmetricKey FromBuffer(SecureBuffer buffer) { buffer.RejectIf().IsNull(nameof(buffer)).OrIf(argument => argument.Length != SerializedLength, nameof(buffer), "The specified buffer is invalid."); try { var keys = (SecureSymmetricKey[])null; buffer.Access(pinnedBuffer => { // Interrogate the final 16 bits to determine the depth. var keyLength = SecureSymmetricKey.SerializedLength; var depth = BitConverter.ToUInt16(pinnedBuffer, (SerializedLength - sizeof(UInt16))); keys = new SecureSymmetricKey[depth]; for (var i = 0; i < depth; i++) { using (var secureBuffer = new SecureBuffer(keyLength)) { secureBuffer.Access(keyBuffer => { // Copy out the key buffers. Array.Copy(pinnedBuffer, (keyLength * i), keyBuffer, 0, keyLength); }); keys[i] = SecureSymmetricKey.FromBuffer(secureBuffer); } } }); return(new CascadingSymmetricKey(keys)); } catch { throw new ArgumentException("The specified buffer is invalid.", nameof(buffer)); } }
/// <summary> /// Creates a new instance of a <see cref="SecureSymmetricKey" /> using the specified buffer. /// </summary> /// <param name="buffer"> /// A binary representation of a <see cref="SecureSymmetricKey" />. /// </param> /// <returns> /// A new instance of a <see cref="SecureSymmetricKey" />. /// </returns> /// <exception cref="ArgumentException"> /// <paramref name="buffer" /> is invalid. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="buffer" /> is <see langword="null" />. /// </exception> public static SecureSymmetricKey FromBuffer(SecureBuffer buffer) { buffer.RejectIf().IsNull(nameof(buffer)).OrIf(argument => argument.Length != SerializedLength, nameof(buffer), "The specified buffer is invalid."); try { var result = (SecureSymmetricKey)null; buffer.Access(pinnedCiphertext => { using (var plaintextBuffer = new PinnedBuffer(SerializedPlaintextLength, true)) { using (var cipher = BufferEncryptionAlgorithm.ToCipher(RandomnessProvider)) { using (var plaintext = cipher.Decrypt(pinnedCiphertext, BufferEncryptionKey)) { Array.Copy(plaintext, 0, plaintextBuffer, 0, SerializedPlaintextLength); } } using (var keySource = new PinnedBuffer(KeySourceLengthInBytes, true)) { Array.Copy(plaintextBuffer, KeySourceBufferIndex, keySource, 0, KeySourceLengthInBytes); var algorithm = (SymmetricAlgorithmSpecification)plaintextBuffer[AlgorithmBufferIndex]; var derivationMode = (SecureSymmetricKeyDerivationMode)plaintextBuffer[DerivationModeBufferIndex]; result = new SecureSymmetricKey(algorithm, derivationMode, keySource); } } }); return(result); } catch { throw new ArgumentException("The specified buffer is invalid.", nameof(buffer)); } }