Adapted to new key creation interface

This commit is contained in:
Sebastian Messmer 2015-10-22 18:48:04 +02:00
parent 9b1152348e
commit 9bf83a6fe7
10 changed files with 71 additions and 81 deletions

View File

@ -36,8 +36,8 @@ public:
return make_unique_ref<EncryptedBlockStore<Cipher>>(std::move(baseBlockStore), Cipher::EncryptionKey::FromString(encKey)); return make_unique_ref<EncryptedBlockStore<Cipher>>(std::move(baseBlockStore), Cipher::EncryptionKey::FromString(encKey));
} }
string createKey() const override { string createKey(cpputils::RandomGenerator &randomGenerator) const override {
return Cipher::EncryptionKey::CreateOSRandom().ToString(); return Cipher::CreateKey(randomGenerator).ToString();
} }
private: private:

View File

@ -6,6 +6,7 @@
#include <string> #include <string>
#include <messmer/cpp-utils/pointer/unique_ref.h> #include <messmer/cpp-utils/pointer/unique_ref.h>
#include <messmer/blockstore/interface/BlockStore.h> #include <messmer/blockstore/interface/BlockStore.h>
#include <messmer/cpp-utils/random/RandomGenerator.h>
namespace cryfs { namespace cryfs {
@ -16,7 +17,7 @@ public:
virtual const std::string &cipherName() const = 0; virtual const std::string &cipherName() const = 0;
virtual const boost::optional<std::string> &warning() const = 0; virtual const boost::optional<std::string> &warning() const = 0;
virtual cpputils::unique_ref<blockstore::BlockStore> createEncryptedBlockstore(cpputils::unique_ref<blockstore::BlockStore> baseBlockStore, const std::string &encKey) const = 0; virtual cpputils::unique_ref<blockstore::BlockStore> createEncryptedBlockstore(cpputils::unique_ref<blockstore::BlockStore> baseBlockStore, const std::string &encKey) const = 0;
virtual std::string createKey() const = 0; virtual std::string createKey(cpputils::RandomGenerator &randomGenerator) const = 0;
}; };
class CryCiphers { class CryCiphers {

View File

@ -4,13 +4,13 @@
using cpputils::Console; using cpputils::Console;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::RandomGenerator;
using std::string; using std::string;
using std::vector; using std::vector;
namespace cryfs { namespace cryfs {
CryConfigCreator::CryConfigCreator(unique_ref<Console> console) CryConfigCreator::CryConfigCreator(unique_ref<Console> console, RandomGenerator &encryptionKeyGenerator)
:_console(std::move(console)) { :_console(std::move(console)), _encryptionKeyGenerator(encryptionKeyGenerator) {
} }
CryConfig CryConfigCreator::create() { CryConfig CryConfigCreator::create() {
@ -21,14 +21,6 @@ namespace cryfs {
return config; return config;
} }
CryConfig CryConfigCreator::createForTest() {
CryConfig config;
config.SetCipher(_generateCipherForTest());
config.SetEncryptionKey(_generateEncKeyForTest(config.Cipher()));
config.SetRootBlob(_generateRootBlobKey());
return config;
}
string CryConfigCreator::_generateCipher() { string CryConfigCreator::_generateCipher() {
vector<string> ciphers = CryCiphers::supportedCipherNames(); vector<string> ciphers = CryCiphers::supportedCipherNames();
string cipherName = ""; string cipherName = "";
@ -51,19 +43,11 @@ namespace cryfs {
string CryConfigCreator::_generateEncKey(const std::string &cipher) { string CryConfigCreator::_generateEncKey(const std::string &cipher) {
_console->print("\nGenerating secure encryption key..."); _console->print("\nGenerating secure encryption key...");
auto key = CryCiphers::find(cipher).createKey(); auto key = CryCiphers::find(cipher).createKey(_encryptionKeyGenerator);
_console->print("done\n"); _console->print("done\n");
return key; return key;
} }
string CryConfigCreator::_generateCipherForTest() {
return "aes-256-gcm";
}
string CryConfigCreator::_generateEncKeyForTest(const std::string &) {
return blockstore::encrypted::AES256_GCM::EncryptionKey::CreatePseudoRandom().ToString();
}
string CryConfigCreator::_generateRootBlobKey() { string CryConfigCreator::_generateRootBlobKey() {
//An empty root blob entry will tell CryDevice to create a new root blob //An empty root blob entry will tell CryDevice to create a new root blob
return ""; return "";

View File

@ -2,27 +2,24 @@
#define CRYFS_SRC_CONFIG_CRYCONFIGCREATOR_H #define CRYFS_SRC_CONFIG_CRYCONFIGCREATOR_H
#include <messmer/cpp-utils/pointer/unique_ref.h> #include <messmer/cpp-utils/pointer/unique_ref.h>
#include <messmer/cpp-utils/random/RandomGenerator.h>
#include <messmer/cpp-utils/io/Console.h> #include <messmer/cpp-utils/io/Console.h>
#include "CryConfig.h" #include "CryConfig.h"
namespace cryfs { namespace cryfs {
class CryConfigCreator final { class CryConfigCreator final {
public: public:
CryConfigCreator(cpputils::unique_ref<cpputils::Console> console); CryConfigCreator(cpputils::unique_ref<cpputils::Console> console, cpputils::RandomGenerator &encryptionKeyGenerator);
CryConfig create(); CryConfig create();
CryConfig createForTest();
private: private:
std::string _generateCipher(); std::string _generateCipher();
std::string _generateEncKey(const std::string &cipher); std::string _generateEncKey(const std::string &cipher);
std::string _generateRootBlobKey(); std::string _generateRootBlobKey();
bool _showWarningForCipherAndReturnIfOk(const std::string &cipherName); bool _showWarningForCipherAndReturnIfOk(const std::string &cipherName);
//TODO Don't have these functions here, but use a CryConfigCreator interface and mock it in the tests
std::string _generateEncKeyForTest(const std::string &cipher);
std::string _generateCipherForTest();
cpputils::unique_ref<cpputils::Console> _console; cpputils::unique_ref<cpputils::Console> _console;
cpputils::RandomGenerator &_encryptionKeyGenerator;
DISALLOW_COPY_AND_ASSIGN(CryConfigCreator); DISALLOW_COPY_AND_ASSIGN(CryConfigCreator);
}; };

View File

@ -1,6 +1,7 @@
#include "CryConfigLoader.h" #include "CryConfigLoader.h"
#include "CryConfigFile.h" #include "CryConfigFile.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <messmer/cpp-utils/random/Random.h>
namespace bf = boost::filesystem; namespace bf = boost::filesystem;
using cpputils::unique_ref; using cpputils::unique_ref;
@ -14,9 +15,10 @@ using std::string;
namespace cryfs { namespace cryfs {
CryConfigLoader::CryConfigLoader(): CryConfigLoader(make_unique_ref<IOStreamConsole>()) {} CryConfigLoader::CryConfigLoader(): CryConfigLoader(make_unique_ref<IOStreamConsole>(), cpputils::Random::OSRandom()) {}
CryConfigLoader::CryConfigLoader(unique_ref<Console> console) : _creator(std::move(console)) {} CryConfigLoader::CryConfigLoader(unique_ref<Console> console, cpputils::RandomGenerator &keyGenerator)
: _creator(std::move(console), keyGenerator) {}
CryConfigFile CryConfigLoader::loadOrCreate(const bf::path &filename) { CryConfigFile CryConfigLoader::loadOrCreate(const bf::path &filename) {
auto config = CryConfigFile::load(filename); auto config = CryConfigFile::load(filename);
@ -33,19 +35,4 @@ CryConfigFile CryConfigLoader::createNew(const bf::path &filename) {
return configFile; return configFile;
} }
CryConfigFile CryConfigLoader::loadOrCreateForTest(const bf::path &filename) {
auto config = CryConfigFile::load(filename);
if (config != none) {
return std::move(*config);
}
return createNewForTest(filename);
}
CryConfigFile CryConfigLoader::createNewForTest(const bf::path &filename) {
auto config = _creator.createForTest();
auto configFile = CryConfigFile::create(filename, std::move(config));
configFile.save();
return configFile;
}
} }

View File

@ -13,15 +13,11 @@ namespace cryfs {
class CryConfigLoader { class CryConfigLoader {
public: public:
CryConfigLoader(); CryConfigLoader();
explicit CryConfigLoader(cpputils::unique_ref<cpputils::Console> console); explicit CryConfigLoader(cpputils::unique_ref<cpputils::Console> console, cpputils::RandomGenerator &keyGenerator);
CryConfigFile loadOrCreate(const boost::filesystem::path &filename); CryConfigFile loadOrCreate(const boost::filesystem::path &filename);
CryConfigFile createNew(const boost::filesystem::path &filename); CryConfigFile createNew(const boost::filesystem::path &filename);
//This methods are only for testing purposes, because creating weak keys is much faster than creating strong keys.
CryConfigFile loadOrCreateForTest(const boost::filesystem::path &filename);
CryConfigFile createNewForTest(const boost::filesystem::path &filename);
private: private:
CryConfigCreator _creator; CryConfigCreator _creator;
}; };

View File

@ -6,6 +6,7 @@
#include <messmer/blockstore/implementations/testfake/FakeBlockStore.h> #include <messmer/blockstore/implementations/testfake/FakeBlockStore.h>
#include <messmer/blockstore/implementations/encrypted/EncryptedBlockStore.h> #include <messmer/blockstore/implementations/encrypted/EncryptedBlockStore.h>
#include <messmer/cpp-utils/data/DataFixture.h> #include <messmer/cpp-utils/data/DataFixture.h>
#include <messmer/cpp-utils/random/Random.h>
using namespace cryfs; using namespace cryfs;
using namespace blockstore::encrypted; using namespace blockstore::encrypted;
@ -22,6 +23,7 @@ using cpputils::DataFixture;
using cpputils::Data; using cpputils::Data;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
using cpputils::Random;
class CryCipherTest : public ::testing::Test { class CryCipherTest : public ::testing::Test {
public: public:
@ -39,13 +41,13 @@ public:
void EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE(const string &cipherName) { void EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE(const string &cipherName) {
const auto &actualCipher = CryCiphers::find(cipherName); const auto &actualCipher = CryCiphers::find(cipherName);
Data dataFixture = DataFixture::generate(1024); Data dataFixture = DataFixture::generate(1024);
string encKey = ExpectedCipher::EncryptionKey::CreatePseudoRandom().ToString(); string encKey = ExpectedCipher::CreateKey(Random::PseudoRandom()).ToString();
_EXPECT_ENCRYPTS_WITH_ACTUAL_BLOCKSTORE_DECRYPTS_CORRECTLY_WITH_EXPECTED_BLOCKSTORE<ExpectedCipher>(actualCipher, encKey, std::move(dataFixture)); _EXPECT_ENCRYPTS_WITH_ACTUAL_BLOCKSTORE_DECRYPTS_CORRECTLY_WITH_EXPECTED_BLOCKSTORE<ExpectedCipher>(actualCipher, encKey, std::move(dataFixture));
} }
template<class ExpectedCipher> template<class ExpectedCipher>
void _EXPECT_ENCRYPTS_WITH_ACTUAL_BLOCKSTORE_DECRYPTS_CORRECTLY_WITH_EXPECTED_BLOCKSTORE(const CryCipher &actualCipher, const std::string &encKey, Data dataFixture) { void _EXPECT_ENCRYPTS_WITH_ACTUAL_BLOCKSTORE_DECRYPTS_CORRECTLY_WITH_EXPECTED_BLOCKSTORE(const CryCipher &actualCipher, const std::string &encKey, Data dataFixture) {
blockstore::Key key = blockstore::Key::CreatePseudoRandom(); blockstore::Key key = cpputils::Random::PseudoRandom().getFixedSize<blockstore::Key::BINARY_LENGTH>();
Data encrypted = _encryptUsingEncryptedBlockStoreWithCipher(actualCipher, encKey, key, dataFixture.copy()); Data encrypted = _encryptUsingEncryptedBlockStoreWithCipher(actualCipher, encKey, key, dataFixture.copy());
Data decrypted = _decryptUsingEncryptedBlockStoreWithCipher<ExpectedCipher>(encKey, key, std::move(encrypted)); Data decrypted = _decryptUsingEncryptedBlockStoreWithCipher<ExpectedCipher>(encKey, key, std::move(encrypted));
EXPECT_EQ(dataFixture, decrypted); EXPECT_EQ(dataFixture, decrypted);
@ -124,13 +126,13 @@ TEST_F(CryCipherTest, ThereIsACipherWithIntegrityWarning) {
} }
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_448) { TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_448) {
EXPECT_EQ(Mars448_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("mars-448-gcm").createKey().size()); EXPECT_EQ(Mars448_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("mars-448-gcm").createKey(Random::PseudoRandom()).size());
} }
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_256) { TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_256) {
EXPECT_EQ(AES256_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("aes-256-gcm").createKey().size()); EXPECT_EQ(AES256_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("aes-256-gcm").createKey(Random::PseudoRandom()).size());
} }
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_128) { TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_128) {
EXPECT_EQ(AES128_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("aes-128-gcm").createKey().size()); EXPECT_EQ(AES128_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("aes-128-gcm").createKey(Random::PseudoRandom()).size());
} }

View File

@ -7,10 +7,13 @@
#include "../../src/filesystem/CryDir.h" #include "../../src/filesystem/CryDir.h"
#include "../../src/filesystem/CryFile.h" #include "../../src/filesystem/CryFile.h"
#include "../../src/filesystem/CryOpenFile.h" #include "../../src/filesystem/CryOpenFile.h"
#include "../testutils/MockConsole.h"
//TODO (whole project) Make constructors explicit when implicit construction not needed //TODO (whole project) Make constructors explicit when implicit construction not needed
using ::testing::Test; using ::testing::Test;
using ::testing::Return;
using ::testing::_;
using cpputils::TempDir; using cpputils::TempDir;
using cpputils::TempFile; using cpputils::TempFile;
using cpputils::dynamic_pointer_move; using cpputils::dynamic_pointer_move;
@ -22,44 +25,38 @@ using blockstore::ondisk::OnDiskBlockStore;
namespace bf = boost::filesystem; namespace bf = boost::filesystem;
using namespace cryfs; using namespace cryfs;
class MockConsole: public Console {
void print(const std::string &) override {}
unsigned int ask(const std::string &, const std::vector<std::string> &) override {
return 0;
}
bool askYesNo(const std::string &) override {
return true;
}
};
class CryFsTest: public Test { class CryFsTest: public Test {
public: public:
CryFsTest(): rootdir(), config(false) {} CryFsTest(): rootdir(), config(false) {
}
unique_ref<MockConsole> mockConsole() {
auto console = make_unique_ref<MockConsole>();
EXPECT_CALL(*console, ask(_, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*console, askYesNo(_)).WillRepeatedly(Return(true));
return console;
}
TempDir rootdir; TempDir rootdir;
TempFile config; TempFile config;
}; };
TEST_F(CryFsTest, CreatedRootdirIsLoadableAfterClosing) { TEST_F(CryFsTest, CreatedRootdirIsLoadableAfterClosing_1) {
{ {
CryDevice dev(CryConfigLoader().createNewForTest(config.path()), make_unique_ref<OnDiskBlockStore>(rootdir.path())); CryDevice dev(
CryConfigLoader(mockConsole(), cpputils::Random::PseudoRandom())
.createNew(config.path()), make_unique_ref<OnDiskBlockStore>(rootdir.path())
);
} }
CryDevice dev(CryConfigFile::load(config.path()).value(), make_unique_ref<OnDiskBlockStore>(rootdir.path())); CryDevice dev(CryConfigFile::load(config.path()).value(), make_unique_ref<OnDiskBlockStore>(rootdir.path()));
auto root = dev.Load(bf::path("/")); auto root = dev.Load(bf::path("/"));
dynamic_pointer_move<CryDir>(root.get()).get()->children(); dynamic_pointer_move<CryDir>(root.get()).get()->children();
} }
TEST_F(CryFsTest, UsingStrongKey1_CreatedRootdirIsLoadableAfterClosing) { TEST_F(CryFsTest, CreatedRootdirIsLoadableAfterClosing_2) {
{ {
CryDevice dev(CryConfigLoader(make_unique_ref<MockConsole>()).createNew(config.path()), make_unique_ref<OnDiskBlockStore>(rootdir.path())); CryDevice dev(
} CryConfigLoader(mockConsole(), cpputils::Random::PseudoRandom())
CryDevice dev(CryConfigFile::load(config.path()).value(), make_unique_ref<OnDiskBlockStore>(rootdir.path())); .loadOrCreate(config.path()), make_unique_ref<OnDiskBlockStore>(rootdir.path())
auto root = dev.Load(bf::path("/")); );
dynamic_pointer_move<CryDir>(root.get()).get()->children();
}
TEST_F(CryFsTest, UsingStrongKey2_CreatedRootdirIsLoadableAfterClosing) {
{
CryDevice dev(CryConfigLoader(make_unique_ref<MockConsole>()).loadOrCreate(config.path()), make_unique_ref<OnDiskBlockStore>(rootdir.path()));
} }
CryDevice dev(CryConfigLoader().loadOrCreate(config.path()), make_unique_ref<OnDiskBlockStore>(rootdir.path())); CryDevice dev(CryConfigLoader().loadOrCreate(config.path()), make_unique_ref<OnDiskBlockStore>(rootdir.path()));
auto root = dev.Load(bf::path("/")); auto root = dev.Load(bf::path("/"));

View File

@ -3,11 +3,14 @@
#include <messmer/cpp-utils/tempfile/TempFile.h> #include <messmer/cpp-utils/tempfile/TempFile.h>
#include "../../src/filesystem/CryDevice.h" #include "../../src/filesystem/CryDevice.h"
#include "../testutils/MockConsole.h"
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
using fspp::Device; using fspp::Device;
using ::testing::Return;
using ::testing::_;
using blockstore::testfake::FakeBlockStore; using blockstore::testfake::FakeBlockStore;
@ -21,10 +24,18 @@ public:
unique_ref<Device> createDevice() override { unique_ref<Device> createDevice() override {
auto blockStore = cpputils::make_unique_ref<FakeBlockStore>(); auto blockStore = cpputils::make_unique_ref<FakeBlockStore>();
auto config = CryConfigLoader().loadOrCreateForTest(configFile.path()); auto config = CryConfigLoader(mockConsole(), cpputils::Random::PseudoRandom())
.loadOrCreate(configFile.path());
return make_unique_ref<CryDevice>(std::move(config), std::move(blockStore)); return make_unique_ref<CryDevice>(std::move(config), std::move(blockStore));
} }
unique_ref<MockConsole> mockConsole() {
auto console = make_unique_ref<MockConsole>();
EXPECT_CALL(*console, ask(_, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*console, askYesNo(_)).WillRepeatedly(Return(true));
return console;
}
cpputils::TempFile configFile; cpputils::TempFile configFile;
}; };

View File

@ -0,0 +1,15 @@
#pragma once
#ifndef MESSMER_CRYFS_TEST_TESTUTILS_MOCKCONSOLE_H
#define MESSMER_CRYFS_TEST_TESTUTILS_MOCKCONSOLE_H
#include <messmer/cpp-utils/io/Console.h>
#include <google/gmock/gmock.h>
class MockConsole: public cpputils::Console {
public:
MOCK_METHOD1(print, void(const std::string&));
MOCK_METHOD2(ask, unsigned int(const std::string&, const std::vector<std::string>&));
MOCK_METHOD1(askYesNo, bool(const std::string&));
};
#endif