Esempio n. 1
0
        public static void TestKeyEncryptingKey()
        {
            AesKey          keyEncryptingKey = new AesKey();
            DocumentHeaders headers          = new DocumentHeaders(keyEncryptingKey);

            Assert.That(headers.KeyEncryptingKey, Is.EqualTo(keyEncryptingKey), "Unexpected key encrypting key retrieved.");
        }
Esempio n. 2
0
        public static void Encrypt(IRuntimeFileInfo sourceFile, Stream destinationStream, AesKey key, AxCryptOptions options, ProgressContext progress)
        {
            if (sourceFile == null)
            {
                throw new ArgumentNullException("sourceFile");
            }
            if (destinationStream == null)
            {
                throw new ArgumentNullException("destinationStream");
            }
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (progress == null)
            {
                throw new ArgumentNullException("progress");
            }

            using (Stream sourceStream = sourceFile.OpenRead())
            {
                using (AxCryptDocument document = new AxCryptDocument())
                {
                    DocumentHeaders headers = new DocumentHeaders(key);
                    headers.FileName          = sourceFile.Name;
                    headers.CreationTimeUtc   = sourceFile.CreationTimeUtc;
                    headers.LastAccessTimeUtc = sourceFile.LastAccessTimeUtc;
                    headers.LastWriteTimeUtc  = sourceFile.LastWriteTimeUtc;
                    document.DocumentHeaders  = headers;
                    document.EncryptTo(headers, sourceStream, destinationStream, options, progress);
                }
            }
        }
Esempio n. 3
0
        public static void TestInvalidHmacInCopyEncryptedTo()
        {
            using (AxCryptDocument document = new AxCryptDocument())
            {
                Passphrase passphrase = new Passphrase("a");
                bool       keyIsOk    = document.Load(FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt), passphrase.DerivedPassphrase);
                Assert.That(keyIsOk, Is.True, "The passphrase provided is correct and should work!");

                Passphrase newPassphrase = new Passphrase("b");
                using (Stream changedStream = new MemoryStream())
                {
                    DocumentHeaders outputDocumentHeaders = new DocumentHeaders(document.DocumentHeaders);
                    outputDocumentHeaders.SetCurrentVersion();
                    outputDocumentHeaders.RewrapMasterKey(newPassphrase.DerivedPassphrase);

                    byte[] modifiedHmacBytes = document.DocumentHeaders.Hmac.GetBytes();
                    modifiedHmacBytes[0]         += 1;
                    document.DocumentHeaders.Hmac = new DataHmac(modifiedHmacBytes);
                    Assert.Throws <Axantum.AxCrypt.Core.Runtime.InvalidDataException>(() =>
                    {
                        document.CopyEncryptedTo(outputDocumentHeaders, changedStream, new ProgressContext());
                    });
                }
            }
        }
Esempio n. 4
0
        public static void TestInvalidArguments()
        {
            using (Stream inputStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Encoding.UTF8.GetBytes("AxCrypt is Great!")))
            {
                using (Stream outputStream = new MemoryStream())
                {
                    using (AxCryptDocument document = new AxCryptDocument())
                    {
                        Passphrase      passphrase = new Passphrase("a");
                        DocumentHeaders headers    = new DocumentHeaders(passphrase.DerivedPassphrase);

                        Assert.Throws <ArgumentNullException>(() => { document.EncryptTo(null, inputStream, outputStream, AxCryptOptions.EncryptWithCompression, new ProgressContext()); });
                        Assert.Throws <ArgumentNullException>(() => { document.EncryptTo(headers, null, outputStream, AxCryptOptions.EncryptWithCompression, new ProgressContext()); });
                        Assert.Throws <ArgumentNullException>(() => { document.EncryptTo(headers, inputStream, null, AxCryptOptions.EncryptWithCompression, new ProgressContext()); });
                        Assert.Throws <ArgumentNullException>(() => { document.EncryptTo(headers, inputStream, outputStream, AxCryptOptions.EncryptWithCompression, null); });
                        Assert.Throws <ArgumentException>(() => { document.EncryptTo(headers, inputStream, new NonSeekableStream(), AxCryptOptions.EncryptWithCompression, new ProgressContext()); });
                        Assert.Throws <ArgumentException>(() => { document.EncryptTo(headers, inputStream, outputStream, AxCryptOptions.EncryptWithCompression | AxCryptOptions.EncryptWithoutCompression, new ProgressContext()); });
                        Assert.Throws <ArgumentException>(() => { document.EncryptTo(headers, inputStream, outputStream, AxCryptOptions.None, new ProgressContext()); });

                        Assert.Throws <ArgumentNullException>(() => { document.CopyEncryptedTo(null, outputStream, new ProgressContext()); });
                        Assert.Throws <ArgumentNullException>(() => { document.CopyEncryptedTo(headers, null, new ProgressContext()); });
                        Assert.Throws <ArgumentException>(() => { document.CopyEncryptedTo(headers, new NonSeekableStream(), new ProgressContext()); });
                        Assert.Throws <InternalErrorException>(() => { document.CopyEncryptedTo(headers, outputStream, new ProgressContext()); });
                    }
                }
            }
        }
Esempio n. 5
0
        public static void TestChangePassphraseForSimpleFile()
        {
            using (AxCryptDocument document = new AxCryptDocument())
            {
                Passphrase passphrase = new Passphrase("a");
                bool       keyIsOk    = document.Load(FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt), passphrase.DerivedPassphrase);
                Assert.That(keyIsOk, Is.True, "The passphrase provided is correct and should work!");

                Passphrase newPassphrase = new Passphrase("b");
                using (Stream changedStream = new MemoryStream())
                {
                    DocumentHeaders outputDocumentHeaders = new DocumentHeaders(document.DocumentHeaders);
                    outputDocumentHeaders.SetCurrentVersion();
                    outputDocumentHeaders.RewrapMasterKey(newPassphrase.DerivedPassphrase);

                    document.CopyEncryptedTo(outputDocumentHeaders, changedStream, new ProgressContext());
                    changedStream.Position = 0;
                    using (AxCryptDocument changedDocument = new AxCryptDocument())
                    {
                        bool changedKeyIsOk = changedDocument.Load(changedStream, newPassphrase.DerivedPassphrase);
                        Assert.That(changedKeyIsOk, Is.True, "The changed passphrase provided is correct and should work!");

                        using (MemoryStream plaintextStream = new MemoryStream())
                        {
                            changedDocument.DecryptTo(plaintextStream, new ProgressContext());
                            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.");
                        }
                    }
                }
            }
        }
Esempio n. 6
0
        public bool VerifyHmac()
        {
            using (Stream encryptedDataStream = CreateEncryptedDataStream())
            {
                encryptedDataStream.CopyTo(Stream.Null);
            }

            DocumentHeaders.Trailers(_reader);
            return(DocumentHeaders.HmacCalculator.Hmac == DocumentHeaders.Hmac);
        }
Esempio n. 7
0
        /// <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(Stream inputStream, Stream outputStream, AxCryptOptions options)
        {
            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }
            if (outputStream == null)
            {
                throw new ArgumentNullException("outputStream");
            }
            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.");
            }

            DocumentHeaders.IsCompressed = options.HasMask(AxCryptOptions.EncryptWithCompression);
            V2HmacCalculator      hmacCalculator   = new V2HmacCalculator(new SymmetricKey(DocumentHeaders.GetHmacKey()));
            V2HmacStream <Stream> outputHmacStream = V2HmacStream.Create(hmacCalculator, outputStream);

            CryptoStreamBase encryptingStream = New <CryptoStreamBase>().Initialize(V2AxCryptDataStream.Create(outputHmacStream), DocumentHeaders.DataCrypto().EncryptingTransform(), CryptoStreamMode.Write);

            DocumentHeaders.WriteStartWithHmac(outputHmacStream);
            if (DocumentHeaders.IsCompressed)
            {
                using (ZOutputStream deflatingStream = new ZOutputStream(encryptingStream, -1))
                {
                    deflatingStream.FlushMode = JZlib.Z_SYNC_FLUSH;
                    inputStream.CopyTo(deflatingStream);
                    deflatingStream.FlushMode = JZlib.Z_FINISH;
                    deflatingStream.Finish();

                    _plaintextLength           = deflatingStream.TotalIn;
                    _compressedPlaintextLength = deflatingStream.TotalOut;
                    encryptingStream.FinalFlush();
                    DocumentHeaders.WriteEndWithHmac(hmacCalculator, outputHmacStream, _plaintextLength, _compressedPlaintextLength);
                }
            }
            else
            {
                try
                {
                    _compressedPlaintextLength = _plaintextLength = StreamExtensions.CopyTo(inputStream, encryptingStream);
                    encryptingStream.FinalFlush();
                    DocumentHeaders.WriteEndWithHmac(hmacCalculator, outputHmacStream, _plaintextLength, _compressedPlaintextLength);
                }
                finally
                {
                    encryptingStream.Dispose();
                }
            }
        }
        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;
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Loads an AxCrypt file from the specified reader. After this, the reader is positioned to
        /// read encrypted data.
        /// </summary>
        /// <param name="stream">The stream to read from. Will be disposed when this instance is disposed.</param>
        /// <returns>True if the key was valid, false if it was wrong.</returns>
        public bool Load(Stream stream, AesKey key)
        {
            _reader = AxCryptReader.Create(stream);
            DocumentHeaders documentHeaders = new DocumentHeaders(key);

            PassphraseIsValid = documentHeaders.Load(_reader);
            if (PassphraseIsValid)
            {
                DocumentHeaders = documentHeaders;
            }
            return(PassphraseIsValid);
        }
Esempio n. 10
0
        private static void EncryptWithCompressionInternal(DocumentHeaders outputDocumentHeaders, Stream inputStream, CryptoStream encryptingStream, ProgressContext progress)
        {
            using (ZOutputStream deflatingStream = new ZOutputStream(encryptingStream, -1))
            {
                deflatingStream.FlushMode = JZlib.Z_SYNC_FLUSH;
                CopyToWithCount(inputStream, deflatingStream, progress);
                deflatingStream.FlushMode = JZlib.Z_FINISH;
                deflatingStream.Finish();

                outputDocumentHeaders.UncompressedLength = deflatingStream.TotalIn;
                outputDocumentHeaders.PlaintextLength    = deflatingStream.TotalOut;
            }
        }
Esempio n. 11
0
 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;
     });
 }
Esempio n. 12
0
        public static void TestBadKey()
        {
            using (Stream testStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt))
            {
                using (AxCryptReader reader = AxCryptReader.Create(testStream))
                {
                    Passphrase passphrase = new Passphrase("b");
                    DocumentHeaders documentHeaders = new DocumentHeaders(passphrase.DerivedPassphrase);
                    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.");
                }
            }
        }
Esempio n. 13
0
        public static void TestBadKey()
        {
            using (Stream testStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt))
            {
                using (AxCryptReader reader = AxCryptReader.Create(testStream))
                {
                    Passphrase      passphrase        = new Passphrase("b");
                    DocumentHeaders documentHeaders   = new DocumentHeaders(passphrase.DerivedPassphrase);
                    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.");
                }
            }
        }
Esempio n. 14
0
 public static void TestInvalidItemType()
 {
     using (MemoryStream inputStream = new MemoryStream())
     {
         AxCrypt1Guid.Write(inputStream);
         new PreambleHeaderBlock().Write(inputStream);
         inputStream.Position = 0;
         using (AxCryptReaderForTest axCryptReader = new AxCryptReaderForTest(inputStream))
         {
             DocumentHeaders documentHeaders = new DocumentHeaders(new AesKey());
             Assert.Throws <InternalErrorException>(() =>
             {
                 documentHeaders.Load(axCryptReader);
             });
         }
     }
 }
Esempio n. 15
0
        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;
            });
        }
Esempio n. 16
0
        /// <summary>
        /// Decrypt from loaded AxCryptDocument to a destination file
        /// </summary>
        /// <param name="document">The loaded AxCryptDocument</param>
        /// <param name="destinationFile">The destination file</param>
        public static void Decrypt(AxCryptDocument document, IRuntimeFileInfo destinationFile, AxCryptOptions options, ProgressContext progress)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }
            if (destinationFile == null)
            {
                throw new ArgumentNullException("destinationFile");
            }
            if (progress == null)
            {
                throw new ArgumentNullException("progress");
            }
            try
            {
                if (OS.Log.IsInfoEnabled)
                {
                    OS.Log.LogInfo("Decrypting to '{0}'.".InvariantFormat(destinationFile.Name));
                }

                using (Stream destinationStream = destinationFile.OpenWrite())
                {
                    document.DecryptTo(destinationStream, progress);
                }

                if (OS.Log.IsInfoEnabled)
                {
                    OS.Log.LogInfo("Decrypted to '{0}'.".InvariantFormat(destinationFile.Name));
                }
            }
            catch (OperationCanceledException)
            {
                if (destinationFile.Exists)
                {
                    AxCryptFile.Wipe(destinationFile, progress);
                }
                throw;
            }
            if (options.HasMask(AxCryptOptions.SetFileTimes))
            {
                DocumentHeaders headers = document.DocumentHeaders;
                destinationFile.SetFileTimes(headers.CreationTimeUtc, headers.LastAccessTimeUtc, headers.LastWriteTimeUtc);
            }
        }
        public static void TestHmac()
        {
            using (Stream inputStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt))
            {
                using (AxCryptReader axCryptReader = new AxCryptStreamReader(inputStream))
                {
                    Assert.Throws <InvalidOperationException>(() =>
                    {
                        if (axCryptReader.Hmac == null)
                        {
                        }
                    }, "The reader is not positioned properly to get the HMAC.");

                    Passphrase      passphrase      = new Passphrase("a");
                    DocumentHeaders documentHeaders = new DocumentHeaders(passphrase.DerivedPassphrase);
                    bool            keyIsOk         = documentHeaders.Load(axCryptReader);
                    Assert.That(keyIsOk, Is.True, "The passphrase provided is correct!");

                    using (Stream encrypedDataStream = axCryptReader.CreateEncryptedDataStream(documentHeaders.HmacSubkey.Key, documentHeaders.CipherTextLength, new ProgressContext()))
                    {
                        Assert.Throws <InvalidOperationException>(() =>
                        {
                            if (axCryptReader.Hmac == null)
                            {
                            }
                        }, "We have not read the encrypted data yet.");

                        Assert.That(axCryptReader.Read(), Is.False, "The reader should be at end of stream now, and Read() should return false.");

                        encrypedDataStream.CopyTo(Stream.Null, 4096);
                        Assert.That(documentHeaders.Hmac, Is.EqualTo(axCryptReader.Hmac), "The HMAC should be correct.");

                        axCryptReader.Dispose();

                        Assert.Throws <ObjectDisposedException>(() =>
                        {
                            DataHmac disposedHmac = axCryptReader.Hmac;
                            Object.Equals(disposedHmac, null);
                        }, "The reader is disposed.");
                    }
                }
            }
        }
Esempio n. 18
0
        public static void TestSimpleEncryptToWithoutCompression()
        {
            DateTime creationTimeUtc   = new DateTime(2012, 1, 1, 1, 2, 3, DateTimeKind.Utc);
            DateTime lastAccessTimeUtc = creationTimeUtc + new TimeSpan(1, 0, 0);
            DateTime lastWriteTimeUtc  = creationTimeUtc + new TimeSpan(2, 0, 0);;

            using (Stream inputStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Encoding.UTF8.GetBytes("AxCrypt is Great!")))
            {
                using (Stream outputStream = new MemoryStream())
                {
                    using (AxCryptDocument document = new AxCryptDocument())
                    {
                        Passphrase      passphrase = new Passphrase("a");
                        DocumentHeaders headers    = new DocumentHeaders(passphrase.DerivedPassphrase);
                        headers.FileName          = "MyFile.txt";
                        headers.CreationTimeUtc   = creationTimeUtc;
                        headers.LastAccessTimeUtc = lastAccessTimeUtc;
                        headers.LastWriteTimeUtc  = lastWriteTimeUtc;
                        document.DocumentHeaders  = headers;
                        document.EncryptTo(headers, inputStream, outputStream, AxCryptOptions.EncryptWithoutCompression, new ProgressContext());
                    }
                    outputStream.Position = 0;
                    using (AxCryptDocument document = new AxCryptDocument())
                    {
                        Passphrase passphrase = new Passphrase("a");
                        bool       keyIsOk    = document.Load(outputStream, passphrase.DerivedPassphrase);
                        Assert.That(keyIsOk, Is.True, "The passphrase provided is correct!");
                        Assert.That(document.DocumentHeaders.FileName, Is.EqualTo("MyFile.txt"));
                        Assert.That(document.DocumentHeaders.CreationTimeUtc, Is.EqualTo(creationTimeUtc));
                        Assert.That(document.DocumentHeaders.LastAccessTimeUtc, Is.EqualTo(lastAccessTimeUtc));
                        Assert.That(document.DocumentHeaders.LastWriteTimeUtc, Is.EqualTo(lastWriteTimeUtc));
                        using (MemoryStream plaintextStream = new MemoryStream())
                        {
                            document.DecryptTo(plaintextStream, new ProgressContext());
                            Assert.That(document.DocumentHeaders.UncompressedLength, Is.EqualTo(-1), "'AxCrypt is Great!' should not return a value at all for uncompressed, since it was not compressed.");
                            Assert.That(document.DocumentHeaders.PlaintextLength, Is.EqualTo(17), "'AxCrypt is Great!' is 17 bytes plaintext length.");
                            Assert.That(Encoding.ASCII.GetString(plaintextStream.GetBuffer(), 0, (int)plaintextStream.Length), Is.EqualTo("AxCrypt is Great!"), "Unexpected result of decryption.");
                        }
                    }
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Encrypt a file
        /// </summary>
        /// <param name="file">The file to encrypt</param>
        /// <param name="destination">The destination file</param>
        /// <remarks>It is the callers responsibility to ensure that the source file exists, that the destination file
        /// does not exist and can be created etc.</remarks>
        public static void Encrypt(IRuntimeFileInfo sourceFile, IRuntimeFileInfo destinationFile, Passphrase passphrase, AxCryptOptions options, ProgressContext progress)
        {
            if (sourceFile == null)
            {
                throw new ArgumentNullException("sourceFile");
            }
            if (destinationFile == null)
            {
                throw new ArgumentNullException("destinationFile");
            }
            if (passphrase == null)
            {
                throw new ArgumentNullException("passphrase");
            }
            if (progress == null)
            {
                throw new ArgumentNullException("progress");
            }

            using (Stream sourceStream = sourceFile.OpenRead())
            {
                using (Stream destinationStream = destinationFile.OpenWrite())
                {
                    using (AxCryptDocument document = new AxCryptDocument())
                    {
                        DocumentHeaders headers = new DocumentHeaders(passphrase.DerivedPassphrase);
                        headers.FileName          = sourceFile.Name;
                        headers.CreationTimeUtc   = sourceFile.CreationTimeUtc;
                        headers.LastAccessTimeUtc = sourceFile.LastAccessTimeUtc;
                        headers.LastWriteTimeUtc  = sourceFile.LastWriteTimeUtc;
                        document.DocumentHeaders  = headers;
                        document.EncryptTo(headers, sourceStream, destinationStream, options, progress);
                    }
                }
                if (options.HasMask(AxCryptOptions.SetFileTimes))
                {
                    destinationFile.SetFileTimes(sourceFile.CreationTimeUtc, sourceFile.LastAccessTimeUtc, sourceFile.LastWriteTimeUtc);
                }
            }
        }
        /// <summary>
        /// Loads an AxCrypt file from the specified reader. After this, the reader is positioned to
        /// read encrypted data.
        /// </summary>
        /// <param name="inputStream">The stream to read from. Will be disposed when this instance is disposed.</param>
        /// <returns>True if the key was valid, false if it was wrong.</returns>
        private bool Load(Passphrase passphrase, AxCryptReader reader, Headers headers)
        {
            _reader = reader;
            ResetState(passphrase);
            PassphraseIsValid = DocumentHeaders.Load(headers);
            if (!PassphraseIsValid)
            {
                return(false);
            }

            _hmacStream = new V1HmacStream(DocumentHeaders.HmacSubkey.Key);
            foreach (HeaderBlock header in DocumentHeaders.Headers.HeaderBlocks)
            {
                if (header.HeaderBlockType != HeaderBlockType.Preamble)
                {
                    header.Write(_hmacStream);
                }
            }

            Properties = EncryptedProperties.Create(this);
            return(true);
        }
Esempio n. 21
0
        /// <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;
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Decrypts the encrypted data to the given stream
        /// </summary>
        /// <param name="outputPlaintextStream">The resulting plain text stream.</param>
        public void DecryptTo(Stream outputPlaintextStream)
        {
            if (outputPlaintextStream == null)
            {
                throw new ArgumentNullException("outputPlaintextStream");
            }

            if (!PassphraseIsValid)
            {
                throw new InternalErrorException("Passphrase is not valid!");
            }

            using (Stream encryptedDataStream = CreateEncryptedDataStream())
            {
                encryptedDataStream.DecryptTo(outputPlaintextStream, DocumentHeaders.DataCrypto().DecryptingTransform(), DocumentHeaders.IsCompressed);
            }

            DocumentHeaders.Trailers(_reader);
            if (DocumentHeaders.HmacCalculator.Hmac != DocumentHeaders.Hmac)
            {
                throw new Axantum.AxCrypt.Core.Runtime.IncorrectDataException("HMAC validation error.", ErrorStatus.HmacValidationError);
            }
        }
Esempio n. 23
0
        /// <summary>
        /// Encrypt a file
        /// </summary>
        /// <param name="file">The file to encrypt</param>
        /// <param name="destination">The destination file</param>
        /// <remarks>It is the callers responsibility to ensure that the source file exists, that the destination file
        /// does not exist and can be created etc.</remarks>
        public static void Encrypt(IRuntimeFileInfo sourceFile, IRuntimeFileInfo destinationFile, Passphrase passphrase, AxCryptOptions options, ProgressContext progress)
        {
            if (sourceFile == null)
            {
                throw new ArgumentNullException("sourceFile");
            }
            if (destinationFile == null)
            {
                throw new ArgumentNullException("destinationFile");
            }
            if (passphrase == null)
            {
                throw new ArgumentNullException("passphrase");
            }
            if (progress == null)
            {
                throw new ArgumentNullException("progress");
            }

            using (Stream sourceStream = sourceFile.OpenRead())
            {
                using (Stream destinationStream = destinationFile.OpenWrite())
                {
                    using (AxCryptDocument document = new AxCryptDocument())
                    {
                        DocumentHeaders headers = new DocumentHeaders(passphrase.DerivedPassphrase);
                        headers.FileName = sourceFile.Name;
                        headers.CreationTimeUtc = sourceFile.CreationTimeUtc;
                        headers.LastAccessTimeUtc = sourceFile.LastAccessTimeUtc;
                        headers.LastWriteTimeUtc = sourceFile.LastWriteTimeUtc;
                        document.DocumentHeaders = headers;
                        document.EncryptTo(headers, sourceStream, destinationStream, options, progress);
                    }
                }
                if (options.HasMask(AxCryptOptions.SetFileTimes))
                {
                    destinationFile.SetFileTimes(sourceFile.CreationTimeUtc, sourceFile.LastAccessTimeUtc, sourceFile.LastWriteTimeUtc);
                }
            }
        }
Esempio n. 24
0
        public static void TestInvalidArguments()
        {
            using (Stream inputStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Encoding.UTF8.GetBytes("AxCrypt is Great!")))
            {
                using (Stream outputStream = new MemoryStream())
                {
                    using (AxCryptDocument document = new AxCryptDocument())
                    {
                        Passphrase passphrase = new Passphrase("a");
                        DocumentHeaders headers = new DocumentHeaders(passphrase.DerivedPassphrase);

                        Assert.Throws<ArgumentNullException>(() => { document.EncryptTo(null, inputStream, outputStream, AxCryptOptions.EncryptWithCompression, new ProgressContext()); });
                        Assert.Throws<ArgumentNullException>(() => { document.EncryptTo(headers, null, outputStream, AxCryptOptions.EncryptWithCompression, new ProgressContext()); });
                        Assert.Throws<ArgumentNullException>(() => { document.EncryptTo(headers, inputStream, null, AxCryptOptions.EncryptWithCompression, new ProgressContext()); });
                        Assert.Throws<ArgumentNullException>(() => { document.EncryptTo(headers, inputStream, outputStream, AxCryptOptions.EncryptWithCompression, null); });
                        Assert.Throws<ArgumentException>(() => { document.EncryptTo(headers, inputStream, new NonSeekableStream(), AxCryptOptions.EncryptWithCompression, new ProgressContext()); });
                        Assert.Throws<ArgumentException>(() => { document.EncryptTo(headers, inputStream, outputStream, AxCryptOptions.EncryptWithCompression | AxCryptOptions.EncryptWithoutCompression, new ProgressContext()); });
                        Assert.Throws<ArgumentException>(() => { document.EncryptTo(headers, inputStream, outputStream, AxCryptOptions.None, new ProgressContext()); });

                        Assert.Throws<ArgumentNullException>(() => { document.CopyEncryptedTo(null, outputStream, new ProgressContext()); });
                        Assert.Throws<ArgumentNullException>(() => { document.CopyEncryptedTo(headers, null, new ProgressContext()); });
                        Assert.Throws<ArgumentException>(() => { document.CopyEncryptedTo(headers, new NonSeekableStream(), new ProgressContext()); });
                        Assert.Throws<InternalErrorException>(() => { document.CopyEncryptedTo(headers, outputStream, new ProgressContext()); });
                    }
                }
            }
        }
Esempio n. 25
0
 public static void TestSimpleEncryptToWithoutCompression()
 {
     DateTime creationTimeUtc = new DateTime(2012, 1, 1, 1, 2, 3, DateTimeKind.Utc);
     DateTime lastAccessTimeUtc = creationTimeUtc + new TimeSpan(1, 0, 0);
     DateTime lastWriteTimeUtc = creationTimeUtc + new TimeSpan(2, 0, 0); ;
     using (Stream inputStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Encoding.UTF8.GetBytes("AxCrypt is Great!")))
     {
         using (Stream outputStream = new MemoryStream())
         {
             using (AxCryptDocument document = new AxCryptDocument())
             {
                 Passphrase passphrase = new Passphrase("a");
                 DocumentHeaders headers = new DocumentHeaders(passphrase.DerivedPassphrase);
                 headers.FileName = "MyFile.txt";
                 headers.CreationTimeUtc = creationTimeUtc;
                 headers.LastAccessTimeUtc = lastAccessTimeUtc;
                 headers.LastWriteTimeUtc = lastWriteTimeUtc;
                 document.DocumentHeaders = headers;
                 document.EncryptTo(headers, inputStream, outputStream, AxCryptOptions.EncryptWithoutCompression, new ProgressContext());
             }
             outputStream.Position = 0;
             using (AxCryptDocument document = new AxCryptDocument())
             {
                 Passphrase passphrase = new Passphrase("a");
                 bool keyIsOk = document.Load(outputStream, passphrase.DerivedPassphrase);
                 Assert.That(keyIsOk, Is.True, "The passphrase provided is correct!");
                 Assert.That(document.DocumentHeaders.FileName, Is.EqualTo("MyFile.txt"));
                 Assert.That(document.DocumentHeaders.CreationTimeUtc, Is.EqualTo(creationTimeUtc));
                 Assert.That(document.DocumentHeaders.LastAccessTimeUtc, Is.EqualTo(lastAccessTimeUtc));
                 Assert.That(document.DocumentHeaders.LastWriteTimeUtc, Is.EqualTo(lastWriteTimeUtc));
                 using (MemoryStream plaintextStream = new MemoryStream())
                 {
                     document.DecryptTo(plaintextStream, new ProgressContext());
                     Assert.That(document.DocumentHeaders.UncompressedLength, Is.EqualTo(-1), "'AxCrypt is Great!' should not return a value at all for uncompressed, since it was not compressed.");
                     Assert.That(document.DocumentHeaders.PlaintextLength, Is.EqualTo(17), "'AxCrypt is Great!' is 17 bytes plaintext length.");
                     Assert.That(Encoding.ASCII.GetString(plaintextStream.GetBuffer(), 0, (int)plaintextStream.Length), Is.EqualTo("AxCrypt is Great!"), "Unexpected result of decryption.");
                 }
             }
         }
     }
 }
Esempio n. 26
0
        public static void TestInvalidHmacInCopyEncryptedTo()
        {
            using (AxCryptDocument document = new AxCryptDocument())
            {
                Passphrase passphrase = new Passphrase("a");
                bool keyIsOk = document.Load(FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt), passphrase.DerivedPassphrase);
                Assert.That(keyIsOk, Is.True, "The passphrase provided is correct and should work!");

                Passphrase newPassphrase = new Passphrase("b");
                using (Stream changedStream = new MemoryStream())
                {
                    DocumentHeaders outputDocumentHeaders = new DocumentHeaders(document.DocumentHeaders);
                    outputDocumentHeaders.SetCurrentVersion();
                    outputDocumentHeaders.RewrapMasterKey(newPassphrase.DerivedPassphrase);

                    byte[] modifiedHmacBytes = document.DocumentHeaders.Hmac.GetBytes();
                    modifiedHmacBytes[0] += 1;
                    document.DocumentHeaders.Hmac = new DataHmac(modifiedHmacBytes);
                    Assert.Throws<Axantum.AxCrypt.Core.Runtime.InvalidDataException>(() =>
                    {
                        document.CopyEncryptedTo(outputDocumentHeaders, changedStream, new ProgressContext());
                    });
                }
            }
        }
        public static void TestHmac()
        {
            using (Stream inputStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt))
            {
                using (AxCryptReader axCryptReader = new AxCryptStreamReader(inputStream))
                {
                    Assert.Throws<InvalidOperationException>(() =>
                    {
                        if (axCryptReader.Hmac == null) { }
                    }, "The reader is not positioned properly to get the HMAC.");

                    Passphrase passphrase = new Passphrase("a");
                    DocumentHeaders documentHeaders = new DocumentHeaders(passphrase.DerivedPassphrase);
                    bool keyIsOk = documentHeaders.Load(axCryptReader);
                    Assert.That(keyIsOk, Is.True, "The passphrase provided is correct!");

                    using (Stream encrypedDataStream = axCryptReader.CreateEncryptedDataStream(documentHeaders.HmacSubkey.Key, documentHeaders.CipherTextLength, new ProgressContext()))
                    {
                        Assert.Throws<InvalidOperationException>(() =>
                        {
                            if (axCryptReader.Hmac == null) { }
                        }, "We have not read the encrypted data yet.");

                        Assert.That(axCryptReader.Read(), Is.False, "The reader should be at end of stream now, and Read() should return false.");

                        encrypedDataStream.CopyTo(Stream.Null, 4096);
                        Assert.That(documentHeaders.Hmac, Is.EqualTo(axCryptReader.Hmac), "The HMAC should be correct.");

                        axCryptReader.Dispose();

                        Assert.Throws<ObjectDisposedException>(() =>
                        {
                            DataHmac disposedHmac = axCryptReader.Hmac;
                            Object.Equals(disposedHmac, null);
                        }, "The reader is disposed.");
                    }
                }
            }
        }
Esempio n. 28
0
        public static void TestChangePassphraseForSimpleFile()
        {
            using (AxCryptDocument document = new AxCryptDocument())
            {
                Passphrase passphrase = new Passphrase("a");
                bool keyIsOk = document.Load(FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt), passphrase.DerivedPassphrase);
                Assert.That(keyIsOk, Is.True, "The passphrase provided is correct and should work!");

                Passphrase newPassphrase = new Passphrase("b");
                using (Stream changedStream = new MemoryStream())
                {
                    DocumentHeaders outputDocumentHeaders = new DocumentHeaders(document.DocumentHeaders);
                    outputDocumentHeaders.SetCurrentVersion();
                    outputDocumentHeaders.RewrapMasterKey(newPassphrase.DerivedPassphrase);

                    document.CopyEncryptedTo(outputDocumentHeaders, changedStream, new ProgressContext());
                    changedStream.Position = 0;
                    using (AxCryptDocument changedDocument = new AxCryptDocument())
                    {
                        bool changedKeyIsOk = changedDocument.Load(changedStream, newPassphrase.DerivedPassphrase);
                        Assert.That(changedKeyIsOk, Is.True, "The changed passphrase provided is correct and should work!");

                        using (MemoryStream plaintextStream = new MemoryStream())
                        {
                            changedDocument.DecryptTo(plaintextStream, new ProgressContext());
                            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.");
                        }
                    }
                }
            }
        }
Esempio n. 29
0
        private static void EncryptWithCompressionInternal(DocumentHeaders outputDocumentHeaders, Stream inputStream, CryptoStream encryptingStream, ProgressContext progress)
        {
            using (ZOutputStream deflatingStream = new ZOutputStream(encryptingStream, -1))
            {
                deflatingStream.FlushMode = JZlib.Z_SYNC_FLUSH;
                CopyToWithCount(inputStream, deflatingStream, progress);
                deflatingStream.FlushMode = JZlib.Z_FINISH;
                deflatingStream.Finish();

                outputDocumentHeaders.UncompressedLength = deflatingStream.TotalIn;
                outputDocumentHeaders.PlaintextLength = deflatingStream.TotalOut;
            }
        }
Esempio n. 30
0
        /// <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;
            }
        }
Esempio n. 31
0
 /// <summary>
 /// Loads an AxCrypt file from the specified reader. After this, the reader is positioned to
 /// read encrypted data.
 /// </summary>
 /// <param name="stream">The stream to read from. Will be disposed when this instance is disposed.</param>
 /// <returns>True if the key was valid, false if it was wrong.</returns>
 public bool Load(Stream stream, AesKey key)
 {
     _reader = AxCryptReader.Create(stream);
     DocumentHeaders documentHeaders = new DocumentHeaders(key);
     PassphraseIsValid = documentHeaders.Load(_reader);
     if (PassphraseIsValid)
     {
         DocumentHeaders = documentHeaders;
     }
     return PassphraseIsValid;
 }
Esempio n. 32
0
        /// <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;
            }
        }
Esempio n. 33
0
 public static void TestInvalidItemType()
 {
     using (MemoryStream inputStream = new MemoryStream())
     {
         AxCrypt1Guid.Write(inputStream);
         new PreambleHeaderBlock().Write(inputStream);
         inputStream.Position = 0;
         using (AxCryptReaderForTest axCryptReader = new AxCryptReaderForTest(inputStream))
         {
             DocumentHeaders documentHeaders = new DocumentHeaders(new AesKey());
             Assert.Throws<InternalErrorException>(() =>
             {
                 documentHeaders.Load(axCryptReader);
             });
         }
     }
 }
Esempio n. 34
0
 public static void TestKeyEncryptingKey()
 {
     AesKey keyEncryptingKey = new AesKey();
     DocumentHeaders headers = new DocumentHeaders(keyEncryptingKey);
     Assert.That(headers.KeyEncryptingKey, Is.EqualTo(keyEncryptingKey), "Unexpected key encrypting key retrieved.");
 }
Esempio n. 35
0
        public static void Encrypt(IRuntimeFileInfo sourceFile, Stream destinationStream, AesKey key, AxCryptOptions options, ProgressContext progress)
        {
            if (sourceFile == null)
            {
                throw new ArgumentNullException("sourceFile");
            }
            if (destinationStream == null)
            {
                throw new ArgumentNullException("destinationStream");
            }
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (progress == null)
            {
                throw new ArgumentNullException("progress");
            }

            using (Stream sourceStream = sourceFile.OpenRead())
            {
                using (AxCryptDocument document = new AxCryptDocument())
                {
                    DocumentHeaders headers = new DocumentHeaders(key);
                    headers.FileName = sourceFile.Name;
                    headers.CreationTimeUtc = sourceFile.CreationTimeUtc;
                    headers.LastAccessTimeUtc = sourceFile.LastAccessTimeUtc;
                    headers.LastWriteTimeUtc = sourceFile.LastWriteTimeUtc;
                    document.DocumentHeaders = headers;
                    document.EncryptTo(headers, sourceStream, destinationStream, options, progress);
                }
            }
        }