diff --git a/src/config/CryCipher.cpp b/src/config/CryCipher.cpp index 30c419b8..27ef6d14 100644 --- a/src/config/CryCipher.cpp +++ b/src/config/CryCipher.cpp @@ -2,11 +2,13 @@ #include #include +#include "crypto/inner/ConcreteInnerEncryptor.h" using std::vector; using std::string; using cpputils::unique_ref; using cpputils::make_unique_ref; +using cpputils::FixedSizeData; using blockstore::BlockStore; using std::shared_ptr; using std::make_shared; @@ -45,6 +47,10 @@ public: return Cipher::CreateKey(randomGenerator).ToString(); } + unique_ref createInnerConfigEncryptor(const FixedSizeData &key) const override { + return make_unique_ref>(key.take()); + } + private: optional _warning; }; @@ -80,7 +86,7 @@ const CryCipher& CryCiphers::find(const string &cipherName) { [cipherName] (const auto& element) { return element->cipherName() == cipherName; }); - ASSERT(found != CryCiphers::SUPPORTED_CIPHERS.end(), "Unknown Cipher"); + ASSERT(found != CryCiphers::SUPPORTED_CIPHERS.end(), "Unknown Cipher: "+cipherName); return **found; } diff --git a/src/config/CryCipher.h b/src/config/CryCipher.h index f3adcef0..c5958f2f 100644 --- a/src/config/CryCipher.h +++ b/src/config/CryCipher.h @@ -7,20 +7,13 @@ #include #include #include +#include "crypto/inner/InnerEncryptor.h" namespace cryfs { -class CryCipher { -public: - virtual ~CryCipher() {} +class CryCipher; - virtual std::string cipherName() const = 0; - virtual const boost::optional &warning() const = 0; - virtual cpputils::unique_ref createEncryptedBlockstore(cpputils::unique_ref baseBlockStore, const std::string &encKey) const = 0; - virtual std::string createKey(cpputils::RandomGenerator &randomGenerator) const = 0; -}; - -class CryCiphers { +class CryCiphers final { public: static std::vector supportedCipherNames(); @@ -36,6 +29,19 @@ private: static const std::vector> SUPPORTED_CIPHERS; }; + +class CryCipher { +public: + virtual ~CryCipher() {} + + virtual std::string cipherName() const = 0; + virtual const boost::optional &warning() const = 0; + virtual cpputils::unique_ref createEncryptedBlockstore(cpputils::unique_ref baseBlockStore, const std::string &encKey) const = 0; + virtual std::string createKey(cpputils::RandomGenerator &randomGenerator) const = 0; + virtual cpputils::unique_ref createInnerConfigEncryptor(const cpputils::FixedSizeData &key) const = 0; +}; + + } #endif diff --git a/src/config/CryConfigFile.cpp b/src/config/CryConfigFile.cpp index c66a9900..1f81fe05 100644 --- a/src/config/CryConfigFile.cpp +++ b/src/config/CryConfigFile.cpp @@ -39,16 +39,20 @@ optional CryConfigFile::load(const bf::path &path, const string & if (decrypted == none) { return none; } - CryConfig config = CryConfig::load(*decrypted); + CryConfig config = CryConfig::load(decrypted->data); + if (config.Cipher() != decrypted->cipherName) { + //TODO Test that this fails + LOG(ERROR) << "Inner cipher algorithm used to encrypt config file doesn't match config value"; + return none; + } return CryConfigFile(path, std::move(config), std::move(*encryptor)); } CryConfigFile CryConfigFile::create(const bf::path &path, CryConfig config, const string &password, const SCryptSettings &scryptSettings) { - using ConfigCipher = cpputils::AES256_GCM; // TODO Take cipher from config instead if (bf::exists(path)) { throw std::runtime_error("Config file exists already."); } - auto result = CryConfigFile(path, std::move(config), CryConfigEncryptorFactory::deriveKey(password, scryptSettings)); + auto result = CryConfigFile(path, std::move(config), CryConfigEncryptorFactory::deriveKey(config.Cipher(), password, scryptSettings)); result.save(); return result; } @@ -59,7 +63,7 @@ CryConfigFile::CryConfigFile(const bf::path &path, CryConfig config, unique_ref< void CryConfigFile::save() const { Data configData = _config.save(); - auto encrypted = _encryptor->encrypt(configData); + auto encrypted = _encryptor->encrypt(configData, _config.Cipher()); encrypted.StoreToFile(_path); } diff --git a/src/config/CryConfigLoader.cpp b/src/config/CryConfigLoader.cpp index b8b5f094..d07e0a41 100644 --- a/src/config/CryConfigLoader.cpp +++ b/src/config/CryConfigLoader.cpp @@ -34,6 +34,7 @@ optional CryConfigLoader::_loadConfig(const bf::path &filename) { return none; } if (_cipher != none && config->config()->Cipher() != *_cipher) { + //TODO Test this fails throw std::runtime_error("Filesystem uses "+config->config()->Cipher()+" cipher and not "+*_cipher+" as specified."); } return std::move(*config); diff --git a/src/config/crypto/CryConfigEncryptor.cpp b/src/config/crypto/CryConfigEncryptor.cpp index bf1b8f13..6f6c494c 100644 --- a/src/config/crypto/CryConfigEncryptor.cpp +++ b/src/config/crypto/CryConfigEncryptor.cpp @@ -1,45 +1,64 @@ #include "CryConfigEncryptor.h" #include -#include "OuterConfig.h" using std::string; using cpputils::unique_ref; +using cpputils::make_unique_ref; using cpputils::Data; using cpputils::RandomPadding; using cpputils::DerivedKeyConfig; +using cpputils::DerivedKey; +using cpputils::FixedSizeData; using boost::optional; using boost::none; using namespace cpputils::logging; namespace cryfs { - CryConfigEncryptor::CryConfigEncryptor(unique_ref innerEncryptor, OuterCipher::EncryptionKey outerKey, DerivedKeyConfig keyConfig) - : _innerEncryptor(std::move(innerEncryptor)), _outerKey(std::move(outerKey)), _keyConfig(std::move(keyConfig)) { + constexpr size_t CryConfigEncryptor::OuterKeySize; + constexpr size_t CryConfigEncryptor::MaxTotalKeySize; + + CryConfigEncryptor::CryConfigEncryptor(DerivedKey derivedKey) + : _derivedKey(std::move(derivedKey)) { } - Data CryConfigEncryptor::encrypt(const Data &plaintext) { - auto inner = _innerEncryptor->encrypt(plaintext); - auto padded = RandomPadding::add(inner, CONFIG_SIZE); - auto ciphertext = OuterCipher::encrypt(static_cast(padded.data()), padded.size(), _outerKey); - return OuterConfig{_keyConfig, std::move(ciphertext)}.serialize(); + Data CryConfigEncryptor::encrypt(const Data &plaintext, const string &cipherName) const { + InnerConfig innerConfig = _innerEncryptor(cipherName)->encrypt(plaintext); + Data serializedInnerConfig = innerConfig.serialize(); + OuterConfig outerConfig = _outerEncryptor()->encrypt(serializedInnerConfig); + return outerConfig.serialize(); } - optional CryConfigEncryptor::decrypt(const Data &data) { + optional CryConfigEncryptor::decrypt(const Data &data) const { + auto innerConfig = _loadInnerConfig(data); + if (innerConfig == none) { + return none; + } + auto plaintext = _innerEncryptor(innerConfig->cipherName)->decrypt(*innerConfig); + if (plaintext == none) { + return none; + } + return Decrypted{std::move(*plaintext), innerConfig->cipherName}; + } + + optional CryConfigEncryptor::_loadInnerConfig(const Data &data) const { auto outerConfig = OuterConfig::deserialize(data); if (outerConfig == none) { return none; } - return _decryptInnerConfig(outerConfig->encryptedInnerConfig); + auto serializedInnerConfig = _outerEncryptor()->decrypt(*outerConfig); + if(serializedInnerConfig == none) { + return none; + } + return InnerConfig::deserialize(*serializedInnerConfig); } - optional CryConfigEncryptor::_decryptInnerConfig(const Data &encryptedInnerConfig) { - auto inner = OuterCipher::decrypt(static_cast(encryptedInnerConfig.data()), encryptedInnerConfig.size(), _outerKey); - if(inner == none) { - return none; - } - auto depadded = RandomPadding::remove(*inner); - if(depadded == none) { - return none; - } - return _innerEncryptor->decrypt(*depadded); + unique_ref CryConfigEncryptor::_outerEncryptor() const { + auto outerKey = _derivedKey.key().take(); + return make_unique_ref(outerKey, _derivedKey.config()); + } + + unique_ref CryConfigEncryptor::_innerEncryptor(const string &cipherName) const { + auto innerKey = _derivedKey.key().drop(); + return CryCiphers::find(cipherName).createInnerConfigEncryptor(innerKey); } } diff --git a/src/config/crypto/CryConfigEncryptor.h b/src/config/crypto/CryConfigEncryptor.h index d81a03be..8b1fec8b 100644 --- a/src/config/crypto/CryConfigEncryptor.h +++ b/src/config/crypto/CryConfigEncryptor.h @@ -5,30 +5,39 @@ #include #include #include -#include "inner/InnerEncryptor.h" #include +#include #include +#include "inner/InnerEncryptor.h" +#include "outer/OuterEncryptor.h" +#include "../CryCipher.h" namespace cryfs { - //TODO Test + //TODO Test (whole crypto folder) //TODO Test that encrypted config data always has the same size, no matter how big the plaintext config data + //TODO Test that specified inner cipher is used (e.g. can't be decrypted with other cipher) //TODO Use own exception for cpputils::Serializer/cpputils::Deserializer errors and only catch them class CryConfigEncryptor { public: - using OuterCipher = cpputils::AES256_GCM; - static constexpr size_t CONFIG_SIZE = 1024; // Config data is grown to this size before encryption to hide its actual size + static constexpr size_t OuterKeySize = OuterEncryptor::Cipher::EncryptionKey::BINARY_LENGTH; + static constexpr size_t MaxTotalKeySize = OuterKeySize + CryCiphers::MAX_KEY_SIZE; - CryConfigEncryptor(cpputils::unique_ref innerEncryptor, OuterCipher::EncryptionKey outerKey, cpputils::DerivedKeyConfig keyConfig); + struct Decrypted { + cpputils::Data data; + std::string cipherName; + }; - cpputils::Data encrypt(const cpputils::Data &plaintext); - boost::optional decrypt(const cpputils::Data &data); + CryConfigEncryptor(cpputils::DerivedKey derivedKey); + + cpputils::Data encrypt(const cpputils::Data &plaintext, const std::string &cipherName) const; + boost::optional decrypt(const cpputils::Data &data) const; private: - boost::optional _decryptInnerConfig(const cpputils::Data &encryptedInnerConfig); + boost::optional _loadInnerConfig(const cpputils::Data &data) const; + cpputils::unique_ref _outerEncryptor() const; + cpputils::unique_ref _innerEncryptor(const std::string &cipherName) const; - cpputils::unique_ref _innerEncryptor; - OuterCipher::EncryptionKey _outerKey; - cpputils::DerivedKeyConfig _keyConfig; + cpputils::DerivedKey _derivedKey; }; } diff --git a/src/config/crypto/CryConfigEncryptorFactory.cpp b/src/config/crypto/CryConfigEncryptorFactory.cpp index 0b544890..f1e2f796 100644 --- a/src/config/crypto/CryConfigEncryptorFactory.cpp +++ b/src/config/crypto/CryConfigEncryptorFactory.cpp @@ -1,6 +1,6 @@ #include "CryConfigEncryptorFactory.h" #include -#include "OuterConfig.h" +#include "outer/OuterConfig.h" using namespace cpputils::logging; using boost::optional; @@ -11,37 +11,32 @@ using cpputils::Data; using cpputils::DerivedKey; using cpputils::DerivedKeyConfig; using cpputils::SCrypt; +using cpputils::SCryptSettings; using std::string; namespace cryfs { - constexpr size_t CryConfigEncryptorFactory::OuterKeySize; - constexpr size_t CryConfigEncryptorFactory::MaxTotalKeySize; - optional> CryConfigEncryptorFactory::loadKey(const Data &data, const string &password) { - using Cipher = cpputils::AES256_GCM; //TODO Allow other ciphers - auto outerConfig = OuterConfig::deserialize(data); if (outerConfig == none) { return none; } auto derivedKey = _deriveKey(outerConfig->keyConfig, password); - auto outerKey = derivedKey.key().take(); - auto innerKey = derivedKey.key().drop().take(); - return make_unique_ref( - make_unique_ref>(innerKey), - outerKey, - derivedKey.moveOutConfig() - ); + return make_unique_ref(std::move(derivedKey)); } - cpputils::DerivedKey + DerivedKey CryConfigEncryptorFactory::_deriveKey(const DerivedKeyConfig &keyConfig, const std::string &password) { //TODO It would be better, not to generate a MaxTotalKeySize key here, but to generate the outer key first, and then // (once we know which inner cipher was used) only generate as many key bytes as we need for the inner cipher. // This would need a change in the scrypt interface though, because right now we can't continue past key computations. - auto key = SCrypt().generateKeyFromConfig(password, keyConfig); - return DerivedKey(keyConfig, std::move(key)); + auto key = SCrypt().generateKeyFromConfig(password, keyConfig); + return DerivedKey(keyConfig, std::move(key)); + } + + unique_ref CryConfigEncryptorFactory::deriveKey(const string &cipherName, const string &password, const SCryptSettings &scryptSettings) { + auto derivedKey = cpputils::SCrypt().generateKey(password, scryptSettings); + return make_unique_ref(std::move(derivedKey)); } } diff --git a/src/config/crypto/CryConfigEncryptorFactory.h b/src/config/crypto/CryConfigEncryptorFactory.h index 46f0b305..81eb9e58 100644 --- a/src/config/crypto/CryConfigEncryptorFactory.h +++ b/src/config/crypto/CryConfigEncryptorFactory.h @@ -12,36 +12,16 @@ namespace cryfs { //TODO Test class CryConfigEncryptorFactory { public: - template - static cpputils::unique_ref deriveKey(const std::string &password, const cpputils::SCryptSettings &scryptSettings); + static cpputils::unique_ref deriveKey(const std::string &cipherName, const std::string &password, const cpputils::SCryptSettings &scryptSettings); static boost::optional> loadKey(const cpputils::Data &ciphertext, const std::string &password); private: - static constexpr size_t OuterKeySize = CryConfigEncryptor::OuterCipher::EncryptionKey::BINARY_LENGTH; - template static constexpr size_t TotalKeySize(); - static constexpr size_t MaxTotalKeySize = OuterKeySize + CryCiphers::MAX_KEY_SIZE; - static cpputils::DerivedKey _deriveKey(const cpputils::DerivedKeyConfig &keyConfig, const std::string &password); + static cpputils::DerivedKey _deriveKey(const cpputils::DerivedKeyConfig &keyConfig, const std::string &password); + static boost::optional _loadCipherName(const OuterEncryptor &outerEncryptor, const OuterConfig &outerConfig); }; - - template constexpr size_t CryConfigEncryptorFactory::TotalKeySize() { - return OuterKeySize + Cipher::EncryptionKey::BINARY_LENGTH; - } - - template - cpputils::unique_ref CryConfigEncryptorFactory::deriveKey(const std::string &password, const cpputils::SCryptSettings &scryptSettings) { - //TODO Use _deriveKey(keyConfig, password) instead and get rid of cpputils::SCryptSettings class in favor of cpputils::DerivedKeyConfig - auto derivedKey = cpputils::SCrypt().generateKey()>(password, scryptSettings); - auto outerKey = derivedKey.key().template take(); - auto innerKey = derivedKey.key().template drop(); - return cpputils::make_unique_ref( - cpputils::make_unique_ref>(innerKey), - outerKey, - derivedKey.moveOutConfig() - ); - } } #endif diff --git a/src/config/crypto/inner/ConcreteInnerEncryptor.h b/src/config/crypto/inner/ConcreteInnerEncryptor.h index 4bb7d884..714b2564 100644 --- a/src/config/crypto/inner/ConcreteInnerEncryptor.h +++ b/src/config/crypto/inner/ConcreteInnerEncryptor.h @@ -17,8 +17,9 @@ namespace cryfs { ConcreteInnerEncryptor(typename Cipher::EncryptionKey key); - cpputils::Data encrypt(const cpputils::Data &plaintext) const override; - boost::optional decrypt(const cpputils::Data &ciphertext) const override; + InnerConfig encrypt(const cpputils::Data &config) const override; + boost::optional decrypt(const InnerConfig &innerConfig) const override; + private: typename Cipher::EncryptionKey _key; @@ -30,16 +31,12 @@ namespace cryfs { } template - boost::optional ConcreteInnerEncryptor::decrypt(const cpputils::Data &ciphertext) const { - auto innerConfig = InnerConfig::deserialize(ciphertext); - if (innerConfig == boost::none) { + boost::optional ConcreteInnerEncryptor::decrypt(const InnerConfig &innerConfig) const { + if (innerConfig.cipherName != Cipher::NAME) { + cpputils::logging::LOG(cpputils::logging::ERROR) << "Initialized ConcreteInnerEncryptor with wrong cipher"; return boost::none; } - if (innerConfig->cipherName != Cipher::NAME) { - cpputils::logging::LOG(cpputils::logging::ERROR) << "Wrong inner cipher used"; - return boost::none; - } - auto decrypted = Cipher::decrypt(static_cast(innerConfig->encryptedConfig.data()), innerConfig->encryptedConfig.size(), _key); + auto decrypted = Cipher::decrypt(static_cast(innerConfig.encryptedConfig.data()), innerConfig.encryptedConfig.size(), _key); if (decrypted == boost::none) { return boost::none; } @@ -51,10 +48,10 @@ namespace cryfs { } template - cpputils::Data ConcreteInnerEncryptor::encrypt(const cpputils::Data &plaintext) const { - auto paddedPlaintext = cpputils::RandomPadding::add(plaintext, CONFIG_SIZE); - auto encrypted = Cipher::encrypt(static_cast(paddedPlaintext.data()), paddedPlaintext.size(), _key); - return InnerConfig{Cipher::NAME, std::move(encrypted)}.serialize(); + InnerConfig ConcreteInnerEncryptor::encrypt(const cpputils::Data &config) const { + auto padded = cpputils::RandomPadding::add(config, CONFIG_SIZE); + auto encrypted = Cipher::encrypt(static_cast(padded.data()), padded.size(), _key); + return InnerConfig{Cipher::NAME, std::move(encrypted)}; } } diff --git a/src/config/crypto/inner/InnerEncryptor.h b/src/config/crypto/inner/InnerEncryptor.h index 04d584e8..07edcd61 100644 --- a/src/config/crypto/inner/InnerEncryptor.h +++ b/src/config/crypto/inner/InnerEncryptor.h @@ -7,12 +7,13 @@ #include #include #include +#include "InnerConfig.h" namespace cryfs { class InnerEncryptor { public: - virtual cpputils::Data encrypt(const cpputils::Data &plaintext) const = 0; - virtual boost::optional decrypt(const cpputils::Data &plaintext) const = 0; + virtual InnerConfig encrypt(const cpputils::Data &plaintext) const = 0; + virtual boost::optional decrypt(const InnerConfig &innerConfig) const = 0; }; } diff --git a/src/config/crypto/OuterConfig.cpp b/src/config/crypto/outer/OuterConfig.cpp similarity index 100% rename from src/config/crypto/OuterConfig.cpp rename to src/config/crypto/outer/OuterConfig.cpp diff --git a/src/config/crypto/OuterConfig.h b/src/config/crypto/outer/OuterConfig.h similarity index 85% rename from src/config/crypto/OuterConfig.h rename to src/config/crypto/outer/OuterConfig.h index f6f4240e..5208c55f 100644 --- a/src/config/crypto/OuterConfig.h +++ b/src/config/crypto/outer/OuterConfig.h @@ -1,6 +1,6 @@ #pragma once -#ifndef CRYFS_OUTERCONFIG_H -#define CRYFS_OUTERCONFIG_H +#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_OUTER_OUTERCONFIG_H +#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_OUTER_OUTERCONFIG_H #include #include diff --git a/src/config/crypto/outer/OuterEncryptor.cpp b/src/config/crypto/outer/OuterEncryptor.cpp new file mode 100644 index 00000000..33dbd315 --- /dev/null +++ b/src/config/crypto/outer/OuterEncryptor.cpp @@ -0,0 +1,33 @@ +#include "OuterEncryptor.h" +#include +#include "OuterConfig.h" + +using std::string; +using cpputils::unique_ref; +using cpputils::Data; +using cpputils::RandomPadding; +using cpputils::DerivedKeyConfig; +using boost::optional; +using boost::none; +using namespace cpputils::logging; + +namespace cryfs { + OuterEncryptor::OuterEncryptor(Cipher::EncryptionKey key, const cpputils::DerivedKeyConfig &keyConfig) + : _key(std::move(key)), _keyConfig(std::move(keyConfig)) { + } + + OuterConfig OuterEncryptor::encrypt(const Data &plaintext) const { + auto padded = RandomPadding::add(plaintext, CONFIG_SIZE); + auto ciphertext = Cipher::encrypt(static_cast(padded.data()), padded.size(), _key); + return OuterConfig{_keyConfig, std::move(ciphertext)}; + } + + optional OuterEncryptor::decrypt(const OuterConfig &outerConfig) const { + ASSERT(outerConfig.keyConfig == _keyConfig, "OuterEncryptor was initialized with wrong key config"); + auto inner = Cipher::decrypt(static_cast(outerConfig.encryptedInnerConfig.data()), outerConfig.encryptedInnerConfig.size(), _key); + if(inner == none) { + return none; + } + return RandomPadding::remove(*inner); + } +} diff --git a/src/config/crypto/outer/OuterEncryptor.h b/src/config/crypto/outer/OuterEncryptor.h new file mode 100644 index 00000000..c5a3dc36 --- /dev/null +++ b/src/config/crypto/outer/OuterEncryptor.h @@ -0,0 +1,29 @@ +#pragma once +#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_OUTER_OUTERENCRYPTOR_H +#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_OUTER_OUTERENCRYPTOR_H + +#include +#include +#include +#include +#include "OuterConfig.h" + +namespace cryfs { + class OuterEncryptor { + public: + using Cipher = cpputils::AES256_GCM; + static constexpr size_t CONFIG_SIZE = 1024; // Config data is grown to this size before encryption to hide its actual size + + OuterEncryptor(Cipher::EncryptionKey key, const cpputils::DerivedKeyConfig &keyConfig); + + OuterConfig encrypt(const cpputils::Data &encryptedInnerConfig) const; + boost::optional decrypt(const OuterConfig &outerConfig) const; + + private: + + Cipher::EncryptionKey _key; + cpputils::DerivedKeyConfig _keyConfig; + }; +} + +#endif diff --git a/test/config/CryConfigFileTest.cpp b/test/config/CryConfigFileTest.cpp index 0e0a14e3..cbd34b42 100644 --- a/test/config/CryConfigFileTest.cpp +++ b/test/config/CryConfigFileTest.cpp @@ -4,6 +4,8 @@ #include #include +//TODO Test that config file is still loadable after changing the cipher and then storing it (i.e. it uses a different inner cipher but is still the same CryConfigFile instance) + using namespace cryfs; using cpputils::TempFile; using std::string; @@ -27,8 +29,14 @@ public: TempFile file; + CryConfig Config() { + CryConfig result; + result.SetCipher("aes-256-gcm"); + return result; + } + CryConfigFile CreateAndLoadEmpty(const string &password = "mypassword") { - Create(CryConfig(), password); + Create(Config(), password); return Load().value(); } @@ -40,6 +48,10 @@ public: return CryConfigFile::load(file.path(), password); } + void CreateWithCipher(const string &cipher) { + return CreateWithCipher(cipher, file); + } + void CreateWithCipher(const string &cipher, const TempFile &tempFile) { CryConfig cfg; cfg.SetCipher(cipher); @@ -48,7 +60,7 @@ public: }; TEST_F(CryConfigFileTest, DoesntLoadIfWrongPassword) { - Create(CryConfig(), "mypassword"); + Create(Config(), "mypassword"); auto loaded = Load("mypassword2"); EXPECT_EQ(none, loaded); } @@ -59,7 +71,7 @@ TEST_F(CryConfigFileTest, RootBlob_Init) { } TEST_F(CryConfigFileTest, RootBlob_CreateAndLoad) { - CryConfig cfg; + CryConfig cfg = Config(); cfg.SetRootBlob("rootblobid"); Create(std::move(cfg)); CryConfigFile loaded = Load().value(); @@ -80,7 +92,7 @@ TEST_F(CryConfigFileTest, EncryptionKey_Init) { } TEST_F(CryConfigFileTest, EncryptionKey_CreateAndLoad) { - CryConfig cfg; + CryConfig cfg = Config(); cfg.SetEncryptionKey("encryptionkey"); Create(std::move(cfg)); CryConfigFile loaded = Load().value(); @@ -97,30 +109,42 @@ TEST_F(CryConfigFileTest, EncryptionKey_SaveAndLoad) { TEST_F(CryConfigFileTest, Cipher_Init) { CryConfigFile created = CreateAndLoadEmpty(); - EXPECT_EQ("", created.config()->Cipher()); + EXPECT_EQ("aes-256-gcm", created.config()->Cipher()); } TEST_F(CryConfigFileTest, Cipher_CreateAndLoad) { - CryConfig cfg; - cfg.SetCipher("cipher"); + CryConfig cfg = Config(); + cfg.SetCipher("twofish-128-cfb"); Create(std::move(cfg)); CryConfigFile loaded = Load().value(); - EXPECT_EQ("cipher", loaded.config()->Cipher()); + EXPECT_EQ("twofish-128-cfb", loaded.config()->Cipher()); } TEST_F(CryConfigFileTest, Cipher_SaveAndLoad) { CryConfigFile created = CreateAndLoadEmpty(); - created.config()->SetCipher("cipher"); + created.config()->SetCipher("twofish-128-cfb"); created.save(); CryConfigFile loaded = Load().value(); - EXPECT_EQ("cipher", loaded.config()->Cipher()); + EXPECT_EQ("twofish-128-cfb", loaded.config()->Cipher()); } //Test that the encrypted config file has the same size, no matter how big the plaintext config data. TEST_F(CryConfigFileTest, ConfigFileHasFixedSize) { TempFile file1(false); TempFile file2(false); - CreateWithCipher("short", file1); - CreateWithCipher("long_cipher_name_that_causes_the_plaintext_config_data_to_be_larger", file2); + //It is important to have different cipher name lengths here, because they're on the outer encryption level. + //So this ensures that there also is a padding happening on the outer encryption level. + CreateWithCipher("aes-128-gcm", file1); // Short cipher name and short key + CreateWithCipher("twofish-256-cfb", file2); // Long cipher name and long key EXPECT_EQ(bf::file_size(file1.path()), bf::file_size(file2.path())); } + +TEST_F(CryConfigFileTest, CanSaveAndLoadModififedCipher) { + CreateWithCipher("aes-256-gcm"); + CryConfigFile created = Load().value(); + EXPECT_EQ("aes-256-gcm", created.config()->Cipher()); + created.config()->SetCipher("twofish-128-cfb"); + created.save(); + CryConfigFile loaded = Load().value(); + EXPECT_EQ("twofish-128-cfb", loaded.config()->Cipher()); +} diff --git a/test/config/CryConfigLoaderTest.cpp b/test/config/CryConfigLoaderTest.cpp index 52c77f2a..aa45ab44 100644 --- a/test/config/CryConfigLoaderTest.cpp +++ b/test/config/CryConfigLoaderTest.cpp @@ -114,7 +114,7 @@ TEST_F(CryConfigLoaderTest, EncryptionKey_Create) { } TEST_F(CryConfigLoaderTest, Cipher_Load) { - CreateWithCipher("ciphername"); + CreateWithCipher("twofish-128-cfb"); auto loaded = Load().value(); EXPECT_EQ("ciphername", loaded.config()->Cipher()); }