public static void RestoreSettings() { try { using (var selectFileDialog = new VistaOpenFileDialog()) { selectFileDialog.Title = "Settings Restore"; if (selectFileDialog.ShowDialog() == DialogResult.OK) { if (selectFileDialog.FileName.EndsWith(".ini", StringComparison.Ordinal)) { File.Copy(selectFileDialog.FileName, _settingsFile, true); // Reload settings ReadSettings(); DisplayMessage.InformationMessageBox("Your settings have been restored.", "Settings Restored"); } else { DisplayMessage.ErrorMessageBox("The selected file is not an INI file. Please select a 'settings.ini' file."); } } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Low); DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to restore settings from the selected file."); } }
public static bool AuthenticateFile(string filePath, byte[] macKey, out byte[] storedHash) { try { bool tampered = true; storedHash = ReadStoredHash(filePath); if (storedHash != null) { byte[] computedHash = new byte[Constants.HashLength]; using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) { // Remove the stored MAC from the file before computing the MAC fileStream.SetLength(fileStream.Length - computedHash.Length); MemoryEncryption.DecryptByteArray(ref macKey); computedHash = HashingAlgorithms.Blake2(fileStream, macKey); MemoryEncryption.EncryptByteArray(ref macKey); } // Invert result tampered = !Sodium.Utilities.Compare(storedHash, computedHash); if (tampered == true) { // Restore the stored MAC AppendHash(filePath, storedHash); } } return(tampered); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to authenticate the file."); storedHash = null; return(true); } }
private static void CallEncryption(bool encryption, string filePath, byte[] passwordBytes, ref int progress, BackgroundWorker backgroundWorker) { try { bool kryptorExtension = filePath.EndsWith(Constants.EncryptedExtension, StringComparison.Ordinal); // Prevent Read-Only file attribute causing errors File.SetAttributes(filePath, FileAttributes.Normal); if (encryption == true && kryptorExtension == false) { Encryption.InitializeEncryption(filePath, passwordBytes, backgroundWorker); OverwriteDisabled(filePath); } else if (encryption == false && kryptorExtension == true) { Decryption.InitializeDecryption(filePath, passwordBytes, backgroundWorker); } else { DisplayFileError(filePath, encryption, kryptorExtension); } ReportProgress.IncrementProgress(ref progress, backgroundWorker); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to set file attributes to normal."); } }
public static char[] GenerateRandomPassphrase(int wordCount, bool uppercase, bool numbers) { try { string wordlistFilePath = Path.Combine(Constants.KryptorDirectory, "wordlist.txt"); if (File.Exists(wordlistFilePath)) { List <char> passphrase = new List <char>(); int wordlistLength = File.ReadLines(wordlistFilePath).Count(); int[] lineNumbers = GenerateLineNumbers(wordlistLength, wordCount); string[] words = GetRandomWords(wordlistFilePath, lineNumbers, wordCount, uppercase, numbers); Array.Clear(lineNumbers, 0, lineNumbers.Length); if (words != null) { FormatPassphrase(words, ref passphrase, wordCount); Array.Clear(words, 0, words.Length); } return(passphrase.ToArray()); } else { File.WriteAllText(wordlistFilePath, Properties.Resources.wordlist); return(GenerateRandomPassphrase(wordCount, uppercase, numbers)); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to generate a random passphrase."); return(Array.Empty <char>()); } }
public static void RestoreDirectoryName(string folderPath) { try { NullChecks.Strings(folderPath); string anonymisedDirectoryName = Path.GetFileName(folderPath); // Get the path where the original directory name is stored string storageFileName = $"{anonymisedDirectoryName}.txt"; string storageFilePath = Path.Combine(folderPath, storageFileName); if (File.Exists(storageFilePath)) { string originalDirectoryName = File.ReadAllText(storageFilePath); string originalDirectoryPath = folderPath.Replace(anonymisedDirectoryName, originalDirectoryName); Directory.Move(folderPath, originalDirectoryPath); storageFilePath = Path.Combine(originalDirectoryPath, storageFileName); if (File.Exists(storageFilePath)) { File.Delete(storageFilePath); } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(folderPath, ex.GetType().Name, "Unable to restore original directory name."); } }
public static void RestoreOriginalFileName(string decryptedFilePath) { try { if (Globals.AnonymousRename == true) { string originalFileName = ReadOriginalFileName(decryptedFilePath); if (!string.IsNullOrEmpty(originalFileName)) { string anonymousFileName = Path.GetFileName(decryptedFilePath); string originalFilePath = Regex.Replace(decryptedFilePath, anonymousFileName, originalFileName); if (File.Exists(originalFilePath)) { // Replace the file File.Delete(originalFilePath); } File.Move(decryptedFilePath, originalFilePath); } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(decryptedFilePath, ex.GetType().Name, "Unable to restore original file name."); } }
private static string[] GetRandomWords(string wordListFilePath, int[] lineNumbers, int wordCount, bool upperCase, bool numbers) { try { string[] words = new string[wordCount]; for (int i = 0; i < wordCount; i++) { words[i] = File.ReadLines(wordListFilePath).Skip(lineNumbers[i]).Take(1).First(); // Remove any numbers/spaces on the line words[i] = Regex.Replace(words[i], @"[\d-]", string.Empty).Trim(); if (upperCase == true) { words[i] = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(words[i].ToLower(CultureInfo.CurrentCulture)); } if (numbers == true) { words[i] += words[i].Length; } } return(words); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex) || ex is RegexMatchTimeoutException) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to retrieve words from the wordlist."); return(null); } }
public static void EncryptionErasure(string filePath, BackgroundWorker bgwShredFiles) { try { string encryptedFilePath = AnonymousRename.GetAnonymousFileName(filePath); using (var ciphertext = new FileStream(encryptedFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) using (var plaintext = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) { byte[] fileBytes = FileHandling.GetBufferSize(plaintext); byte[] key = SodiumCore.GetRandomBytes(Constants.EncryptionKeySize); byte[] nonce = SodiumCore.GetRandomBytes(Constants.XChaChaNonceLength); StreamCiphers.Encrypt(plaintext, ciphertext, 0, fileBytes, nonce, key, bgwShredFiles); Utilities.ZeroArray(key); Utilities.ZeroArray(nonce); } // Overwrite the original file File.Copy(encryptedFilePath, filePath, true); ShredFiles.EraseFileMetadata(encryptedFilePath); File.Delete(encryptedFilePath); } catch (Exception ex) when(ex is CryptographicException || ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "'Encryption' erasure failed."); } }
private static void RetrieveArgon2Parameters(string filePath, ref string memorySize, ref string iterations) { try { // Read the first line of the file using (var streamReader = new StreamReader(filePath, true)) { string firstLine = streamReader.ReadLine(); int memorySizeIndex = firstLine.IndexOf(Constants.MemorySizeFlag, StringComparison.Ordinal); if (memorySizeIndex != -1) { int iterationsIndex = firstLine.IndexOf(Constants.IterationsFlag, StringComparison.Ordinal); int endIndex = firstLine.IndexOf(Constants.EndFlag, StringComparison.Ordinal); // If the strings are found on the line if (memorySizeIndex != -1 && iterationsIndex != -1 && endIndex != -1) { memorySize = firstLine.Substring(memorySizeIndex, iterationsIndex - memorySizeIndex); iterations = firstLine.Substring(iterationsIndex, endIndex - iterationsIndex); } } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex) || ExceptionFilters.CharacterEncodingExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to read Argon2 parameters from the file."); } }
public static void ReadSettings() { try { if (File.Exists(_settingsFile)) { string[] settingsLines = File.ReadAllLines(_settingsFile); var settings = new List <string>(); foreach (string line in settingsLines) { string[] splitLine = line.Split(':'); // Ignore the name of each setting - only store values settings.Add(splitLine[1]); } LoadSettings(settings); } else { // Create settings file with default settings SaveSettings(); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to read the settings file."); } }
private static void ShredDirectory(string directoryPath, ref int progress, BackgroundWorker bgwShredFiles) { try { var directoryInfo = new DirectoryInfo(directoryPath) { Attributes = FileAttributes.NotContentIndexed }; string[] files = Directory.GetFiles(directoryPath, "*.*", SearchOption.AllDirectories); Globals.TotalCount += files.Length; foreach (string filePath in files) { CallShredFilesMethod(filePath, ref progress, bgwShredFiles); } string anonymisedDirectoryPath = AnonymousRename.MoveFile(directoryPath, false); Directory.Delete(anonymisedDirectoryPath, true); Globals.ResultsText += $"{Path.GetFileName(directoryPath)}: Folder erasure successful.{Environment.NewLine}"; Globals.SuccessfulCount += 1; } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(directoryPath, ex.GetType().Name, "Unable to access the directory."); } }
private static void ExportPublicKey(string publicKey) { try { if (!string.IsNullOrEmpty(publicKey)) { using (var saveFileDialog = new VistaSaveFileDialog()) { saveFileDialog.Title = "Export Public Key"; saveFileDialog.DefaultExt = ".txt"; saveFileDialog.FileName = "KRYPTOR PUBLIC KEY"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { File.WriteAllText(saveFileDialog.FileName, publicKey); File.SetAttributes(saveFileDialog.FileName, FileAttributes.ReadOnly); } } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Low); DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to export public key."); } }
public static void MakeFileReadOnly(string filePath) { try { File.SetAttributes(filePath, FileAttributes.ReadOnly); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to make the file read-only."); } }
public static void OverwriteFile(string fileToDelete, string fileToCopy) { try { File.Copy(fileToCopy, fileToDelete, true); File.Delete(fileToDelete); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.ErrorResultsText(fileToDelete, ex.GetType().Name, "Unable to overwrite and/or delete."); } }
private static string[] GetAllDirectories(string folderPath) { try { return(Directory.GetDirectories(folderPath, "*", SearchOption.AllDirectories)); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(folderPath, ex.GetType().Name, "Unable to get subdirectories in selected folder."); return(null); } }
public static bool?IsDirectory(string filePath) { try { var fileAttributes = File.GetAttributes(filePath); return(fileAttributes.HasFlag(FileAttributes.Directory)); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to check if file path is a directory."); return(null); } }
public static void LogException(string exceptionMessage, Severity severity) { try { const string logFileName = "error log.txt"; string logFilePath = Path.Combine(Constants.KryptorDirectory, logFileName); string logMessage = $"[Error] Severity = {severity}" + Environment.NewLine + exceptionMessage + Environment.NewLine; File.AppendAllText(logFilePath, logMessage); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to log exception."); } }
public static void EraseFileMetadata(string filePath) { try { var eraseDate = new DateTime(2001, 11, 26, 12, 0, 0); File.SetCreationTime(filePath, eraseDate); File.SetLastWriteTime(filePath, eraseDate); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Erasure of file metadata failed."); } }
public static void DeleteFile(string filePath) { try { if (File.Exists(filePath)) { File.Delete(filePath); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to delete the file."); } }
private static void DeleteFile(string filePath) { try { string anonymisedFilePath = AnonymousRename.MoveFile(filePath, true); EraseFileMetadata(anonymisedFilePath); File.Delete(anonymisedFilePath); Globals.ResultsText += $"{Path.GetFileName(filePath)}: File erasure successful." + Environment.NewLine; Globals.SuccessfulCount += 1; } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to delete the file."); } }
public static string ReadOriginalFileName(string filePath) { try { // Read the last line of the decrypted file string originalFileName = File.ReadLines(filePath).Last().Trim('\0'); RemoveStoredFileName(filePath, originalFileName); return(originalFileName); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex) || ex is InvalidOperationException) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to read original file name."); return(string.Empty); } }
private static bool GenerateKeyfile(string filePath) { try { byte[] keyfileBytes = SodiumCore.GetRandomBytes(Constants.MACKeySize); File.WriteAllBytes(filePath, keyfileBytes); File.SetAttributes(filePath, FileAttributes.ReadOnly); Utilities.ZeroArray(keyfileBytes); return(true); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to generate keyfile."); return(false); } }
public static bool AppendHash(string filePath, byte[] fileHash) { try { NullChecks.ByteArray(fileHash); using (var fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Read)) { fileStream.Write(fileHash, 0, fileHash.Length); } return(true); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to append the MAC to the file. This data is required for decryption of the file."); return(false); } }
private static void RemoveStoredFileName(string filePath, string originalFileName) { try { int removeLength = GetFileNameLength(filePath, originalFileName); if (removeLength != 0) { using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) { fileStream.SetLength(fileStream.Length - removeLength); } } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to remove the original file name stored in the decrypted file. The file should be decrypted, but there is a leftover string at the end of the file."); } }
public static void DeleteFirstRunFile() { const string firstRunFile = "first run.tmp"; try { // Prevent Argon2 benchmark reoccuring automatically string firstRunFilePath = Path.Combine(Constants.KryptorDirectory, firstRunFile); if (File.Exists(firstRunFilePath)) { File.Delete(firstRunFilePath); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.Medium); DisplayMessage.ErrorMessageBox(ex.GetType().Name, $"Unable to delete {Constants.KryptorDirectory}\\{firstRunFile}. Please manually delete this file to prevent the Argon2 benchmark from automatically running again."); } }
private static byte[] ReadHeader(string filePath, int headerLength, int offset) { try { byte[] header = new byte[headerLength]; using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { fileStream.Seek(offset, SeekOrigin.Begin); fileStream.Read(header, 0, header.Length); } return(header); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to read salt or nonce from the selected file."); return(null); } }
private static string AnonymiseDirectoryName(string folderPath) { try { string originalDirectoryName = Path.GetFileName(folderPath); string anonymisedPath = GetAnonymousFileName(folderPath); Directory.Move(folderPath, anonymisedPath); // Store the original directory name in a text file inside the directory string storageFilePath = Path.Combine(anonymisedPath, $"{Path.GetFileName(anonymisedPath)}.txt"); File.WriteAllText(storageFilePath, originalDirectoryName); return(anonymisedPath); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(folderPath, ex.GetType().Name, "Unable to anonymise directory name."); return(folderPath); } }
public static void SaveSettings() { try { if (File.Exists(_settingsFile)) { var settings = new Dictionary <string, string> { { "Encryption Algorithm", Invariant.ToString(Globals.EncryptionAlgorithm) }, { "Memory Encryption", Globals.MemoryEncryption.ToString() }, { "Anonymous Rename", Globals.AnonymousRename.ToString() }, { "Overwrite Files", Globals.OverwriteFiles.ToString() }, { "Argon2 Memory Size", Invariant.ToString(Globals.MemorySize) }, { "Argon2 Iterations", Invariant.ToString(Globals.Iterations) }, { "Show Password", Globals.ShowPasswordByDefault.ToString() }, { "Auto Clear Password", Globals.AutoClearPassword.ToString() }, { "Auto Clear Clipboard", Invariant.ToString(Globals.ClearClipboardInterval) }, { "Exit Clipboard Clear", Globals.ExitClearClipboard.ToString() }, { "Shred Files Method", Invariant.ToString(Globals.ShredFilesMethod) }, { "Check for Updates", Globals.CheckForUpdates.ToString() }, { "Dark Theme", Globals.DarkTheme.ToString() } }; using (var streamWriter = new StreamWriter(_settingsFile)) { foreach (var keyValuePair in settings) { streamWriter.WriteLine($"{keyValuePair.Key}: {keyValuePair.Value}"); } } } else { File.Create(_settingsFile).Close(); SaveSettings(); } } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to save settings."); } }
private static byte[] ReadStoredHash(string filePath) { try { byte[] storedHash = new byte[Constants.HashLength]; using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { // Read the last 64 bytes of the file fileStream.Seek(fileStream.Length - storedHash.Length, SeekOrigin.Begin); fileStream.Read(storedHash, 0, storedHash.Length); } return(storedHash); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex)) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to read the MAC stored in the file."); return(null); } }
public static bool AppendOriginalFileName(string filePath) { try { string fileName = Path.GetFileName(filePath); EncodeFileName(filePath, fileName, out byte[] newLineBytes, out byte[] fileNameBytes); using (var fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Read)) { fileStream.Write(newLineBytes, 0, newLineBytes.Length); fileStream.Write(fileNameBytes, 0, fileNameBytes.Length); } return(true); } catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex) || ex is EncoderFallbackException) { Logging.LogException(ex.ToString(), Logging.Severity.High); DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Could not store original file name."); return(false); } }