public AxCryptDataStream CreateEncryptedDataStream(AesKey hmacKey, long cipherTextLength, ProgressContext progress) { if (hmacKey == null) { throw new ArgumentNullException("hmacKey"); } if (progress == null) { throw new ArgumentNullException("progress"); } if (_disposed) { throw new ObjectDisposedException(GetType().FullName); } if (CurrentItemType != AxCryptItemType.Data) { throw new InvalidOperationException("GetEncryptedDataStream() was called when the reader is not positioned at the data."); } CurrentItemType = AxCryptItemType.EndOfStream; _hmacStream = new HmacStream(hmacKey); _hmacBufferStream.Position = 0; _hmacBufferStream.CopyTo(_hmacStream, OS.Current.StreamBufferSize); _expectedTotalHmacLength = _hmacBufferStream.Length + cipherTextLength; AxCryptDataStream encryptedDataStream = new AxCryptDataStream(_inputStream, _hmacStream, cipherTextLength); return encryptedDataStream; }
private void DecryptEncryptedDataStream(Stream outputPlaintextStream, ICryptoTransform decryptor, AxCryptDataStream encryptedDataStream, ProgressContext progress) { Exception savedExceptionIfCloseCausesCryptographicException = null; try { if (DocumentHeaders.IsCompressed) { using (CryptoStream deflatedPlaintextStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read)) { using (ZInputStream inflatedPlaintextStream = new ZInputStream(deflatedPlaintextStream)) { try { CopyToWithCount(inflatedPlaintextStream, outputPlaintextStream, encryptedDataStream, progress); } catch (Exception ex) { savedExceptionIfCloseCausesCryptographicException = ex; throw; } } } } else { using (Stream plainStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read)) { try { CopyToWithCount(plainStream, outputPlaintextStream, encryptedDataStream, progress); } catch (Exception ex) { savedExceptionIfCloseCausesCryptographicException = ex; throw; } } } } catch (CryptographicException) { throw savedExceptionIfCloseCausesCryptographicException; } }
public static void TestAxCryptDataStream() { string streamData = "This is some data in the streamEXTRA"; using (Stream inputStream = new MemoryStream()) { byte[] streamBytes = Encoding.UTF8.GetBytes(streamData); inputStream.Write(streamBytes, 0, streamBytes.Length); using (Stream hmacStream = new MemoryStream()) { Assert.Throws<ArgumentNullException>(() => { using (AxCryptDataStream axCryptDataStream = new AxCryptDataStream(null, hmacStream, inputStream.Length)) { } }, "An input stream must be given, it cannot be null."); Assert.Throws<ArgumentNullException>(() => { using (AxCryptDataStream axCryptDataStream = new AxCryptDataStream(inputStream, null, inputStream.Length)) { } }, "An HmacStream must be given, it cannot be null."); Assert.Throws<ArgumentOutOfRangeException>(() => { using (AxCryptDataStream axCryptDataStream = new AxCryptDataStream(inputStream, hmacStream, -inputStream.Length)) { } }, "Negative length is not allowed."); inputStream.Position = 0; using (AxCryptDataStream axCryptDataStream = new AxCryptDataStream(inputStream, hmacStream, inputStream.Length - 5)) { Assert.Throws<NotSupportedException>(() => { axCryptDataStream.Seek(0, SeekOrigin.Begin); }, "Seek is not supported."); Assert.Throws<NotSupportedException>(() => { axCryptDataStream.SetLength(0); }, "SetLength is not supported."); Assert.Throws<NotSupportedException>(() => { axCryptDataStream.Write(new byte[1], 0, 1); }, "Write is not supported."); Assert.Throws<NotSupportedException>(() => { axCryptDataStream.Position = 0; }, "Setting the position is not supported."); Assert.Throws<NotSupportedException>(() => { axCryptDataStream.Flush(); }, "Flush is not supported, and not meaningful on a read-only stream."); Assert.That(axCryptDataStream.CanRead, Is.True, "AxCryptDataStream can be read."); Assert.That(axCryptDataStream.CanSeek, Is.True, "AxCryptDataStream is a forward only reader stream, but it does support Length and Position therefore it reports that it can Seek."); Assert.That(axCryptDataStream.CanWrite, Is.False, "AxCryptDataStream is a forward only reader stream, it does not support writing."); Assert.That(axCryptDataStream.Length, Is.EqualTo(inputStream.Length - 5), "The stream should report the length provided in the constructor."); inputStream.Position = 5; Assert.That(axCryptDataStream.Position, Is.EqualTo(0), "The original position should be zero, regardless of the actual position of the input stream."); inputStream.Position = 0; byte[] buffer = new byte[3]; int count; int total = 0; while ((count = axCryptDataStream.Read(buffer, 0, buffer.Length)) > 0) { total += count; } Assert.That(total, Is.EqualTo(inputStream.Length - 5), "The AxCryptDataStream should be limited to the length provided, not the backing stream."); Assert.That(hmacStream.Length, Is.EqualTo(total), "The hmac stream should have all data read written to it."); } } } }