Beispiel #1
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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to make the file read-only.");
     }
 }
Beispiel #2
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.ErrorResultsText(fileToDelete, ex.GetType().Name, "Unable to overwrite and/or delete.");
     }
 }
Beispiel #3
0
 private static bool?LoadBooleanSetting(string setting)
 {
     try
     {
         return(Invariant.ToBoolean(setting));
     }
     catch (Exception ex) when(ExceptionFilters.SettingsExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Low);
         DisplayMessage.ErrorMessageBox(ex.GetType().Name, $"Unable to load {setting} setting. The default setting will be used.");
         return(null);
     }
 }
Beispiel #4
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.ErrorResultsText(folderPath, ex.GetType().Name, "Unable to get subdirectories in selected folder.");
         return(null);
     }
 }
Beispiel #5
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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to check if file path is a directory.");
         return(null);
     }
 }
Beispiel #6
0
 private static int GetFileNameLength(string filePath, string originalFileName)
 {
     try
     {
         EncodeFileName(filePath, originalFileName, out byte[] newLineBytes, out byte[] fileNameBytes);
         return(newLineBytes.Length + fileNameBytes.Length);
     }
     catch (Exception ex) when(ExceptionFilters.CharacterEncodingExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.ErrorResultsText(filePath, ex.GetType().Name, "Unable to remove the original file name stored in the file. The length of the stored file name could not be calculated.");
         return(0);
     }
 }
Beispiel #7
0
 private static char[] EncryptPassword(byte[] plaintext, byte[] publicKey)
 {
     try
     {
         byte[] ciphertext = SealedPublicKeyBox.Create(plaintext, publicKey);
         return(Convert.ToBase64String(ciphertext).ToCharArray());
     }
     catch (Exception ex) when(ExceptionFilters.PasswordSharingExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Low);
         GetErrorMessage(ex, "Encryption");
         return(Array.Empty <char>());
     }
 }
Beispiel #8
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.ErrorMessageBox(ex.GetType().Name, "Unable to log exception.");
     }
 }
Beispiel #9
0
 public static void SetClipboard(string text)
 {
     try
     {
         if (!string.IsNullOrEmpty(text))
         {
             Clipboard.SetText(text);
         }
     }
     catch (Exception ex) when(ExceptionFilters.ClipboardExceptions(ex))
     {
         DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to copy text to the clipboard.");
     }
 }
Beispiel #10
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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to delete the file.");
     }
 }
Beispiel #11
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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to read original file name.");
         return(string.Empty);
     }
 }
Beispiel #12
0
 private static (byte[], byte[], byte[]) GetParametersBytes(string memorySize, string iterations)
 {
     try
     {
         Encoding encoding        = Encoding.UTF8;
         byte[]   memorySizeBytes = encoding.GetBytes(memorySize);
         byte[]   iterationsBytes = encoding.GetBytes(iterations);
         byte[]   endFlagBytes    = encoding.GetBytes(Constants.EndFlag);
         return(memorySizeBytes, iterationsBytes, endFlagBytes);
     }
     catch (Exception ex) when(ExceptionFilters.CharacterEncodingExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.High);
         DisplayMessage.ErrorResultsText(string.Empty, ex.GetType().Name, "Unable to convert Argon2 parameters to bytes.");
         return(null, null, null);
     }
 }
Beispiel #13
0
 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);
     }
 }
Beispiel #14
0
 private static char[] DecryptPassword(byte[] ciphertext, byte[] privateKey)
 {
     try
     {
         using (var keyPair = PublicKeyBox.GenerateKeyPair(privateKey))
         {
             byte[] plaintext = SealedPublicKeyBox.Open(ciphertext, keyPair);
             return(Encoding.UTF8.GetChars(plaintext));
         }
     }
     catch (Exception ex) when(ExceptionFilters.PasswordSharingExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Low);
         GetErrorMessage(ex, "Decryption");
         return(Array.Empty <char>());
     }
 }
Beispiel #15
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.ErrorResultsText(filePath, ex.GetType().Name, "Failed to backup the MAC. This data is required for decryption.");
                }
            }
            Utilities.ZeroArray(macBackup);
        }
Beispiel #16
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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to append the MAC to the file. This data is required for decryption of the file.");
         return(false);
     }
 }
Beispiel #17
0
 public static void BackgroundWorkerReportProgress(long progress, long total, BackgroundWorker backgroundWorker)
 {
     try
     {
         NullChecks.BackgroundWorkers(backgroundWorker);
         int percentage = (int)Math.Round((double)((double)progress / total) * 100);
         // Prevent unnecessary calls
         if (percentage != 0 && percentage != _previousPercentage)
         {
             backgroundWorker.ReportProgress(percentage);
         }
         _previousPercentage = percentage;
     }
     catch (Exception ex) when(ExceptionFilters.ReportProgressExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Bug);
         DisplayMessage.ErrorResultsText(string.Empty, ex.GetType().Name, "Background worker report progress exception. This is a bug - please report it.");
     }
 }
Beispiel #18
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.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.");
     }
 }
Beispiel #19
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.ErrorResultsText(folderPath, ex.GetType().Name, "Unable to anonymise directory name.");
         return(folderPath);
     }
 }
Beispiel #20
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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to read salt from the selected file.");
         return(null);
     }
 }
Beispiel #21
0
        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.");
            }
        }
Beispiel #22
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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to read the MAC stored in the file.");
         return(null);
     }
 }
Beispiel #23
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.ErrorResultsText(encryptedFilePath, ex.GetType().Name, "Unable to compute MAC.");
         return(null);
     }
 }
Beispiel #24
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.ErrorResultsText(filePath, ex.GetType().Name, "Could not store original file name.");
         return(false);
     }
 }
Beispiel #25
0
 public static void BackupSettings()
 {
     try
     {
         using (var selectFolderDialog = new VistaFolderBrowserDialog())
         {
             selectFolderDialog.Description = "Settings Backup";
             if (selectFolderDialog.ShowDialog() == DialogResult.OK)
             {
                 string backupFile = Path.Combine(selectFolderDialog.SelectedPath, Path.GetFileName(_settingsFile));
                 File.Copy(_settingsFile, backupFile, true);
             }
         }
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Low);
         DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to backup settings file.");
     }
 }
Beispiel #26
0
 private static void StoreBenchmarkResults(int[] benchmarkTimes, List <int> memorySize, int recommendedMemorySize, int delayPerFile)
 {
     try
     {
         var benchmarkResults = new List <string>();
         for (int i = 0; i < benchmarkTimes.Length; i++)
         {
             benchmarkResults.Add($"{memorySize[i] / Constants.Mebibyte} MiB = {benchmarkTimes[i]} ms");
         }
         benchmarkResults.Add(string.Empty);
         benchmarkResults.Add($"Recommended Memory Size: {Invariant.ToString(recommendedMemorySize / Constants.Mebibyte)} MiB");
         benchmarkResults.Add($"This memory size was chosen because it was <= {delayPerFile} ms. This is the delay per file that it takes for Argon2 to derive an encryption key and MAC key. You can speed up key derivation by lowering the memory size, but this will decrease your security. For more information about Argon2, please read the documentation (https://kryptor.co.uk/key-derivation.html).");
         string benchmarkFilePath = Path.Combine(Constants.KryptorDirectory, "benchmark.txt");
         File.WriteAllLines(benchmarkFilePath, benchmarkResults);
     }
     catch (Exception ex) when(ExceptionFilters.FileAccessExceptions(ex))
     {
         Logging.LogException(ex.ToString(), Logging.Severity.Low);
         DisplayMessage.ErrorMessageBox(ex.GetType().Name, "Unable to store benchmark results.");
     }
 }
Beispiel #27
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.ErrorResultsText(string.Empty, ex.GetType().Name, "Unable to read keyfile. The selected keyfile has not been used.");
         return(null);
     }
 }
Beispiel #28
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) },
                 { "Show Password", Globals.ShowPasswordByDefault.ToString() },
                 { "Auto Clear Password", Globals.AutoClearPassword.ToString() },
                 { "Auto Clear Clipboard", Invariant.ToString(Globals.ClearClipboardInterval) },
                 { "Exit Clipboard Clear", Globals.ExitClearClipboard.ToString() },
                 { "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.");
     }
 }
Beispiel #29
0
 public static void OpenLink(string link)
 {
     try
     {
         if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
         {
             Process.Start(link);
         }
         else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
         {
             Process.Start("xdg-open", link);
         }
         else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
         {
             Process.Start("open", link);
         }
     }
     catch (Exception ex) when(ExceptionFilters.OpenLinkExceptions(ex))
     {
         DisplayMessage.ErrorMessageBox(ex.GetType().Name, $"Unable to automatically open link. Please visit {link} manually using your browser.");
     }
 }
Beispiel #30
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.ErrorResultsText(filePath, ex.GetType().Name, "Unable to anonymously rename file/folder.");
         return(filePath);
     }
 }