Refactor folder structure and put classes in own files
This commit is contained in:
parent
fd184b45d2
commit
aceeb2644f
@ -1,5 +0,0 @@
|
|||||||
#include "CryConfigEncryptor.h"
|
|
||||||
|
|
||||||
namespace cryfs {
|
|
||||||
const std::string CryConfigEncryptor::HEADER = "cryfs.config;0.8.1;scrypt";
|
|
||||||
}
|
|
@ -1,159 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYCONFIGENCRYPTOR_H
|
|
||||||
#define MESSMER_CRYFS_SRC_CONFIG_CRYCONFIGENCRYPTOR_H
|
|
||||||
|
|
||||||
#include <messmer/cpp-utils/data/Serializer.h>
|
|
||||||
#include <messmer/cpp-utils/data/Deserializer.h>
|
|
||||||
#include <messmer/cpp-utils/data/Data.h>
|
|
||||||
#include <messmer/cpp-utils/random/Random.h>
|
|
||||||
#include <messmer/cpp-utils/logging/logging.h>
|
|
||||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
|
||||||
#include <messmer/blockstore/implementations/encrypted/ciphers/ciphers.h>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "crypto/Scrypt.h"
|
|
||||||
#include "RandomPadding.h"
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace cryfs {
|
|
||||||
//TODO Test
|
|
||||||
//TODO Test that encrypted config data always has the same size, no matter how big the plaintext config data
|
|
||||||
//TODO Don't only encrypt with the main cipher, but also use user specified cipher.
|
|
||||||
//TODO Use own exception for cpputils::Serializer/cpputils::Deserializer errors and only catch them
|
|
||||||
class CryConfigEncryptor {
|
|
||||||
public:
|
|
||||||
template<class Cipher> static cpputils::unique_ref<CryConfigEncryptor> deriveKey(const std::string &password);
|
|
||||||
static boost::optional<cpputils::unique_ref<CryConfigEncryptor>> loadKey(const cpputils::Data &ciphertext, const std::string &password);
|
|
||||||
|
|
||||||
virtual cpputils::Data encrypt(const cpputils::Data &plaintext) = 0;
|
|
||||||
virtual boost::optional<cpputils::Data> decrypt(const cpputils::Data &plaintext) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _checkHeader(cpputils::Deserializer *deserializer);
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<class Cipher> static DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH> _loadKey(cpputils::Deserializer *deserializer, const std::string &password);
|
|
||||||
|
|
||||||
static const std::string HEADER;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Cipher>
|
|
||||||
class ConcreteCryConfigEncryptor: public CryConfigEncryptor {
|
|
||||||
public:
|
|
||||||
using ConfigEncryptionKey = DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH>;
|
|
||||||
static constexpr size_t CONFIG_SIZE = 1024; // Config data is grown to this size before encryption to hide its actual size
|
|
||||||
|
|
||||||
ConcreteCryConfigEncryptor(ConfigEncryptionKey key);
|
|
||||||
|
|
||||||
cpputils::Data encrypt(const cpputils::Data &plaintext) override;
|
|
||||||
boost::optional<cpputils::Data> decrypt(const cpputils::Data &ciphertext) override;
|
|
||||||
private:
|
|
||||||
void _ignoreKey(cpputils::Deserializer *deserializer);
|
|
||||||
cpputils::Data _loadAndDecryptConfigData(cpputils::Deserializer *deserializer);
|
|
||||||
cpputils::Data _serialize(const cpputils::Data &ciphertext);
|
|
||||||
|
|
||||||
ConfigEncryptionKey _key;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Cipher>
|
|
||||||
cpputils::unique_ref<CryConfigEncryptor> CryConfigEncryptor::deriveKey(const std::string &password) {
|
|
||||||
//TODO This is only kept here to recognize when this is run in tests. After tests are faster, replace this with something in main(), saying something like "Loading configuration file..."
|
|
||||||
std::cout << "Deriving secure key for config file..." << std::flush;
|
|
||||||
auto key = SCrypt().generateKey<Cipher::EncryptionKey::BINARY_LENGTH>(password);
|
|
||||||
std::cout << "done" << std::endl;
|
|
||||||
return cpputils::make_unique_ref<ConcreteCryConfigEncryptor<Cipher>>(std::move(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline boost::optional<cpputils::unique_ref<CryConfigEncryptor>> CryConfigEncryptor::loadKey(const cpputils::Data &ciphertext, const std::string &password) {
|
|
||||||
cpputils::Deserializer deserializer(&ciphertext);
|
|
||||||
try {
|
|
||||||
_checkHeader(&deserializer);
|
|
||||||
auto key = _loadKey<blockstore::encrypted::AES256_GCM>(&deserializer, password); //TODO Allow other ciphers
|
|
||||||
return boost::optional<cpputils::unique_ref<CryConfigEncryptor>>(cpputils::make_unique_ref<ConcreteCryConfigEncryptor<blockstore::encrypted::AES256_GCM>>(std::move(key))); //TODO Allow other ciphers
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
cpputils::logging::LOG(cpputils::logging::ERROR) << "Error loading configuration: " << e.what();
|
|
||||||
return boost::none; // This can be caused by invalid loaded data and is not necessarily a programming logic error. Don't throw exception.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CryConfigEncryptor::_checkHeader(cpputils::Deserializer *deserializer) {
|
|
||||||
std::string header = deserializer->readString();
|
|
||||||
if (header != HEADER) {
|
|
||||||
throw std::runtime_error("Invalid header");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Cipher>
|
|
||||||
DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH> CryConfigEncryptor::_loadKey(cpputils::Deserializer *deserializer, const std::string &password) {
|
|
||||||
auto keyConfig = DerivedKeyConfig::load(deserializer);
|
|
||||||
//TODO This is only kept here to recognize when this is run in tests. After tests are faster, replace this with something in main(), saying something like "Loading configuration file..."
|
|
||||||
std::cout << "Deriving secure key for config file..." << std::flush;
|
|
||||||
auto key = SCrypt().generateKeyFromConfig<Cipher::EncryptionKey::BINARY_LENGTH>(password, keyConfig);
|
|
||||||
std::cout << "done" << std::endl;
|
|
||||||
return DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH>(std::move(keyConfig), std::move(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Cipher>
|
|
||||||
ConcreteCryConfigEncryptor<Cipher>::ConcreteCryConfigEncryptor(ConfigEncryptionKey key): _key(std::move(key)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Cipher>
|
|
||||||
boost::optional<cpputils::Data> ConcreteCryConfigEncryptor<Cipher>::decrypt(const cpputils::Data &data) {
|
|
||||||
cpputils::Deserializer deserializer(&data);
|
|
||||||
try {
|
|
||||||
_checkHeader(&deserializer);
|
|
||||||
_ignoreKey(&deserializer);
|
|
||||||
return _loadAndDecryptConfigData(&deserializer);
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
cpputils::logging::LOG(cpputils::logging::ERROR) << "Error loading configuration: " << e.what();
|
|
||||||
return boost::none; // This can be caused by invalid loaded data and is not necessarily a programming logic error. Don't throw exception.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Cipher>
|
|
||||||
void ConcreteCryConfigEncryptor<Cipher>::_ignoreKey(cpputils::Deserializer *deserializer) {
|
|
||||||
DerivedKeyConfig::load(deserializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Cipher>
|
|
||||||
cpputils::Data ConcreteCryConfigEncryptor<Cipher>::_loadAndDecryptConfigData(cpputils::Deserializer *deserializer) {
|
|
||||||
auto ciphertext = deserializer->readData();
|
|
||||||
auto decrypted = Cipher::decrypt(static_cast<const uint8_t*>(ciphertext.data()), ciphertext.size(), _key.key());
|
|
||||||
if (decrypted == boost::none) {
|
|
||||||
throw std::runtime_error("Couldn't decrypt config file. Wrong password?");
|
|
||||||
}
|
|
||||||
auto configData = RandomPadding::remove(*decrypted);
|
|
||||||
if (configData == boost::none) {
|
|
||||||
throw std::runtime_error("Couldn't decrypt config file because of wrong padding");
|
|
||||||
}
|
|
||||||
return std::move(*configData);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Cipher>
|
|
||||||
cpputils::Data ConcreteCryConfigEncryptor<Cipher>::encrypt(const cpputils::Data &plaintext) {
|
|
||||||
auto paddedPlaintext = RandomPadding::add(plaintext, CONFIG_SIZE);
|
|
||||||
auto ciphertext = Cipher::encrypt(static_cast<const uint8_t*>(paddedPlaintext.data()), paddedPlaintext.size(), _key.key());
|
|
||||||
return _serialize(ciphertext);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Cipher>
|
|
||||||
cpputils::Data ConcreteCryConfigEncryptor<Cipher>::_serialize(const cpputils::Data &ciphertext) {
|
|
||||||
try {
|
|
||||||
cpputils::Serializer serializer(cpputils::Serializer::StringSize(HEADER)
|
|
||||||
+ _key.config().serializedSize()
|
|
||||||
+ cpputils::Serializer::DataSize(ciphertext));
|
|
||||||
serializer.writeString(HEADER);
|
|
||||||
_key.config().serialize(&serializer);
|
|
||||||
serializer.writeData(ciphertext);
|
|
||||||
return serializer.finished();
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
cpputils::logging::LOG(cpputils::logging::ERROR) << "Error serializing CryConfigEncryptor: " << e.what();
|
|
||||||
throw; // This is a programming logic error. Pass through exception.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -2,8 +2,8 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "crypto/Scrypt.h"
|
|
||||||
#include <messmer/cpp-utils/logging/logging.h>
|
#include <messmer/cpp-utils/logging/logging.h>
|
||||||
|
#include "crypto/CryConfigEncryptorFactory.h"
|
||||||
|
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
using boost::none;
|
using boost::none;
|
||||||
@ -30,7 +30,7 @@ CryConfigFile CryConfigFile::create(const bf::path &path, CryConfig config, cons
|
|||||||
if (bf::exists(path)) {
|
if (bf::exists(path)) {
|
||||||
throw std::runtime_error("Config file exists already.");
|
throw std::runtime_error("Config file exists already.");
|
||||||
}
|
}
|
||||||
auto result = CryConfigFile(path, std::move(config), CryConfigEncryptor::deriveKey<ConfigCipher>(password));
|
auto result = CryConfigFile(path, std::move(config), CryConfigEncryptorFactory::deriveKey<ConfigCipher>(password));
|
||||||
result.save();
|
result.save();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ optional<CryConfigFile> CryConfigFile::load(const bf::path &path, const string &
|
|||||||
LOG(ERROR) << "Config file not found";
|
LOG(ERROR) << "Config file not found";
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
auto encryptor = CryConfigEncryptor::loadKey(*encryptedConfigData, password);
|
auto encryptor = CryConfigEncryptorFactory::loadKey(*encryptedConfigData, password);
|
||||||
if (encryptor == none) {
|
if (encryptor == none) {
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include "CryConfig.h"
|
#include "CryConfig.h"
|
||||||
#include "CryConfigEncryptor.h"
|
#include "crypto/CryConfigEncryptor.h"
|
||||||
#include <messmer/blockstore/implementations/encrypted/ciphers/ciphers.h>
|
#include <messmer/blockstore/implementations/encrypted/ciphers/ciphers.h>
|
||||||
|
|
||||||
namespace cryfs {
|
namespace cryfs {
|
||||||
|
1
src/config/crypto/ConcreteCryConfigEncryptor.cpp
Normal file
1
src/config/crypto/ConcreteCryConfigEncryptor.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "ConcreteCryConfigEncryptor.h"
|
91
src/config/crypto/ConcreteCryConfigEncryptor.h
Normal file
91
src/config/crypto/ConcreteCryConfigEncryptor.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_CONCRETECRYCONFIGENCRYPTOR_H
|
||||||
|
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_CONCRETECRYCONFIGENCRYPTOR_H
|
||||||
|
|
||||||
|
#include <messmer/cpp-utils/data/Serializer.h>
|
||||||
|
#include <messmer/cpp-utils/data/Deserializer.h>
|
||||||
|
#include "RandomPadding.h"
|
||||||
|
#include "CryConfigEncryptor.h"
|
||||||
|
|
||||||
|
namespace cryfs {
|
||||||
|
template<class Cipher>
|
||||||
|
class ConcreteCryConfigEncryptor: public CryConfigEncryptor {
|
||||||
|
public:
|
||||||
|
using ConfigEncryptionKey = DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH>;
|
||||||
|
static constexpr size_t CONFIG_SIZE = 1024; // Config data is grown to this size before encryption to hide its actual size
|
||||||
|
|
||||||
|
ConcreteCryConfigEncryptor(ConfigEncryptionKey key);
|
||||||
|
|
||||||
|
cpputils::Data encrypt(const cpputils::Data &plaintext) override;
|
||||||
|
boost::optional<cpputils::Data> decrypt(const cpputils::Data &ciphertext) override;
|
||||||
|
private:
|
||||||
|
void _ignoreKey(cpputils::Deserializer *deserializer);
|
||||||
|
cpputils::Data _loadAndDecryptConfigData(cpputils::Deserializer *deserializer);
|
||||||
|
cpputils::Data _serialize(const cpputils::Data &ciphertext);
|
||||||
|
|
||||||
|
ConfigEncryptionKey _key;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class Cipher>
|
||||||
|
ConcreteCryConfigEncryptor<Cipher>::ConcreteCryConfigEncryptor(ConfigEncryptionKey key): _key(std::move(key)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Cipher>
|
||||||
|
boost::optional<cpputils::Data> ConcreteCryConfigEncryptor<Cipher>::decrypt(const cpputils::Data &data) {
|
||||||
|
cpputils::Deserializer deserializer(&data);
|
||||||
|
try {
|
||||||
|
checkHeader(&deserializer);
|
||||||
|
_ignoreKey(&deserializer);
|
||||||
|
return _loadAndDecryptConfigData(&deserializer);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
cpputils::logging::LOG(cpputils::logging::ERROR) << "Error loading configuration: " << e.what();
|
||||||
|
return boost::none; // This can be caused by invalid loaded data and is not necessarily a programming logic error. Don't throw exception.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Cipher>
|
||||||
|
void ConcreteCryConfigEncryptor<Cipher>::_ignoreKey(cpputils::Deserializer *deserializer) {
|
||||||
|
DerivedKeyConfig::load(deserializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Cipher>
|
||||||
|
cpputils::Data ConcreteCryConfigEncryptor<Cipher>::_loadAndDecryptConfigData(cpputils::Deserializer *deserializer) {
|
||||||
|
auto ciphertext = deserializer->readData();
|
||||||
|
auto decrypted = Cipher::decrypt(static_cast<const uint8_t*>(ciphertext.data()), ciphertext.size(), _key.key());
|
||||||
|
if (decrypted == boost::none) {
|
||||||
|
throw std::runtime_error("Couldn't decrypt config file. Wrong password?");
|
||||||
|
}
|
||||||
|
auto configData = RandomPadding::remove(*decrypted);
|
||||||
|
if (configData == boost::none) {
|
||||||
|
throw std::runtime_error("Couldn't decrypt config file because of wrong padding");
|
||||||
|
}
|
||||||
|
return std::move(*configData);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Cipher>
|
||||||
|
cpputils::Data ConcreteCryConfigEncryptor<Cipher>::encrypt(const cpputils::Data &plaintext) {
|
||||||
|
auto paddedPlaintext = RandomPadding::add(plaintext, CONFIG_SIZE);
|
||||||
|
auto ciphertext = Cipher::encrypt(static_cast<const uint8_t*>(paddedPlaintext.data()), paddedPlaintext.size(), _key.key());
|
||||||
|
return _serialize(ciphertext);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Cipher>
|
||||||
|
cpputils::Data ConcreteCryConfigEncryptor<Cipher>::_serialize(const cpputils::Data &ciphertext) {
|
||||||
|
try {
|
||||||
|
cpputils::Serializer serializer(cpputils::Serializer::StringSize(HEADER)
|
||||||
|
+ _key.config().serializedSize()
|
||||||
|
+ cpputils::Serializer::DataSize(ciphertext));
|
||||||
|
writeHeader(&serializer);
|
||||||
|
_key.config().serialize(&serializer);
|
||||||
|
serializer.writeData(ciphertext);
|
||||||
|
return serializer.finished();
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
cpputils::logging::LOG(cpputils::logging::ERROR) << "Error serializing CryConfigEncryptor: " << e.what();
|
||||||
|
throw; // This is a programming logic error. Pass through exception.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
22
src/config/crypto/CryConfigEncryptor.cpp
Normal file
22
src/config/crypto/CryConfigEncryptor.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "CryConfigEncryptor.h"
|
||||||
|
#include <messmer/cpp-utils/logging/logging.h>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using cpputils::Deserializer;
|
||||||
|
using cpputils::Serializer;
|
||||||
|
|
||||||
|
namespace cryfs {
|
||||||
|
const string CryConfigEncryptor::HEADER = "cryfs.config;0.8.1;scrypt";
|
||||||
|
|
||||||
|
void CryConfigEncryptor::checkHeader(Deserializer *deserializer) {
|
||||||
|
string header = deserializer->readString();
|
||||||
|
if (header != HEADER) {
|
||||||
|
throw std::runtime_error("Invalid header");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CryConfigEncryptor::writeHeader(Serializer *serializer) {
|
||||||
|
serializer->writeString(HEADER);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
src/config/crypto/CryConfigEncryptor.h
Normal file
36
src/config/crypto/CryConfigEncryptor.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_CRYCONFIGENCRYPTOR_H
|
||||||
|
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_CRYCONFIGENCRYPTOR_H
|
||||||
|
|
||||||
|
#include <messmer/cpp-utils/data/Data.h>
|
||||||
|
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||||
|
#include <messmer/cpp-utils/data/Deserializer.h>
|
||||||
|
#include <messmer/cpp-utils/data/Serializer.h>
|
||||||
|
#include "kdf/DerivedKey.h"
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace cryfs {
|
||||||
|
//TODO Test
|
||||||
|
//TODO Test that encrypted config data always has the same size, no matter how big the plaintext config data
|
||||||
|
//TODO Don't only encrypt with the main cipher, but also use user specified cipher.
|
||||||
|
//TODO Use own exception for cpputils::Serializer/cpputils::Deserializer errors and only catch them
|
||||||
|
class CryConfigEncryptor {
|
||||||
|
public:
|
||||||
|
virtual cpputils::Data encrypt(const cpputils::Data &plaintext) = 0;
|
||||||
|
|
||||||
|
virtual boost::optional <cpputils::Data> decrypt(const cpputils::Data &plaintext) = 0;
|
||||||
|
|
||||||
|
static void checkHeader(cpputils::Deserializer *deserializer);
|
||||||
|
static void writeHeader(cpputils::Serializer *serializer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<class Cipher>
|
||||||
|
static DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH> _loadKey(cpputils::Deserializer *deserializer,
|
||||||
|
const std::string &password);
|
||||||
|
|
||||||
|
static const std::string HEADER;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
41
src/config/crypto/CryConfigEncryptorFactory.cpp
Normal file
41
src/config/crypto/CryConfigEncryptorFactory.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "CryConfigEncryptorFactory.h"
|
||||||
|
#include <messmer/blockstore/implementations/encrypted/ciphers/ciphers.h>
|
||||||
|
|
||||||
|
using namespace cpputils::logging;
|
||||||
|
using boost::optional;
|
||||||
|
using boost::none;
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
using cpputils::make_unique_ref;
|
||||||
|
using cpputils::Data;
|
||||||
|
using cpputils::Deserializer;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
namespace cryfs {
|
||||||
|
|
||||||
|
template<class Cipher>
|
||||||
|
DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH> CryConfigEncryptorFactory::_loadKey(cpputils::Deserializer *deserializer,
|
||||||
|
const std::string &password) {
|
||||||
|
auto keyConfig = DerivedKeyConfig::load(deserializer);
|
||||||
|
//TODO This is only kept here to recognize when this is run in tests. After tests are faster, replace this with something in main(), saying something like "Loading configuration file..."
|
||||||
|
std::cout << "Deriving secure key for config file..." << std::flush;
|
||||||
|
auto key = SCrypt().generateKeyFromConfig<Cipher::EncryptionKey::BINARY_LENGTH>(password, keyConfig);
|
||||||
|
std::cout << "done" << std::endl;
|
||||||
|
return DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH>(std::move(keyConfig), std::move(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
optional <unique_ref<CryConfigEncryptor>> CryConfigEncryptorFactory::loadKey(const Data &ciphertext,
|
||||||
|
const string &password) {
|
||||||
|
Deserializer deserializer(&ciphertext);
|
||||||
|
try {
|
||||||
|
CryConfigEncryptor::checkHeader(&deserializer);
|
||||||
|
auto key = _loadKey<blockstore::encrypted::AES256_GCM>(&deserializer, password); //TODO Allow other ciphers
|
||||||
|
return optional < unique_ref < CryConfigEncryptor >> (make_unique_ref < ConcreteCryConfigEncryptor <
|
||||||
|
blockstore::encrypted::AES256_GCM >>
|
||||||
|
(std::move(key))); //TODO Allow other ciphers
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
LOG(ERROR) << "Error loading configuration: " << e.what();
|
||||||
|
return none; // This can be caused by invalid loaded data and is not necessarily a programming logic error. Don't throw exception.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
src/config/crypto/CryConfigEncryptorFactory.h
Normal file
34
src/config/crypto/CryConfigEncryptorFactory.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_CRYCONFIGENCRYPTORFACTORY_H
|
||||||
|
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_CRYCONFIGENCRYPTORFACTORY_H
|
||||||
|
|
||||||
|
#include "ConcreteCryConfigEncryptor.h"
|
||||||
|
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||||
|
#include "kdf/Scrypt.h"
|
||||||
|
|
||||||
|
namespace cryfs {
|
||||||
|
class CryConfigEncryptorFactory {
|
||||||
|
public:
|
||||||
|
template<class Cipher>
|
||||||
|
static cpputils::unique_ref <CryConfigEncryptor> deriveKey(const std::string &password);
|
||||||
|
|
||||||
|
static boost::optional <cpputils::unique_ref<CryConfigEncryptor>> loadKey(const cpputils::Data &ciphertext,
|
||||||
|
const std::string &password);
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<class Cipher>
|
||||||
|
static DerivedKey<Cipher::EncryptionKey::BINARY_LENGTH> _loadKey(cpputils::Deserializer *deserializer,
|
||||||
|
const std::string &password);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Cipher>
|
||||||
|
cpputils::unique_ref<CryConfigEncryptor> CryConfigEncryptorFactory::deriveKey(const std::string &password) {
|
||||||
|
//TODO This is only kept here to recognize when this is run in tests. After tests are faster, replace this with something in main(), saying something like "Loading configuration file..."
|
||||||
|
std::cout << "Deriving secure key for config file..." << std::flush;
|
||||||
|
auto key = SCrypt().generateKey<Cipher::EncryptionKey::BINARY_LENGTH>(password);
|
||||||
|
std::cout << "done" << std::endl;
|
||||||
|
return cpputils::make_unique_ref<ConcreteCryConfigEncryptor<Cipher>>(std::move(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_PADDING_H
|
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_PADDING_H
|
||||||
#define MESSMER_CRYFS_SRC_CONFIG_PADDING_H
|
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_PADDING_H
|
||||||
|
|
||||||
#include <messmer/cpp-utils/data/Data.h>
|
#include <messmer/cpp-utils/data/Data.h>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_DERIVEDKEY_H
|
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KDF_DERIVEDKEY_H
|
||||||
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_DERIVEDKEY_H
|
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KDF_DERIVEDKEY_H
|
||||||
|
|
||||||
#include <messmer/cpp-utils/data/FixedSizeData.h>
|
#include <messmer/cpp-utils/data/FixedSizeData.h>
|
||||||
#include "DerivedKeyConfig.h"
|
#include "DerivedKeyConfig.h"
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KEYCONFIG_H
|
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KDF_KEYCONFIG_H
|
||||||
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KEYCONFIG_H
|
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KDF_KEYCONFIG_H
|
||||||
|
|
||||||
#include <messmer/cpp-utils/data/Data.h>
|
#include <messmer/cpp-utils/data/Data.h>
|
||||||
#include <messmer/cpp-utils/data/Serializer.h>
|
#include <messmer/cpp-utils/data/Serializer.h>
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_SCRYPT_H
|
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KDF_SCRYPT_H
|
||||||
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_SCRYPT_H
|
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KDF_SCRYPT_H
|
||||||
|
|
||||||
#include <messmer/cpp-utils/macros.h>
|
#include <messmer/cpp-utils/macros.h>
|
||||||
#include <messmer/cpp-utils/random/Random.h>
|
#include <messmer/cpp-utils/random/Random.h>
|
@ -1,5 +1,5 @@
|
|||||||
#include <google/gtest/gtest.h>
|
#include <google/gtest/gtest.h>
|
||||||
#include "../../../src/config/crypto/DerivedKeyConfig.h"
|
#include "../../../../src/config/crypto/kdf/DerivedKeyConfig.h"
|
||||||
#include <messmer/cpp-utils/data/DataFixture.h>
|
#include <messmer/cpp-utils/data/DataFixture.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
#include <google/gtest/gtest.h>
|
#include <google/gtest/gtest.h>
|
||||||
#include "../../../src/config/crypto/DerivedKey.h"
|
#include "../../../../src/config/crypto/kdf/DerivedKey.h"
|
||||||
#include <messmer/cpp-utils/data/DataFixture.h>
|
#include <messmer/cpp-utils/data/DataFixture.h>
|
||||||
|
|
||||||
using namespace cryfs;
|
using namespace cryfs;
|
@ -1,5 +1,5 @@
|
|||||||
#include <google/gtest/gtest.h>
|
#include <google/gtest/gtest.h>
|
||||||
#include "../../../src/config/crypto/Scrypt.h"
|
#include "../../../../src/config/crypto/kdf/Scrypt.h"
|
||||||
|
|
||||||
using namespace cryfs;
|
using namespace cryfs;
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user