diff --git a/cc/hybrid/BUILD.bazel b/cc/hybrid/BUILD.bazel index 2254ae6bd67fc06474af1381941b936a85309b50..01f15d7adc1fe58f5e14d6f9d9f08e980a95fa4c 100644 --- a/cc/hybrid/BUILD.bazel +++ b/cc/hybrid/BUILD.bazel @@ -412,13 +412,14 @@ cc_test( ":ecies_aead_hkdf_private_key_manager", ":ecies_aead_hkdf_public_key_manager", ":hybrid_key_templates", - "//cc:core/private_key_manager_impl", "//cc:hybrid_decrypt", "//cc/aead:aead_key_templates", "//cc/aead:aes_ctr_hmac_aead_key_manager", "//cc/aead:aes_gcm_key_manager", + "//cc/subtle:hybrid_test_util", "//cc/util:status", "//cc/util:statusor", + "//cc/util:test_matchers", "//cc/util:test_util", "//proto:aes_eax_cc_proto", "//proto:common_cc_proto", @@ -438,9 +439,11 @@ cc_test( ":ecies_aead_hkdf_public_key_manager", "//cc:hybrid_encrypt", "//cc:registry", + "//cc/aead:aead_key_templates", "//cc/aead:aes_gcm_key_manager", "//cc/util:status", "//cc/util:statusor", + "//cc/util:test_matchers", "//cc/util:test_util", "//proto:aes_eax_cc_proto", "//proto:common_cc_proto", diff --git a/cc/hybrid/CMakeLists.txt b/cc/hybrid/CMakeLists.txt index c6f3230322c16b35b7ae7287e27f8107e000f6ce..74cc3c0ae653b4a378b938d717bf51a055aec80f 100644 --- a/cc/hybrid/CMakeLists.txt +++ b/cc/hybrid/CMakeLists.txt @@ -342,13 +342,14 @@ tink_cc_test( tink::hybrid::ecies_aead_hkdf_public_key_manager tink::hybrid::hybrid_key_templates tink::core::hybrid_decrypt - tink::core::private_key_manager_impl tink::aead::aead_key_templates tink::aead::aes_ctr_hmac_aead_key_manager tink::aead::aes_gcm_key_manager tink::util::status tink::util::statusor + tink::util::test_matchers tink::util::test_util + tink::subtle::hybrid_test_util tink::proto::aes_eax_cc_proto tink::proto::common_cc_proto tink::proto::ecies_aead_hkdf_cc_proto @@ -359,12 +360,15 @@ tink_cc_test( NAME ecies_aead_hkdf_public_key_manager_test SRCS ecies_aead_hkdf_public_key_manager_test.cc DEPS + tink::hybrid::ecies_aead_hkdf_private_key_manager tink::hybrid::ecies_aead_hkdf_public_key_manager tink::core::hybrid_encrypt tink::core::registry + tink::aead::aead_key_templates tink::aead::aes_gcm_key_manager tink::util::status tink::util::statusor + tink::util::test_matchers tink::util::test_util tink::proto::aes_eax_cc_proto tink::proto::common_cc_proto diff --git a/cc/hybrid/ecies_aead_hkdf_private_key_manager_test.cc b/cc/hybrid/ecies_aead_hkdf_private_key_manager_test.cc index d67efbd9f152c5742bba9133b75685e5d6091f77..5f88ed9d60e6d5fe49ab626426c11087593fdc39 100644 --- a/cc/hybrid/ecies_aead_hkdf_private_key_manager_test.cc +++ b/cc/hybrid/ecies_aead_hkdf_private_key_manager_test.cc @@ -16,18 +16,19 @@ #include "tink/hybrid/ecies_aead_hkdf_private_key_manager.h" -#include "tink/core/private_key_manager_impl.h" -#include "tink/hybrid_decrypt.h" -#include "tink/registry.h" +#include "gtest/gtest.h" #include "tink/aead/aead_key_templates.h" #include "tink/aead/aes_ctr_hmac_aead_key_manager.h" #include "tink/aead/aes_gcm_key_manager.h" #include "tink/hybrid/ecies_aead_hkdf_public_key_manager.h" #include "tink/hybrid/hybrid_key_templates.h" +#include "tink/hybrid_decrypt.h" +#include "tink/registry.h" +#include "tink/subtle/hybrid_test_util.h" #include "tink/util/status.h" #include "tink/util/statusor.h" +#include "tink/util/test_matchers.h" #include "tink/util/test_util.h" -#include "gtest/gtest.h" #include "proto/aes_eax.pb.h" #include "proto/common.pb.h" #include "proto/ecies_aead_hkdf.pb.h" @@ -36,369 +37,235 @@ namespace crypto { namespace tink { -using google::crypto::tink::AesEaxKey; -using google::crypto::tink::EciesAeadHkdfKeyFormat; -using google::crypto::tink::EciesAeadHkdfPrivateKey; -using google::crypto::tink::EcPointFormat; -using google::crypto::tink::EllipticCurveType; -using google::crypto::tink::HashType; -using google::crypto::tink::KeyData; +using ::crypto::tink::test::IsOk; +using ::crypto::tink::test::StatusIs; +using ::google::crypto::tink::EciesAeadHkdfKeyFormat; +using ::google::crypto::tink::EciesAeadHkdfPrivateKey; +using ::google::crypto::tink::EciesAeadHkdfPublicKey; +using ::google::crypto::tink::EcPointFormat; +using ::google::crypto::tink::EllipticCurveType; +using ::google::crypto::tink::HashType; +using ::google::crypto::tink::KeyData; +using ::testing::Eq; +using ::testing::IsEmpty; +using ::testing::Not; namespace { -class EciesAeadHkdfPrivateKeyManagerTest : public ::testing::Test { - protected: - static void SetUpTestSuite() { - ASSERT_TRUE(Registry::RegisterKeyTypeManager( - absl::make_unique<AesGcmKeyManager>(), true) - .ok()); - ASSERT_TRUE(Registry::RegisterKeyManager( - absl::make_unique<AesCtrHmacAeadKeyManager>(), true) - .ok()); - } - - std::string key_type_prefix = "type.googleapis.com/"; - std::string ecies_private_key_type = - "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey"; -}; - -// Checks whether given key is compatible with the given format. -void CheckNewKey(const EciesAeadHkdfPrivateKey& ecies_key, - const EciesAeadHkdfKeyFormat& key_format) { - EciesAeadHkdfPrivateKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridDecrypt>(&key_type_manager); - EXPECT_EQ(0, ecies_key.version()); - EXPECT_TRUE(ecies_key.has_public_key()); - EXPECT_GT(ecies_key.key_value().length(), 0); - EXPECT_EQ(0, ecies_key.public_key().version()); - EXPECT_GT(ecies_key.public_key().x().length(), 0); - EXPECT_GT(ecies_key.public_key().y().length(), 0); - EXPECT_EQ(ecies_key.public_key().params().SerializeAsString(), - key_format.params().SerializeAsString()); - auto primitive_result = key_manager->GetPrimitive(ecies_key); - EXPECT_TRUE(primitive_result.ok()) << primitive_result.status(); +TEST(EciesAeadHkdfPrivateKeyManagerTest, Basics) { + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().get_version(), Eq(0)); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().key_material_type(), + Eq(KeyData::ASYMMETRIC_PRIVATE)); + EXPECT_THAT( + EciesAeadHkdfPrivateKeyManager().get_key_type(), + Eq("type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey")); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateEmptyKey) { + EXPECT_THAT( + EciesAeadHkdfPrivateKeyManager().ValidateKey(EciesAeadHkdfPrivateKey()), + StatusIs(util::error::INVALID_ARGUMENT)); +} + +EciesAeadHkdfKeyFormat CreateValidKeyFormat() { + EciesAeadHkdfKeyFormat key_format; + key_format.mutable_params()->set_ec_point_format(EcPointFormat::UNCOMPRESSED); + auto dem_params = key_format.mutable_params()->mutable_dem_params(); + *(dem_params->mutable_aead_dem()) = AeadKeyTemplates::Aes128Gcm(); + auto kem_params = key_format.mutable_params()->mutable_kem_params(); + kem_params->set_curve_type(EllipticCurveType::NIST_P256); + kem_params->set_hkdf_hash_type(HashType::SHA256); + kem_params->set_hkdf_salt(""); + return key_format; } -TEST_F(EciesAeadHkdfPrivateKeyManagerTest, testBasic) { - EciesAeadHkdfPrivateKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridDecrypt>(&key_type_manager); +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyFormat) { + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKeyFormat( + CreateValidKeyFormat()), + IsOk()); +} - EXPECT_EQ(0, key_manager->get_version()); - EXPECT_EQ("type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey", - key_manager->get_key_type()); - EXPECT_TRUE(key_manager->DoesSupport(key_manager->get_key_type())); +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyFormatNoPoint) { + EciesAeadHkdfKeyFormat key_format = CreateValidKeyFormat(); + key_format.mutable_params()->set_ec_point_format( + EcPointFormat::UNKNOWN_FORMAT); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKeyFormat(key_format), + StatusIs(util::error::INVALID_ARGUMENT)); } -TEST_F(EciesAeadHkdfPrivateKeyManagerTest, testKeyDataErrors) { - EciesAeadHkdfPrivateKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridDecrypt>(&key_type_manager); - - { // Bad key type. - KeyData key_data; - std::string bad_key_type = - "type.googleapis.com/google.crypto.tink.SomeOtherKey"; - key_data.set_type_url(bad_key_type); - auto result = key_manager->GetPrimitive(key_data); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not supported", - result.status().error_message()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, bad_key_type, - result.status().error_message()); - } - - { // Bad key value. - KeyData key_data; - key_data.set_type_url(ecies_private_key_type); - key_data.set_value("some bad serialized proto"); - auto result = key_manager->GetPrimitive(key_data); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not parse", - result.status().error_message()); - } - - { // Bad version. - KeyData key_data; - EciesAeadHkdfPrivateKey key; - key.set_version(1); - key_data.set_type_url(ecies_private_key_type); - key_data.set_value(key.SerializeAsString()); - auto result = key_manager->GetPrimitive(key_data); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "version", - result.status().error_message()); - } +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyFormatNoDem) { + EciesAeadHkdfKeyFormat key_format = CreateValidKeyFormat(); + key_format.mutable_params()->mutable_dem_params()->clear_aead_dem(); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKeyFormat(key_format), + StatusIs(util::error::INVALID_ARGUMENT)); } -TEST_F(EciesAeadHkdfPrivateKeyManagerTest, testKeyMessageErrors) { - EciesAeadHkdfPrivateKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridDecrypt>(&key_type_manager); - - { // Bad protobuffer. - AesEaxKey key; - auto result = key_manager->GetPrimitive(key); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "AesEaxKey", - result.status().error_message()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not supported", - result.status().error_message()); - } +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyFormatNoKemCurve) { + EciesAeadHkdfKeyFormat key_format = CreateValidKeyFormat(); + key_format.mutable_params()->mutable_kem_params()->set_curve_type( + EllipticCurveType::UNKNOWN_CURVE); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKeyFormat(key_format), + StatusIs(util::error::INVALID_ARGUMENT)); } -TEST_F(EciesAeadHkdfPrivateKeyManagerTest, testPrimitives) { - std::string plaintext = "some plaintext"; - std::string context_info = "some context info"; - EciesAeadHkdfPublicKeyManager public_key_type_manager; - EciesAeadHkdfPrivateKeyManager private_key_type_manager; - auto public_key_manager = - internal::MakeKeyManager<HybridEncrypt>(&public_key_type_manager); - auto private_key_manager = - internal::MakePrivateKeyManager<HybridDecrypt>(&private_key_type_manager, - &public_key_type_manager); - - EciesAeadHkdfPrivateKey key = test::GetEciesAesGcmHkdfTestKey( - EllipticCurveType::NIST_P256, EcPointFormat::UNCOMPRESSED, - HashType::SHA256, 32); - auto hybrid_encrypt = std::move(public_key_manager->GetPrimitive( - key.public_key()).ValueOrDie()); - std::string ciphertext = - hybrid_encrypt->Encrypt(plaintext, context_info).ValueOrDie(); - - { // Using Key proto. - auto result = private_key_manager->GetPrimitive(key); - EXPECT_TRUE(result.ok()) << result.status(); - auto hybrid_decrypt = std::move(result.ValueOrDie()); - auto decrypt_result = hybrid_decrypt->Decrypt(ciphertext, context_info); - EXPECT_TRUE(decrypt_result.ok()) << decrypt_result.status(); - } - - { // Using KeyData proto. - KeyData key_data; - key_data.set_type_url(ecies_private_key_type); - key_data.set_value(key.SerializeAsString()); - auto result = private_key_manager->GetPrimitive(key_data); - EXPECT_TRUE(result.ok()) << result.status(); - auto hybrid_decrypt = std::move(result.ValueOrDie()); - auto decrypt_result = hybrid_decrypt->Decrypt(ciphertext, context_info); - EXPECT_TRUE(decrypt_result.ok()) << decrypt_result.status(); - } +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyFormatNoKemHash) { + EciesAeadHkdfKeyFormat key_format = CreateValidKeyFormat(); + key_format.mutable_params()->mutable_kem_params()->set_hkdf_hash_type( + HashType::UNKNOWN_HASH); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKeyFormat(key_format), + StatusIs(util::error::INVALID_ARGUMENT)); } -TEST_F(EciesAeadHkdfPrivateKeyManagerTest, testNewKeyCreation) { - EciesAeadHkdfPublicKeyManager public_key_type_manager; - EciesAeadHkdfPrivateKeyManager private_key_type_manager; - auto public_key_manager = - internal::MakeKeyManager<HybridEncrypt>(&public_key_type_manager); - auto private_key_manager = - internal::MakePrivateKeyManager<HybridDecrypt>(&private_key_type_manager, - &public_key_type_manager); - const KeyFactory& key_factory = private_key_manager->get_key_factory(); - - { // Via NewKey(format_proto). - EciesAeadHkdfKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128Gcm().value())); - auto result = key_factory.NewKey(key_format); - EXPECT_TRUE(result.ok()) << result.status(); - auto key = std::move(result.ValueOrDie()); - ASSERT_EQ(ecies_private_key_type, key_type_prefix + key->GetTypeName()); - std::unique_ptr<EciesAeadHkdfPrivateKey> ecies_key( - reinterpret_cast<EciesAeadHkdfPrivateKey*>(key.release())); - CheckNewKey(*ecies_key, key_format); - } - - { // Via NewKey(format_proto). - EciesAeadHkdfKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - HybridKeyTemplates::EciesP256CompressedHkdfHmacSha256Aes128Gcm() - .value())); - auto result = key_factory.NewKey(key_format); - EXPECT_TRUE(result.ok()) << result.status(); - auto key = std::move(result.ValueOrDie()); - ASSERT_EQ(ecies_private_key_type, key_type_prefix + key->GetTypeName()); - std::unique_ptr<EciesAeadHkdfPrivateKey> ecies_key( - reinterpret_cast<EciesAeadHkdfPrivateKey*>(key.release())); - CheckNewKey(*ecies_key, key_format); - } - - { // Via NewKey(serialized_format_proto). - EciesAeadHkdfKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128CtrHmacSha256() - .value())); - auto result = key_factory.NewKey(key_format.SerializeAsString()); - EXPECT_TRUE(result.ok()) << result.status(); - auto key = std::move(result.ValueOrDie()); - ASSERT_EQ(ecies_private_key_type, key_type_prefix + key->GetTypeName()); - std::unique_ptr<EciesAeadHkdfPrivateKey> ecies_key( - reinterpret_cast<EciesAeadHkdfPrivateKey*>(key.release())); - CheckNewKey(*ecies_key, key_format); - } - - { // Via NewKey(serialized_format_proto). - EciesAeadHkdfKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - HybridKeyTemplates:: - EciesP256CompressedHkdfHmacSha256Aes128CtrHmacSha256() - .value())); - auto result = key_factory.NewKey(key_format.SerializeAsString()); - EXPECT_TRUE(result.ok()) << result.status(); - auto key = std::move(result.ValueOrDie()); - ASSERT_EQ(ecies_private_key_type, key_type_prefix + key->GetTypeName()); - std::unique_ptr<EciesAeadHkdfPrivateKey> ecies_key( - reinterpret_cast<EciesAeadHkdfPrivateKey*>(key.release())); - CheckNewKey(*ecies_key, key_format); - } - - { // Via NewKeyData(serialized_format_proto). - EciesAeadHkdfKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128CtrHmacSha256() - .value())); - auto result = key_factory.NewKeyData(key_format.SerializeAsString()); - EXPECT_TRUE(result.ok()) << result.status(); - auto key_data = std::move(result.ValueOrDie()); - EXPECT_EQ(ecies_private_key_type, key_data->type_url()); - EXPECT_EQ(KeyData::ASYMMETRIC_PRIVATE, key_data->key_material_type()); - EciesAeadHkdfPrivateKey ecies_key; - ASSERT_TRUE(ecies_key.ParseFromString(key_data->value())); - CheckNewKey(ecies_key, key_format); - } +TEST(EciesAeadHkdfPrivateKeyManagerTest, CreateKey) { + EciesAeadHkdfKeyFormat key_format = CreateValidKeyFormat(); + ASSERT_THAT(EciesAeadHkdfPrivateKeyManager().CreateKey(key_format).status(), + IsOk()); + EciesAeadHkdfPrivateKey key = + EciesAeadHkdfPrivateKeyManager().CreateKey(key_format).ValueOrDie(); + EXPECT_THAT(key.public_key().params().kem_params().curve_type(), + Eq(key_format.params().kem_params().curve_type())); + EXPECT_THAT(key.public_key().params().kem_params().hkdf_hash_type(), + Eq(key_format.params().kem_params().hkdf_hash_type())); + EXPECT_THAT(key.public_key().params().dem_params().aead_dem().type_url(), + Eq(key_format.params().dem_params().aead_dem().type_url())); + EXPECT_THAT(key.public_key().params().dem_params().aead_dem().value(), + Eq(key_format.params().dem_params().aead_dem().value())); + EXPECT_THAT( + key.public_key().params().dem_params().aead_dem().output_prefix_type(), + Eq(key_format.params().dem_params().aead_dem().output_prefix_type())); + + EXPECT_THAT(key.public_key().x(), Not(IsEmpty())); + EXPECT_THAT(key.public_key().y(), Not(IsEmpty())); + EXPECT_THAT(key.key_value(), Not(IsEmpty())); } -TEST_F(EciesAeadHkdfPrivateKeyManagerTest, testPublicKeyExtraction) { - EciesAeadHkdfPublicKeyManager public_key_type_manager; - EciesAeadHkdfPrivateKeyManager private_key_type_manager; - auto public_key_manager = - internal::MakeKeyManager<HybridEncrypt>(&public_key_type_manager); - auto private_key_manager = - internal::MakePrivateKeyManager<HybridDecrypt>(&private_key_type_manager, - &public_key_type_manager); - auto private_key_factory = dynamic_cast<const PrivateKeyFactory*>( - &(private_key_manager->get_key_factory())); - ASSERT_NE(private_key_factory, nullptr); - - auto new_key_result = private_key_factory->NewKey( - HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128CtrHmacSha256().value()); - std::unique_ptr<EciesAeadHkdfPrivateKey> new_key( - reinterpret_cast<EciesAeadHkdfPrivateKey*>( - new_key_result.ValueOrDie().release())); - auto public_key_data_result = private_key_factory->GetPublicKeyData( - new_key->SerializeAsString()); - EXPECT_TRUE(public_key_data_result.ok()) << public_key_data_result.status(); - auto public_key_data = std::move(public_key_data_result.ValueOrDie()); - EXPECT_EQ(EciesAeadHkdfPublicKeyManager().get_key_type(), - public_key_data->type_url()); - EXPECT_EQ(KeyData::ASYMMETRIC_PUBLIC, public_key_data->key_material_type()); - EXPECT_EQ(new_key->public_key().SerializeAsString(), - public_key_data->value()); +EciesAeadHkdfPrivateKey CreateValidKey() { + return EciesAeadHkdfPrivateKeyManager() + .CreateKey(CreateValidKeyFormat()) + .ValueOrDie(); } -TEST_F(EciesAeadHkdfPrivateKeyManagerTest, testPublicKeyExtractionErrors) { - EciesAeadHkdfPublicKeyManager public_key_type_manager; - EciesAeadHkdfPrivateKeyManager private_key_type_manager; - auto public_key_manager = - internal::MakeKeyManager<HybridEncrypt>(&public_key_type_manager); - auto private_key_manager = - internal::MakePrivateKeyManager<HybridDecrypt>(&private_key_type_manager, - &public_key_type_manager); - auto private_key_factory = dynamic_cast<const PrivateKeyFactory*>( - &(private_key_manager->get_key_factory())); - ASSERT_NE(private_key_factory, nullptr); - - AesCtrHmacAeadKeyManager aead_key_manager; - auto aead_private_key_factory = dynamic_cast<const PrivateKeyFactory*>( - &(aead_key_manager.get_key_factory())); - ASSERT_EQ(nullptr, aead_private_key_factory); - - auto aead_key_result = aead_key_manager.get_key_factory().NewKey( - AeadKeyTemplates::Aes128CtrHmacSha256().value()); - ASSERT_TRUE(aead_key_result.ok()) << aead_key_result.status(); - auto aead_key = std::move(aead_key_result.ValueOrDie()); - auto public_key_data_result = private_key_factory->GetPublicKeyData( - aead_key->SerializeAsString()); - EXPECT_FALSE(public_key_data_result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, - public_key_data_result.status().error_code()); +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyEmpty) { + EXPECT_THAT( + EciesAeadHkdfPrivateKeyManager().ValidateKey(EciesAeadHkdfPrivateKey()), + StatusIs(util::error::INVALID_ARGUMENT)); } -TEST_F(EciesAeadHkdfPrivateKeyManagerTest, testNewKeyErrors) { - EciesAeadHkdfPublicKeyManager public_key_type_manager; - EciesAeadHkdfPrivateKeyManager private_key_type_manager; - auto public_key_manager = - internal::MakeKeyManager<HybridEncrypt>(&public_key_type_manager); - auto private_key_manager = - internal::MakePrivateKeyManager<HybridDecrypt>(&private_key_type_manager, - &public_key_type_manager); - const KeyFactory& key_factory = private_key_manager->get_key_factory(); - - // Empty key format. - EciesAeadHkdfKeyFormat key_format; - { - auto result = key_factory.NewKey(key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "Missing params", - result.status().error_message()); - } - - // Missing kem_params. - auto params = key_format.mutable_params(); - { - auto result = key_factory.NewKey(key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "Missing kem_params", - result.status().error_message()); - } - - // Invalid kem_params. - auto kem_params = params->mutable_kem_params(); - { - auto result = key_factory.NewKey(key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "Invalid kem_params", - result.status().error_message()); - } - - // Missing dem_params. - kem_params->set_curve_type(EllipticCurveType::NIST_P256); - kem_params->set_hkdf_hash_type(HashType::SHA256); - { - auto result = key_factory.NewKey(key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "Missing dem_params", - result.status().error_message()); - } - - // Invalid dem_params. - auto dem_params = params->mutable_dem_params(); - { - auto result = key_factory.NewKey(key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "Invalid dem_params", - result.status().error_message()); - } - - // Invalid EC point format. - dem_params->mutable_aead_dem()->set_type_url("some type_url"); - { - auto result = key_factory.NewKey(key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "Unknown EC point format", - result.status().error_message()); - } +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKey) { + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKey(CreateValidKey()), + IsOk()); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyWrongVersion) { + EciesAeadHkdfPrivateKey key = CreateValidKey(); + key.set_version(1); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKey(key), + StatusIs(util::error::INVALID_ARGUMENT)); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyNoPoint) { + EciesAeadHkdfPrivateKey key = CreateValidKey(); + key.mutable_public_key()->mutable_params()->set_ec_point_format( + EcPointFormat::UNKNOWN_FORMAT); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKey(key), + StatusIs(util::error::INVALID_ARGUMENT)); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyNoDem) { + EciesAeadHkdfPrivateKey key = CreateValidKey(); + key.mutable_public_key() + ->mutable_params() + ->mutable_dem_params() + ->clear_aead_dem(); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKey(key), + StatusIs(util::error::INVALID_ARGUMENT)); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyNoKemCurve) { + EciesAeadHkdfPrivateKey key = CreateValidKey(); + key.mutable_public_key() + ->mutable_params() + ->mutable_kem_params() + ->set_curve_type(EllipticCurveType::UNKNOWN_CURVE); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKey(key), + StatusIs(util::error::INVALID_ARGUMENT)); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, ValidateKeyNoKemHash) { + EciesAeadHkdfPrivateKey key = CreateValidKey(); + key.mutable_public_key() + ->mutable_params() + ->mutable_kem_params() + ->set_hkdf_hash_type(HashType::UNKNOWN_HASH); + EXPECT_THAT(EciesAeadHkdfPrivateKeyManager().ValidateKey(key), + StatusIs(util::error::INVALID_ARGUMENT)); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, GetPublicKey) { + EciesAeadHkdfPrivateKey key = CreateValidKey(); + ASSERT_THAT(EciesAeadHkdfPrivateKeyManager().GetPublicKey(key).status(), + IsOk()); + EciesAeadHkdfPublicKey public_key = + EciesAeadHkdfPrivateKeyManager().GetPublicKey(key).ValueOrDie(); + EXPECT_THAT(public_key.params().kem_params().curve_type(), + Eq(key.public_key().params().kem_params().curve_type())); + EXPECT_THAT(public_key.params().kem_params().hkdf_hash_type(), + Eq(key.public_key().params().kem_params().hkdf_hash_type())); + EXPECT_THAT(public_key.params().dem_params().aead_dem().type_url(), + Eq(key.public_key().params().dem_params().aead_dem().type_url())); + EXPECT_THAT(public_key.params().dem_params().aead_dem().value(), + Eq(key.public_key().params().dem_params().aead_dem().value())); + EXPECT_THAT(public_key.params().dem_params().aead_dem().output_prefix_type(), + Eq(key.public_key() + .params() + .dem_params() + .aead_dem() + .output_prefix_type())); + + EXPECT_THAT(public_key.x(), Not(IsEmpty())); + EXPECT_THAT(public_key.y(), Not(IsEmpty())); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, Create) { + ASSERT_THAT(Registry::RegisterKeyTypeManager( + absl::make_unique<AesGcmKeyManager>(), true), IsOk()); + + EciesAeadHkdfPrivateKey private_key = CreateValidKey(); + EciesAeadHkdfPublicKey public_key = + EciesAeadHkdfPrivateKeyManager().GetPublicKey(private_key).ValueOrDie(); + + auto decrypt_or = + EciesAeadHkdfPrivateKeyManager().GetPrimitive<HybridDecrypt>(private_key); + ASSERT_THAT(decrypt_or.status(), IsOk()); + auto encrypt_or = EciesAeadHkdfHybridEncrypt::New(public_key); + ASSERT_THAT(encrypt_or.status(), IsOk()); + + ASSERT_THAT(HybridEncryptThenDecrypt(encrypt_or.ValueOrDie().get(), + decrypt_or.ValueOrDie().get(), + "some text", "some aad"), + IsOk()); +} + +TEST(EciesAeadHkdfPrivateKeyManagerTest, CreateDifferentKey) { + ASSERT_THAT(Registry::RegisterKeyTypeManager( + absl::make_unique<AesGcmKeyManager>(), true), IsOk()); + + EciesAeadHkdfPrivateKey private_key = CreateValidKey(); + // Note: we create a new private key in the next line. + EciesAeadHkdfPublicKey public_key = EciesAeadHkdfPrivateKeyManager() + .GetPublicKey(CreateValidKey()) + .ValueOrDie(); + + auto decrypt_or = + EciesAeadHkdfPrivateKeyManager().GetPrimitive<HybridDecrypt>(private_key); + ASSERT_THAT(decrypt_or.status(), IsOk()); + auto encrypt_or = EciesAeadHkdfHybridEncrypt::New(public_key); + ASSERT_THAT(encrypt_or.status(), IsOk()); + + ASSERT_THAT(HybridEncryptThenDecrypt(encrypt_or.ValueOrDie().get(), + decrypt_or.ValueOrDie().get(), + "some text", "some aad"), + Not(IsOk())); } } // namespace diff --git a/cc/hybrid/ecies_aead_hkdf_public_key_manager_test.cc b/cc/hybrid/ecies_aead_hkdf_public_key_manager_test.cc index 4d38cb5e9e06cdd34ef7a1c12129de20ceeeece7..f5ef9bee37eb0fd1a03d2b84246795067ffd5346 100644 --- a/cc/hybrid/ecies_aead_hkdf_public_key_manager_test.cc +++ b/cc/hybrid/ecies_aead_hkdf_public_key_manager_test.cc @@ -16,13 +16,16 @@ #include "tink/hybrid/ecies_aead_hkdf_public_key_manager.h" +#include "gtest/gtest.h" +#include "tink/aead/aead_key_templates.h" +#include "tink/aead/aes_gcm_key_manager.h" +#include "tink/hybrid/ecies_aead_hkdf_private_key_manager.h" #include "tink/hybrid_encrypt.h" #include "tink/registry.h" -#include "tink/aead/aes_gcm_key_manager.h" #include "tink/util/status.h" #include "tink/util/statusor.h" +#include "tink/util/test_matchers.h" #include "tink/util/test_util.h" -#include "gtest/gtest.h" #include "proto/aes_eax.pb.h" #include "proto/common.pb.h" #include "proto/ecies_aead_hkdf.pb.h" @@ -30,163 +33,87 @@ namespace crypto { namespace tink { - -using google::crypto::tink::AesEaxKey; -using google::crypto::tink::EciesAeadHkdfKeyFormat; -using google::crypto::tink::EciesAeadHkdfPublicKey; -using google::crypto::tink::EcPointFormat; -using google::crypto::tink::EllipticCurveType; -using google::crypto::tink::HashType; -using google::crypto::tink::KeyData; - namespace { -class EciesAeadHkdfPublicKeyManagerTest : public ::testing::Test { - protected: - static void SetUpTestSuite() { - ASSERT_TRUE(Registry::RegisterKeyTypeManager( - absl::make_unique<AesGcmKeyManager>(), true) - .ok()); - } - - std::string key_type_prefix = "type.googleapis.com/"; - std::string ecies_public_key_type = - "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey"; -}; - -TEST_F(EciesAeadHkdfPublicKeyManagerTest, testBasic) { - EciesAeadHkdfPublicKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridEncrypt>(&key_type_manager); - EXPECT_EQ(0, key_manager->get_version()); - EXPECT_EQ("type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey", - key_manager->get_key_type()); - EXPECT_TRUE(key_manager->DoesSupport(key_manager->get_key_type())); +using ::crypto::tink::test::IsOk; +using ::crypto::tink::test::StatusIs; +using ::google::crypto::tink::EciesAeadHkdfKeyFormat; +using ::google::crypto::tink::EciesAeadHkdfParams; +using ::google::crypto::tink::EciesAeadHkdfPublicKey; +using ::google::crypto::tink::EcPointFormat; +using ::google::crypto::tink::EllipticCurveType; +using ::google::crypto::tink::HashType; +using ::google::crypto::tink::KeyData; +using ::testing::Eq; + +TEST(EciesAeadHkdfPublicKeyManagerTest, Basics) { + EXPECT_THAT(EciesAeadHkdfPublicKeyManager().get_version(), Eq(0)); + EXPECT_THAT(EciesAeadHkdfPublicKeyManager().key_material_type(), + Eq(KeyData::ASYMMETRIC_PUBLIC)); + EXPECT_THAT( + EciesAeadHkdfPublicKeyManager().get_key_type(), + Eq("type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey")); } -TEST_F(EciesAeadHkdfPublicKeyManagerTest, testKeyDataErrors) { - EciesAeadHkdfPublicKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridEncrypt>(&key_type_manager); - - { // Bad key type. - KeyData key_data; - std::string bad_key_type = - "type.googleapis.com/google.crypto.tink.SomeOtherKey"; - key_data.set_type_url(bad_key_type); - auto result = key_manager->GetPrimitive(key_data); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not supported", - result.status().error_message()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, bad_key_type, - result.status().error_message()); - } - - { // Bad key value. - KeyData key_data; - key_data.set_type_url(ecies_public_key_type); - key_data.set_value("some bad serialized proto"); - auto result = key_manager->GetPrimitive(key_data); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not parse", - result.status().error_message()); - } - - { // Bad version. - KeyData key_data; - EciesAeadHkdfPublicKey key; - key.set_version(1); - key_data.set_type_url(ecies_public_key_type); - key_data.set_value(key.SerializeAsString()); - auto result = key_manager->GetPrimitive(key_data); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "version", - result.status().error_message()); - } +TEST(EciesAeadHkdfPublicKeyManagerTest, ValidateEmptyKey) { + EXPECT_THAT( + EciesAeadHkdfPublicKeyManager().ValidateKey(EciesAeadHkdfPublicKey()), + StatusIs(util::error::INVALID_ARGUMENT)); } -TEST_F(EciesAeadHkdfPublicKeyManagerTest, testKeyMessageErrors) { - EciesAeadHkdfPublicKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridEncrypt>(&key_type_manager); - - { // Bad protobuffer. - AesEaxKey key; - auto result = key_manager->GetPrimitive(key); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "AesEaxKey", - result.status().error_message()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not supported", - result.status().error_message()); - } +EciesAeadHkdfPublicKey CreatePublicKey() { + EciesAeadHkdfKeyFormat key_format; + key_format.mutable_params()->set_ec_point_format(EcPointFormat::UNCOMPRESSED); + auto dem_params = key_format.mutable_params()->mutable_dem_params(); + *(dem_params->mutable_aead_dem()) = AeadKeyTemplates::Aes128Gcm(); + auto kem_params = key_format.mutable_params()->mutable_kem_params(); + kem_params->set_curve_type(EllipticCurveType::NIST_P256); + kem_params->set_hkdf_hash_type(HashType::SHA256); + kem_params->set_hkdf_salt(""); + auto private_key_manager = EciesAeadHkdfPrivateKeyManager(); + return private_key_manager + .GetPublicKey( + private_key_manager.CreateKey(key_format).ValueOrDie()) + .ValueOrDie(); } -TEST_F(EciesAeadHkdfPublicKeyManagerTest, testPrimitives) { - std::string plaintext = "some plaintext"; - std::string context_info = "some context info"; - EciesAeadHkdfPublicKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridEncrypt>(&key_type_manager); - EciesAeadHkdfPublicKey key = test::GetEciesAesGcmHkdfTestKey( - EllipticCurveType::NIST_P256, EcPointFormat::UNCOMPRESSED, - HashType::SHA256, 32).public_key(); - - { // Using Key proto. - auto result = key_manager->GetPrimitive(key); - EXPECT_TRUE(result.ok()) << result.status(); - auto hybrid_encrypt = std::move(result.ValueOrDie()); - auto encrypt_result = hybrid_encrypt->Encrypt(plaintext, context_info); - EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status(); - } +TEST(EciesAeadHkdfPublicKeyManagerTest, ValidateParams) { + EXPECT_THAT(EciesAeadHkdfPublicKeyManager().ValidateParams( + CreatePublicKey().params()), + IsOk()); +} - { // Using KeyData proto. - KeyData key_data; - key_data.set_type_url(ecies_public_key_type); - key_data.set_value(key.SerializeAsString()); - auto result = key_manager->GetPrimitive(key_data); - EXPECT_TRUE(result.ok()) << result.status(); - auto hybrid_encrypt = std::move(result.ValueOrDie()); - auto encrypt_result = hybrid_encrypt->Encrypt(plaintext, context_info); - EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status(); - } +TEST(EciesAeadHkdfPublicKeyManagerTest, ValidateKeyNoPoint) { + EciesAeadHkdfParams params = CreatePublicKey().params(); + params.set_ec_point_format(EcPointFormat::UNKNOWN_FORMAT); + EXPECT_THAT(EciesAeadHkdfPublicKeyManager().ValidateParams(params), + StatusIs(util::error::INVALID_ARGUMENT)); } -TEST_F(EciesAeadHkdfPublicKeyManagerTest, testNewKeyError) { - EciesAeadHkdfPublicKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<HybridEncrypt>(&key_type_manager); - const KeyFactory& key_factory = key_manager->get_key_factory(); +TEST(EciesAeadHkdfPublicKeyManagerTest, ValidateKeyNoDem) { + EciesAeadHkdfParams params = CreatePublicKey().params(); + params.mutable_dem_params()->clear_aead_dem(); + EXPECT_THAT(EciesAeadHkdfPublicKeyManager().ValidateParams(params), + StatusIs(util::error::INVALID_ARGUMENT)); +} - { // Via NewKey(format_proto). - EciesAeadHkdfKeyFormat key_format; - auto result = key_factory.NewKey(key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::UNIMPLEMENTED, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not supported", - result.status().error_message()); - } +TEST(EciesAeadHkdfPublicKeyManagerTest, ValidateKeyNoKemCurve) { + EciesAeadHkdfParams params = CreatePublicKey().params(); + params.mutable_kem_params()->set_curve_type(EllipticCurveType::UNKNOWN_CURVE); + EXPECT_THAT(EciesAeadHkdfPublicKeyManager().ValidateParams(params), + StatusIs(util::error::INVALID_ARGUMENT)); +} - { // Via NewKey(serialized_format_proto). - EciesAeadHkdfKeyFormat key_format; - auto result = key_factory.NewKey(key_format.SerializeAsString()); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::UNIMPLEMENTED, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not supported", - result.status().error_message()); - } +TEST(EciesAeadHkdfPublicKeyManagerTest, ValidateKeyNoKemHash) { + EciesAeadHkdfParams params = CreatePublicKey().params(); + params.mutable_kem_params()->set_hkdf_hash_type(HashType::UNKNOWN_HASH); + EXPECT_THAT(EciesAeadHkdfPublicKeyManager().ValidateParams(params), + StatusIs(util::error::INVALID_ARGUMENT)); +} - { // Via NewKeyData(serialized_format_proto). - EciesAeadHkdfKeyFormat key_format; - auto result = key_factory.NewKeyData(key_format.SerializeAsString()); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::UNIMPLEMENTED, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, "not supported", - result.status().error_message()); - } +TEST(EciesAeadHkdfPublicKeyManagerTest, ValidateGeneratedKey) { + EXPECT_THAT(EciesAeadHkdfPublicKeyManager().ValidateKey(CreatePublicKey()), + IsOk()); } } // namespace