public static void TestPrematureEndOfFile(CryptoImplementation cryptoImplementation) { SetupAssembly.AssemblySetupCrypto(cryptoImplementation); V1DocumentHeaders headers = new V1DocumentHeaders(new Passphrase("passphrase"), 10); using (MemoryStream stream = new MemoryStream()) { headers.WriteWithoutHmac(stream); stream.Position = 0; using (V1AxCryptReader reader = new V1AxCryptReader(new LookAheadStream(stream))) { AxCryptItemType lastItemType = AxCryptItemType.Undefined; while (reader.Read()) { lastItemType = reader.CurrentItemType; } Assert.That(lastItemType, Is.EqualTo(AxCryptItemType.Data)); Assert.That(reader.CurrentItemType, Is.EqualTo(AxCryptItemType.Data)); reader.SetStartOfData(); Assert.That(reader.Read(), Is.False); Assert.That(reader.CurrentItemType, Is.EqualTo(AxCryptItemType.EndOfStream)); Assert.That(reader.Read(), Is.False); Assert.That(reader.CurrentItemType, Is.EqualTo(AxCryptItemType.EndOfStream)); } } }
public void TestInvalidArguments() { using (Stream inputStream = FakeDataStore.ExpandableMemoryStream(Encoding.UTF8.GetBytes("AxCrypt is Great!"))) { using (Stream outputStream = new MemoryStream()) { using (V1AxCryptDocument document = new V1AxCryptDocument()) { Assert.Throws <ArgumentNullException>(() => { document.EncryptTo(inputStream, null, AxCryptOptions.EncryptWithCompression); }); Assert.Throws <ArgumentNullException>(() => { document.EncryptTo(null, outputStream, AxCryptOptions.EncryptWithCompression); }); Assert.Throws <ArgumentException>(() => { document.EncryptTo(inputStream, new NonSeekableStream(), AxCryptOptions.EncryptWithCompression); }); Assert.Throws <ArgumentException>(() => { document.EncryptTo(inputStream, outputStream, AxCryptOptions.EncryptWithCompression | AxCryptOptions.EncryptWithoutCompression); }); Assert.Throws <ArgumentException>(() => { document.EncryptTo(inputStream, outputStream, AxCryptOptions.None); }); Passphrase passphrase = new Passphrase("a"); V1DocumentHeaders headers = new V1DocumentHeaders(passphrase, 13); Assert.Throws <ArgumentNullException>(() => { document.CopyEncryptedTo(null, outputStream); }); Assert.Throws <ArgumentNullException>(() => { document.CopyEncryptedTo(headers, null); }); Assert.Throws <ArgumentException>(() => { document.CopyEncryptedTo(headers, new NonSeekableStream()); }); Assert.Throws <InternalErrorException>(() => { document.CopyEncryptedTo(headers, outputStream); }); } } } }
public void TestInvalidHmacInCopyEncryptedTo() { Passphrase passphrase = new Passphrase("a"); using (V1AxCryptDocument document = new V1AxCryptDocument()) { bool keyIsOk = document.Load(passphrase, new V1Aes128CryptoFactory().CryptoId, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); Assert.That(keyIsOk, Is.True, "The passphrase provided is correct and should work!"); Passphrase newPassphrase = new Passphrase("b"); using (Stream changedStream = new MemoryStream()) { V1DocumentHeaders outputDocumentHeaders = new V1DocumentHeaders(document.DocumentHeaders); outputDocumentHeaders.RewrapMasterKey(new V1DerivedKey(newPassphrase), 15); byte[] modifiedHmacBytes = document.DocumentHeaders.Headers.Hmac.GetBytes(); modifiedHmacBytes[0] += 1; document.DocumentHeaders.Headers.Hmac = new V1Hmac(modifiedHmacBytes); Assert.Throws <Axantum.AxCrypt.Core.Runtime.IncorrectDataException>(() => { document.CopyEncryptedTo(outputDocumentHeaders, changedStream); }); } } }
public void TestChangePassphraseForSimpleFile() { Passphrase passphrase = new Passphrase("a"); using (V1AxCryptDocument document = new V1AxCryptDocument()) { bool keyIsOk = document.Load(passphrase, new V1Aes128CryptoFactory().CryptoId, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); Assert.That(keyIsOk, Is.True, "The passphrase provided is correct and should work!"); Passphrase newPassphrase = new Passphrase("b"); using (Stream changedStream = new MemoryStream()) { V1DocumentHeaders outputDocumentHeaders = new V1DocumentHeaders(document.DocumentHeaders); outputDocumentHeaders.RewrapMasterKey(new V1DerivedKey(newPassphrase), 35); document.CopyEncryptedTo(outputDocumentHeaders, changedStream); changedStream.Position = 0; using (V1AxCryptDocument changedDocument = new V1AxCryptDocument()) { bool changedKeyIsOk = changedDocument.Load(newPassphrase, new V1Aes128CryptoFactory().CryptoId, changedStream); Assert.That(changedKeyIsOk, Is.True, "The changed passphrase provided is correct and should work!"); using (MemoryStream plaintextStream = new MemoryStream()) { changedDocument.DecryptTo(plaintextStream); Assert.That(Encoding.ASCII.GetString(plaintextStream.GetBuffer(), 0, (int)plaintextStream.Length), Is.EqualTo("HelloWorld"), "Unexpected result of decryption."); Assert.That(changedDocument.DocumentHeaders.PlaintextLength, Is.EqualTo(10), "'HelloWorld' should be 10 bytes uncompressed plaintext."); } } } } }
public static void TestHeaderBlockFactory(CryptoImplementation cryptoImplementation) { SetupAssembly.AssemblySetupCrypto(cryptoImplementation); V1DocumentHeaders headers = new V1DocumentHeaders(new Passphrase("passphrase"), 10); using (MemoryStream stream = new MemoryStream()) { headers.WriteWithoutHmac(stream); stream.Position = 0; UnversionedAxCryptReader reader = new UnversionedAxCryptReader(new LookAheadStream(stream)); bool unexpectedHeaderTypeFound = false; while (reader.Read()) { if (reader.CurrentItemType != AxCryptItemType.HeaderBlock) { continue; } switch (reader.CurrentHeaderBlock.HeaderBlockType) { case HeaderBlockType.Preamble: case HeaderBlockType.Version: case HeaderBlockType.Data: case HeaderBlockType.Unrecognized: break; default: unexpectedHeaderTypeFound = !(reader.CurrentHeaderBlock is UnrecognizedHeaderBlock); break; } } Assert.That(unexpectedHeaderTypeFound, Is.False); } }
private void ResetState(Passphrase passphrase) { DocumentHeaders = new V1DocumentHeaders(passphrase); PassphraseIsValid = false; Properties = EncryptedProperties.Create(this); if (_hmacStream != null) { _hmacStream.Dispose(); _hmacStream = null; } }
private static void EncryptWithCompressionInternal(V1DocumentHeaders outputDocumentHeaders, Stream inputStream, Stream encryptingStream) { using (ZOutputStream deflatingStream = new ZOutputStream(encryptingStream, -1)) { deflatingStream.FlushMode = JZlib.Z_SYNC_FLUSH; inputStream.CopyTo(deflatingStream); deflatingStream.FlushMode = JZlib.Z_FINISH; deflatingStream.Finish(); outputDocumentHeaders.UncompressedLength = deflatingStream.TotalIn; outputDocumentHeaders.PlaintextLength = deflatingStream.TotalOut; } }
public void TestInvalidItemType() { using (MemoryStream inputStream = new MemoryStream()) { AxCrypt1Guid.Write(inputStream); new PreambleHeaderBlock().Write(inputStream); inputStream.Position = 0; using (AxCryptReaderForTest axCryptReader = new AxCryptReaderForTest(new LookAheadStream(inputStream))) { V1DocumentHeaders documentHeaders = new V1DocumentHeaders(new Passphrase("secret"), 15); Assert.Throws <InternalErrorException>(() => { documentHeaders.Load(axCryptReader); }); } } }
public void TestBadKey() { using (Stream testStream = FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)) { using (V1AxCryptReader reader = new V1AxCryptReader(new LookAheadStream(testStream))) { Passphrase passphrase = new Passphrase("b"); V1DocumentHeaders documentHeaders = new V1DocumentHeaders(passphrase, 73); bool isPassphraseValid = documentHeaders.Load(reader); Assert.That(isPassphraseValid, Is.False, "The passphrase is intentionally wrong for this test case."); Assert.That(documentHeaders.HmacSubkey, Is.Null, "Since the passphrase is wrong, HmacSubkey should return null."); Assert.That(documentHeaders.DataSubkey, Is.Null, "Since the passphrase is wrong, DataSubkey should return null."); Assert.That(documentHeaders.HeadersSubkey, Is.Null, "Since the passphrase is wrong, HeadersSubkey should return null."); } } }
public void TestBadArguments() { V1DocumentHeaders documentHeaders = new V1DocumentHeaders(Passphrase.Empty, 37); Assert.Throws <ArgumentNullException>(() => { documentHeaders.WriteWithHmac(null); }); Assert.Throws <ArgumentNullException>(() => { documentHeaders.WriteWithoutHmac(null); }); Assert.Throws <ArgumentNullException>(() => { documentHeaders.Headers.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(V1DocumentHeaders outputDocumentHeaders, Stream cipherStream) { 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 (!PassphraseIsValid) { throw new InternalErrorException("Passphrase is not valid."); } using (V1HmacStream hmacStreamOutput = new V1HmacStream(outputDocumentHeaders.HmacSubkey.Key, cipherStream)) { outputDocumentHeaders.WriteWithHmac(hmacStreamOutput); using (V1AxCryptDataStream encryptedDataStream = CreateEncryptedDataStream(_reader.InputStream, DocumentHeaders.CipherTextLength)) { encryptedDataStream.CopyTo(hmacStreamOutput); if (Hmac != DocumentHeaders.Headers.Hmac) { throw new Axantum.AxCrypt.Core.Runtime.IncorrectDataException("HMAC validation error in the input stream.", ErrorStatus.HmacValidationError); } } outputDocumentHeaders.Headers.Hmac = hmacStreamOutput.HmacResult; // Rewind and rewrite the headers, now with the updated HMAC outputDocumentHeaders.WriteWithoutHmac(cipherStream); cipherStream.Position = cipherStream.Length; } }
public V1AxCryptDocument(Passphrase passphrase, long keyWrapIterations) : this() { DocumentHeaders = new V1DocumentHeaders(passphrase, keyWrapIterations); }