diff --git a/src/CryCipher.cpp b/src/CryCipher.cpp index 41e263d6..40770bc6 100644 --- a/src/CryCipher.cpp +++ b/src/CryCipher.cpp @@ -10,6 +10,8 @@ using cpputils::make_unique_ref; using blockstore::BlockStore; using std::shared_ptr; using std::make_shared; +using boost::optional; +using boost::none; using namespace cryfs; using namespace blockstore::encrypted; @@ -19,13 +21,17 @@ class CryCipherInstance: public CryCipher { public: BOOST_CONCEPT_ASSERT((CipherConcept)); - CryCipherInstance(const std::string &cipherName): _cipherName(cipherName) { + CryCipherInstance(const std::string &cipherName, const optional warning = none): _cipherName(cipherName), _warning(warning) { } - string cipherName() const override { + const string &cipherName() const override { return _cipherName; } + const optional &warning() const override { + return _warning; + } + unique_ref createEncryptedBlockstore(unique_ref baseBlockStore, const string &encKey) const override { return make_unique_ref>(std::move(baseBlockStore), Cipher::EncryptionKey::FromString(encKey)); } @@ -36,30 +42,33 @@ public: private: string _cipherName; + optional _warning; }; +const string INTEGRITY_WARNING = "This cipher does not ensure integrity."; + //We have to use shared_ptr instead of unique_ref, because c++ initializer_list needs copyable values const vector> CryCiphers::SUPPORTED_CIPHERS = { make_shared>("aes-256-gcm"), - make_shared>("aes-256-cfb"), + make_shared>("aes-256-cfb", INTEGRITY_WARNING), make_shared>("aes-128-gcm"), - make_shared>("aes-128-cfb"), + make_shared>("aes-128-cfb", INTEGRITY_WARNING), make_shared>("twofish-256-gcm"), - make_shared>("twofish-256-cfb"), + make_shared>("twofish-256-cfb", INTEGRITY_WARNING), make_shared>("twofish-128-gcm"), - make_shared>("twofish-128-cfb"), + make_shared>("twofish-128-cfb", INTEGRITY_WARNING), make_shared>("serpent-256-gcm"), - make_shared>("serpent-256-cfb"), + make_shared>("serpent-256-cfb", INTEGRITY_WARNING), make_shared>("serpent-128-gcm"), - make_shared>("serpent-128-cfb"), + make_shared>("serpent-128-cfb", INTEGRITY_WARNING), make_shared>("cast-256-gcm"), - make_shared>("cast-256-cfb"), + make_shared>("cast-256-cfb", INTEGRITY_WARNING), make_shared>("mars-448-gcm"), - make_shared>("mars-448-cfb"), + make_shared>("mars-448-cfb", INTEGRITY_WARNING), make_shared>("mars-256-gcm"), - make_shared>("mars-256-cfb"), + make_shared>("mars-256-cfb", INTEGRITY_WARNING), make_shared>("mars-128-gcm"), - make_shared>("mars-128-cfb") + make_shared>("mars-128-cfb", INTEGRITY_WARNING) }; const CryCipher& CryCiphers::find(const string &cipherName) { @@ -71,7 +80,7 @@ const CryCipher& CryCiphers::find(const string &cipherName) { return **found; } -vector CryCiphers::supportedCiphers() { +vector CryCiphers::supportedCipherNames() { vector result; for (const auto& cipher : CryCiphers::SUPPORTED_CIPHERS) { result.push_back(cipher->cipherName()); diff --git a/src/CryCipher.h b/src/CryCipher.h index 06ae099c..cdc5221c 100644 --- a/src/CryCipher.h +++ b/src/CryCipher.h @@ -10,14 +10,15 @@ namespace cryfs { class CryCipher { public: - virtual std::string cipherName() const = 0; + virtual const 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() const = 0; }; class CryCiphers { public: - static std::vector supportedCiphers(); + static std::vector supportedCipherNames(); static const CryCipher& find(const std::string &cipherName); diff --git a/src/CryConfigLoader.cpp b/src/CryConfigLoader.cpp index 2bcbc36a..4ee973cf 100644 --- a/src/CryConfigLoader.cpp +++ b/src/CryConfigLoader.cpp @@ -43,9 +43,23 @@ void CryConfigLoader::_initializeConfigWithWeakKey(CryConfig *config) { } void CryConfigLoader::_generateCipher(CryConfig *config) { - vector ciphers = CryCiphers::supportedCiphers(); - int cipherIndex = _console->ask("Which block cipher do you want to use?", ciphers); - config->SetCipher(ciphers[cipherIndex]); + vector ciphers = CryCiphers::supportedCipherNames(); + string cipherName = ""; + bool askAgain = true; + while(askAgain) { + int cipherIndex = _console->ask("Which block cipher do you want to use?", ciphers); + cipherName = ciphers[cipherIndex]; + askAgain = !_showWarningForCipherAndReturnIfOk(cipherName); + }; + config->SetCipher(cipherName); +} + +bool CryConfigLoader::_showWarningForCipherAndReturnIfOk(const string &cipherName) { + auto warning = CryCiphers::find(cipherName).warning(); + if (warning == boost::none) { + return true; + } + return _console->askYesNo(string() + (*warning) + " Do you want to take this cipher nevertheless?"); } void CryConfigLoader::_generateEncKey(CryConfig *config) { diff --git a/src/CryConfigLoader.h b/src/CryConfigLoader.h index 55c8a8be..90ea5cba 100644 --- a/src/CryConfigLoader.h +++ b/src/CryConfigLoader.h @@ -35,6 +35,8 @@ private: void _generateWeakEncKey(CryConfig *config); // TODO Rename to _generateTestEncKey void _generateTestCipher(CryConfig *config); + bool _showWarningForCipherAndReturnIfOk(const std::string &cipherName); + cpputils::unique_ref _console; };