Example #1
0
 public static void SaveSettings()
 {
     try
     {
         if (File.Exists(_settingsFile))
         {
             var settings = new Dictionary <string, string>
             {
                 { "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) },
             };
             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.Error(ex.GetType().Name, "Unable to save settings.");
     }
 }
Example #2
0
 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.Error(filePath, ex.GetType().Name, "Unable to read Argon2 parameters from the file.");
     }
 }
Example #3
0
 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.Error(decryptedFilePath, ex.GetType().Name, "Unable to restore original file name.");
     }
 }
Example #4
0
 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.Error(ex.GetType().Name, "Unable to read the settings file.");
     }
 }
Example #5
0
 private static void CallEncryption(bool encryption, string filePath, byte[] passwordBytes)
 {
     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);
             OverwriteDisabled(filePath);
         }
         else if (encryption == false && kryptorExtension == true)
         {
             Decryption.InitializeDecryption(filePath, passwordBytes);
         }
         else
         {
             DisplayMessage.FileError(filePath, encryption, kryptorExtension);
         }
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to set file attributes to normal.");
     }
 }
Example #6
0
 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.Error(folderPath, ex.GetType().Name, "Unable to restore original directory name.");
     }
 }
Example #7
0
 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, Constants.FileBufferSize, FileOptions.SequentialScan))
             {
                 // 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.Error(filePath, ex.GetType().Name, "Unable to authenticate the file.");
         storedHash = null;
         return(true);
     }
 }
Example #8
0
 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.Error(ex.GetType().Name, "Unable to retrieve words from the wordlist.");
         return(null);
     }
 }
Example #9
0
 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.Error(ex.GetType().Name, "Unable to generate a random passphrase.");
         return(Array.Empty <char>());
     }
 }
Example #10
0
 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.Error(filePath, ex.GetType().Name, "Unable to make the file read-only.");
     }
 }
Example #11
0
 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.Error(folderPath, ex.GetType().Name, "Unable to get subdirectories in selected folder.");
         return(null);
     }
 }
Example #12
0
 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.Error(fileToDelete, ex.GetType().Name, "Unable to overwrite and/or delete.");
     }
 }
Example #13
0
 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.Error(ex.GetType().Name, "Unable to log exception.");
     }
 }
Example #14
0
 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.Error(filePath, ex.GetType().Name, "Unable to check if file path is a directory.");
         return(null);
     }
 }
Example #15
0
 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.Error(filePath, ex.GetType().Name, "Unable to delete the file.");
     }
 }
Example #16
0
 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.Error(filePath, ex.GetType().Name, "Unable to read original file name.");
         return(string.Empty);
     }
 }
Example #17
0
 public static void GenerateKeyfile(string filePath)
 {
     try
     {
         byte[] keyfileBytes = SodiumCore.GetRandomBytes(Constants.MACKeySize);
         File.WriteAllBytes(filePath, keyfileBytes);
         File.SetAttributes(filePath, FileAttributes.ReadOnly);
         Utilities.ZeroArray(keyfileBytes);
         Console.WriteLine("Keyfile successfully generated.");
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Low);
         DisplayMessage.Error(ex.GetType().Name, "Keyfile generation failed.");
     }
 }
Example #18
0
        private static void RestoreMAC(string filePath, byte[] macBackup)
        {
            bool restored = FileAuthentication.AppendHash(filePath, macBackup);

            if (restored == false)
            {
                try
                {
                    File.WriteAllBytes($"{filePath}.backup", macBackup);
                }
                catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
                {
                    Logging.LogException(ex.ToString(), Logging.Severity.High);
                    DisplayMessage.Error(filePath, ex.GetType().Name, "Failed to backup the MAC. This data is required for decryption.");
                }
            }
            Utilities.ZeroArray(macBackup);
        }
Example #19
0
 public static bool AppendHash(string filePath, byte[] fileHash)
 {
     try
     {
         NullChecks.ByteArray(fileHash);
         using (var fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Read, Constants.FileBufferSize, FileOptions.RandomAccess))
         {
             fileStream.Write(fileHash, 0, fileHash.Length);
         }
         return(true);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to append the MAC to the file. This data is required for decryption of the file.");
         return(false);
     }
 }
Example #20
0
 private static void RemoveStoredFileName(string filePath, string originalFileName)
 {
     try
     {
         int fileNameLength = GetFileNameLength(filePath, originalFileName);
         if (fileNameLength != 0)
         {
             using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, Constants.FileBufferSize, FileOptions.RandomAccess))
             {
                 fileStream.SetLength(fileStream.Length - fileNameLength);
             }
         }
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.Error(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.");
     }
 }
Example #21
0
 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.Error(folderPath, ex.GetType().Name, "Unable to anonymise directory name.");
         return(folderPath);
     }
 }
Example #22
0
 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, Constants.FileBufferSize, FileOptions.RandomAccess))
         {
             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.Error(filePath, ex.GetType().Name, "Unable to read salt from the selected file.");
         return(null);
     }
 }
Example #23
0
 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, Constants.FileBufferSize, FileOptions.RandomAccess))
         {
             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.Error(filePath, ex.GetType().Name, "Could not store original file name.");
         return(false);
     }
 }
Example #24
0
 private static byte[] ComputeFileHash(string encryptedFilePath, byte[] macKey)
 {
     try
     {
         byte[] computedHash = new byte[Constants.HashLength];
         using (var fileStream = new FileStream(encryptedFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileBufferSize, FileOptions.SequentialScan))
         {
             MemoryEncryption.DecryptByteArray(ref macKey);
             computedHash = HashingAlgorithms.Blake2(fileStream, macKey);
             MemoryEncryption.EncryptByteArray(ref macKey);
         }
         return(computedHash);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.Error(encryptedFilePath, ex.GetType().Name, "Unable to compute MAC.");
         return(null);
     }
 }
Example #25
0
 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, Constants.FileBufferSize, FileOptions.RandomAccess))
         {
             // 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.Error(filePath, ex.GetType().Name, "Unable to read the MAC stored in the file.");
         return(null);
     }
 }
Example #26
0
 public static byte[] ReadKeyfile(string keyfilePath)
 {
     try
     {
         File.SetAttributes(keyfilePath, FileAttributes.Normal);
         byte[] keyfileBytes = new byte[Constants.MACKeySize];
         // Read the first 64 bytes of a keyfile
         using (var fileStream = new FileStream(keyfilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
         {
             fileStream.Read(keyfileBytes, 0, keyfileBytes.Length);
         }
         File.SetAttributes(keyfilePath, FileAttributes.ReadOnly);
         return(keyfileBytes);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Medium);
         DisplayMessage.Error(ex.GetType().Name, "Unable to read keyfile. The selected keyfile has not been used.");
         return(null);
     }
 }
Example #27
0
 public static string MoveFile(string filePath, bool file)
 {
     try
     {
         string anonymisedFilePath = GetAnonymousFileName(filePath);
         if (file == true)
         {
             File.Move(filePath, anonymisedFilePath);
         }
         else
         {
             Directory.Move(filePath, anonymisedFilePath);
         }
         return(anonymisedFilePath);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Medium);
         DisplayMessage.Error(filePath, ex.GetType().Name, "Unable to anonymously rename file/folder.");
         return(filePath);
     }
 }
Example #28
0
 private static bool?CheckForUpdates(string kryptorVersion)
 {
     try
     {
         bool?updateAvailable = false;
         // Compare assembly version to online version file
         string downloadFilePath = Path.Combine(Constants.KryptorDirectory, "version.txt");
         DownloadVersionFile(downloadFilePath);
         // Remove new line char & any leading/trailing whitespace
         string latestVersion = File.ReadAllText(downloadFilePath).Trim('\n').Trim();
         if (kryptorVersion != latestVersion)
         {
             updateAvailable = true;
         }
         File.Delete(downloadFilePath);
         return(updateAvailable);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex) || ex is WebException)
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Medium);
         return(null);
     }
 }
Example #29
0
 private static void DirectoryEncryption(bool encryption, string folderPath, byte[] passwordBytes)
 {
     try
     {
         // Anonymise directory names before encryption (if enabled)
         folderPath = AnonymousRename.AnonymiseDirectories(encryption, folderPath);
         // Get all files in all directories
         string[] files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories);
         // -1 for the selected directory
         Globals.TotalCount += files.Length - 1;
         foreach (string filePath in files)
         {
             CallEncryption(encryption, filePath, passwordBytes);
         }
         // Deanonymise directory names after decryption (if enabled)
         AnonymousRename.DeanonymiseDirectories(encryption, folderPath);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.Error(folderPath, ex.GetType().Name, "Unable to get files in the directory.");
     }
 }