From 5541324416df601848bb7b7cd1b8f4b183bbcdfc Mon Sep 17 00:00:00 2001 From: tholenst <tholenst@google.com> Date: Thu, 29 Aug 2019 06:17:45 -0700 Subject: [PATCH] Migrate the Ed25519 Sign Key Manager. PiperOrigin-RevId: 266124911 --- cc/signature/BUILD.bazel | 14 +-- cc/signature/CMakeLists.txt | 12 +- cc/signature/ed25519_sign_key_manager.cc | 105 ++++-------------- cc/signature/ed25519_sign_key_manager.h | 58 ++++++---- cc/signature/ed25519_sign_key_manager_test.cc | 65 +++++++---- cc/signature/ed25519_verify_key_manager.cc | 36 +----- cc/signature/ed25519_verify_key_manager.h | 46 ++++---- .../ed25519_verify_key_manager_test.cc | 52 +++++---- cc/signature/signature_config.cc | 6 +- cc/signature/signature_key_templates_test.cc | 11 +- 10 files changed, 183 insertions(+), 222 deletions(-) diff --git a/cc/signature/BUILD.bazel b/cc/signature/BUILD.bazel index e598441cb..75afe81d5 100644 --- a/cc/signature/BUILD.bazel +++ b/cc/signature/BUILD.bazel @@ -155,11 +155,11 @@ cc_library( strip_include_prefix = "/cc", deps = [ ":ed25519_verify_key_manager", - "//cc:key_manager", - "//cc:key_manager_base", + "//cc:core/private_key_type_manager", "//cc:public_key_sign", "//cc/subtle:ed25519_sign_boringssl", "//cc/subtle:subtle_util_boringssl", + "//cc/util:constants", "//cc/util:enums", "//cc/util:errors", "//cc/util:protobuf_helper", @@ -167,8 +167,6 @@ cc_library( "//cc/util:statusor", "//cc/util:validation", "//proto:ed25519_cc_proto", - "//proto:empty_cc_proto", - "//proto:tink_cc_proto", "@com_google_absl//absl/memory", "@com_google_absl//absl/strings", ], @@ -181,11 +179,11 @@ cc_library( include_prefix = "tink", strip_include_prefix = "/cc", deps = [ - "//cc:key_manager", - "//cc:key_manager_base", + "//cc:core/key_type_manager", "//cc:public_key_verify", "//cc/subtle:ed25519_verify_boringssl", "//cc/subtle:subtle_util_boringssl", + "//cc/util:constants", "//cc/util:errors", "//cc/util:protobuf_helper", "//cc/util:status", @@ -456,6 +454,7 @@ cc_test( deps = [ ":ed25519_sign_key_manager", ":ed25519_verify_key_manager", + "//cc:core/key_manager_impl", "//cc:public_key_sign", "//cc:public_key_verify", "//cc:registry", @@ -544,6 +543,7 @@ cc_test( ":ed25519_sign_key_manager", ":ed25519_verify_key_manager", ":signature_key_templates", + "//cc:core/private_key_manager_impl", "//cc:public_key_sign", "//cc:registry", "//cc/aead:aead_key_templates", @@ -555,7 +555,6 @@ cc_test( "//proto:aes_eax_cc_proto", "//proto:common_cc_proto", "//proto:ed25519_cc_proto", - "//proto:empty_cc_proto", "//proto:tink_cc_proto", "@com_google_googletest//:gtest_main", ], @@ -644,6 +643,7 @@ cc_test( deps = [ ":ecdsa_sign_key_manager", ":ed25519_sign_key_manager", + ":ed25519_verify_key_manager", ":rsa_ssa_pkcs1_sign_key_manager", ":rsa_ssa_pss_sign_key_manager", ":signature_key_templates", diff --git a/cc/signature/CMakeLists.txt b/cc/signature/CMakeLists.txt index 0b6751669..9dd65892d 100644 --- a/cc/signature/CMakeLists.txt +++ b/cc/signature/CMakeLists.txt @@ -136,11 +136,11 @@ tink_cc_library( ed25519_sign_key_manager.h DEPS tink::signature::ed25519_verify_key_manager - tink::core::key_manager - tink::core::key_manager_base + tink::core::private_key_type_manager tink::core::public_key_sign tink::subtle::ed25519_sign_boringssl tink::subtle::subtle_util_boringssl + tink::util::constants tink::util::enums tink::util::errors tink::util::protobuf_helper @@ -148,8 +148,6 @@ tink_cc_library( tink::util::statusor tink::util::validation tink::proto::ed25519_cc_proto - tink::proto::empty_cc_proto - tink::proto::tink_cc_proto absl::memory absl::strings ) @@ -160,11 +158,11 @@ tink_cc_library( ed25519_verify_key_manager.cc ed25519_verify_key_manager.h DEPS - tink::core::key_manager - tink::core::key_manager_base + tink::core::key_type_manager tink::core::public_key_verify tink::subtle::ed25519_verify_boringssl tink::subtle::subtle_util_boringssl + tink::util::constants tink::util::errors tink::util::protobuf_helper tink::util::status @@ -397,6 +395,7 @@ tink_cc_test( DEPS tink::signature::ed25519_sign_key_manager tink::signature::ed25519_verify_key_manager + tink::core::key_manager_impl tink::core::public_key_sign tink::core::public_key_verify tink::core::registry @@ -473,6 +472,7 @@ tink_cc_test( tink::signature::ed25519_sign_key_manager tink::signature::ed25519_verify_key_manager tink::signature::signature_key_templates + tink::core::private_key_manager_impl tink::core::public_key_sign tink::core::registry tink::aead::aead_key_templates diff --git a/cc/signature/ed25519_sign_key_manager.cc b/cc/signature/ed25519_sign_key_manager.cc index 9b9d27b65..9e78b4ecb 100644 --- a/cc/signature/ed25519_sign_key_manager.cc +++ b/cc/signature/ed25519_sign_key_manager.cc @@ -18,8 +18,6 @@ #include "absl/memory/memory.h" #include "absl/strings/string_view.h" -#include "tink/core/key_manager_base.h" -#include "tink/key_manager.h" #include "tink/public_key_sign.h" #include "tink/signature/ed25519_verify_key_manager.h" #include "tink/subtle/ed25519_sign_boringssl.h" @@ -31,117 +29,54 @@ #include "tink/util/statusor.h" #include "tink/util/validation.h" #include "proto/ed25519.pb.h" -#include "proto/tink.pb.h" namespace crypto { namespace tink { using crypto::tink::util::Status; using crypto::tink::util::StatusOr; -using google::crypto::tink::Ed25519PrivateKey; using google::crypto::tink::Ed25519KeyFormat; -using google::crypto::tink::KeyData; - -class Ed25519PrivateKeyFactory - : public PrivateKeyFactory, - public KeyFactoryBase<Ed25519PrivateKey, Ed25519KeyFormat> { - public: - Ed25519PrivateKeyFactory() {} - - KeyData::KeyMaterialType key_material_type() const override { - return KeyData::ASYMMETRIC_PRIVATE; - } - - // Returns KeyData proto that contains Ed25519PublicKey - // extracted from the given serialized_private_key, which must contain - // Ed25519PrivateKey-proto. - crypto::tink::util::StatusOr<std::unique_ptr<google::crypto::tink::KeyData>> - GetPublicKeyData(absl::string_view serialized_private_key) const override; - - protected: - StatusOr<std::unique_ptr<Ed25519PrivateKey>> NewKeyFromFormat( - const Ed25519KeyFormat& unused) const override; -}; +using google::crypto::tink::Ed25519PrivateKey; -StatusOr<std::unique_ptr<Ed25519PrivateKey>> -Ed25519PrivateKeyFactory::NewKeyFromFormat( - const Ed25519KeyFormat& unused) const { +StatusOr<Ed25519PrivateKey> Ed25519SignKeyManager::CreateKey( + const Ed25519KeyFormat& key_format) const { auto key = subtle::SubtleUtilBoringSSL::GetNewEd25519Key(); - // Build Ed25519PrivateKey. - std::unique_ptr<Ed25519PrivateKey> ed25519_private_key( - new Ed25519PrivateKey()); - ed25519_private_key->set_version(Ed25519SignKeyManager::kVersion); - ed25519_private_key->set_key_value(key->private_key); + Ed25519PrivateKey ed25519_private_key; + ed25519_private_key.set_version(get_version()); + ed25519_private_key.set_key_value(key->private_key); // Build Ed25519PublicKey. - auto ed25519_public_key = ed25519_private_key->mutable_public_key(); - ed25519_public_key->set_version(Ed25519SignKeyManager::kVersion); + auto ed25519_public_key = ed25519_private_key.mutable_public_key(); + ed25519_public_key->set_version(get_version()); ed25519_public_key->set_key_value(key->public_key); - return absl::implicit_cast<StatusOr<std::unique_ptr<Ed25519PrivateKey>>>( - std::move(ed25519_private_key)); -} - -StatusOr<std::unique_ptr<KeyData>> Ed25519PrivateKeyFactory::GetPublicKeyData( - absl::string_view serialized_private_key) const { - Ed25519PrivateKey private_key; - if (!private_key.ParseFromString(std::string(serialized_private_key))) { - return Status( - util::error::INVALID_ARGUMENT, - absl::StrCat("Could not parse the passed string as proto '", - Ed25519VerifyKeyManager::static_key_type(), "'.")); - return util::Status::OK; - } - auto status = Ed25519SignKeyManager::Validate(private_key); - if (!status.ok()) return status; - auto key_data = absl::make_unique<KeyData>(); - key_data->set_type_url(Ed25519VerifyKeyManager::static_key_type()); - key_data->set_value(private_key.public_key().SerializeAsString()); - key_data->set_key_material_type(KeyData::ASYMMETRIC_PUBLIC); - return std::move(key_data); + return ed25519_private_key; } -constexpr uint32_t Ed25519SignKeyManager::kVersion; - -Ed25519SignKeyManager::Ed25519SignKeyManager() - : key_factory_(absl::make_unique<Ed25519PrivateKeyFactory>()) {} - -const KeyFactory& Ed25519SignKeyManager::get_key_factory() const { - return *key_factory_; -} - -uint32_t Ed25519SignKeyManager::get_version() const { return kVersion; } - StatusOr<std::unique_ptr<PublicKeySign>> -Ed25519SignKeyManager::GetPrimitiveFromKey( - const Ed25519PrivateKey& ed25519_private_key) const { - Status status = Validate(ed25519_private_key); - if (!status.ok()) return status; - +Ed25519SignKeyManager::PublicKeySignFactory::Create( + const Ed25519PrivateKey& private_key) const { // BoringSSL expects a 64-byte private key which contains the public key as a // suffix. - std::string sk = ed25519_private_key.key_value() + - ed25519_private_key.public_key().key_value(); - - auto ed25519_result = subtle::Ed25519SignBoringSsl::New(sk); - if (!ed25519_result.ok()) return ed25519_result.status(); + std::string sk = private_key.key_value() + private_key.public_key().key_value(); - std::unique_ptr<PublicKeySign> ed25519(ed25519_result.ValueOrDie().release()); - return std::move(ed25519); + return subtle::Ed25519SignBoringSsl::New(sk); } -// static -Status Ed25519SignKeyManager::Validate(const Ed25519PrivateKey& key) { - Status status = ValidateVersion(key.version(), kVersion); +Status Ed25519SignKeyManager::ValidateKey(const Ed25519PrivateKey& key) const { + Status status = ValidateVersion(key.version(), get_version()); if (!status.ok()) return status; - if (key.key_value().length() != 32) { return Status(util::error::INVALID_ARGUMENT, "The ED25519 private key must be 32-bytes long."); } + return Ed25519VerifyKeyManager().ValidateKey(key.public_key()); +} - return Ed25519VerifyKeyManager::Validate(key.public_key()); +Status Ed25519SignKeyManager::ValidateKeyFormat( + const Ed25519KeyFormat& key_format) const { + return util::OkStatus(); } } // namespace tink diff --git a/cc/signature/ed25519_sign_key_manager.h b/cc/signature/ed25519_sign_key_manager.h index 7e62a1fd6..c94267fa7 100644 --- a/cc/signature/ed25519_sign_key_manager.h +++ b/cc/signature/ed25519_sign_key_manager.h @@ -20,48 +20,62 @@ #include <vector> #include "absl/strings/string_view.h" -#include "tink/core/key_manager_base.h" -#include "tink/key_manager.h" +#include "tink/core/private_key_type_manager.h" #include "tink/public_key_sign.h" +#include "tink/util/constants.h" #include "tink/util/errors.h" #include "tink/util/protobuf_helper.h" #include "tink/util/status.h" #include "tink/util/statusor.h" #include "proto/ed25519.pb.h" -#include "proto/tink.pb.h" namespace crypto { namespace tink { class Ed25519SignKeyManager - : public KeyManagerBase<PublicKeySign, - google::crypto::tink::Ed25519PrivateKey> { + : public PrivateKeyTypeManager<google::crypto::tink::Ed25519PrivateKey, + google::crypto::tink::Ed25519KeyFormat, + google::crypto::tink::Ed25519PublicKey, + List<PublicKeySign>> { public: - static constexpr uint32_t kVersion = 0; + class PublicKeySignFactory : public PrimitiveFactory<PublicKeySign> { + crypto::tink::util::StatusOr<std::unique_ptr<PublicKeySign>> Create( + const google::crypto::tink::Ed25519PrivateKey& private_key) + const override; + }; - Ed25519SignKeyManager(); + Ed25519SignKeyManager() + : PrivateKeyTypeManager(absl::make_unique<PublicKeySignFactory>()) {} - // Returns the version of this key manager. - uint32_t get_version() const override; + uint32_t get_version() const override { return 0; } - // Returns a factory that generates keys of the key type - // handled by this manager. - const KeyFactory& get_key_factory() const override; + google::crypto::tink::KeyData::KeyMaterialType key_material_type() + const override { + return google::crypto::tink::KeyData::ASYMMETRIC_PRIVATE; + } - ~Ed25519SignKeyManager() override {} + const std::string& get_key_type() const override { return key_type_; } - protected: - crypto::tink::util::StatusOr<std::unique_ptr<PublicKeySign>> - GetPrimitiveFromKey(const google::crypto::tink::Ed25519PrivateKey& - ed25519_private_key) const override; + crypto::tink::util::Status ValidateKey( + const google::crypto::tink::Ed25519PrivateKey& key) const override; - private: - friend class Ed25519PrivateKeyFactory; + crypto::tink::util::Status ValidateKeyFormat( + const google::crypto::tink::Ed25519KeyFormat& key_format) const override; + + crypto::tink::util::StatusOr<google::crypto::tink::Ed25519PrivateKey> + CreateKey( + const google::crypto::tink::Ed25519KeyFormat& key_format) const override; - std::unique_ptr<KeyFactory> key_factory_; + crypto::tink::util::StatusOr<google::crypto::tink::Ed25519PublicKey> + GetPublicKey(const google::crypto::tink::Ed25519PrivateKey& private_key) + const override { + return private_key.public_key(); + } - static crypto::tink::util::Status Validate( - const google::crypto::tink::Ed25519PrivateKey& key); + private: + const std::string key_type_ = + absl::StrCat(kTypeGoogleapisCom, + google::crypto::tink::Ed25519PrivateKey().GetTypeName()); }; } // namespace tink diff --git a/cc/signature/ed25519_sign_key_manager_test.cc b/cc/signature/ed25519_sign_key_manager_test.cc index 36c4da86f..35178ac81 100644 --- a/cc/signature/ed25519_sign_key_manager_test.cc +++ b/cc/signature/ed25519_sign_key_manager_test.cc @@ -19,6 +19,7 @@ #include "gtest/gtest.h" #include "tink/aead/aead_key_templates.h" #include "tink/aead/aes_gcm_key_manager.h" +#include "tink/core/private_key_manager_impl.h" #include "tink/public_key_sign.h" #include "tink/registry.h" #include "tink/signature/ed25519_verify_key_manager.h" @@ -50,22 +51,28 @@ class Ed25519SignKeyManagerTest : public ::testing::Test { }; TEST_F(Ed25519SignKeyManagerTest, testBasic) { - Ed25519SignKeyManager key_manager; + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_key_type_manager); - EXPECT_EQ(0, key_manager.get_version()); + EXPECT_EQ(0, key_manager->get_version()); EXPECT_EQ("type.googleapis.com/google.crypto.tink.Ed25519PrivateKey", - key_manager.get_key_type()); - EXPECT_TRUE(key_manager.DoesSupport(key_manager.get_key_type())); + key_manager->get_key_type()); + EXPECT_TRUE(key_manager->DoesSupport(key_manager->get_key_type())); } TEST_F(Ed25519SignKeyManagerTest, testKeyDataErrors) { - Ed25519SignKeyManager key_manager; + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_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); + 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", @@ -78,7 +85,7 @@ TEST_F(Ed25519SignKeyManagerTest, testKeyDataErrors) { KeyData key_data; key_data.set_type_url(ed25519_sign_key_type_); key_data.set_value("some bad serialized proto"); - auto result = key_manager.GetPrimitive(key_data); + 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", @@ -91,7 +98,7 @@ TEST_F(Ed25519SignKeyManagerTest, testKeyDataErrors) { key.set_version(1); key_data.set_type_url(ed25519_sign_key_type_); key_data.set_value(key.SerializeAsString()); - auto result = key_manager.GetPrimitive(key_data); + 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", @@ -100,11 +107,14 @@ TEST_F(Ed25519SignKeyManagerTest, testKeyDataErrors) { } TEST_F(Ed25519SignKeyManagerTest, testKeyMessageErrors) { - Ed25519SignKeyManager key_manager; + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_key_type_manager); { // Bad protobuffer. AesEaxKey key; - auto result = key_manager.GetPrimitive(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", @@ -116,11 +126,17 @@ TEST_F(Ed25519SignKeyManagerTest, testKeyMessageErrors) { TEST_F(Ed25519SignKeyManagerTest, testPrimitives) { std::string message = "some message to sign"; - Ed25519SignKeyManager sign_key_manager; + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto sign_key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_key_type_manager); + auto verify_key_manager = + internal::MakeKeyManager<PublicKeyVerify>(&verify_key_type_manager); + Ed25519PrivateKey key = test::GetEd25519TestPrivateKey(); { // Using Key proto. - auto result = sign_key_manager.GetPrimitive(key); + auto result = sign_key_manager->GetPrimitive(key); EXPECT_TRUE(result.ok()) << result.status(); auto sign = std::move(result.ValueOrDie()); auto signing_result = sign->Sign(message); @@ -131,7 +147,7 @@ TEST_F(Ed25519SignKeyManagerTest, testPrimitives) { KeyData key_data; key_data.set_type_url(ed25519_sign_key_type_); key_data.set_value(key.SerializeAsString()); - auto result = sign_key_manager.GetPrimitive(key_data); + auto result = sign_key_manager->GetPrimitive(key_data); EXPECT_TRUE(result.ok()) << result.status(); auto sign = std::move(result.ValueOrDie()); auto signing_result = sign->Sign(message); @@ -140,9 +156,12 @@ TEST_F(Ed25519SignKeyManagerTest, testPrimitives) { } TEST_F(Ed25519SignKeyManagerTest, testPublicKeyExtraction) { - Ed25519SignKeyManager key_manager; + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_key_type_manager); auto private_key_factory = - dynamic_cast<const PrivateKeyFactory*>(&(key_manager.get_key_factory())); + dynamic_cast<const PrivateKeyFactory*>(&(key_manager->get_key_factory())); ASSERT_NE(private_key_factory, nullptr); auto new_key_result = @@ -154,7 +173,7 @@ TEST_F(Ed25519SignKeyManagerTest, testPublicKeyExtraction) { 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(Ed25519VerifyKeyManager::static_key_type(), + EXPECT_EQ(Ed25519VerifyKeyManager().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(), @@ -162,9 +181,12 @@ TEST_F(Ed25519SignKeyManagerTest, testPublicKeyExtraction) { } TEST_F(Ed25519SignKeyManagerTest, testPublicKeyExtractionErrors) { - Ed25519SignKeyManager key_manager; + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_key_type_manager); auto private_key_factory = - dynamic_cast<const PrivateKeyFactory*>(&(key_manager.get_key_factory())); + dynamic_cast<const PrivateKeyFactory*>(&(key_manager->get_key_factory())); ASSERT_NE(private_key_factory, nullptr); auto public_key_data_result = private_key_factory->GetPublicKeyData( @@ -175,8 +197,11 @@ TEST_F(Ed25519SignKeyManagerTest, testPublicKeyExtractionErrors) { } TEST_F(Ed25519SignKeyManagerTest, testNewKey) { - Ed25519SignKeyManager key_manager; - const KeyFactory& key_factory = key_manager.get_key_factory(); + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_key_type_manager); + const KeyFactory& key_factory = key_manager->get_key_factory(); Ed25519KeyFormat key_format; auto result = key_factory.NewKey(key_format); EXPECT_TRUE(result.ok()); diff --git a/cc/signature/ed25519_verify_key_manager.cc b/cc/signature/ed25519_verify_key_manager.cc index 52abae06a..30b5d9bbc 100644 --- a/cc/signature/ed25519_verify_key_manager.cc +++ b/cc/signature/ed25519_verify_key_manager.cc @@ -17,7 +17,6 @@ #include "tink/signature/ed25519_verify_key_manager.h" #include "absl/strings/string_view.h" -#include "tink/key_manager.h" #include "tink/public_key_verify.h" #include "tink/subtle/ed25519_verify_boringssl.h" #include "tink/subtle/subtle_util_boringssl.h" @@ -35,45 +34,20 @@ using crypto::tink::util::Status; using crypto::tink::util::StatusOr; using google::crypto::tink::Ed25519PublicKey; -constexpr uint32_t Ed25519VerifyKeyManager::kVersion; - -Ed25519VerifyKeyManager::Ed25519VerifyKeyManager() - : key_factory_(KeyFactory::AlwaysFailingFactory( - util::Status(util::error::UNIMPLEMENTED, - "Operation not supported for public keys, " - "please use the Ed25519SignKeyManager."))) {} - -const KeyFactory& Ed25519VerifyKeyManager::get_key_factory() const { - return *key_factory_; -} - -uint32_t Ed25519VerifyKeyManager::get_version() const { return kVersion; } - StatusOr<std::unique_ptr<PublicKeyVerify>> -Ed25519VerifyKeyManager::GetPrimitiveFromKey( - const Ed25519PublicKey& ed25519_public_key) const { - Status status = Validate(ed25519_public_key); - if (!status.ok()) return status; - - auto ed25519_result = - subtle::Ed25519VerifyBoringSsl::New(ed25519_public_key.key_value()); - if (!ed25519_result.ok()) return ed25519_result.status(); - - std::unique_ptr<PublicKeyVerify> ed25519( - ed25519_result.ValueOrDie().release()); - return std::move(ed25519); +Ed25519VerifyKeyManager::PublicKeyVerifyFactory::Create( + const Ed25519PublicKey& public_key) const { + return subtle::Ed25519VerifyBoringSsl::New(public_key.key_value()); } -// static -Status Ed25519VerifyKeyManager::Validate(const Ed25519PublicKey& key) { - Status status = ValidateVersion(key.version(), kVersion); +Status Ed25519VerifyKeyManager::ValidateKey(const Ed25519PublicKey& key) const { + Status status = ValidateVersion(key.version(), get_version()); if (!status.ok()) return status; if (key.key_value().length() != 32) { return Status(util::error::INVALID_ARGUMENT, "The ED25519 public key must be 32-bytes long."); } - return Status::OK; } diff --git a/cc/signature/ed25519_verify_key_manager.h b/cc/signature/ed25519_verify_key_manager.h index 3cacbec9c..2fbaf6a81 100644 --- a/cc/signature/ed25519_verify_key_manager.h +++ b/cc/signature/ed25519_verify_key_manager.h @@ -20,9 +20,9 @@ #include <vector> #include "absl/strings/string_view.h" -#include "tink/core/key_manager_base.h" -#include "tink/key_manager.h" +#include "tink/core/key_type_manager.h" #include "tink/public_key_verify.h" +#include "tink/util/constants.h" #include "tink/util/errors.h" #include "tink/util/protobuf_helper.h" #include "tink/util/status.h" @@ -33,36 +33,34 @@ namespace crypto { namespace tink { class Ed25519VerifyKeyManager - : public KeyManagerBase<PublicKeyVerify, - google::crypto::tink::Ed25519PublicKey> { + : public KeyTypeManager<google::crypto::tink::Ed25519PublicKey, void, + List<PublicKeyVerify>> { public: - static constexpr uint32_t kVersion = 0; + class PublicKeyVerifyFactory : public PrimitiveFactory<PublicKeyVerify> { + crypto::tink::util::StatusOr<std::unique_ptr<PublicKeyVerify>> Create( + const google::crypto::tink::Ed25519PublicKey& ecdsa_public_key) + const override; + }; - Ed25519VerifyKeyManager(); + Ed25519VerifyKeyManager() + : KeyTypeManager(absl::make_unique<PublicKeyVerifyFactory>()) {} - // Returns the version of this key manager. - uint32_t get_version() const override; + uint32_t get_version() const override { return 0; } - // Returns a factory that generates keys of the key type - // handled by this manager. - const KeyFactory& get_key_factory() const override; + google::crypto::tink::KeyData::KeyMaterialType key_material_type() + const override { + return google::crypto::tink::KeyData::ASYMMETRIC_PUBLIC; + } - ~Ed25519VerifyKeyManager() override {} + const std::string& get_key_type() const override { return key_type_; } - protected: - crypto::tink::util::StatusOr<std::unique_ptr<PublicKeyVerify>> - GetPrimitiveFromKey(const google::crypto::tink::Ed25519PublicKey& - ed25519_public_key) const override; + crypto::tink::util::Status ValidateKey( + const google::crypto::tink::Ed25519PublicKey& key) const override; private: - // Friends that re-use proto validation helpers. - friend class Ed25519PrivateKeyFactory; - friend class Ed25519SignKeyManager; - - std::unique_ptr<KeyFactory> key_factory_; - - static crypto::tink::util::Status Validate( - const google::crypto::tink::Ed25519PublicKey& key); + const std::string key_type_ = + absl::StrCat(kTypeGoogleapisCom, + google::crypto::tink::Ed25519PublicKey().GetTypeName()); }; } // namespace tink diff --git a/cc/signature/ed25519_verify_key_manager_test.cc b/cc/signature/ed25519_verify_key_manager_test.cc index 1629be082..b5d50aee5 100644 --- a/cc/signature/ed25519_verify_key_manager_test.cc +++ b/cc/signature/ed25519_verify_key_manager_test.cc @@ -17,6 +17,7 @@ #include "tink/signature/ed25519_verify_key_manager.h" #include "gtest/gtest.h" +#include "tink/core/key_manager_impl.h" #include "tink/public_key_sign.h" #include "tink/public_key_verify.h" #include "tink/registry.h" @@ -48,22 +49,26 @@ class Ed25519VerifyKeyManagerTest : public ::testing::Test { }; TEST_F(Ed25519VerifyKeyManagerTest, testBasic) { - Ed25519VerifyKeyManager key_manager; + Ed25519VerifyKeyManager key_type_manager; + auto key_manager = + internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); - EXPECT_EQ(0, key_manager.get_version()); + EXPECT_EQ(0, key_manager->get_version()); EXPECT_EQ("type.googleapis.com/google.crypto.tink.Ed25519PublicKey", - key_manager.get_key_type()); - EXPECT_TRUE(key_manager.DoesSupport(key_manager.get_key_type())); + key_manager->get_key_type()); + EXPECT_TRUE(key_manager->DoesSupport(key_manager->get_key_type())); } TEST_F(Ed25519VerifyKeyManagerTest, testKeyDataErrors) { - Ed25519VerifyKeyManager key_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto key_manager = + internal::MakeKeyManager<PublicKeyVerify>(&verify_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); + 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", @@ -76,7 +81,7 @@ TEST_F(Ed25519VerifyKeyManagerTest, testKeyDataErrors) { KeyData key_data; key_data.set_type_url(ed25519_verify_key_type_); key_data.set_value("some bad serialized proto"); - auto result = key_manager.GetPrimitive(key_data); + 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", @@ -89,7 +94,7 @@ TEST_F(Ed25519VerifyKeyManagerTest, testKeyDataErrors) { key.set_version(1); key_data.set_type_url(ed25519_verify_key_type_); key_data.set_value(key.SerializeAsString()); - auto result = key_manager.GetPrimitive(key_data); + 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", @@ -98,11 +103,13 @@ TEST_F(Ed25519VerifyKeyManagerTest, testKeyDataErrors) { } TEST_F(Ed25519VerifyKeyManagerTest, testKeyMessageErrors) { - Ed25519VerifyKeyManager key_manager; + Ed25519VerifyKeyManager key_type_manager; + auto key_manager = + internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); { // Bad protobuffer. AesEaxKey key; - auto result = key_manager.GetPrimitive(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", @@ -114,16 +121,21 @@ TEST_F(Ed25519VerifyKeyManagerTest, testKeyMessageErrors) { TEST_F(Ed25519VerifyKeyManagerTest, testPrimitives) { std::string message = "some message to sign"; - Ed25519SignKeyManager sign_key_manager; - Ed25519VerifyKeyManager verify_key_manager; + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto sign_key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_key_type_manager); + auto verify_key_manager = internal::MakeKeyManager<PublicKeyVerify>( + &verify_key_type_manager); + Ed25519PrivateKey private_key = test::GetEd25519TestPrivateKey(); Ed25519PublicKey key = private_key.public_key(); auto sign = - std::move(sign_key_manager.GetPrimitive(private_key).ValueOrDie()); + std::move(sign_key_manager->GetPrimitive(private_key).ValueOrDie()); std::string signature = sign->Sign(message).ValueOrDie(); { // Using Key proto. - auto result = verify_key_manager.GetPrimitive(key); + auto result = verify_key_manager->GetPrimitive(key); EXPECT_TRUE(result.ok()) << result.status(); auto verify = std::move(result.ValueOrDie()); auto verify_status = verify->Verify(signature, message); @@ -134,7 +146,7 @@ TEST_F(Ed25519VerifyKeyManagerTest, testPrimitives) { KeyData key_data; key_data.set_type_url(ed25519_verify_key_type_); key_data.set_value(key.SerializeAsString()); - auto result = verify_key_manager.GetPrimitive(key_data); + auto result = verify_key_manager->GetPrimitive(key_data); EXPECT_TRUE(result.ok()) << result.status(); auto verify = std::move(result.ValueOrDie()); auto verify_status = verify->Verify(signature, message); @@ -143,14 +155,14 @@ TEST_F(Ed25519VerifyKeyManagerTest, testPrimitives) { } TEST_F(Ed25519VerifyKeyManagerTest, testNewKey) { - Ed25519VerifyKeyManager key_manager; - const KeyFactory& key_factory = key_manager.get_key_factory(); + Ed25519VerifyKeyManager key_type_manager; + auto key_manager = + internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); + const KeyFactory& key_factory = key_manager->get_key_factory(); Ed25519KeyFormat key_format; auto result = key_factory.NewKey(key_format); EXPECT_FALSE(result.ok()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, - "Operation not supported for public keys, please use the " - "Ed25519SignKeyManager.", + EXPECT_PRED_FORMAT2(testing::IsSubstring, "not supported", result.status().error_message()); } diff --git a/cc/signature/signature_config.cc b/cc/signature/signature_config.cc index 8ada0f648..70351cef6 100644 --- a/cc/signature/signature_config.cc +++ b/cc/signature/signature_config.cc @@ -53,10 +53,8 @@ util::Status SignatureConfig::Register() { if (!status.ok()) return status; // ED25519 - status = Registry::RegisterKeyManager( - absl::make_unique<Ed25519SignKeyManager>(), true); - if (!status.ok()) return status; - status = Registry::RegisterKeyManager( + status = Registry::RegisterAsymmetricKeyManagers( + absl::make_unique<Ed25519SignKeyManager>(), absl::make_unique<Ed25519VerifyKeyManager>(), true); if (!status.ok()) return status; diff --git a/cc/signature/signature_key_templates_test.cc b/cc/signature/signature_key_templates_test.cc index 7499dfa9e..9d8cd5769 100644 --- a/cc/signature/signature_key_templates_test.cc +++ b/cc/signature/signature_key_templates_test.cc @@ -24,6 +24,7 @@ #include "tink/signature/ecdsa_sign_key_manager.h" #include "tink/signature/ecdsa_verify_key_manager.h" #include "tink/signature/ed25519_sign_key_manager.h" +#include "tink/signature/ed25519_verify_key_manager.h" #include "tink/signature/rsa_ssa_pkcs1_sign_key_manager.h" #include "tink/signature/rsa_ssa_pss_sign_key_manager.h" #include "tink/subtle/subtle_util_boringssl.h" @@ -351,10 +352,14 @@ TEST(SignatureKeyTemplatesTest, KeyTemplatesWithEd25519) { EXPECT_EQ(&key_template, &key_template_2); // Check that the key manager works with the template. - Ed25519SignKeyManager key_manager; - EXPECT_EQ(key_manager.get_key_type(), key_template.type_url()); + Ed25519SignKeyManager sign_key_type_manager; + Ed25519VerifyKeyManager verify_key_type_manager; + auto key_manager = internal::MakePrivateKeyManager<PublicKeySign>( + &sign_key_type_manager, &verify_key_type_manager); + + EXPECT_EQ(key_manager->get_key_type(), key_template.type_url()); Ed25519KeyFormat key_format; - auto new_key_result = key_manager.get_key_factory().NewKey(key_format); + auto new_key_result = key_manager->get_key_factory().NewKey(key_format); EXPECT_TRUE(new_key_result.ok()) << new_key_result.status(); } -- GitLab