/// <summary> /// Decrypt a source file to a destination file, given a passphrase /// </summary> /// <param name="sourceFile">The source file</param> /// <param name="destinationFile">The destination file</param> /// <param name="passphrase">The passphrase</param> /// <returns>true if the passphrase was correct</returns> public static bool Decrypt(IRuntimeFileInfo sourceFile, IRuntimeFileInfo destinationFile, AesKey key, AxCryptOptions options, ProgressContext progress) { if (sourceFile == null) { throw new ArgumentNullException("sourceFile"); } if (destinationFile == null) { throw new ArgumentNullException("destinationFile"); } if (key == null) { throw new ArgumentNullException("key"); } if (progress == null) { throw new ArgumentNullException("progress"); } using (AxCryptDocument document = Document(sourceFile, key, new ProgressContext())) { if (!document.PassphraseIsValid) { return false; } Decrypt(document, destinationFile, options, progress); } return true; }
public static void DecryptAndOpenFile(IRuntimeFileInfo encryptedDocument, Passphrase passphrase, ProgressContext progress, Action<string, ProgressContext> failure = null) { string tempPath = Path.GetTempPath(); string decryptedFileName; lastUsedKey = passphrase.DerivedPassphrase; if (!TryDecrypt(encryptedDocument, tempPath, lastUsedKey, progress, out decryptedFileName)) { failure("Could not open file", progress); return; } string fullPathToDecryptedFile = Path.Combine(tempPath, decryptedFileName); IRuntimeFileInfo decryptedFile = OS.Current.FileInfo(fullPathToDecryptedFile); NSDictionary userInfo = new NSDictionary(Launcher.TargetFileUserInfoKey, decryptedFile.FullName); NSNotification notification = NSNotification.FromName(Launcher.FileDecryptedNotification, new NSObject(), userInfo); NSNotificationCenter.DefaultCenter.PostNotification(notification); ILauncher launcher = OS.Current.Launch (fullPathToDecryptedFile); launcher.Exited += (sender, e) => { fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); }; fileSystemState.Add (new ActiveFile(encryptedDocument, decryptedFile, lastUsedKey, ActiveFileStatus.AssumedOpenAndDecrypted, launcher)); //fileSystemState.Save (); }
public DecryptionViewController (string sourceFilePath) { this.context = new ProgressContext (); // context.Progressing += (sender, e) => { // SetProgress(e.Percent, "Decrypting ..."); // }; this.sourceFile = OS.Current.FileInfo (sourceFilePath); }
public static void TestRuntimeFileInfo() { IRuntimeFileInfo runtimeFileInfo = OS.Current.FileInfo(Path.Combine(Path.GetTempPath(), "A File.txt")); Assert.That(runtimeFileInfo is RuntimeFileInfo, "The instance returned should be of type RuntimeFileInfo"); Assert.That(runtimeFileInfo.Name, Is.EqualTo("A File.txt")); runtimeFileInfo = OS.Current.FileInfo(Path.Combine(Path.GetTempPath(), "A File.txt")); Assert.That(runtimeFileInfo.Name, Is.EqualTo("A File.txt")); }
public static void TestDecryptToDestinationDirectory() { IRuntimeFileInfo sourceFileInfo = OS.Current.FileInfo(_helloWorldAxxPath); string destinationDirectory = Path.Combine(_rootPath, "Encrypted"); string destinationFileName = AxCryptFile.Decrypt(sourceFileInfo, destinationDirectory, new Passphrase("a").DerivedPassphrase, AxCryptOptions.None, new ProgressContext()); Assert.That(destinationFileName, Is.EqualTo("HelloWorld-Key-a.txt"), "The correct filename should be returned from decryption."); }
public static void TestDecryptFileWithRepeatedPassphraseQueries() { FileOperationsController controller = new FileOperationsController(_fileSystemState); int passphraseTry = 0; controller.QueryDecryptionPassphrase += (object sender, FileOperationEventArgs e) => { switch (++passphraseTry) { case 1: e.Passphrase = "b"; break; case 2: e.Passphrase = "d"; break; case 3: e.Passphrase = "a"; break; case 4: e.Passphrase = "e"; break; } ; }; string destinationPath = String.Empty; controller.Completed += (object sender, FileOperationEventArgs e) => { destinationPath = e.SaveFileFullName; }; bool knownKeyWasAdded = false; controller.KnownKeyAdded += (object sender, FileOperationEventArgs e) => { knownKeyWasAdded = e.Key == new Passphrase("a").DerivedPassphrase; }; FileOperationStatus status = controller.DecryptFile(_helloWorldAxxPath); Assert.That(status, Is.EqualTo(FileOperationStatus.Success), "The status should indicate success."); Assert.That(knownKeyWasAdded, "A new known key was used, so the KnownKeyAdded event should have been raised."); Assert.That(passphraseTry, Is.EqualTo(3), "The third key was the correct one."); IRuntimeFileInfo destinationInfo = OS.Current.FileInfo(destinationPath); Assert.That(destinationInfo.Exists, "After decryption the destination file should be created."); string fileContent; using (Stream stream = destinationInfo.OpenRead()) { fileContent = new StreamReader(stream).ReadToEnd(); } Assert.That(fileContent.Contains("Hello"), "A file named Hello World should contain that text when decrypted."); }
public static void Wipe(IRuntimeFileInfo fileInfo, ProgressContext progress) { if (fileInfo == null) { throw new ArgumentNullException("fileInfo"); } if (!fileInfo.Exists) { return; } if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Wiping '{0}'.".InvariantFormat(fileInfo.Name)); } bool cancelPending = false; progress.NotifyLevelStart(); using (Stream stream = fileInfo.OpenWrite()) { long length = stream.Length + OS.Current.StreamBufferSize - stream.Length % OS.Current.StreamBufferSize; progress.AddTotal(length); for (long position = 0; position < length; position += OS.Current.StreamBufferSize) { byte[] random = OS.Current.GetRandomBytes(OS.Current.StreamBufferSize); stream.Write(random, 0, random.Length); stream.Flush(); try { progress.AddCount(random.Length); } catch (OperationCanceledException) { cancelPending = true; progress.Cancel = false; progress.AddCount(random.Length); } } } string randomName; do { randomName = GenerateRandomFileName(fileInfo.FullName); } while (OS.Current.FileInfo(randomName).Exists); IRuntimeFileInfo moveToFileInfo = OS.Current.FileInfo(fileInfo.FullName); moveToFileInfo.MoveTo(randomName); moveToFileInfo.Delete(); progress.NotifyLevelFinished(); if (cancelPending) { progress.Cancel = true; throw new OperationCanceledException("Delayed cancel during wipe."); } }
public static void TestMethodIsModified() { IRuntimeFileInfo decryptedFileInfo = OS.Current.FileInfo(Path.Combine(_rootPath, "doesnotexist.txt")); IRuntimeFileInfo encryptedFileInfo = OS.Current.FileInfo(_helloWorldAxxPath); using (ActiveFile activeFile = new ActiveFile(encryptedFileInfo, decryptedFileInfo, new AesKey(), ActiveFileStatus.None, null)) { Assert.That(activeFile.IsModified, Is.False, "A non-existing decrypted file should not be treated as modified."); } }
static bool TryDecrypt(IRuntimeFileInfo file, string filePath, AesKey key, ProgressContext progress, out string encryptedFileName) { encryptedFileName = AxCryptFile.Decrypt(file, filePath, key, AxCryptOptions.EncryptWithCompression, progress); if (encryptedFileName == null) { return(false); } return(true); }
private void Initialize(IRuntimeFileInfo encryptedFileInfo, IRuntimeFileInfo decryptedFileInfo, DateTime lastWriteTimeUtc, AesKey key, AesKeyThumbprint thumbprint, ActiveFileStatus status, ILauncher process) { EncryptedFileInfo = OS.Current.FileInfo(encryptedFileInfo.FullName); DecryptedFileInfo = OS.Current.FileInfo(decryptedFileInfo.FullName); Key = key; Thumbprint = thumbprint; Status = status; LastActivityTimeUtc = OS.Current.UtcNow; Process = process; LastEncryptionWriteTimeUtc = lastWriteTimeUtc; }
public static void TestFileLockMethods() { IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_fileExtPath); Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file yet."); using (FileLock lock1 = FileLock.Lock(fileInfo)) { Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should be now be a lock for this file."); } Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file again."); }
public static FileOperationStatus OpenAndLaunchApplication(this FileSystemState fileSystemState, string file, IEnumerable <AesKey> keys, ProgressContext progress) { if (fileSystemState == null) { throw new ArgumentNullException("fileSystemState"); } if (file == null) { throw new ArgumentNullException("file"); } if (keys == null) { throw new ArgumentNullException("keys"); } if (progress == null) { throw new ArgumentNullException("progress"); } IRuntimeFileInfo fileInfo = OS.Current.FileInfo(file); if (!fileInfo.Exists) { if (OS.Log.IsWarningEnabled) { OS.Log.LogWarning("Tried to open non-existing '{0}'.".InvariantFormat(fileInfo.FullName)); } return(FileOperationStatus.FileDoesNotExist); } ActiveFile destinationActiveFile = fileSystemState.FindEncryptedPath(fileInfo.FullName); if (destinationActiveFile == null || !destinationActiveFile.DecryptedFileInfo.Exists) { IRuntimeFileInfo destinationFolderInfo = GetTemporaryDestinationFolder(destinationActiveFile); destinationActiveFile = TryDecrypt(fileInfo, destinationFolderInfo, keys, progress); } else { destinationActiveFile = CheckKeysForAlreadyDecryptedFile(destinationActiveFile, keys, progress); } if (destinationActiveFile == null) { return(FileOperationStatus.InvalidKey); } fileSystemState.Add(destinationActiveFile); fileSystemState.Save(); FileOperationStatus status = LaunchApplicationForDocument(fileSystemState, destinationActiveFile); return(status); }
/// <summary> /// Enumerate all apparently plaintext files in the list of watched folders. /// </summary> /// <param name="fileSystemState">The associated <see cref="FileSystemState"/>.</param> /// <returns>An enumeration of found files.</returns> public static IEnumerable <IRuntimeFileInfo> DecryptedFilesInWatchedFolders(this FileSystemState fileSystemState) { IEnumerable <IRuntimeFileInfo> newFiles = new List <IRuntimeFileInfo>(); foreach (WatchedFolder watchedFolder in fileSystemState.WatchedFolders) { IRuntimeFileInfo fileInfo = OS.Current.FileInfo(watchedFolder.Path); newFiles = newFiles.Concat(fileInfo.Files); } return(newFiles.Where((IRuntimeFileInfo fileInfo) => { return !fileInfo.Name.IsEncryptedName(); })); }
public static void TestWriteToFileWithBackupWithCancel() { IRuntimeFileInfo destinationFileInfo = OS.Current.FileInfo(_rootPath.PathCombine("Written", "File.txt")); using (MemoryStream inputStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Encoding.UTF8.GetBytes("A string with some text"))) { Assert.Throws <OperationCanceledException>(() => { AxCryptFile.WriteToFileWithBackup(destinationFileInfo, (Stream stream) => { throw new OperationCanceledException(); }, new ProgressContext()); }); string tempFilePath = _rootPath.PathCombine("Written", "File.bak"); IRuntimeFileInfo tempFileInfo = OS.Current.FileInfo(tempFilePath); Assert.That(tempFileInfo.Exists, Is.False, "The .bak file should be removed."); } }
public static void TestWipe() { string testFile = _rootPath.PathCombine("Folder", "file-to-be-wiped.txt"); IRuntimeFileInfo fileInfo = OS.Current.FileInfo(testFile); using (Stream writeStream = fileInfo.OpenWrite()) { } Assert.That(fileInfo.Exists, "Now it should exist."); AxCryptFile.Wipe(fileInfo, new ProgressContext()); Assert.That(!fileInfo.Exists, "And now it should not exist after wiping."); }
public static void TestInvalidArguments() { IRuntimeFileInfo sourceFileInfo = OS.Current.FileInfo(_testTextPath); IRuntimeFileInfo destinationFileInfo = sourceFileInfo.CreateEncryptedName(); AxCryptDocument document = new AxCryptDocument(); IRuntimeFileInfo decryptedFileInfo = OS.Current.FileInfo(Path.Combine(_rootPath, "decrypted test.txt")); AxCryptDocument nullDocument = null; IRuntimeFileInfo nullFileInfo = null; AesKey nullKey = null; ProgressContext nullProgress = null; Passphrase nullPassphrase = null; Stream nullStream = null; string nullString = null; Action <Stream> nullStreamAction = null; Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Encrypt(nullFileInfo, destinationFileInfo, new Passphrase("axcrypt"), AxCryptOptions.EncryptWithCompression, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Encrypt(sourceFileInfo, nullFileInfo, new Passphrase("axcrypt"), AxCryptOptions.EncryptWithCompression, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Encrypt(sourceFileInfo, destinationFileInfo, nullPassphrase, AxCryptOptions.EncryptWithCompression, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Encrypt(sourceFileInfo, destinationFileInfo, new Passphrase("axcrypt"), AxCryptOptions.EncryptWithCompression, nullProgress); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Encrypt(nullFileInfo, new MemoryStream(), new AesKey(), AxCryptOptions.None, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Encrypt(sourceFileInfo, nullStream, new AesKey(), AxCryptOptions.None, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Encrypt(sourceFileInfo, new MemoryStream(), nullKey, AxCryptOptions.None, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Encrypt(sourceFileInfo, new MemoryStream(), new AesKey(), AxCryptOptions.None, nullProgress); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(nullDocument, decryptedFileInfo, AxCryptOptions.SetFileTimes, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(document, nullFileInfo, AxCryptOptions.SetFileTimes, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(document, decryptedFileInfo, AxCryptOptions.SetFileTimes, nullProgress); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(nullFileInfo, decryptedFileInfo, new AesKey(), AxCryptOptions.SetFileTimes, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(sourceFileInfo, nullFileInfo, new AesKey(), AxCryptOptions.SetFileTimes, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(sourceFileInfo, decryptedFileInfo, nullKey, AxCryptOptions.SetFileTimes, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(sourceFileInfo, decryptedFileInfo, new AesKey(), AxCryptOptions.SetFileTimes, nullProgress); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(nullFileInfo, Path.Combine(_rootPath, "Directory"), new AesKey(), AxCryptOptions.SetFileTimes, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(sourceFileInfo, nullString, new AesKey(), AxCryptOptions.SetFileTimes, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(sourceFileInfo, Path.Combine(_rootPath, "Directory"), nullKey, AxCryptOptions.SetFileTimes, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Decrypt(sourceFileInfo, Path.Combine(_rootPath, "Directory"), new AesKey(), AxCryptOptions.SetFileTimes, nullProgress); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Document(nullFileInfo, new AesKey(), new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Document(sourceFileInfo, nullKey, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Document(sourceFileInfo, new AesKey(), nullProgress); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.WriteToFileWithBackup(null, (Stream stream) => { }, new ProgressContext()); }); IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_testTextPath); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.WriteToFileWithBackup(fileInfo, nullStreamAction, new ProgressContext()); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.MakeAxCryptFileName(nullFileInfo); }); Assert.Throws <ArgumentNullException>(() => { AxCryptFile.Wipe(nullFileInfo, new ProgressContext()); }); }
private bool OpenAxCryptDocument(string fullName, FileOperationEventArgs e) { e.AxCryptDocument = null; try { IRuntimeFileInfo source = OS.Current.FileInfo(fullName); e.OpenFileFullName = source.FullName; foreach (AesKey key in _fileSystemState.KnownKeys.Keys) { e.AxCryptDocument = AxCryptFile.Document(source, key, new ProgressContext()); if (e.AxCryptDocument.PassphraseIsValid) { break; } e.AxCryptDocument.Dispose(); e.AxCryptDocument = null; } Passphrase passphrase; while (e.AxCryptDocument == null) { OnQueryDecryptionPassphrase(e); if (e.Cancel) { e.Status = FileOperationStatus.Canceled; return(false); } passphrase = new Passphrase(e.Passphrase); e.AxCryptDocument = AxCryptFile.Document(source, passphrase.DerivedPassphrase, new ProgressContext()); if (!e.AxCryptDocument.PassphraseIsValid) { e.AxCryptDocument.Dispose(); e.AxCryptDocument = null; continue; } e.Key = passphrase.DerivedPassphrase; OnKnownKeyAdded(e); } } catch (IOException ioex) { if (e.AxCryptDocument != null) { e.AxCryptDocument.Dispose(); e.AxCryptDocument = null; } FileOperationStatus status = ioex is FileNotFoundException ? FileOperationStatus.FileDoesNotExist : FileOperationStatus.Exception; e.Status = status; return(false); } return(true); }
public static void TestInvalidPassphrase() { IRuntimeFileInfo sourceFileInfo = OS.Current.FileInfo(_testTextPath); IRuntimeFileInfo encryptedFileInfo = sourceFileInfo.CreateEncryptedName(); Assert.That(encryptedFileInfo.Name, Is.EqualTo("test-txt.axx"), "Wrong encrypted file name based on the plain text file name."); AxCryptFile.Encrypt(sourceFileInfo, encryptedFileInfo, new Passphrase("axcrypt"), AxCryptOptions.EncryptWithCompression, new ProgressContext()); IRuntimeFileInfo decryptedFileInfo = OS.Current.FileInfo(Path.Combine(_rootPath, "decrypted.txt")); bool isPassphraseOk = AxCryptFile.Decrypt(encryptedFileInfo, decryptedFileInfo, new Passphrase("wrong").DerivedPassphrase, AxCryptOptions.None, new ProgressContext()); Assert.That(isPassphraseOk, Is.False, "The passphrase is wrong and should be wrong!"); }
public static void TestUpdateActiveFileWithKeyIfKeyMatchesThumbprintWithKnownKey() { IRuntimeFileInfo encryptedFileInfo = OS.Current.FileInfo(_encryptedFile1); IRuntimeFileInfo decryptedFileInfo = OS.Current.FileInfo(_decryptedFile1); AesKey key = new AesKey(); ActiveFile activeFile = new ActiveFile(encryptedFileInfo, decryptedFileInfo, key, ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.NotShareable, null); _fileSystemState.Add(activeFile); bool updateWasMade = _fileSystemState.UpdateActiveFileWithKeyIfKeyMatchesThumbprint(key); Assert.That(updateWasMade, Is.False, "Since there are only ActiveFiles with known keys in the list, no update should be made."); }
public static void TestWipeWithDelayedUntilDoneCancel() { IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_davidCopperfieldTxtPath); ProgressContext progress = new ProgressContext(TimeSpan.Zero); progress.Progressing += (object sender, ProgressEventArgs e) => { ((ProgressContext)sender).Cancel = true; }; Assert.Throws <OperationCanceledException>(() => { AxCryptFile.Wipe(fileInfo, progress); }); Assert.That(!fileInfo.Exists, "The file should be completely wiped, even if canceled at start."); }
public static string MakeAxCryptFileName(IRuntimeFileInfo fileInfo) { if (fileInfo == null) { throw new ArgumentNullException("fileInfo"); } string axCryptExtension = OS.Current.AxCryptExtension; string originalExtension = Path.GetExtension(fileInfo.Name); string modifiedExtension = originalExtension.Length == 0 ? String.Empty : "-" + originalExtension.Substring(1); string axCryptFileName = Path.Combine(Path.GetDirectoryName(fileInfo.FullName), Path.GetFileNameWithoutExtension(fileInfo.Name) + modifiedExtension + axCryptExtension); return(axCryptFileName); }
public static void TestCheckActiveFilesUpdateButWithTargetLockedForSharing() { DateTime utcNow = OS.Current.UtcNow; FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); Passphrase passphrase = new Passphrase("a"); AxCryptFile.Decrypt(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), passphrase.DerivedPassphrase, AxCryptOptions.None, new ProgressContext()); ActiveFile activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), passphrase.DerivedPassphrase, ActiveFileStatus.AssumedOpenAndDecrypted, null); _fileSystemState.Add(activeFile); IRuntimeFileInfo decryptedFileInfo = OS.Current.FileInfo(_decryptedFile1); decryptedFileInfo.SetFileTimes(utcNow.AddSeconds(30), utcNow.AddSeconds(30), utcNow.AddSeconds(30)); SetupAssembly.FakeRuntimeEnvironment.TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); _fileSystemState.KnownKeys.Add(passphrase.DerivedPassphrase); EventHandler eventHandler = ((object sender, EventArgs e) => { FakeRuntimeFileInfo fileInfo = (FakeRuntimeFileInfo)sender; if (fileInfo.FullName == _decryptedFile1) { throw new IOException("Faked sharing violation."); } }); FakeRuntimeFileInfo.OpeningForRead += eventHandler; try { _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); } finally { FakeRuntimeFileInfo.OpeningForRead -= eventHandler; } Assert.That(changedWasRaised, Is.True, "The ActiveFile should be modified because it should now be marked as not shareable."); activeFile = _fileSystemState.FindEncryptedPath(_encryptedFile1); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotShareable), Is.True, "The ActiveFile should be marked as not shareable after the checking of active files."); }
public static void TestFileLockCaseSensitivity() { IRuntimeFileInfo fileInfo1 = OS.Current.FileInfo(_fileExtPath); IRuntimeFileInfo fileInfo2 = OS.Current.FileInfo(_fileExtPath.ToUpper(CultureInfo.InvariantCulture)); Assert.That(FileLock.IsLocked(fileInfo1), Is.False, "There should be no lock for this file yet."); Assert.That(FileLock.IsLocked(fileInfo2), Is.False, "There should be no lock for this file yet."); using (FileLock lock1 = FileLock.Lock(fileInfo1)) { Assert.That(FileLock.IsLocked(fileInfo1), Is.True, "There should be now be a lock for this file."); Assert.That(FileLock.IsLocked(fileInfo2), Is.False, "There should be no lock for this file still."); } Assert.That(FileLock.IsLocked(fileInfo1), Is.False, "There should be no lock for this file again."); }
public static void TestUncompressedEncryptedDecryptAxCrypt17() { IRuntimeFileInfo sourceRuntimeFileInfo = OS.Current.FileInfo(_uncompressedAxxPath); IRuntimeFileInfo destinationRuntimeFileInfo = OS.Current.FileInfo(Path.Combine(Path.GetDirectoryName(_uncompressedAxxPath), "Uncompressed.zip")); Passphrase passphrase = new Passphrase("Uncompressable"); using (AxCryptDocument document = new AxCryptDocument()) { bool isOk = document.Load(sourceRuntimeFileInfo.OpenRead(), passphrase.DerivedPassphrase); Assert.That(isOk, Is.True, "The document should load ok."); AxCryptFile.Decrypt(document, destinationRuntimeFileInfo, AxCryptOptions.None, new ProgressContext()); Assert.That(document.DocumentHeaders.UncompressedLength, Is.EqualTo(0), "Since the data is not compressed, there should not be a CompressionInfo, but in 1.x there is, with value zero."); } }
public void Load(IRuntimeFileInfo path) { if (path == null) { throw new ArgumentNullException("path"); } if (!path.Exists) { _path = path.FullName; if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("No existing FileSystemState. Save location is '{0}'.".InvariantFormat(_path)); } return; } DataContractSerializer serializer = CreateSerializer(); IRuntimeFileInfo loadInfo = OS.Current.FileInfo(path.FullName); using (Stream fileSystemStateStream = loadInfo.OpenRead()) { FileSystemState fileSystemState; try { fileSystemState = (FileSystemState)serializer.ReadObject(fileSystemStateStream); } catch (Exception ex) { if (OS.Log.IsErrorEnabled) { OS.Log.LogError("Exception {1} reading {0}. Ignoring and re-initializing state.".InvariantFormat(path.FullName, ex.Message)); } fileSystemState = new FileSystemState(); } _path = path.FullName; foreach (ActiveFile activeFile in fileSystemState.ActiveFiles) { Add(activeFile); } KnownKeys = fileSystemState.KnownKeys; KeyWrapIterations = fileSystemState.KeyWrapIterations; ThumbprintSalt = fileSystemState.ThumbprintSalt; WatchedFolders = fileSystemState.WatchedFolders; if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Loaded FileSystemState from '{0}'.".InvariantFormat(fileSystemState._path)); } } }
public static void TestWriteToFileWithBackup() { string destinationFilePath = _rootPath.PathCombine("Written", "File.txt"); using (MemoryStream inputStream = FakeRuntimeFileInfo.ExpandableMemoryStream(Encoding.UTF8.GetBytes("A string with some text"))) { IRuntimeFileInfo destinationFileInfo = OS.Current.FileInfo(destinationFilePath); AxCryptFile.WriteToFileWithBackup(destinationFileInfo, (Stream stream) => { inputStream.CopyTo(stream, 4096); }, new ProgressContext()); using (TextReader read = new StreamReader(destinationFileInfo.OpenRead())) { string readString = read.ReadToEnd(); Assert.That(readString, Is.EqualTo("A string with some text"), "Where expecting the same string to be read back."); } } }
public static void TestSimpleDecryptAndLaunchOnThreadWorker() { FakeLauncher launcher = null; FakeRuntimeEnvironment environment = (FakeRuntimeEnvironment)OS.Current; environment.Launcher = ((string path) => { launcher = new FakeLauncher(path); return(launcher); }); FileOperationsController controller = new FileOperationsController(_fileSystemState); controller.QueryDecryptionPassphrase += (object sender, FileOperationEventArgs e) => { e.Passphrase = "a"; }; FileOperationStatus status = FileOperationStatus.Unknown; controller.Completed += (object sender, FileOperationEventArgs e) => { status = e.Status; }; using (ThreadWorker worker = new ThreadWorker(new ProgressContext())) { controller.DecryptAndLaunch(_helloWorldAxxPath, worker); worker.Join(); } Assert.That(status, Is.EqualTo(FileOperationStatus.Success), "The status should indicate success."); Assert.That(launcher, Is.Not.Null, "There should be a call to launch."); Assert.That(Path.GetFileName(launcher.Path), Is.EqualTo("HelloWorld-Key-a.txt"), "The file should be decrypted and the name should be the original from the encrypted headers."); IRuntimeFileInfo destinationInfo = OS.Current.FileInfo(launcher.Path); Assert.That(destinationInfo.Exists, "After decryption the destination file should be created."); string fileContent; using (Stream stream = destinationInfo.OpenRead()) { fileContent = new StreamReader(stream).ReadToEnd(); } Assert.That(fileContent.Contains("Hello"), "A file named Hello World should contain that text when decrypted."); }
public static void EncryptFile(ProgressContext progress, Action <string, ProgressContext> failure) { CreatePassphraseViewController passphraseController = new CreatePassphraseViewController { EncryptedFileName = DateTime.Now.ToString("yyyyMMddHHmmss") }; NSOpenPanel open = new NSOpenPanel { AccessoryView = passphraseController.View, AllowsMultipleSelection = false, CanChooseDirectories = false, CanChooseFiles = true, CanSelectHiddenExtension = true, CollectionBehavior = NSWindowCollectionBehavior.Transient, ExtensionHidden = true, Message = "Please select the file you would like to encrypt", Prompt = "Encrypt file", Title = "Encrypt", TreatsFilePackagesAsDirectories = false, }; open.Begin(result => { if (result == 0 || open.Urls.Length == 0) { return; } if (!open.Urls[0].IsFileUrl) { return; } string sourceFilePath = open.Urls[0].Path; open.Close(); IRuntimeFileInfo sourceFile = OS.Current.FileInfo(sourceFilePath); Passphrase passphrase = passphraseController.VerifiedPassphrase; if (passphrase == null) { return; } IRuntimeFileInfo targetFile = GetTargetFileName(sourceFilePath, passphraseController.EncryptedFileName); ThreadPool.QueueUserWorkItem(delegate { using (new NSAutoreleasePool()) { AxCryptFile.EncryptFileWithBackupAndWipe(sourceFile, targetFile, passphrase.DerivedPassphrase, progress); }; }); }); }
public static void TestEncryptToStream() { IRuntimeFileInfo sourceFileInfo = OS.Current.FileInfo(_testTextPath); IRuntimeFileInfo destinationFileInfo = sourceFileInfo.CreateEncryptedName(); Assert.That(destinationFileInfo.Name, Is.EqualTo("test-txt.axx"), "Wrong encrypted file name based on the plain text file name."); using (Stream destinationStream = destinationFileInfo.OpenWrite()) { AxCryptFile.Encrypt(sourceFileInfo, destinationStream, new Passphrase("axcrypt").DerivedPassphrase, AxCryptOptions.EncryptWithCompression, new ProgressContext()); } using (AxCryptDocument document = AxCryptFile.Document(destinationFileInfo, new Passphrase("axcrypt").DerivedPassphrase, new ProgressContext())) { Assert.That(document.PassphraseIsValid, Is.True, "The passphrase should be ok."); } }
public ActiveFile(IRuntimeFileInfo encryptedFileInfo, IRuntimeFileInfo decryptedFileInfo, AesKey key, ActiveFileStatus status, ILauncher process) { if (encryptedFileInfo == null) { throw new ArgumentNullException("encryptedFileInfo"); } if (decryptedFileInfo == null) { throw new ArgumentNullException("decryptedFileInfo"); } if (key == null) { throw new ArgumentNullException("key"); } Initialize(encryptedFileInfo, decryptedFileInfo, decryptedFileInfo.LastWriteTimeUtc, key, null, status, process); }
public static void TestEncryptFileWithBackupAndWipeFileName() { string sourceFilePath = _davidCopperfieldTxtPath; string destinationFilePath = Path.Combine(Path.GetDirectoryName(sourceFilePath), "David Copperfield-txt.axx"); AesKey key = new AesKey(); ProgressContext progress = new ProgressContext(); AxCryptFile.EncryptFileWithBackupAndWipe(sourceFilePath, destinationFilePath, key, progress); IRuntimeFileInfo sourceFileInfo = OS.Current.FileInfo(sourceFilePath); IRuntimeFileInfo destinationFileInfo = OS.Current.FileInfo(destinationFilePath); Assert.That(sourceFileInfo.Exists, Is.False, "The source should be wiped."); Assert.That(destinationFileInfo.Exists, Is.True, "The destination should be created and exist now."); }
private static string MakeAlternatePath(IRuntimeFileInfo fileInfo, string extension) { string alternatePath; IRuntimeFileInfo alternateFileInfo; int version = 0; do { string alternateExtension = (version > 0 ? "." + version.ToString(CultureInfo.InvariantCulture) : String.Empty) + extension; alternatePath = Path.Combine(Path.GetDirectoryName(fileInfo.FullName), Path.GetFileNameWithoutExtension(fileInfo.Name) + alternateExtension); alternateFileInfo = OS.Current.FileInfo(alternatePath); ++version; } while (alternateFileInfo.Exists); return(alternatePath); }
public static void TestWipeFileDoesNotExist() { ProgressContext progress = new ProgressContext(TimeSpan.Zero); bool progressed = false; progress.Progressing += (object sender, ProgressEventArgs e) => { progressed = true; }; string filePath = Path.Combine(Path.Combine(_rootPath, "Folder"), "DoesNot.Exist"); IRuntimeFileInfo fileInfo = OS.Current.FileInfo(filePath); Assert.DoesNotThrow(() => { AxCryptFile.Wipe(fileInfo, progress); }); Assert.That(!progressed, "There should be no progress-notification since nothing should happen."); }
public static FileLock Lock(IRuntimeFileInfo fileInfo) { if (fileInfo == null) { throw new ArgumentNullException("fileInfo"); } lock (_lockedFiles) { if (IsLocked(fileInfo)) { return null; } _lockedFiles.Add(fileInfo.FullName); if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Locking file '{0}'.".InvariantFormat(fileInfo.FullName)); } return new FileLock(fileInfo.FullName); } }
public static void EncryptFileWithBackupAndWipe(IRuntimeFileInfo sourceFileInfo, IRuntimeFileInfo destinationFileInfo, AesKey key, ProgressContext progress) { if (sourceFileInfo == null) { throw new ArgumentNullException("sourceFileInfo"); } if (destinationFileInfo == null) { throw new ArgumentNullException("destinationFileInfo"); } if (key == null) { throw new ArgumentNullException("key"); } if (progress == null) { throw new ArgumentNullException("progress"); } progress.NotifyLevelStart(); using (Stream activeFileStream = sourceFileInfo.OpenRead()) { WriteToFileWithBackup(destinationFileInfo, (Stream destination) => { Encrypt(sourceFileInfo, destination, key, AxCryptOptions.EncryptWithCompression, progress); }, progress); } Wipe(sourceFileInfo, progress); progress.NotifyLevelFinished(); }
public static string MakeAxCryptFileName(IRuntimeFileInfo fileInfo) { if (fileInfo == null) { throw new ArgumentNullException("fileInfo"); } string axCryptExtension = OS.Current.AxCryptExtension; string originalExtension = Path.GetExtension(fileInfo.Name); string modifiedExtension = originalExtension.Length == 0 ? String.Empty : "-" + originalExtension.Substring(1); string axCryptFileName = Path.Combine(Path.GetDirectoryName(fileInfo.FullName), Path.GetFileNameWithoutExtension(fileInfo.Name) + modifiedExtension + axCryptExtension); return axCryptFileName; }
/// <summary> /// Decrypt a source file to a destination file, given a passphrase /// </summary> /// <param name="sourceFile">The source file</param> /// <param name="destinationFile">The destination file</param> /// <param name="passphrase">The passphrase</param> /// <returns>true if the passphrase was correct</returns> public static string Decrypt(IRuntimeFileInfo sourceFile, string destinationDirectory, AesKey key, AxCryptOptions options, ProgressContext progress) { if (sourceFile == null) { throw new ArgumentNullException("sourceFile"); } if (destinationDirectory == null) { throw new ArgumentNullException("destinationDirectory"); } if (key == null) { throw new ArgumentNullException("key"); } if (progress == null) { throw new ArgumentNullException("progress"); } string destinationFileName = null; using (AxCryptDocument document = Document(sourceFile, key, new ProgressContext())) { if (!document.PassphraseIsValid) { return destinationFileName; } destinationFileName = document.DocumentHeaders.FileName; IRuntimeFileInfo destinationFullPath = OS.Current.FileInfo(Path.Combine(destinationDirectory, destinationFileName)); Decrypt(document, destinationFullPath, options, progress); } return destinationFileName; }
/// <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); } } }
public static void WriteToFileWithBackup(IRuntimeFileInfo destinationFileInfo, Action<Stream> writeFileStreamTo, ProgressContext progress) { if (destinationFileInfo == null) { throw new ArgumentNullException("destinationFileInfo"); } if (writeFileStreamTo == null) { throw new ArgumentNullException("writeFileStreamTo"); } string temporaryFilePath = MakeAlternatePath(destinationFileInfo, ".tmp"); IRuntimeFileInfo temporaryFileInfo = OS.Current.FileInfo(temporaryFilePath); try { using (Stream temporaryStream = temporaryFileInfo.OpenWrite()) { writeFileStreamTo(temporaryStream); } } catch (OperationCanceledException) { if (temporaryFileInfo.Exists) { AxCryptFile.Wipe(temporaryFileInfo, progress); } throw; } if (destinationFileInfo.Exists) { string backupFilePath = MakeAlternatePath(destinationFileInfo, ".bak"); IRuntimeFileInfo backupFileInfo = OS.Current.FileInfo(destinationFileInfo.FullName); backupFileInfo.MoveTo(backupFilePath); temporaryFileInfo.MoveTo(destinationFileInfo.FullName); AxCryptFile.Wipe(backupFileInfo, progress); } else { temporaryFileInfo.MoveTo(destinationFileInfo.FullName); } }
public LockingStream(IRuntimeFileInfo fileInfo, Stream stream) { _stream = stream; _fileLock = FileLock.Lock(fileInfo); }
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); } } }
static bool TryDecrypt(IRuntimeFileInfo file, string filePath, AesKey key, ProgressContext progress, out string encryptedFileName) { encryptedFileName = AxCryptFile.Decrypt(file, filePath, key, AxCryptOptions.EncryptWithCompression, progress); if (encryptedFileName == null) { return false; } return true; }
private static ActiveFile DecryptActiveFileDocument(IRuntimeFileInfo sourceFileInfo, IRuntimeFileInfo destinationFolderInfo, AxCryptDocument document, ProgressContext progress) { string destinationName = document.DocumentHeaders.FileName; string destinationPath = Path.Combine(destinationFolderInfo.FullName, destinationName); IRuntimeFileInfo destinationFileInfo = OS.Current.FileInfo(destinationPath); using (FileLock fileLock = FileLock.Lock(destinationFileInfo)) { AxCryptFile.Decrypt(document, destinationFileInfo, AxCryptOptions.SetFileTimes, progress); } ActiveFile destinationActiveFile = new ActiveFile(sourceFileInfo, destinationFileInfo, document.DocumentHeaders.KeyEncryptingKey, ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.IgnoreChange, null); if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("File decrypted from '{0}' to '{1}'".InvariantFormat(sourceFileInfo.FullName, destinationActiveFile.DecryptedFileInfo.FullName)); } return destinationActiveFile; }
private static string MakeAlternatePath(IRuntimeFileInfo fileInfo, string extension) { string alternatePath; IRuntimeFileInfo alternateFileInfo; int version = 0; do { string alternateExtension = (version > 0 ? "." + version.ToString(CultureInfo.InvariantCulture) : String.Empty) + extension; alternatePath = Path.Combine(Path.GetDirectoryName(fileInfo.FullName), Path.GetFileNameWithoutExtension(fileInfo.Name) + alternateExtension); alternateFileInfo = OS.Current.FileInfo(alternatePath); ++version; } while (alternateFileInfo.Exists); return alternatePath; }
/// <summary> /// Load an AxCryptDocument from a source file with a passphrase /// </summary> /// <param name="sourceFile">The source file</param> /// <param name="passphrase">The passphrase</param> /// <returns>An instance of AxCryptDocument. Use IsPassphraseValid property to determine validity.</returns> public static AxCryptDocument Document(IRuntimeFileInfo sourceFile, AesKey key, ProgressContext progress) { if (sourceFile == null) { throw new ArgumentNullException("sourceFile"); } if (key == null) { throw new ArgumentNullException("key"); } if (progress == null) { throw new ArgumentNullException("progress"); } AxCryptDocument document = new AxCryptDocument(); Stream stream = new ProgressStream(sourceFile.OpenRead(), progress); progress.AddTotal(stream.Length); document.Load(stream, key); return document; }
private static ActiveFile TryDecrypt(IRuntimeFileInfo sourceFileInfo, IRuntimeFileInfo destinationFolderInfo, IEnumerable<AesKey> keys, ProgressContext progress) { ActiveFile destinationActiveFile = null; foreach (AesKey key in keys) { if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Decrypting '{0}'".InvariantFormat(sourceFileInfo.FullName)); } using (FileLock sourceLock = FileLock.Lock(sourceFileInfo)) { using (AxCryptDocument document = AxCryptFile.Document(sourceFileInfo, key, new ProgressContext())) { if (!document.PassphraseIsValid) { continue; } destinationActiveFile = DecryptActiveFileDocument(sourceFileInfo, destinationFolderInfo, document, progress); break; } } } return destinationActiveFile; }
/// <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); } }