public void EncryptTo(Stream inputStream, Stream outputStream, AxCryptOptions options) { if (inputStream == null) { throw new ArgumentNullException("inputStream"); } if (outputStream == null) { throw new ArgumentNullException("outputStream"); } if (!outputStream.CanSeek) { throw new ArgumentException("The output stream must support seek in order to back-track and write the HMAC."); } if (options.HasMask(AxCryptOptions.EncryptWithCompression) && options.HasMask(AxCryptOptions.EncryptWithoutCompression)) { throw new ArgumentException("Invalid options, cannot specify both with and without compression."); } if (!options.HasMask(AxCryptOptions.EncryptWithCompression) && !options.HasMask(AxCryptOptions.EncryptWithoutCompression)) { throw new ArgumentException("Invalid options, must specify either with or without compression."); } bool isCompressed = options.HasMask(AxCryptOptions.EncryptWithCompression); DocumentHeaders.IsCompressed = isCompressed; DocumentHeaders.WriteWithoutHmac(outputStream); using (ICryptoTransform encryptor = DataCrypto.EncryptingTransform()) { long outputStartPosition = outputStream.Position; using (Stream encryptingStream = New <CryptoStreamBase>().Initialize(new NonClosingStream(outputStream), encryptor, CryptoStreamMode.Write)) { if (isCompressed) { EncryptWithCompressionInternal(DocumentHeaders, inputStream, encryptingStream); } else { DocumentHeaders.PlaintextLength = StreamExtensions.CopyTo(inputStream, encryptingStream); } } outputStream.Flush(); DocumentHeaders.CipherTextLength = outputStream.Position - outputStartPosition; using (V1HmacStream outputHmacStream = new V1HmacStream(DocumentHeaders.HmacSubkey.Key, outputStream)) { DocumentHeaders.WriteWithHmac(outputHmacStream); outputHmacStream.ReadFrom(outputStream); DocumentHeaders.Headers.Hmac = outputHmacStream.HmacResult; } // Rewind and rewrite the headers, now with the updated HMAC DocumentHeaders.WriteWithoutHmac(outputStream); outputStream.Position = outputStream.Length; } }
public static void TestBadArguments() { DocumentHeaders documentHeaders = new DocumentHeaders(new AesKey()); Assert.Throws<ArgumentNullException>(() => { documentHeaders.WriteWithHmac(null); }); Assert.Throws<ArgumentNullException>(() => { documentHeaders.WriteWithoutHmac(null); }); Assert.Throws<ArgumentNullException>(() => { documentHeaders.Hmac = null; }); }
public static void TestBadArguments() { DocumentHeaders documentHeaders = new DocumentHeaders(new AesKey()); Assert.Throws <ArgumentNullException>(() => { documentHeaders.WriteWithHmac(null); }); Assert.Throws <ArgumentNullException>(() => { documentHeaders.WriteWithoutHmac(null); }); Assert.Throws <ArgumentNullException>(() => { documentHeaders.Hmac = null; }); }
/// <summary> /// Write a copy of the current encrypted stream. Used to change meta-data /// and encryption key(s) etc. /// </summary> /// <param name="outputStream"></param> public void CopyEncryptedTo(DocumentHeaders outputDocumentHeaders, Stream cipherStream, ProgressContext progress) { if (outputDocumentHeaders == null) { throw new ArgumentNullException("outputDocumentHeaders"); } if (cipherStream == null) { throw new ArgumentNullException("cipherStream"); } if (!cipherStream.CanSeek) { throw new ArgumentException("The output stream must support seek in order to back-track and write the HMAC."); } if (DocumentHeaders == null) { throw new InternalErrorException("Document headers are not loaded"); } using (HmacStream hmacStreamOutput = new HmacStream(outputDocumentHeaders.HmacSubkey.Key, cipherStream)) { outputDocumentHeaders.WriteWithHmac(hmacStreamOutput); using (AxCryptDataStream encryptedDataStream = _reader.CreateEncryptedDataStream(DocumentHeaders.HmacSubkey.Key, DocumentHeaders.CipherTextLength, progress)) { CopyToWithCount(encryptedDataStream, hmacStreamOutput, progress); if (_reader.Hmac != DocumentHeaders.Hmac) { throw new Axantum.AxCrypt.Core.Runtime.InvalidDataException("HMAC validation error in the input stream.", ErrorStatus.HmacValidationError); } } outputDocumentHeaders.Hmac = hmacStreamOutput.HmacResult; // Rewind and rewrite the headers, now with the updated HMAC outputDocumentHeaders.WriteWithoutHmac(cipherStream); cipherStream.Position = cipherStream.Length; } }
/// <summary> /// Encrypt a stream with a given set of headers and write to an output stream. The caller is responsible for consistency and completeness /// of the headers. Headers that are not known until encryption and compression are added here. /// </summary> /// <param name="outputDocumentHeaders"></param> /// <param name="inputStream"></param> /// <param name="outputStream"></param> public void EncryptTo(DocumentHeaders outputDocumentHeaders, Stream inputStream, Stream outputStream, AxCryptOptions options, ProgressContext progress) { if (outputDocumentHeaders == null) { throw new ArgumentNullException("outputDocumentHeaders"); } if (inputStream == null) { throw new ArgumentNullException("inputStream"); } if (outputStream == null) { throw new ArgumentNullException("outputStream"); } if (progress == null) { throw new ArgumentNullException("progress"); } if (!outputStream.CanSeek) { throw new ArgumentException("The output stream must support seek in order to back-track and write the HMAC."); } if (options.HasMask(AxCryptOptions.EncryptWithCompression) && options.HasMask(AxCryptOptions.EncryptWithoutCompression)) { throw new ArgumentException("Invalid options, cannot specify both with and without compression."); } if (!options.HasMask(AxCryptOptions.EncryptWithCompression) && !options.HasMask(AxCryptOptions.EncryptWithoutCompression)) { throw new ArgumentException("Invalid options, must specify either with or without compression."); } bool isCompressed = options.HasMask(AxCryptOptions.EncryptWithCompression); outputDocumentHeaders.IsCompressed = isCompressed; outputDocumentHeaders.WriteWithoutHmac(outputStream); using (ICryptoTransform encryptor = DataCrypto.CreateEncryptingTransform()) { long outputStartPosition = outputStream.Position; using (CryptoStream encryptingStream = new CryptoStream(new NonClosingStream(outputStream), encryptor, CryptoStreamMode.Write)) { if (isCompressed) { EncryptWithCompressionInternal(outputDocumentHeaders, inputStream, encryptingStream, progress); } else { outputDocumentHeaders.PlaintextLength = CopyToWithCount(inputStream, encryptingStream, progress); } } outputStream.Flush(); outputDocumentHeaders.CipherTextLength = outputStream.Position - outputStartPosition; using (HmacStream outputHmacStream = new HmacStream(outputDocumentHeaders.HmacSubkey.Key, outputStream)) { outputDocumentHeaders.WriteWithHmac(outputHmacStream); outputHmacStream.ReadFrom(outputStream); outputDocumentHeaders.Hmac = outputHmacStream.HmacResult; } // Rewind and rewrite the headers, now with the updated HMAC outputDocumentHeaders.WriteWithoutHmac(outputStream); outputStream.Position = outputStream.Length; } }