Пример #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.");
     }
 }
Пример #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.");
     }
 }
Пример #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);
     }
 }
Пример #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);
     }
 }
Пример #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);
     }
 }
Пример #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);
     }
 }
Пример #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>());
     }
 }
Пример #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.");
     }
 }
Пример #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.");
     }
 }
Пример #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.");
     }
 }
Пример #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);
     }
 }
Пример #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);
     }
 }
Пример #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);
     }
 }
Пример #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>());
     }
 }
Пример #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);
        }
Пример #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);
     }
 }
Пример #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.");
     }
 }
Пример #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.");
     }
 }
Пример #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);
     }
 }
Пример #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);
     }
 }
Пример #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.");
            }
        }
Пример #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);
     }
 }
Пример #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);
     }
 }
Пример #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);
     }
 }
Пример #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.");
     }
 }
Пример #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.");
     }
 }
Пример #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);
     }
 }
Пример #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.");
     }
 }
Пример #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.");
     }
 }
Пример #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);
     }
 }