2022-05-22 13:43:23 +02:00
|
|
|
#include "GCrypt/Key.h"
|
|
|
|
#include "GCrypt/GHash.h"
|
|
|
|
#include "GCrypt/Util.h"
|
2022-05-22 17:24:56 +02:00
|
|
|
#include <random>
|
|
|
|
#include <cassert>
|
2022-05-22 17:54:26 +02:00
|
|
|
#include <sstream>
|
|
|
|
#include <fstream>
|
2022-05-22 13:43:23 +02:00
|
|
|
|
|
|
|
namespace Leonetienne::GCrypt {
|
|
|
|
|
|
|
|
Key Key::FromPassword(const std::string& password) {
|
|
|
|
return GHash::CalculateHashsum(
|
|
|
|
StringToBits(password)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-05-22 17:24:56 +02:00
|
|
|
Key Key::Random() {
|
|
|
|
// Create our truly-random rng
|
|
|
|
std::random_device rng;
|
|
|
|
constexpr std::size_t bitsPerCall = sizeof(std::random_device::result_type) * 8;
|
|
|
|
|
|
|
|
// Fetch BLOCK_SIZE bits
|
|
|
|
std::stringstream ss;
|
|
|
|
for (std::size_t i = 0; i < BLOCK_SIZE / bitsPerCall; i++) {
|
|
|
|
ss << std::bitset<bitsPerCall>(rng());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify that we actually have the correct size
|
|
|
|
assert(ss.str().length() == BLOCK_SIZE);
|
|
|
|
|
|
|
|
// Return them as a key
|
|
|
|
return Key(Block(ss.str()));
|
|
|
|
}
|
|
|
|
|
2022-05-22 17:54:26 +02:00
|
|
|
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
|
2022-05-24 01:02:06 +02:00
|
|
|
const std::string keybytes = BitsToBytes(ToString());
|
2022-05-22 17:54:26 +02:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2022-05-22 13:43:23 +02:00
|
|
|
Key::Key() : Block() {
|
|
|
|
}
|
|
|
|
|
|
|
|
Key::Key(const Block& b) : Block(b) {
|
|
|
|
}
|
|
|
|
|
|
|
|
Key::Key(const Key& k) : Block(k) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|