diff --git a/GCryptLib/include/GCrypt/Key.h b/GCryptLib/include/GCrypt/Key.h index c7d505b..d0133da 100644 --- a/GCryptLib/include/GCrypt/Key.h +++ b/GCryptLib/include/GCrypt/Key.h @@ -17,6 +17,12 @@ namespace Leonetienne::GCrypt { //! Will generate a random key from actual randomness (std::random_device) static Key Random(); + //! Loads a keyfile + static Key LoadFromFile(const std::string& path); + + //! Will save a keyfile + void WriteToFile(const std::string& path); + Key(); Key(const Key& k); Key(const Block& b); diff --git a/GCryptLib/src/Key.cpp b/GCryptLib/src/Key.cpp index f77623b..c353d9d 100644 --- a/GCryptLib/src/Key.cpp +++ b/GCryptLib/src/Key.cpp @@ -3,6 +3,8 @@ #include "GCrypt/Util.h" #include #include +#include +#include namespace Leonetienne::GCrypt { @@ -30,6 +32,55 @@ namespace Leonetienne::GCrypt { return Key(Block(ss.str())); } + Key Key::LoadFromFile(const std::string& path) { + // Read this many chars + const std::size_t maxChars = BLOCK_SIZE / 8; + + // Open ifilestream for keyfile + std::ifstream ifs(path, std::ios::in | std::ios::binary); + + // Is the file open now? Or were there any issues... + if (!ifs.good()) { + throw std::runtime_error(std::string("Unable to open ifilestream for keyfile \"") + path + "\"! Aborting..."); + } + + // Read these chars to buffer + char* ckeyfileContent = new char[maxChars]; + memset(ckeyfileContent, 0, maxChars * sizeof(char)); + ifs.read(ckeyfileContent, maxChars); + ifs.close(); + + // Convert the buffer to a bit block of key size + std::stringstream ss; + for (std::size_t i = 0; i < maxChars; i++) + ss << std::bitset<8>(ckeyfileContent[i]); + + Block key(ss.str()); + + // And delete the buffer + delete[] ckeyfileContent; + ckeyfileContent = nullptr; + + // Return it + return key; + } + + void Key::WriteToFile(const std::string& path) { + // Transform key to bytes + const std::string keybytes = BitsToBytes(to_string()); + + // Create an ofilestream + std::ofstream ofs(path, std::ios::out | std::ios::binary); + + // Write the key + ofs.write(keybytes.data(), BLOCK_SIZE/8); + + // Close the file handle + ofs.close(); + + return; + } + Key::Key() : Block() { }