Refactor CryConfigEncryptor: Store instance instead of static

This commit is contained in:
Sebastian Messmer 2015-10-26 16:36:57 +01:00
parent a840bbba47
commit fd184b45d2
13 changed files with 176 additions and 129 deletions

View File

@ -8,12 +8,10 @@ ADD_BII_TARGETS()
ACTIVATE_CPP14()
ADD_BOOST(program_options)
ADD_BOOST(program_options chrono)
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
#SET_TARGET_PROPERTIES(${BII_test_main_TARGET} PROPERTIES LINK_FLAGS -rdynamic)
GIT_VERSION_INIT()
ENABLE_STYLE_WARNINGS()

View File

@ -1 +1,5 @@
#include "CryConfigEncryptor.h"
namespace cryfs {
const std::string CryConfigEncryptor::HEADER = "cryfs.config;0.8.1;scrypt";
}

View File

@ -7,75 +7,77 @@
#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
template<class Cipher>
class 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
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);
static ConfigEncryptionKey deriveKey(const std::string &password);
static boost::optional<std::pair<ConfigEncryptionKey, cpputils::Data>> decrypt(const cpputils::Data &ciphertext, const std::string &password);
static cpputils::Data encrypt(const cpputils::Data &plaintext, const ConfigEncryptionKey &key);
private:
static std::pair<ConfigEncryptionKey, cpputils::Data> _decrypt(cpputils::Deserializer *deserializer, 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);
static ConfigEncryptionKey _loadKey(cpputils::Deserializer *deserializer, const std::string &password);
static cpputils::Data _loadAndDecryptConfigData(cpputils::Deserializer *deserializer, const typename Cipher::EncryptionKey &key);
static cpputils::Data _serialize(const cpputils::Data &ciphertext, const ConfigEncryptionKey &key);
//TODO Test that encrypted config data always has the same size, no matter how big the plaintext config data
static cpputils::Data _addPadding(const cpputils::Data &data);
static boost::optional<cpputils::Data> _removePadding(const cpputils::Data &data);
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> const std::string CryConfigEncryptor<Cipher>::HEADER = "cryfs.config;0.8.1;scrypt";
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>
typename CryConfigEncryptor<Cipher>::ConfigEncryptionKey CryConfigEncryptor<Cipher>::deriveKey(const std::string &password) {
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 key;
return cpputils::make_unique_ref<ConcreteCryConfigEncryptor<Cipher>>(std::move(key));
}
template<class Cipher>
boost::optional<std::pair<typename CryConfigEncryptor<Cipher>::ConfigEncryptionKey, cpputils::Data>>
CryConfigEncryptor<Cipher>::decrypt(const cpputils::Data &data, const std::string &password) {
cpputils::Deserializer deserializer(&data);
inline boost::optional<cpputils::unique_ref<CryConfigEncryptor>> CryConfigEncryptor::loadKey(const cpputils::Data &ciphertext, const std::string &password) {
cpputils::Deserializer deserializer(&ciphertext);
try {
auto result = _decrypt(&deserializer, password);
deserializer.finished();
return result;
_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.
}
};
}
template<class Cipher>
std::pair<typename CryConfigEncryptor<Cipher>::ConfigEncryptionKey, cpputils::Data>
CryConfigEncryptor<Cipher>::_decrypt(cpputils::Deserializer *deserializer, const std::string &password) {
_checkHeader(deserializer);
auto key = _loadKey(deserializer, password);
auto configData = _loadAndDecryptConfigData(deserializer, key.key());
return std::make_pair(std::move(key), std::move(configData));
};
template<class Cipher>
void CryConfigEncryptor<Cipher>::_checkHeader(cpputils::Deserializer *deserializer) {
inline void CryConfigEncryptor::_checkHeader(cpputils::Deserializer *deserializer) {
std::string header = deserializer->readString();
if (header != HEADER) {
throw std::runtime_error("Invalid header");
@ -83,23 +85,47 @@ namespace cryfs {
}
template<class Cipher>
typename CryConfigEncryptor<Cipher>::ConfigEncryptionKey CryConfigEncryptor<Cipher>::_loadKey(cpputils::Deserializer *deserializer, const std::string &password) {
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 ConfigEncryptionKey(std::move(keyConfig), std::move(key));
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>
cpputils::Data CryConfigEncryptor<Cipher>::_loadAndDecryptConfigData(cpputils::Deserializer *deserializer, const typename Cipher::EncryptionKey &key) {
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);
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 = _removePadding(*decrypted);
auto configData = RandomPadding::remove(*decrypted);
if (configData == boost::none) {
throw std::runtime_error("Couldn't decrypt config file because of wrong padding");
}
@ -107,20 +133,20 @@ namespace cryfs {
}
template<class Cipher>
cpputils::Data CryConfigEncryptor<Cipher>::encrypt(const cpputils::Data &plaintext, const ConfigEncryptionKey &key) {
auto paddedPlaintext = _addPadding(plaintext);
auto ciphertext = Cipher::encrypt(static_cast<const uint8_t*>(paddedPlaintext.data()), paddedPlaintext.size(), key.key());
return _serialize(ciphertext, key);
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 CryConfigEncryptor<Cipher>::_serialize(const cpputils::Data &ciphertext, const ConfigEncryptionKey &key) {
cpputils::Data ConcreteCryConfigEncryptor<Cipher>::_serialize(const cpputils::Data &ciphertext) {
try {
cpputils::Serializer serializer(cpputils::Serializer::StringSize(HEADER)
+ key.config().serializedSize()
+ _key.config().serializedSize()
+ cpputils::Serializer::DataSize(ciphertext));
serializer.writeString(HEADER);
key.config().serialize(&serializer);
_key.config().serialize(&serializer);
serializer.writeData(ciphertext);
return serializer.finished();
} catch (const std::exception &e) {
@ -128,32 +154,6 @@ namespace cryfs {
throw; // This is a programming logic error. Pass through exception.
}
}
template<class Cipher>
cpputils::Data CryConfigEncryptor<Cipher>::_addPadding(const cpputils::Data &data) {
uint32_t size = data.size();
ASSERT(size < CONFIG_SIZE - sizeof(size), "Config data too large. We should increase CONFIG_SIZE.");
cpputils::Data randomData = cpputils::Random::PseudoRandom().get(CONFIG_SIZE-sizeof(size)-size);
ASSERT(sizeof(size) + size + randomData.size() == CONFIG_SIZE, "Calculated size of randomData incorrectly");
cpputils::Data result(CONFIG_SIZE);
std::memcpy(reinterpret_cast<char*>(result.data()), &size, sizeof(size));
std::memcpy(reinterpret_cast<char*>(result.dataOffset(sizeof(size))), reinterpret_cast<const char*>(data.data()), size);
std::memcpy(reinterpret_cast<char*>(result.dataOffset(sizeof(size)+size)), reinterpret_cast<const char*>(randomData.data()), randomData.size());
return result;
}
template<class Cipher>
boost::optional<cpputils::Data> CryConfigEncryptor<Cipher>::_removePadding(const cpputils::Data &data) {
uint32_t size;
std::memcpy(&size, reinterpret_cast<const char*>(data.data()), sizeof(size));
if(sizeof(size) + size >= data.size()) {
cpputils::logging::LOG(cpputils::logging::ERROR) << "Config file is invalid: Invalid padding.";
return boost::none;
};
cpputils::Data result(size);
std::memcpy(reinterpret_cast<char*>(result.data()), reinterpret_cast<const char*>(data.dataOffset(sizeof(size))), size);
return std::move(result);
}
}
#endif

View File

@ -15,46 +15,51 @@ using std::ostringstream;
using std::stringstream;
using std::istream;
using cpputils::Data;
using cpputils::unique_ref;
namespace bf = boost::filesystem;
using namespace cpputils::logging;
namespace cryfs {
CryConfigFile::~CryConfigFile() {
//We do not call save() here, because we do not want the config file to be re-encrypted on each filesystem run
}
CryConfigFile CryConfigFile::create(const bf::path &path, CryConfig config, const string &password) {
using ConfigCipher = blockstore::encrypted::AES256_GCM; // TODO Take cipher from config instead
if (bf::exists(path)) {
throw std::runtime_error("Config file exists already.");
}
auto configEncKey = Encryptor::deriveKey(password);
auto result = CryConfigFile(path, std::move(config), std::move(configEncKey));
auto result = CryConfigFile(path, std::move(config), CryConfigEncryptor::deriveKey<ConfigCipher>(password));
result.save();
return result;
}
CryConfigFile::~CryConfigFile() {
//We do not call save() here, because we do not want the config file to be re-encrypted on each filesystem run
}
optional<CryConfigFile> CryConfigFile::load(const bf::path &path, const string &password) {
auto encryptedConfigData = Data::LoadFromFile(path);
if (encryptedConfigData == none) {
LOG(ERROR) << "Config file not found";
return none;
}
auto decrypted = Encryptor::decrypt(*encryptedConfigData, password);
auto encryptor = CryConfigEncryptor::loadKey(*encryptedConfigData, password);
if (encryptor == none) {
return none;
}
auto decrypted = (*encryptor)->decrypt(*encryptedConfigData);
if (decrypted == none) {
return none;
}
CryConfig config = CryConfig::load(decrypted->second);
return CryConfigFile(path, std::move(config), std::move(decrypted->first));
CryConfig config = CryConfig::load(*decrypted);
return CryConfigFile(path, std::move(config), std::move(*encryptor));
}
CryConfigFile::CryConfigFile(const bf::path &path, CryConfig config, ConfigEncryptionKey configEncKey)
: _path (path), _config(std::move(config)), _configEncKey(std::move(configEncKey)) {
CryConfigFile::CryConfigFile(const bf::path &path, CryConfig config, unique_ref<CryConfigEncryptor> encryptor)
: _path (path), _config(std::move(config)), _encryptor(std::move(encryptor)) {
}
void CryConfigFile::save() const {
Data configData = _config.save();
auto encrypted = Encryptor::encrypt(configData, _configEncKey);
auto encrypted = _encryptor->encrypt(configData);
encrypted.StoreToFile(_path);
}

View File

@ -11,9 +11,6 @@
namespace cryfs {
class CryConfigFile final {
public:
using ConfigCipher = blockstore::encrypted::AES256_GCM;
using ConfigEncryptionKey = DerivedKey<ConfigCipher::EncryptionKey::BINARY_LENGTH>;
CryConfigFile(CryConfigFile &&rhs) = default;
~CryConfigFile();
@ -24,16 +21,11 @@ namespace cryfs {
CryConfig *config();
private:
CryConfigFile(const boost::filesystem::path &path, CryConfig config, ConfigEncryptionKey configEncKey);
static ConfigEncryptionKey _deriveKey(const std::string &password);
static std::string _decrypt(cpputils::Data content, const ConfigEncryptionKey &configEncKey);
static cpputils::Data _encrypt(const std::string &content, const ConfigEncryptionKey &configEncKey);
CryConfigFile(const boost::filesystem::path &path, CryConfig config, cpputils::unique_ref<CryConfigEncryptor> encryptor);
boost::filesystem::path _path;
CryConfig _config;
ConfigEncryptionKey _configEncKey;
using Encryptor = CryConfigEncryptor<ConfigCipher>;
cpputils::unique_ref<CryConfigEncryptor> _encryptor;
DISALLOW_COPY_AND_ASSIGN(CryConfigFile);
};

View File

@ -2,6 +2,7 @@
#include "CryConfigFile.h"
#include <boost/filesystem.hpp>
#include <messmer/cpp-utils/random/Random.h>
#include <messmer/cpp-utils/logging/logging.h>
namespace bf = boost::filesystem;
using cpputils::unique_ref;
@ -15,6 +16,7 @@ using boost::none;
using std::vector;
using std::string;
using std::function;
using namespace cpputils::logging;
namespace cryfs {
@ -22,7 +24,7 @@ CryConfigLoader::CryConfigLoader(unique_ref<Console> console, RandomGenerator &k
: _creator(std::move(console), keyGenerator), _askPassword(askPassword) {
}
CryConfigFile CryConfigLoader::loadOrCreate(const bf::path &filename) {
optional<CryConfigFile> CryConfigLoader::loadOrCreate(const bf::path &filename) {
if (bf::exists(filename)) {
return _loadConfig(filename);
} else {
@ -30,12 +32,12 @@ CryConfigFile CryConfigLoader::loadOrCreate(const bf::path &filename) {
}
}
CryConfigFile CryConfigLoader::_loadConfig(const bf::path &filename) {
optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
string password = _askPassword();
auto config = CryConfigFile::load(filename, password);
if (config == none) {
std::cerr << "Could not load config file. Wrong password?" << std::endl;
exit(1);
LOG(ERROR) << "Could not load config file. Wrong password?";
return none;
}
return std::move(*config);
}

View File

@ -15,10 +15,10 @@ public:
CryConfigLoader(cpputils::unique_ref<cpputils::Console> console, cpputils::RandomGenerator &keyGenerator, std::function<std::string()> askPassword);
CryConfigLoader(CryConfigLoader &&rhs) = default;
CryConfigFile loadOrCreate(const boost::filesystem::path &filename);
boost::optional<CryConfigFile> loadOrCreate(const boost::filesystem::path &filename);
private:
CryConfigFile _loadConfig(const boost::filesystem::path &filename);
boost::optional<CryConfigFile> _loadConfig(const boost::filesystem::path &filename);
CryConfigFile _createConfig(const boost::filesystem::path &filename);
CryConfigCreator _creator;

View File

@ -0,0 +1,34 @@
#include "RandomPadding.h"
#include <messmer/cpp-utils/logging/logging.h>
#include <messmer/cpp-utils/random/Random.h>
using cpputils::Data;
using cpputils::Random;
using boost::optional;
using namespace cpputils::logging;
namespace cryfs {
Data RandomPadding::add(const Data &data, size_t targetSize) {
uint32_t size = data.size();
ASSERT(size < targetSize - sizeof(size), "Config data too large. We should increase padding target size.");
Data randomData = Random::PseudoRandom().get(targetSize-sizeof(size)-size);
ASSERT(sizeof(size) + size + randomData.size() == targetSize, "Calculated size of randomData incorrectly");
Data result(targetSize);
std::memcpy(reinterpret_cast<char*>(result.data()), &size, sizeof(size));
std::memcpy(reinterpret_cast<char*>(result.dataOffset(sizeof(size))), reinterpret_cast<const char*>(data.data()), size);
std::memcpy(reinterpret_cast<char*>(result.dataOffset(sizeof(size)+size)), reinterpret_cast<const char*>(randomData.data()), randomData.size());
return result;
}
optional<Data> RandomPadding::remove(const Data &data) {
uint32_t size;
std::memcpy(&size, reinterpret_cast<const char*>(data.data()), sizeof(size));
if(sizeof(size) + size >= data.size()) {
LOG(ERROR) << "Config file is invalid: Invalid padding.";
return boost::none;
};
Data result(size);
std::memcpy(reinterpret_cast<char*>(result.data()), reinterpret_cast<const char*>(data.dataOffset(sizeof(size))), size);
return std::move(result);
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#ifndef MESSMER_CRYFS_SRC_CONFIG_PADDING_H
#define MESSMER_CRYFS_SRC_CONFIG_PADDING_H
#include <messmer/cpp-utils/data/Data.h>
#include <boost/optional.hpp>
namespace cryfs {
//TODO Test
class RandomPadding {
public:
static cpputils::Data add(const cpputils::Data &data, size_t targetSize);
static boost::optional<cpputils::Data> remove(const cpputils::Data &data);
};
}
#endif

View File

@ -91,7 +91,11 @@ CryConfigFile loadOrCreateConfig(const ProgramOptions &options) {
auto configFile = determineConfigFile(options);
auto console = make_unique_ref<IOStreamConsole>();
auto &keyGenerator = Random::OSRandom();
return CryConfigLoader(std::move(console), keyGenerator, &askPassword).loadOrCreate(configFile);
auto config = CryConfigLoader(std::move(console), keyGenerator, &askPassword).loadOrCreate(configFile);
if (config == none) {
std::cerr << "Could not load config file. Did you enter the correct password?" << std::endl;
exit(1);
}
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << std::endl;
exit(1);

View File

@ -26,28 +26,28 @@ public:
CryConfigFile Create(const string &password = "mypassword") {
EXPECT_FALSE(file.exists());
return loader(password).loadOrCreate(file.path());
return loader(password).loadOrCreate(file.path()).value();
}
CryConfigFile Load(const string &password = "mypassword") {
optional<CryConfigFile> Load(const string &password = "mypassword") {
EXPECT_TRUE(file.exists());
return loader(password).loadOrCreate(file.path());
}
void CreateWithRootBlob(const string &rootBlob, const string &password = "mypassword") {
auto cfg = loader(password).loadOrCreate(file.path());
auto cfg = loader(password).loadOrCreate(file.path()).value();
cfg.config()->SetRootBlob(rootBlob);
cfg.save();
}
void CreateWithCipher(const string &cipher, const string &password = "mypassword") {
auto cfg = loader(password).loadOrCreate(file.path());
auto cfg = loader(password).loadOrCreate(file.path()).value();
cfg.config()->SetCipher(cipher);
cfg.save();
}
void CreateWithEncryptionKey(const string &encKey, const string &password = "mypassword") {
auto cfg = loader(password).loadOrCreate(file.path());
auto cfg = loader(password).loadOrCreate(file.path()).value();
cfg.config()->SetEncryptionKey(encKey);
cfg.save();
}
@ -66,24 +66,15 @@ TEST_F(CryConfigLoaderTest, DoesntCrashIfExisting) {
Load();
}
//Giving the test case a "DeathTest" suffix causes gtest to run it before other tests.
//This is necessary, because otherwise the call to exit() will fail and deadlock because the DeathTest is run
//in a forked process. Some of the other tests here access global singletons that create a thread and want to join
//it on process exit. But threads aren't forked by the fork syscall, so it waits forever.
using CryConfigLoaderTest_DeathTest = CryConfigLoaderTest;
TEST_F(CryConfigLoaderTest_DeathTest, DoesntLoadIfWrongPassword) {
TEST_F(CryConfigLoaderTest, DoesntLoadIfWrongPassword) {
Create("mypassword");
EXPECT_EXIT(
Load("mypassword2"),
::testing::ExitedWithCode(1),
"Wrong password"
);
auto loaded = Load("mypassword2");
EXPECT_EQ(none, loaded);
}
TEST_F(CryConfigLoaderTest, RootBlob_Load) {
CreateWithRootBlob("rootblobid");
auto loaded = Load();
auto loaded = Load().value();
EXPECT_EQ("rootblobid", loaded.config()->RootBlob());
}
@ -94,7 +85,7 @@ TEST_F(CryConfigLoaderTest, RootBlob_Create) {
TEST_F(CryConfigLoaderTest, EncryptionKey_Load) {
CreateWithEncryptionKey("encryptionkey");
auto loaded = Load();
auto loaded = Load().value();
EXPECT_EQ("encryptionkey", loaded.config()->EncryptionKey());
}
@ -106,7 +97,7 @@ TEST_F(CryConfigLoaderTest, EncryptionKey_Create) {
TEST_F(CryConfigLoaderTest, Cipher_Load) {
CreateWithCipher("ciphername");
auto loaded = Load();
auto loaded = Load().value();
EXPECT_EQ("ciphername", loaded.config()->Cipher());
}

View File

@ -33,7 +33,7 @@ public:
}
CryConfigFile loadOrCreateConfig() {
return CryConfigLoader(mockConsole(), Random::PseudoRandom(), [] {return "mypassword";}).loadOrCreate(config.path());
return CryConfigLoader(mockConsole(), Random::PseudoRandom(), [] {return "mypassword";}).loadOrCreate(config.path()).value();
}
unique_ref<OnDiskBlockStore> blockStore() {

View File

@ -27,7 +27,7 @@ public:
unique_ref<Device> createDevice() override {
auto blockStore = cpputils::make_unique_ref<FakeBlockStore>();
auto config = CryConfigLoader(mockConsole(), Random::PseudoRandom(), [] {return "mypassword";})
.loadOrCreate(configFile.path());
.loadOrCreate(configFile.path()).value();
return make_unique_ref<CryDevice>(std::move(config), std::move(blockStore));
}