diff --git a/GCryptCLI/include/ModulePrepareKey.h b/GCryptCLI/include/ModulePrepareKey.h new file mode 100644 index 0000000..4f06bc9 --- /dev/null +++ b/GCryptCLI/include/ModulePrepareKey.h @@ -0,0 +1,26 @@ +#ifndef GCRYPTCLI_MODULE_PREPAREKEY_H +#define GCRYPTCLI_MODULE_PREPAREKEY_H + +#include + +using namespace Leonetienne::GCrypt; + +// This class has the task to supply the encryption key. +class ModulePrepareKey { + public: + //! Will prepare the key. Be it from cli, a file, or, random, or whatever. + static void PrepareKey(); + + //! Will return the key, if prepared. + static const Key& GetKey(); + + private: + //! Will ask for a password on stdin, + //! hiding the input. + static std::string PasswordPrompt(); + + static Key key; +}; + +#endif + diff --git a/GCryptCLI/src/ModulePrepareKey.cpp b/GCryptCLI/src/ModulePrepareKey.cpp new file mode 100644 index 0000000..061499b --- /dev/null +++ b/GCryptCLI/src/ModulePrepareKey.cpp @@ -0,0 +1,104 @@ +#include "ModulePrepareKey.h" +#include "CommandlineInterface.h" +#include "Configuration.h" +#include +#include + +// Required for hidden password input +#if defined _WIN32 || defined _WIN64 +#include +#elif defined __GNUG__ +#include +#include +#endif + +void ModulePrepareKey::PrepareKey() { + + // Special-case: We are hashing: + // no key needed. + if (Configuration::activeModule == Configuration::MODULE::HASH) { + return; + } + + // Special-case: We are generating a keyfile: + // just take a random one + else if (Configuration::activeModule == Configuration::MODULE::GENERATE_KEYFILE) { + key = Key::Random(); + return; + } + + // Else: + // Is a password passed on the command line? + else if (CommandlineInterface::Get().HasParam("--key")) { + // Fetch it, and hash it to a key + std::string password = CommandlineInterface::Get()["--key"].GetString(); + + key = Key::FromPassword(password); + + // Don't forget to zero string memory. + memset(password.data(), 0, password.size()); + return; + } + + // Should we prompt for a password on stdin? + else if (CommandlineInterface::Get().HasParam("--keyask")) { + // Create a password prompt + std::string password = PasswordPrompt(); + + key = Key::FromPassword(password); + + // Don't forget to zero string memory. + memset(password.data(), 0, password.size()); + return; + } + + // Else: + // Should we read from a keyfile? + else if (CommandlineInterface::Get().HasParam("--keyfile")) { + // Fetch the filename, and read it + const std::string filepath = CommandlineInterface::Get()["--keyfile"].GetString(); + key = Key::LoadFromFile(filepath); + return; + } + +} + + +const Key& ModulePrepareKey::GetKey() { + return key; +} + +std::string ModulePrepareKey::PasswordPrompt() { +// Disable stdin-echo +#if defined _WIN32 || defined _WIN64 + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + GetConsoleMode(hStdin, &mode); + SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT)); + +#elif defined __GNUG__ + termios oldt; + tcgetattr(STDIN_FILENO, &oldt); + termios newt = oldt; + newt.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + +#endif + + // Prompt stdin + std::string password; + std::cin >> password; + +// Restore previous config +#if defined _WIN32 || defined _WIN64 + SetConsoleMode(hStdin, mode); + +#elif defined __GNUG__ + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); +#endif + + return password; +} + +Key ModulePrepareKey::key; + diff --git a/GCryptCLI/src/main.cpp b/GCryptCLI/src/main.cpp index 5f16f6f..ec4fbfb 100644 --- a/GCryptCLI/src/main.cpp +++ b/GCryptCLI/src/main.cpp @@ -1,5 +1,7 @@ #include "CommandlineInterface.h" #include "Configuration.h" +#include "ModulePrepareKey.h" +#include int main(int argc, char* const* argv) { @@ -9,6 +11,9 @@ int main(int argc, char* const* argv) { // Parse configuration Configuration::Parse(); + // Prepare the key + ModulePrepareKey::PrepareKey(); + return 0; }