Skip to content

Commit

Permalink
src: Improve directory validation.
Browse files Browse the repository at this point in the history
  • Loading branch information
samuel-lucas6 committed Jul 4, 2021
1 parent b372b27 commit fdfa704
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 79 deletions.
41 changes: 18 additions & 23 deletions src/KryptorCLI/FileEncryption/DirectoryDecryption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,7 @@ public static void UsingPassword(string directoryPath, byte[] passwordBytes)
}
catch (Exception ex) when (ExceptionFilters.FileAccess(ex))
{
if (ex is ArgumentException || ex is FileNotFoundException)
{
DisplayMessage.FilePathError(directoryPath, ex.Message);
return;
}
DisplayMessage.FilePathException(directoryPath, ex.GetType().Name, "Unable to decrypt the directory.");
DirectoryException(directoryPath, ex);
}
}

Expand All @@ -53,11 +48,7 @@ private static void DecryptEachFileWithPassword(string[] filePaths, byte[] keyEn
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileDecryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
if (!validFilePath) { continue; }
try
{
using var inputFile = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.RandomAccess);
Expand Down Expand Up @@ -92,13 +83,14 @@ public static void UsingPublicKey(string directoryPath, byte[] sharedSecret, byt
{
try
{
FilePathValidation.DirectoryDecryption(directoryPath);
string[] filePaths = GetFiles(directoryPath);
DecryptEachFileWithPublicKey(filePaths, sharedSecret, recipientPrivateKey);
Finalize(directoryPath);
}
catch (Exception ex) when (ExceptionFilters.FileAccess(ex))
{
DisplayMessage.FilePathException(directoryPath, ex.GetType().Name, "Unable to decrypt the directory.");
DirectoryException(directoryPath, ex);
}
}

Expand All @@ -107,11 +99,7 @@ private static void DecryptEachFileWithPublicKey(string[] filePaths, byte[] shar
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileDecryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
if (!validFilePath) { continue; }
try
{
using var inputFile = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.RandomAccess);
Expand All @@ -133,13 +121,14 @@ public static void UsingPrivateKey(string directoryPath, byte[] privateKey)
{
try
{
FilePathValidation.DirectoryDecryption(directoryPath);
string[] filePaths = GetFiles(directoryPath);
DecryptEachFileWithPrivateKey(filePaths, privateKey);
Finalize(directoryPath);
}
catch (Exception ex) when (ExceptionFilters.FileAccess(ex))
{
DisplayMessage.FilePathException(directoryPath, ex.GetType().Name, "Unable to decrypt the directory.");
DirectoryException(directoryPath, ex);
}
}

Expand All @@ -148,11 +137,7 @@ private static void DecryptEachFileWithPrivateKey(string[] filePaths, byte[] pri
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileDecryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
if (!validFilePath) { continue; }
try
{
using var inputFile = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.RandomAccess);
Expand Down Expand Up @@ -192,6 +177,16 @@ private static void Finalize(string directoryPath)
}
}

private static void DirectoryException(string directoryPath, Exception ex)
{
if (ex is ArgumentException || ex is FileNotFoundException)
{
DisplayMessage.FilePathError(directoryPath, ex.Message);
return;
}
DisplayMessage.FilePathException(directoryPath, ex.GetType().Name, "Unable to decrypt the directory.");
}

private static void FileException(string inputFilePath, Exception ex)
{
if (ex is ArgumentException)
Expand Down
37 changes: 19 additions & 18 deletions src/KryptorCLI/FileEncryption/DirectoryEncryption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public static void UsingPassword(string directoryPath, byte[] passwordBytes)
bool overwriteOption = Globals.Overwrite;
try
{
FilePathValidation.DirectoryEncryption(directoryPath);
// Always overwrite directories
string backupDirectoryPath = BackupDirectory(directoryPath);
Globals.Overwrite = true;
Expand All @@ -43,7 +44,7 @@ public static void UsingPassword(string directoryPath, byte[] passwordBytes)
}
catch (Exception ex) when (ExceptionFilters.FileAccess(ex))
{
DisplayMessage.FilePathException(directoryPath, ex.GetType().Name, "Unable to encrypt the directory.");
DirectoryException(directoryPath, ex);
}
finally
{
Expand Down Expand Up @@ -96,11 +97,7 @@ private static void EncryptEachFileWithPassword(string[] filePaths, byte[] salt,
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
if (!validFilePath) { continue; }
// Fill unused header with random public key
byte[] ephemeralPublicKey = Generate.EphemeralPublicKeyHeader();
string outputFilePath = FileEncryption.GetOutputFilePath(inputFilePath);
Expand Down Expand Up @@ -135,6 +132,7 @@ public static void UsingPublicKey(string directoryPath, byte[] sharedSecret, byt
bool overwriteOption = Globals.Overwrite;
try
{
FilePathValidation.DirectoryEncryption(directoryPath);
// Always overwrite directories
string backupDirectoryPath = BackupDirectory(directoryPath);
Globals.Overwrite = true;
Expand All @@ -144,7 +142,7 @@ public static void UsingPublicKey(string directoryPath, byte[] sharedSecret, byt
}
catch (Exception ex) when (ExceptionFilters.FileAccess(ex))
{
DisplayMessage.FilePathException(directoryPath, ex.GetType().Name, "Unable to encrypt the directory.");
DirectoryException(directoryPath, ex);
}
finally
{
Expand All @@ -157,11 +155,7 @@ private static void EncryptEachFileWithPublicKey(string[] filePaths, byte[] shar
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
if (!validFilePath) { continue; }
// Derive a unique KEK per file
byte[] ephemeralSharedSecret = KeyExchange.GetEphemeralSharedSecret(recipientPublicKey, out byte[] ephemeralPublicKey);
byte[] salt = Generate.Salt();
Expand All @@ -177,6 +171,7 @@ public static void UsingPrivateKey(string directoryPath, byte[] privateKey)
bool overwriteOption = Globals.Overwrite;
try
{
FilePathValidation.DirectoryEncryption(directoryPath);
// Always overwrite directories
string backupDirectoryPath = BackupDirectory(directoryPath);
Globals.Overwrite = true;
Expand All @@ -186,7 +181,7 @@ public static void UsingPrivateKey(string directoryPath, byte[] privateKey)
}
catch (Exception ex) when (ExceptionFilters.FileAccess(ex))
{
DisplayMessage.FilePathException(directoryPath, ex.GetType().Name, "Unable to encrypt the directory.");
DirectoryException(directoryPath, ex);
}
finally
{
Expand All @@ -199,11 +194,7 @@ private static void EncryptEachFileWithPrivateKey(string[] filePaths, byte[] pri
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
if (!validFilePath) { continue; }
// Derive a unique KEK per file
byte[] ephemeralSharedSecret = KeyExchange.GetPrivateKeySharedSecret(privateKey, out byte[] ephemeralPublicKey);
byte[] salt = Generate.Salt();
Expand All @@ -213,5 +204,15 @@ private static void EncryptEachFileWithPrivateKey(string[] filePaths, byte[] pri
CryptographicOperations.ZeroMemory(keyEncryptionKey);
}
}

private static void DirectoryException(string directoryPath, Exception ex)
{
if (ex is ArgumentException)
{
DisplayMessage.FilePathError(directoryPath, ex.Message);
return;
}
DisplayMessage.FilePathException(directoryPath, ex.GetType().Name, "Unable to encrypt the directory.");
}
}
}
18 changes: 0 additions & 18 deletions src/KryptorCLI/FileEncryption/FileDecryption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ public static void DecryptEachFileWithPassword(string[] filePaths, byte[] passwo
Globals.TotalCount = filePaths.Length;
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileDecryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
UsingPassword(inputFilePath, passwordBytes);
}
CryptographicOperations.ZeroMemory(passwordBytes);
Expand Down Expand Up @@ -74,12 +68,6 @@ public static void DecryptEachFileWithPublicKey(string[] filePaths, byte[] recip
byte[] sharedSecret = KeyExchange.GetSharedSecret(recipientPrivateKey, senderPublicKey);
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileDecryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
UsingPublicKey(inputFilePath, sharedSecret, recipientPrivateKey);
}
CryptographicOperations.ZeroMemory(recipientPrivateKey);
Expand Down Expand Up @@ -120,12 +108,6 @@ public static void DecryptEachFileWithPrivateKey(string[] filePaths, byte[] priv
if (privateKey == null) { return; }
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileDecryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
UsingPrivateKey(inputFilePath, privateKey);
}
CryptographicOperations.ZeroMemory(privateKey);
Expand Down
18 changes: 0 additions & 18 deletions src/KryptorCLI/FileEncryption/FileEncryption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ public static void EncryptEachFileWithPassword(string[] filePaths, byte[] passwo
Globals.TotalCount = filePaths.Length;
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
UsingPassword(inputFilePath, passwordBytes);
}
CryptographicOperations.ZeroMemory(passwordBytes);
Expand Down Expand Up @@ -76,12 +70,6 @@ public static void EncryptEachFileWithPublicKey(string[] filePaths, byte[] sende
CryptographicOperations.ZeroMemory(senderPrivateKey);
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
UsingPublicKey(inputFilePath, sharedSecret, recipientPublicKey);
}
CryptographicOperations.ZeroMemory(sharedSecret);
Expand Down Expand Up @@ -120,12 +108,6 @@ public static void EncryptEachFileWithPrivateKey(string[] filePaths, byte[] priv
if (privateKey == null) { return; }
foreach (string inputFilePath in filePaths)
{
bool validFilePath = FilePathValidation.FileEncryption(inputFilePath);
if (!validFilePath)
{
--Globals.TotalCount;
continue;
}
UsingPrivateKey(inputFilePath, privateKey);
}
CryptographicOperations.ZeroMemory(privateKey);
Expand Down
31 changes: 29 additions & 2 deletions src/KryptorCLI/Validation/FilePathValidation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public static class FilePathValidation
{
private static readonly string _fileDoesNotExist = "This file/folder doesn't exist.";
private static readonly string _fileInaccessible = "Unable to access the file.";
private static readonly string _directoryEmpty = "This directory is empty.";

public static bool FileEncryption(string inputFilePath)
{
Expand All @@ -37,7 +38,14 @@ public static bool FileEncryption(string inputFilePath)

public static string GetFileEncryptionError(string inputFilePath)
{
if (Directory.Exists(inputFilePath)) { return null; }
if (Directory.Exists(inputFilePath))
{
if (FileHandling.IsDirectoryEmpty(inputFilePath))
{
return _directoryEmpty;
}
return null;
}
if (!File.Exists(inputFilePath)) { return _fileDoesNotExist; }
bool? validMagicBytes = FileHandling.IsKryptorFile(inputFilePath);
if (validMagicBytes == null) { return _fileInaccessible; }
Expand Down Expand Up @@ -75,6 +83,18 @@ public static string KeyfilePath(string keyfilePath)
}
}

public static void DirectoryEncryption(string directoryPath)
{
string saltFilePath = Path.Combine(directoryPath, Constants.SaltFile);
if (File.Exists(saltFilePath)) { throw new ArgumentException("This directory has already been encrypted."); }
}

public static void DirectoryDecryption(string directoryPath)
{
string saltFilePath = Path.Combine(directoryPath, Constants.SaltFile);
if (File.Exists(saltFilePath)) { throw new ArgumentException("This directory was encrypted using a password."); }
}

public static bool FileDecryption(string inputFilePath)
{
if (inputFilePath.Contains(Constants.SaltFile))
Expand All @@ -90,7 +110,14 @@ public static bool FileDecryption(string inputFilePath)

public static string GetFileDecryptionError(string inputFilePath)
{
if (Directory.Exists(inputFilePath)) { return null; }
if (Directory.Exists(inputFilePath))
{
if (FileHandling.IsDirectoryEmpty(inputFilePath))
{
return _directoryEmpty;
}
return null;
}
if (!File.Exists(inputFilePath)) { return _fileDoesNotExist; }
bool? validMagicBytes = FileHandling.IsKryptorFile(inputFilePath);
if (validMagicBytes == null) { return _fileInaccessible; }
Expand Down

0 comments on commit fdfa704

Please sign in to comment.