From 7cfca3dc4b982ea91a38b125327a9d909c401859 Mon Sep 17 00:00:00 2001 From: tholenst <tholenst@google.com> Date: Tue, 3 Sep 2019 02:18:45 -0700 Subject: [PATCH] Migrate the tests for the RsaSsaPss{Sign,Verify}KeyManager to directly operate on the KeyTypeManager interface. PiperOrigin-RevId: 266884315 --- cc/signature/BUILD.bazel | 21 +- cc/signature/CMakeLists.txt | 22 +- .../rsa_ssa_pss_sign_key_manager_test.cc | 560 +++++++----------- .../rsa_ssa_pss_verify_key_manager_test.cc | 334 +++++------ 4 files changed, 399 insertions(+), 538 deletions(-) diff --git a/cc/signature/BUILD.bazel b/cc/signature/BUILD.bazel index 72194d7af..708f9af74 100644 --- a/cc/signature/BUILD.bazel +++ b/cc/signature/BUILD.bazel @@ -498,17 +498,18 @@ cc_test( srcs = ["rsa_ssa_pss_verify_key_manager_test.cc"], copts = ["-Iexternal/gtest/include"], deps = [ + ":rsa_ssa_pss_sign_key_manager", ":rsa_ssa_pss_verify_key_manager", - "//cc:config", "//cc:public_key_sign", "//cc:public_key_verify", - "//cc:registry", + "//cc/subtle:rsa_ssa_pss_sign_boringssl", + "//cc/subtle:subtle_util_boringssl", "//cc/util:status", + "//cc/util:statusor", + "//cc/util:test_matchers", "//cc/util:test_util", - "//proto:aes_eax_cc_proto", - "//proto:common_cc_proto", "//proto:rsa_ssa_pss_cc_proto", - "//proto:tink_cc_proto", + "@boringssl//:crypto", "@com_google_absl//absl/strings", "@com_google_googletest//:gtest_main", ], @@ -592,19 +593,17 @@ cc_test( ":rsa_ssa_pss_sign_key_manager", ":rsa_ssa_pss_verify_key_manager", ":signature_key_templates", - "//cc:config", "//cc:public_key_sign", "//cc:registry", - "//cc/aead:aead_key_templates", - "//cc/aead:aes_gcm_key_manager", + "//cc/subtle:rsa_ssa_pss_verify_boringssl", "//cc/subtle:subtle_util_boringssl", "//cc/util:status", + "//cc/util:statusor", + "//cc/util:test_matchers", "//cc/util:test_util", - "//proto:aes_eax_cc_proto", - "//proto:common_cc_proto", "//proto:rsa_ssa_pss_cc_proto", - "//proto:tink_cc_proto", "@boringssl//:crypto", + "@com_google_absl//absl/container:flat_hash_set", "@com_google_googletest//:gtest_main", ], ) diff --git a/cc/signature/CMakeLists.txt b/cc/signature/CMakeLists.txt index b668af8cd..060e98d2f 100644 --- a/cc/signature/CMakeLists.txt +++ b/cc/signature/CMakeLists.txt @@ -431,18 +431,18 @@ tink_cc_test( NAME rsa_ssa_pss_verify_key_manager_test SRCS rsa_ssa_pss_verify_key_manager_test.cc DEPS + tink::signature::rsa_ssa_pss_sign_key_manager tink::signature::rsa_ssa_pss_verify_key_manager - tink::core::config tink::core::public_key_sign tink::core::public_key_verify - tink::core::registry tink::util::status + tink::util::statusor tink::util::test_util - tink::proto::aes_eax_cc_proto - tink::proto::common_cc_proto + tink::util::test_matchers tink::proto::rsa_ssa_pss_cc_proto - tink::proto::tink_cc_proto absl::strings + crypto + gmock ) tink_cc_test( @@ -514,19 +514,17 @@ tink_cc_test( tink::signature::rsa_ssa_pss_sign_key_manager tink::signature::rsa_ssa_pss_verify_key_manager tink::signature::signature_key_templates - tink::core::config tink::core::public_key_sign - tink::core::registry - tink::aead::aead_key_templates - tink::aead::aes_gcm_key_manager + tink::subtle::rsa_ssa_pss_verify_boringssl tink::subtle::subtle_util_boringssl 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 tink::proto::rsa_ssa_pss_cc_proto - tink::proto::tink_cc_proto + absl::flat_hash_set crypto + gmock ) tink_cc_test( diff --git a/cc/signature/rsa_ssa_pss_sign_key_manager_test.cc b/cc/signature/rsa_ssa_pss_sign_key_manager_test.cc index f21ffe9ce..e6152aa95 100644 --- a/cc/signature/rsa_ssa_pss_sign_key_manager_test.cc +++ b/cc/signature/rsa_ssa_pss_sign_key_manager_test.cc @@ -16,61 +16,137 @@ #include "tink/signature/rsa_ssa_pss_sign_key_manager.h" +#include "gmock/gmock.h" #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 "absl/container/flat_hash_set.h" +#include "openssl/rsa.h" #include "tink/public_key_sign.h" -#include "tink/registry.h" #include "tink/signature/rsa_ssa_pss_verify_key_manager.h" #include "tink/signature/signature_key_templates.h" +#include "tink/subtle/rsa_ssa_pss_verify_boringssl.h" #include "tink/subtle/subtle_util_boringssl.h" #include "tink/util/status.h" #include "tink/util/statusor.h" +#include "tink/util/test_matchers.h" #include "tink/util/test_util.h" -#include "proto/aes_eax.pb.h" -#include "proto/common.pb.h" #include "proto/rsa_ssa_pss.pb.h" -#include "proto/tink.pb.h" - -namespace pb = google::crypto::tink; namespace crypto { namespace tink { +namespace { -using google::crypto::tink::AesEaxKeyFormat; -using google::crypto::tink::KeyData; -using google::crypto::tink::RsaSsaPssKeyFormat; -using google::crypto::tink::RsaSsaPssPrivateKey; -using google::crypto::tink::RsaSsaPssPublicKey; -using subtle::SubtleUtilBoringSSL; +using ::crypto::tink::subtle::SubtleUtilBoringSSL; +using ::crypto::tink::test::IsOk; +using ::crypto::tink::util::StatusOr; +using ::google::crypto::tink::HashType; +using ::google::crypto::tink::KeyData; +using ::google::crypto::tink::RsaSsaPssKeyFormat; +using ::google::crypto::tink::RsaSsaPssPrivateKey; +using ::google::crypto::tink::RsaSsaPssPublicKey; +using ::testing::Eq; +using ::testing::Gt; +using ::testing::Not; +using ::testing::SizeIs; + +TEST(RsaSsaPssSignKeyManagerTest, Basic) { + EXPECT_THAT(RsaSsaPssSignKeyManager().get_version(), Eq(0)); + EXPECT_THAT(RsaSsaPssSignKeyManager().key_material_type(), + Eq(KeyData::ASYMMETRIC_PRIVATE)); + EXPECT_THAT(RsaSsaPssSignKeyManager().get_key_type(), + Eq("type.googleapis.com/google.crypto.tink.RsaSsaPssPrivateKey")); +} -namespace { +RsaSsaPssKeyFormat CreateKeyFormat(HashType sig_hash, HashType mgf1_hash, + int salt_length, int modulus_size_in_bits, + int public_exponent) { + RsaSsaPssKeyFormat key_format; + auto params = key_format.mutable_params(); + params->set_sig_hash(sig_hash); + params->set_mgf1_hash(mgf1_hash); + params->set_salt_length(salt_length); + key_format.set_modulus_size_in_bits(modulus_size_in_bits); + + bssl::UniquePtr<BIGNUM> e(BN_new()); + BN_set_word(e.get(), public_exponent); + key_format.set_public_exponent( + subtle::SubtleUtilBoringSSL::bn2str(e.get(), BN_num_bytes(e.get())) + .ValueOrDie()); + + return key_format; +} -class RsaSsaPssSignKeyManagerTest : public ::testing::Test { - protected: - std::string key_type_prefix_ = "type.googleapis.com/"; - std::string rsa_ssa_pss_sign_key_type_ = - "type.googleapis.com/google.crypto.tink.RsaSsaPssPrivateKey"; -}; +RsaSsaPssKeyFormat ValidKeyFormat() { + return CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4); +} + +TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormat) { + EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(ValidKeyFormat()), + IsOk()); +} + +TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatSha512Allowed) { + RsaSsaPssKeyFormat key_format = ValidKeyFormat(); + key_format.mutable_params()->set_sig_hash(HashType::SHA512); + key_format.mutable_params()->set_mgf1_hash(HashType::SHA512); + EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(ValidKeyFormat()), + IsOk()); +} + +TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatSha1Disallowed) { + RsaSsaPssKeyFormat key_format = ValidKeyFormat(); + key_format.mutable_params()->set_sig_hash(HashType::SHA1); + EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format), + Not(IsOk())); +} -// Checks whether given key is compatible with the given format. +TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatSmallModulusDisallowed) { + RsaSsaPssKeyFormat key_format = ValidKeyFormat(); + key_format.set_modulus_size_in_bits(512); + EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format), + Not(IsOk())); +} + +TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatHashMismatchDisallowed) { + RsaSsaPssKeyFormat key_format = ValidKeyFormat(); + key_format.mutable_params()->set_sig_hash(HashType::SHA512); + key_format.mutable_params()->set_mgf1_hash(HashType::SHA256); + EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format), + Not(IsOk())); +} + +TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatHashMismatchDisallowed2) { + RsaSsaPssKeyFormat key_format = ValidKeyFormat(); + key_format.mutable_params()->set_sig_hash(HashType::SHA256); + key_format.mutable_params()->set_mgf1_hash(HashType::SHA512); + EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format), + Not(IsOk())); +} + +TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatUnkownHashDisallowed) { + RsaSsaPssKeyFormat key_format = ValidKeyFormat(); + key_format.mutable_params()->set_sig_hash(HashType::UNKNOWN_HASH); + key_format.mutable_params()->set_mgf1_hash(HashType::UNKNOWN_HASH); + EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format), + Not(IsOk())); +} + +// Runs several sanity checks, checking if a given private key fits a format. void CheckNewKey(const RsaSsaPssPrivateKey& private_key, const RsaSsaPssKeyFormat& key_format) { - RsaSsaPssSignKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeySign>(&key_type_manager); RsaSsaPssPublicKey public_key = private_key.public_key(); - EXPECT_EQ(0, private_key.version()); - EXPECT_TRUE(private_key.has_public_key()); - EXPECT_EQ(0, public_key.version()); - EXPECT_GT(public_key.n().length(), 0); - EXPECT_GT(public_key.e().length(), 0); - EXPECT_EQ(public_key.params().SerializeAsString(), - key_format.params().SerializeAsString()); - EXPECT_EQ(key_format.public_exponent(), public_key.e()); - auto primitive_result = key_manager->GetPrimitive(private_key); - EXPECT_TRUE(primitive_result.ok()) << primitive_result.status(); + + EXPECT_THAT(private_key.version(), Eq(0)); + EXPECT_THAT(private_key.version(), Eq(public_key.version())); + EXPECT_THAT(public_key.n().length(), Gt(0)); + EXPECT_THAT(public_key.e().length(), Gt(0)); + EXPECT_THAT(public_key.params().sig_hash(), + Eq(key_format.params().sig_hash())); + EXPECT_THAT(public_key.params().mgf1_hash(), + Eq(key_format.params().mgf1_hash())); + EXPECT_THAT(public_key.params().salt_length(), + Eq(key_format.params().salt_length())); + + EXPECT_THAT(key_format.public_exponent(), Eq(public_key.e())); auto n = std::move(SubtleUtilBoringSSL::str2bn(public_key.n()).ValueOrDie()); auto d = std::move(SubtleUtilBoringSSL::str2bn(private_key.d()).ValueOrDie()); auto p = std::move(SubtleUtilBoringSSL::str2bn(private_key.p()).ValueOrDie()); @@ -83,345 +159,149 @@ void CheckNewKey(const RsaSsaPssPrivateKey& private_key, // Check n = p * q. auto n_calc = bssl::UniquePtr<BIGNUM>(BN_new()); - ASSERT_TRUE(BN_mul(n_calc.get(), p.get(), q.get(), ctx.get())); - ASSERT_TRUE(BN_equal_consttime(n_calc.get(), n.get())); + EXPECT_TRUE(BN_mul(n_calc.get(), p.get(), q.get(), ctx.get())); + EXPECT_TRUE(BN_equal_consttime(n_calc.get(), n.get())); // Check n size >= modulus_size_in_bits bit. EXPECT_GE(BN_num_bits(n.get()), key_format.modulus_size_in_bits()); // dp = d mod (p - 1) auto pm1 = bssl::UniquePtr<BIGNUM>(BN_dup(p.get())); - ASSERT_TRUE(BN_sub_word(pm1.get(), 1)); + EXPECT_TRUE(BN_sub_word(pm1.get(), 1)); auto dp_calc = bssl::UniquePtr<BIGNUM>(BN_new()); - ASSERT_TRUE(BN_mod(dp_calc.get(), d.get(), pm1.get(), ctx.get())); - ASSERT_TRUE(BN_equal_consttime(dp_calc.get(), dp.get())); + EXPECT_TRUE(BN_mod(dp_calc.get(), d.get(), pm1.get(), ctx.get())); + EXPECT_TRUE(BN_equal_consttime(dp_calc.get(), dp.get())); // dq = d mod (q - 1) auto qm1 = bssl::UniquePtr<BIGNUM>(BN_dup(q.get())); - ASSERT_TRUE(BN_sub_word(qm1.get(), 1)); + EXPECT_TRUE(BN_sub_word(qm1.get(), 1)); auto dq_calc = bssl::UniquePtr<BIGNUM>(BN_new()); - ASSERT_TRUE(BN_mod(dq_calc.get(), d.get(), qm1.get(), ctx.get())); - - ASSERT_TRUE(BN_equal_consttime(dq_calc.get(), dq.get())); + EXPECT_TRUE(BN_mod(dq_calc.get(), d.get(), qm1.get(), ctx.get())); + EXPECT_TRUE(BN_equal_consttime(dq_calc.get(), dq.get())); } -TEST_F(RsaSsaPssSignKeyManagerTest, Basic) { - RsaSsaPssSignKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeySign>(&key_type_manager); - EXPECT_EQ(0, key_manager->get_version()); - EXPECT_EQ("type.googleapis.com/google.crypto.tink.RsaSsaPssPrivateKey", - key_manager->get_key_type()); - EXPECT_TRUE(key_manager->DoesSupport(key_manager->get_key_type())); +TEST(RsaSsaPssSignKeyManagerTest, CreateKey) { + RsaSsaPssKeyFormat key_format = ValidKeyFormat(); + StatusOr<RsaSsaPssPrivateKey> private_key_or = + RsaSsaPssSignKeyManager().CreateKey(key_format); + ASSERT_THAT(private_key_or.status(), IsOk()); + CheckNewKey(private_key_or.ValueOrDie(), key_format); } -TEST_F(RsaSsaPssSignKeyManagerTest, NewKeyFromKeyFormat) { - RsaSsaPssSignKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeySign>(&key_type_manager); - const KeyFactory& key_factory = key_manager->get_key_factory(); - RsaSsaPssKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4().value())); - auto result = key_factory.NewKey(key_format); - EXPECT_TRUE(result.ok()) << result.status(); - auto key = std::move(result.ValueOrDie()); - ASSERT_EQ(rsa_ssa_pss_sign_key_type_, key_type_prefix_ + key->GetTypeName()); - std::unique_ptr<RsaSsaPssPrivateKey> rsa_key( - static_cast<RsaSsaPssPrivateKey*>(key.release())); - CheckNewKey(*rsa_key, key_format); -} - -TEST_F(RsaSsaPssSignKeyManagerTest, NewKeyFromSerializedKeyFormat) { - RsaSsaPssSignKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeySign>(&key_type_manager); - const KeyFactory& key_factory = key_manager->get_key_factory(); - RsaSsaPssKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - SignatureKeyTemplates::RsaSsaPss4096Sha512Sha512F4().value())); - auto result = key_factory.NewKey(key_format.SerializeAsString()); - EXPECT_TRUE(result.ok()) << result.status(); - auto key = std::move(result.ValueOrDie()); - ASSERT_EQ(rsa_ssa_pss_sign_key_type_, key_type_prefix_ + key->GetTypeName()); - std::unique_ptr<RsaSsaPssPrivateKey> rsa_key( - static_cast<RsaSsaPssPrivateKey*>(key.release())); - CheckNewKey(*rsa_key, key_format); -} - -TEST_F(RsaSsaPssSignKeyManagerTest, NewKeyDataFromSerializedKeyFormat) { - RsaSsaPssSignKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeySign>(&key_type_manager); - const KeyFactory& key_factory = key_manager->get_key_factory(); - RsaSsaPssKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - SignatureKeyTemplates::RsaSsaPss4096Sha512Sha512F4().value())); - auto result = key_factory.NewKeyData(key_format.SerializeAsString()); - EXPECT_TRUE(result.ok()) << result.status(); - auto key_data = std::move(result.ValueOrDie()); - ASSERT_EQ(rsa_ssa_pss_sign_key_type_, key_data->type_url()); - RsaSsaPssPrivateKey rsa_key; - ASSERT_TRUE(rsa_key.ParseFromString(key_data->value())); - CheckNewKey(rsa_key, key_format); -} +TEST(RsaSsaPssSignKeyManagerTest, CreateKeySmallKey) { + RsaSsaPssKeyFormat key_format = + CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4); -TEST_F(RsaSsaPssSignKeyManagerTest, PublicKeyExtraction) { - RsaSsaPssSignKeyManager sign_key_type_manager; - RsaSsaPssVerifyKeyManager verify_key_type_manager; - auto verify_key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&verify_key_type_manager); - auto sign_key_manager = internal::MakePrivateKeyManager<PublicKeySign>( - &sign_key_type_manager, &verify_key_type_manager); - - auto private_key_factory = dynamic_cast<const PrivateKeyFactory*>( - &(sign_key_manager->get_key_factory())); - ASSERT_NE(private_key_factory, nullptr); - auto new_key_result = private_key_factory->NewKey( - SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4().value()); - std::unique_ptr<RsaSsaPssPrivateKey> private_key( - static_cast<RsaSsaPssPrivateKey*>(new_key_result.ValueOrDie().release())); - auto public_key_data_result = - private_key_factory->GetPublicKeyData(private_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(RsaSsaPssVerifyKeyManager().get_key_type(), - public_key_data->type_url()); - EXPECT_EQ(KeyData::ASYMMETRIC_PUBLIC, public_key_data->key_material_type()); - EXPECT_EQ(private_key->public_key().SerializeAsString(), - public_key_data->value()); - // Sign with private key and verify with public key. - auto signer = sign_key_manager->GetPrimitive(*private_key); - auto verifier = verify_key_manager->GetPrimitive(*public_key_data); - std::string message = "Wycheproof"; - EXPECT_TRUE( - verifier.ValueOrDie() - ->Verify(signer.ValueOrDie()->Sign(message).ValueOrDie(), message) - .ok()); + StatusOr<RsaSsaPssPrivateKey> private_key_or = + RsaSsaPssSignKeyManager().CreateKey(key_format); + ASSERT_THAT(private_key_or.status(), IsOk()); + CheckNewKey(private_key_or.ValueOrDie(), key_format); } -TEST_F(RsaSsaPssSignKeyManagerTest, NewKeyWithWeakSignatureHash) { - RsaSsaPssSignKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); - const KeyFactory& key_factory = key_manager->get_key_factory(); - RsaSsaPssKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4().value())); - key_format.mutable_params()->set_sig_hash(pb::HashType::SHA1); - auto result = key_factory.NewKey(key_format.SerializeAsString()); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, - "SHA1 is not safe for digital signature", - result.status().error_message()); -} +TEST(RsaSsaPssSignKeyManagerTest, CreateKeyLargeKey) { + RsaSsaPssKeyFormat key_format = + CreateKeyFormat(HashType::SHA512, HashType::SHA512, 64, 4096, RSA_F4); -TEST_F(RsaSsaPssSignKeyManagerTest, NewKeyWithSmallModulus) { - RsaSsaPssSignKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); - const KeyFactory& key_factory = key_manager->get_key_factory(); - RsaSsaPssKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4().value())); - key_format.set_modulus_size_in_bits(512); - auto result = key_factory.NewKey(key_format.SerializeAsString()); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, - "only modulus size >= 2048-bit is supported", - result.status().error_message()); + StatusOr<RsaSsaPssPrivateKey> private_key_or = + RsaSsaPssSignKeyManager().CreateKey(key_format); + ASSERT_THAT(private_key_or.status(), IsOk()); + CheckNewKey(private_key_or.ValueOrDie(), key_format); } -TEST_F(RsaSsaPssSignKeyManagerTest, NewKeyWithMismatchMg1HashAndSigHash) { - RsaSsaPssSignKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); - const KeyFactory& key_factory = key_manager->get_key_factory(); - RsaSsaPssKeyFormat key_format; - ASSERT_TRUE(key_format.ParseFromString( - SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4().value())); - key_format.mutable_params()->set_sig_hash(pb::HashType::SHA512); - key_format.mutable_params()->set_mgf1_hash(pb::HashType::SHA256); - auto result = key_factory.NewKey(key_format.SerializeAsString()); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); +TEST(RsaSsaPssSignKeyManagerTest, CreateKeyValid) { + StatusOr<RsaSsaPssPrivateKey> key_or = + RsaSsaPssSignKeyManager().CreateKey(ValidKeyFormat()); + ASSERT_THAT(key_or.status(), IsOk()); + EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKey(key_or.ValueOrDie()), + IsOk()); } -TEST_F(RsaSsaPssSignKeyManagerTest, - GetPrimitiveWithMismatchMgf1HashAndSigHash) { - RsaSsaPssSignKeyManager sign_key_type_manager; - RsaSsaPssVerifyKeyManager verify_key_type_manager; - auto verify_key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&verify_key_type_manager); - auto sign_key_manager = internal::MakePrivateKeyManager<PublicKeySign>( - &sign_key_type_manager, &verify_key_type_manager); - - auto private_key_factory = dynamic_cast<const PrivateKeyFactory*>( - &(sign_key_manager->get_key_factory())); - ASSERT_NE(private_key_factory, nullptr); - auto new_key_result = private_key_factory->NewKey( - SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4().value()); - std::unique_ptr<RsaSsaPssPrivateKey> private_key( - static_cast<RsaSsaPssPrivateKey*>(new_key_result.ValueOrDie().release())); - private_key->mutable_public_key()->mutable_params()->set_sig_hash( - pb::HashType::SHA256); - private_key->mutable_public_key()->mutable_params()->set_mgf1_hash( - pb::HashType::SHA512); - - auto result = sign_key_manager->GetPrimitive(*private_key); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); +// Check that in a bunch of CreateKey calls all generated primes are distinct. +TEST(RsaSsaPssSignKeyManagerTest, CreateKeyAlwaysNewRsaPair) { + absl::flat_hash_set<std::string> keys; + // This test takes about a second per key. + int num_generated_keys = 5; + for (int i = 0; i < num_generated_keys; ++i) { + StatusOr<RsaSsaPssPrivateKey> key_or = + RsaSsaPssSignKeyManager().CreateKey(ValidKeyFormat()); + ASSERT_THAT(key_or.status(), IsOk()); + keys.insert(key_or.ValueOrDie().p()); + keys.insert(key_or.ValueOrDie().q()); + } + EXPECT_THAT(keys, SizeIs(2 * num_generated_keys)); } -TEST_F(RsaSsaPssSignKeyManagerTest, GetPrimitiveWithWeakSignatureHash) { - RsaSsaPssSignKeyManager sign_key_type_manager; - RsaSsaPssVerifyKeyManager verify_key_type_manager; - auto verify_key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&verify_key_type_manager); - auto sign_key_manager = internal::MakePrivateKeyManager<PublicKeySign>( - &sign_key_type_manager, &verify_key_type_manager); - - auto private_key_factory = dynamic_cast<const PrivateKeyFactory*>( - &(sign_key_manager->get_key_factory())); - ASSERT_NE(private_key_factory, nullptr); - auto new_key_result = private_key_factory->NewKey( - SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4().value()); - std::unique_ptr<RsaSsaPssPrivateKey> private_key( - static_cast<RsaSsaPssPrivateKey*>(new_key_result.ValueOrDie().release())); - private_key->mutable_public_key()->mutable_params()->set_sig_hash( - pb::HashType::SHA1); - auto result = sign_key_manager->GetPrimitive(*private_key); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, - "SHA1 is not safe for digital signature", - result.status().error_message()); +TEST(RsaSsaPssSignKeyManagerTest, GetPublicKey) { + StatusOr<RsaSsaPssPrivateKey> key_or = + RsaSsaPssSignKeyManager().CreateKey(ValidKeyFormat()); + ASSERT_THAT(key_or.status(), IsOk()); + StatusOr<RsaSsaPssPublicKey> public_key_or = + RsaSsaPssSignKeyManager().GetPublicKey(key_or.ValueOrDie()); + ASSERT_THAT(public_key_or.status(), IsOk()); + EXPECT_THAT(public_key_or.ValueOrDie().version(), + Eq(key_or.ValueOrDie().public_key().version())); + EXPECT_THAT(public_key_or.ValueOrDie().n(), + Eq(key_or.ValueOrDie().public_key().n())); + EXPECT_THAT(public_key_or.ValueOrDie().e(), + Eq(key_or.ValueOrDie().public_key().e())); } -TEST_F(RsaSsaPssSignKeyManagerTest, GetPrimitiveWithSmallModulus) { - RsaSsaPssSignKeyManager sign_key_type_manager; - RsaSsaPssVerifyKeyManager verify_key_type_manager; - auto verify_key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&verify_key_type_manager); - auto sign_key_manager = internal::MakePrivateKeyManager<PublicKeySign>( - &sign_key_type_manager, &verify_key_type_manager); - - auto private_key_factory = dynamic_cast<const PrivateKeyFactory*>( - &(sign_key_manager->get_key_factory())); - ASSERT_NE(private_key_factory, nullptr); - auto new_key_result = private_key_factory->NewKey( - SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4().value()); - std::unique_ptr<RsaSsaPssPrivateKey> private_key( - static_cast<RsaSsaPssPrivateKey*>(new_key_result.ValueOrDie().release())); - private_key->mutable_public_key()->set_n("\x23"); - private_key->mutable_public_key()->set_e("\x3"); - auto result = sign_key_manager->GetPrimitive(*private_key); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, - "only modulus size >= 2048-bit is supported", - result.status().error_message()); +TEST(EcdsaSignKeyManagerTest, Create) { + RsaSsaPssKeyFormat key_format = + CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4); + StatusOr<RsaSsaPssPrivateKey> key_or = + RsaSsaPssSignKeyManager().CreateKey(key_format); + ASSERT_THAT(key_or.status(), IsOk()); + RsaSsaPssPrivateKey key = key_or.ValueOrDie(); + + auto signer_or = RsaSsaPssSignKeyManager().GetPrimitive<PublicKeySign>(key); + ASSERT_THAT(signer_or.status(), IsOk()); + + subtle::SubtleUtilBoringSSL::RsaSsaPssParams params; + params.sig_hash = subtle::HashType::SHA256; + params.mgf1_hash = subtle::HashType::SHA256; + params.salt_length = 32; + auto direct_verifier_or = subtle::RsaSsaPssVerifyBoringSsl::New( + {key.public_key().n(), key.public_key().e()}, params); + + ASSERT_THAT(direct_verifier_or.status(), IsOk()); + + std::string message = "Some message"; + EXPECT_THAT(direct_verifier_or.ValueOrDie()->Verify( + signer_or.ValueOrDie()->Sign(message).ValueOrDie(), message), + IsOk()); } -TEST_F(RsaSsaPssSignKeyManagerTest, KeyDataErrors) { - RsaSsaPssSignKeyManager sign_key_type_manager; - RsaSsaPssVerifyKeyManager verify_key_type_manager; - auto verify_key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&verify_key_type_manager); - auto sign_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 = sign_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(rsa_ssa_pss_sign_key_type_); - key_data.set_value("some bad serialized proto"); - auto result = sign_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; - RsaSsaPssPrivateKey key; - key.set_version(1); - key_data.set_type_url(rsa_ssa_pss_sign_key_type_); - key_data.set_value(key.SerializeAsString()); - auto result = sign_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(EcdsaSignKeyManagerTest, CreateWrongKey) { + RsaSsaPssKeyFormat key_format = + CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4); + StatusOr<RsaSsaPssPrivateKey> key_or = + RsaSsaPssSignKeyManager().CreateKey(key_format); + ASSERT_THAT(key_or.status(), IsOk()); + RsaSsaPssPrivateKey key = key_or.ValueOrDie(); -TEST_F(RsaSsaPssSignKeyManagerTest, NewKeyErrors) { - RsaSsaPssSignKeyManager sign_key_type_manager; - RsaSsaPssVerifyKeyManager verify_key_type_manager; - auto verify_key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&verify_key_type_manager); - auto sign_key_manager = internal::MakePrivateKeyManager<PublicKeySign>( - &sign_key_type_manager, &verify_key_type_manager); + auto signer_or = RsaSsaPssSignKeyManager().GetPrimitive<PublicKeySign>(key); - const KeyFactory& key_factory = sign_key_manager->get_key_factory(); + StatusOr<RsaSsaPssPrivateKey> second_key_or = + RsaSsaPssSignKeyManager().CreateKey(key_format); + ASSERT_THAT(second_key_or.status(), IsOk()); + RsaSsaPssPrivateKey second_key = second_key_or.ValueOrDie(); - // Empty key format. - RsaSsaPssKeyFormat key_format; - { - auto result = key_factory.NewKey(key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - } + ASSERT_THAT(signer_or.status(), IsOk()); - // Bad serialized format. - { - auto result = key_factory.NewKey("some bad serialization"); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - } + subtle::SubtleUtilBoringSSL::RsaSsaPssParams params; + params.sig_hash = subtle::HashType::SHA256; + params.mgf1_hash = subtle::HashType::SHA256; + params.salt_length = 32; + auto direct_verifier_or = subtle::RsaSsaPssVerifyBoringSsl::New( + {second_key.public_key().n(), second_key.public_key().e()}, params); - // Wrong format proto. - { - AesEaxKeyFormat wrong_key_format; - auto result = key_factory.NewKey(wrong_key_format); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, result.status().error_code()); - } -} + ASSERT_THAT(direct_verifier_or.status(), IsOk()); -TEST_F(RsaSsaPssSignKeyManagerTest, PublicKeyExtractionErrors) { - RsaSsaPssSignKeyManager sign_key_type_manager; - RsaSsaPssVerifyKeyManager verify_key_type_manager; - auto verify_key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&verify_key_type_manager); - auto sign_key_manager = internal::MakePrivateKeyManager<PublicKeySign>( - &sign_key_type_manager, &verify_key_type_manager); - - auto private_key_factory = dynamic_cast<const PrivateKeyFactory*>( - &(sign_key_manager->get_key_factory())); - ASSERT_NE(private_key_factory, nullptr); - - auto public_key_data_result = private_key_factory->GetPublicKeyData( - google::crypto::tink::AesGcmKey().SerializeAsString()); - EXPECT_FALSE(public_key_data_result.ok()); - EXPECT_EQ(util::error::INVALID_ARGUMENT, - public_key_data_result.status().error_code()); + std::string message = "Some message"; + EXPECT_THAT(direct_verifier_or.ValueOrDie()->Verify( + signer_or.ValueOrDie()->Sign(message).ValueOrDie(), message), + Not(IsOk())); } } // namespace diff --git a/cc/signature/rsa_ssa_pss_verify_key_manager_test.cc b/cc/signature/rsa_ssa_pss_verify_key_manager_test.cc index add999453..a8fa3a9f2 100644 --- a/cc/signature/rsa_ssa_pss_verify_key_manager_test.cc +++ b/cc/signature/rsa_ssa_pss_verify_key_manager_test.cc @@ -16,37 +16,159 @@ #include "tink/signature/rsa_ssa_pss_verify_key_manager.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/strings/escaping.h" +#include "openssl/rsa.h" #include "tink/public_key_sign.h" #include "tink/public_key_verify.h" - -#include "tink/registry.h" +#include "tink/signature/rsa_ssa_pss_sign_key_manager.h" +#include "tink/subtle/rsa_ssa_pss_sign_boringssl.h" +#include "tink/subtle/subtle_util_boringssl.h" #include "tink/util/status.h" #include "tink/util/statusor.h" +#include "tink/util/test_matchers.h" #include "tink/util/test_util.h" -#include "proto/common.pb.h" #include "proto/rsa_ssa_pss.pb.h" -#include "proto/tink.pb.h" - -namespace pb = google::crypto::tink; -// TODO(quannguyen): add more tests once RsaSsaPssSignKeyManager is available. namespace crypto { namespace tink { +namespace { -using google::crypto::tink::KeyData; -using google::crypto::tink::RsaSsaPssKeyFormat; -using google::crypto::tink::RsaSsaPssPublicKey; +using ::crypto::tink::test::IsOk; +using ::crypto::tink::test::StatusIs; +using ::crypto::tink::util::StatusOr; +using ::google::crypto::tink::HashType; +using ::google::crypto::tink::KeyData; +using ::google::crypto::tink::RsaSsaPssKeyFormat; +using ::google::crypto::tink::RsaSsaPssPrivateKey; +using ::google::crypto::tink::RsaSsaPssPublicKey; +using ::testing::Eq; +using ::testing::Not; +using ::testing::HasSubstr; + +TEST(RsaSsaPssVerifyKeyManagerTest, Basics) { + EXPECT_THAT(RsaSsaPssVerifyKeyManager().get_version(), Eq(0)); + EXPECT_THAT(RsaSsaPssVerifyKeyManager().key_material_type(), + Eq(KeyData::ASYMMETRIC_PUBLIC)); + EXPECT_THAT(RsaSsaPssVerifyKeyManager().get_key_type(), + Eq("type.googleapis.com/google.crypto.tink.RsaSsaPssPublicKey")); +} -namespace { +TEST(RsaSsaPssVerifyKeyManagerTest, ValidateEmptyKey) { + EXPECT_THAT(RsaSsaPssVerifyKeyManager().ValidateKey(RsaSsaPssPublicKey()), + Not(IsOk())); +} -class RsaSsaPssVerifyKeyManagerTest : public ::testing::Test { - protected: - std::string key_type_prefix_ = "type.googleapis.com/"; - std::string rsa_ssa_pss_verify_key_type_ = - "type.googleapis.com/google.crypto.tink.RsaSsaPssPublicKey"; -}; +RsaSsaPssKeyFormat CreateKeyFormat(HashType sig_hash, HashType mgf1_hash, + int salt_length, int modulus_size_in_bits, + int public_exponent) { + RsaSsaPssKeyFormat key_format; + auto params = key_format.mutable_params(); + params->set_sig_hash(sig_hash); + params->set_mgf1_hash(mgf1_hash); + params->set_salt_length(salt_length); + key_format.set_modulus_size_in_bits(modulus_size_in_bits); + + bssl::UniquePtr<BIGNUM> e(BN_new()); + BN_set_word(e.get(), public_exponent); + key_format.set_public_exponent( + subtle::SubtleUtilBoringSSL::bn2str(e.get(), BN_num_bytes(e.get())) + .ValueOrDie()); + + return key_format; +} + +RsaSsaPssKeyFormat ValidKeyFormat() { + return CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4); +} + +RsaSsaPssPrivateKey CreateValidPrivateKey() { + return RsaSsaPssSignKeyManager().CreateKey(ValidKeyFormat()).ValueOrDie(); +} + +RsaSsaPssPublicKey CreateValidPublicKey() { + return RsaSsaPssSignKeyManager() + .GetPublicKey(CreateValidPrivateKey()) + .ValueOrDie(); +} + +// Checks that a public key generaed by the SignKeyManager is considered valid. +TEST(RsaSsaPssVerifyKeyManagerTest, PublicKeyValid) { + RsaSsaPssPublicKey key = CreateValidPublicKey(); + EXPECT_THAT(RsaSsaPssVerifyKeyManager().ValidateKey(key), IsOk()); +} + +TEST(RsaSsaPssVerifyKeyManagerTest, PublicKeyWrongVersion) { + RsaSsaPssPublicKey key = CreateValidPublicKey(); + key.set_version(1); + EXPECT_THAT(RsaSsaPssVerifyKeyManager().ValidateKey(key), Not(IsOk())); +} + +TEST(RsaSsaPssVerifyKeyManagerTest, PublicKeyHashMismatchDisallowed) { + RsaSsaPssPublicKey key = CreateValidPublicKey(); + key.mutable_params()->set_sig_hash(HashType::SHA512); + key.mutable_params()->set_mgf1_hash(HashType::SHA256); + EXPECT_THAT(RsaSsaPssVerifyKeyManager().ValidateKey(key), Not(IsOk())); +} + +TEST(RsaSsaPssVerifyKeyManagerTest, PublicKeyHashMismatchDisallowed2) { + RsaSsaPssPublicKey key = CreateValidPublicKey(); + key.mutable_params()->set_sig_hash(HashType::SHA256); + key.mutable_params()->set_mgf1_hash(HashType::SHA512); + EXPECT_THAT(RsaSsaPssVerifyKeyManager().ValidateKey(key), Not(IsOk())); +} + +TEST(RsaSsaPssVerifyKeyManagerTest, PublicKeyUnkownHashDisallowed) { + RsaSsaPssPublicKey key = CreateValidPublicKey(); + key.mutable_params()->set_sig_hash(HashType::UNKNOWN_HASH); + key.mutable_params()->set_mgf1_hash(HashType::UNKNOWN_HASH); + EXPECT_THAT(RsaSsaPssVerifyKeyManager().ValidateKey(key), Not(IsOk())); +} + +TEST(RsaSsaPssVerifyKeyManagerTest, ValidateKeyFormatSmallModulusDisallowed) { + RsaSsaPssPublicKey key = CreateValidPublicKey(); + key.set_n("\x23"); + key.set_e("\x3"); + EXPECT_THAT(RsaSsaPssVerifyKeyManager().ValidateKey(key), + StatusIs(util::error::INVALID_ARGUMENT, + HasSubstr("only modulus size >= 2048"))); +} + +TEST(RsaSsaPssSignKeyManagerTest, Create) { + RsaSsaPssKeyFormat key_format = + CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4); + StatusOr<RsaSsaPssPrivateKey> private_key_or = + RsaSsaPssSignKeyManager().CreateKey(key_format); + ASSERT_THAT(private_key_or.status(), IsOk()); + RsaSsaPssPrivateKey private_key = private_key_or.ValueOrDie(); + RsaSsaPssPublicKey public_key = + RsaSsaPssSignKeyManager().GetPublicKey(private_key).ValueOrDie(); + + subtle::SubtleUtilBoringSSL::RsaPrivateKey private_key_subtle; + private_key_subtle.n = private_key.public_key().n(); + private_key_subtle.e = private_key.public_key().e(); + private_key_subtle.d = private_key.d(); + private_key_subtle.p = private_key.p(); + private_key_subtle.q = private_key.q(); + private_key_subtle.dp = private_key.dp(); + private_key_subtle.dq = private_key.dq(); + private_key_subtle.crt = private_key.crt(); + + auto direct_signer_or = subtle::RsaSsaPssSignBoringSsl::New( + private_key_subtle, {crypto::tink::subtle::HashType::SHA256, + crypto::tink::subtle::HashType::SHA256, 32}); + + auto verifier_or = + RsaSsaPssVerifyKeyManager().GetPrimitive<PublicKeyVerify>(public_key); + ASSERT_THAT(verifier_or.status(), IsOk()); + + std::string message = "Some message"; + EXPECT_THAT( + verifier_or.ValueOrDie()->Verify( + direct_signer_or.ValueOrDie()->Sign(message).ValueOrDie(), message), + IsOk()); +} // Test vector from // https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Digital-Signatures @@ -55,12 +177,13 @@ struct NistTestVector { std::string e; std::string message; std::string signature; - pb::HashType sig_hash; - pb::HashType mgf1_hash; + HashType sig_hash; + HashType mgf1_hash; int salt_length; }; -static const NistTestVector nist_test_vector{ +// clang-format off +static const NistTestVector* nist_test_vector = new NistTestVector({ absl::HexStringToBytes( "a47d04e7cacdba4ea26eca8a4c6e14563c2ce03b623b768c0d49868a57121301dbf783" "d82f4c055e73960e70550187d0af62ac3496f0a3d9103c2eb7919a72752fa7ce8c688d" @@ -85,166 +208,27 @@ static const NistTestVector nist_test_vector{ "b5388383c26079f344e2aea600d0e324164b450f7b9b465111b7265f3b1b063089ae7e" "2623fc0fda8052cf4bf3379102fbf71d7c98e8258664ceed637d20f95ff0111881e650" "ce61f251d9c3a629ef222d"), - pb::HashType::SHA256, - pb::HashType::SHA256, - 32}; + HashType::SHA256, + HashType::SHA256, + 32}); +// clang-format on -TEST_F(RsaSsaPssVerifyKeyManagerTest, testBasic) { - RsaSsaPssVerifyKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); - - EXPECT_EQ(0, key_manager->get_version()); - EXPECT_EQ("type.googleapis.com/google.crypto.tink.RsaSsaPssPublicKey", - key_manager->get_key_type()); - EXPECT_TRUE(key_manager->DoesSupport(key_manager->get_key_type())); - - // NIST test vector should work. +TEST(RsaSsaPssVerifyKeyManagerTest, TestVector) { RsaSsaPssPublicKey key; - key.mutable_params()->set_mgf1_hash(nist_test_vector.mgf1_hash); - key.mutable_params()->set_sig_hash(nist_test_vector.sig_hash); - key.mutable_params()->set_salt_length(nist_test_vector.salt_length); + key.mutable_params()->set_mgf1_hash(nist_test_vector->mgf1_hash); + key.mutable_params()->set_sig_hash(nist_test_vector->sig_hash); + key.mutable_params()->set_salt_length(nist_test_vector->salt_length); key.set_version(0); - key.set_n(nist_test_vector.n); - key.set_e(nist_test_vector.e); - auto result = key_manager->GetPrimitive(key); - EXPECT_TRUE(result.ok()); - EXPECT_TRUE(result.ValueOrDie() - ->Verify(nist_test_vector.signature, nist_test_vector.message) - .ok()); -} - -TEST_F(RsaSsaPssVerifyKeyManagerTest, testKeyDataErrors) { - RsaSsaPssVerifyKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&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(rsa_ssa_pss_verify_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; - RsaSsaPssPublicKey key; - key.set_version(1); - key_data.set_type_url(rsa_ssa_pss_verify_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_F(RsaSsaPssVerifyKeyManagerTest, testKeyMessageErrors) { - RsaSsaPssVerifyKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); - - { // Use SHA1 as signature hash. - RsaSsaPssPublicKey key; - key.mutable_params()->set_mgf1_hash(pb::HashType::SHA1); - key.mutable_params()->set_sig_hash(pb::HashType::SHA1); - key.mutable_params()->set_salt_length(20); - key.set_version(0); - key.set_n(nist_test_vector.n); - key.set_e(nist_test_vector.e); - 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, - "SHA1 is not safe for digital signature", - result.status().error_message()); - } - - { // Small modulus. - RsaSsaPssPublicKey key; - key.mutable_params()->set_mgf1_hash(pb::HashType::SHA256); - key.mutable_params()->set_sig_hash(pb::HashType::SHA256); - key.mutable_params()->set_salt_length(32); - key.set_version(0); - key.set_n("\x23"); - key.set_e("\x3"); - 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, - "only modulus size >= 2048-bit is supported", - result.status().error_message()); - } - - { // MGF1 hash and signature hash mismatch. - RsaSsaPssPublicKey key; - key.mutable_params()->set_mgf1_hash(pb::HashType::SHA256); - key.mutable_params()->set_sig_hash(pb::HashType::SHA512); - key.mutable_params()->set_salt_length(32); - key.set_version(0); - key.set_n(nist_test_vector.n); - key.set_e(nist_test_vector.e); - 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, - "is different from signature hash", - result.status().error_message()); - } -} - -TEST_F(RsaSsaPssVerifyKeyManagerTest, testNewKeyError) { - RsaSsaPssVerifyKeyManager key_type_manager; - auto key_manager = - internal::MakeKeyManager<PublicKeyVerify>(&key_type_manager); - const KeyFactory& key_factory = key_manager->get_key_factory(); - - { // Via NewKey(format_proto). - RsaSsaPssKeyFormat 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()); - } - - { // Via NewKey(serialized_format_proto). - RsaSsaPssKeyFormat 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()); - } - - { // Via NewKeyData(serialized_format_proto). - RsaSsaPssKeyFormat 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()); - } + key.set_n(nist_test_vector->n); + key.set_e(nist_test_vector->e); + auto result = RsaSsaPssVerifyKeyManager().GetPrimitive<PublicKeyVerify>(key); + ASSERT_THAT(result.status(), IsOk()); + EXPECT_THAT(result.ValueOrDie()->Verify(nist_test_vector->signature, + nist_test_vector->message), + IsOk()); } } // namespace } // namespace tink } // namespace crypto + -- GitLab