2015-11-11 20:03:05 +01:00
|
|
|
#include <google/gtest/gtest.h>
|
|
|
|
#include "../../../../src/config/crypto/inner/ConcreteInnerEncryptor.h"
|
|
|
|
#include <messmer/cpp-utils/crypto/symmetric/ciphers.h>
|
|
|
|
#include <messmer/cpp-utils/data/DataFixture.h>
|
|
|
|
#include <boost/optional/optional_io.hpp>
|
|
|
|
|
|
|
|
using std::ostream;
|
|
|
|
using boost::none;
|
|
|
|
using cpputils::Data;
|
|
|
|
using cpputils::DataFixture;
|
|
|
|
using cpputils::unique_ref;
|
|
|
|
using cpputils::make_unique_ref;
|
|
|
|
using cpputils::AES256_GCM;
|
|
|
|
using cpputils::AES256_CFB;
|
|
|
|
using cpputils::Twofish128_CFB;
|
|
|
|
using namespace cryfs;
|
|
|
|
|
|
|
|
// This is needed for google test
|
|
|
|
namespace boost {
|
2015-11-11 20:58:09 +01:00
|
|
|
inline ostream &operator<<(ostream &stream, const Data &) {
|
2015-11-11 20:03:05 +01:00
|
|
|
return stream << "cpputils::Data()";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ConcreteInnerEncryptorTest : public ::testing::Test {
|
|
|
|
public:
|
|
|
|
template<class Cipher>
|
|
|
|
unique_ref<InnerEncryptor> makeInnerEncryptor() {
|
|
|
|
auto key = DataFixture::generateFixedSize<Cipher::EncryptionKey::BINARY_LENGTH>();
|
|
|
|
return make_unique_ref<ConcreteInnerEncryptor<Cipher>>(key);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(ConcreteInnerEncryptorTest, EncryptAndDecrypt_AES) {
|
|
|
|
auto encryptor = makeInnerEncryptor<AES256_GCM>();
|
|
|
|
InnerConfig encrypted = encryptor->encrypt(DataFixture::generate(200));
|
|
|
|
Data decrypted = encryptor->decrypt(encrypted).value();
|
|
|
|
EXPECT_EQ(DataFixture::generate(200), decrypted);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ConcreteInnerEncryptorTest, EncryptAndDecrypt_Twofish) {
|
|
|
|
auto encryptor = makeInnerEncryptor<Twofish128_CFB>();
|
|
|
|
InnerConfig encrypted = encryptor->encrypt(DataFixture::generate(200));
|
|
|
|
Data decrypted = encryptor->decrypt(encrypted).value();
|
|
|
|
EXPECT_EQ(DataFixture::generate(200), decrypted);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ConcreteInnerEncryptorTest, EncryptAndDecrypt_EmptyData) {
|
|
|
|
auto encryptor = makeInnerEncryptor<AES256_GCM>();
|
|
|
|
InnerConfig encrypted = encryptor->encrypt(Data(0));
|
|
|
|
Data decrypted = encryptor->decrypt(encrypted).value();
|
|
|
|
EXPECT_EQ(Data(0), decrypted);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ConcreteInnerEncryptorTest, DoesntDecryptWithWrongCipherName) {
|
|
|
|
auto encryptor = makeInnerEncryptor<Twofish128_CFB>();
|
|
|
|
InnerConfig encrypted = encryptor->encrypt(Data(0));
|
|
|
|
encrypted.cipherName = AES256_CFB::NAME;
|
|
|
|
auto decrypted = encryptor->decrypt(encrypted);
|
|
|
|
EXPECT_EQ(none, decrypted);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ConcreteInnerEncryptorTest, InvalidCiphertext) {
|
|
|
|
auto encryptor = makeInnerEncryptor<AES256_GCM>();
|
|
|
|
InnerConfig encrypted = encryptor->encrypt(DataFixture::generate(200));
|
|
|
|
*(char*)encrypted.encryptedConfig.data() = *(char*)encrypted.encryptedConfig.data()+1; //Modify ciphertext
|
|
|
|
auto decrypted = encryptor->decrypt(encrypted);
|
|
|
|
EXPECT_EQ(none, decrypted);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ConcreteInnerEncryptorTest, DoesntEncryptWhenTooLarge) {
|
|
|
|
auto encryptor = makeInnerEncryptor<AES256_GCM>();
|
|
|
|
EXPECT_THROW(
|
|
|
|
encryptor->encrypt(DataFixture::generate(2000)),
|
|
|
|
std::runtime_error
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ConcreteInnerEncryptorTest, EncryptionIsFixedSize) {
|
|
|
|
auto encryptor = makeInnerEncryptor<AES256_GCM>();
|
2015-11-11 20:58:09 +01:00
|
|
|
InnerConfig encrypted1 = encryptor->encrypt(DataFixture::generate(100));
|
|
|
|
InnerConfig encrypted2 = encryptor->encrypt(DataFixture::generate(200));
|
|
|
|
InnerConfig encrypted3 = encryptor->encrypt(Data(0));
|
2015-11-11 20:03:05 +01:00
|
|
|
|
|
|
|
EXPECT_EQ(encrypted1.encryptedConfig.size(), encrypted2.encryptedConfig.size());
|
2015-11-11 20:58:09 +01:00
|
|
|
EXPECT_EQ(encrypted1.encryptedConfig.size(), encrypted3.encryptedConfig.size());
|
2015-11-11 20:03:05 +01:00
|
|
|
}
|