diff --git a/tink/signature/BUILD.bazel b/tink/signature/BUILD.bazel index d4633595..f8fc6f27 100644 --- a/tink/signature/BUILD.bazel +++ b/tink/signature/BUILD.bazel @@ -347,6 +347,7 @@ cc_library( ":rsa_ssa_pkcs1_proto_serialization", ":rsa_ssa_pkcs1_sign_key_manager", ":rsa_ssa_pkcs1_verify_key_manager", + ":rsa_ssa_pss_proto_serialization", ":rsa_ssa_pss_sign_key_manager", ":rsa_ssa_pss_verify_key_manager", "//tink:registry", @@ -1025,6 +1026,9 @@ cc_test( ":rsa_ssa_pkcs1_parameters", ":rsa_ssa_pkcs1_private_key", ":rsa_ssa_pkcs1_public_key", + ":rsa_ssa_pss_parameters", + ":rsa_ssa_pss_private_key", + ":rsa_ssa_pss_public_key", ":rsa_ssa_pss_sign_key_manager", ":rsa_ssa_pss_verify_key_manager", ":signature_config", diff --git a/tink/signature/CMakeLists.txt b/tink/signature/CMakeLists.txt index 4012976e..5fd588fb 100644 --- a/tink/signature/CMakeLists.txt +++ b/tink/signature/CMakeLists.txt @@ -330,6 +330,7 @@ tink_cc_library( tink::signature::rsa_ssa_pkcs1_proto_serialization tink::signature::rsa_ssa_pkcs1_sign_key_manager tink::signature::rsa_ssa_pkcs1_verify_key_manager + tink::signature::rsa_ssa_pss_proto_serialization tink::signature::rsa_ssa_pss_sign_key_manager tink::signature::rsa_ssa_pss_verify_key_manager absl::core_headers @@ -978,6 +979,9 @@ tink_cc_test( tink::signature::rsa_ssa_pkcs1_parameters tink::signature::rsa_ssa_pkcs1_private_key tink::signature::rsa_ssa_pkcs1_public_key + tink::signature::rsa_ssa_pss_parameters + tink::signature::rsa_ssa_pss_private_key + tink::signature::rsa_ssa_pss_public_key tink::signature::rsa_ssa_pss_sign_key_manager tink::signature::rsa_ssa_pss_verify_key_manager tink::signature::signature_config diff --git a/tink/signature/signature_config.cc b/tink/signature/signature_config.cc index 1c5e16af..33e04e4c 100644 --- a/tink/signature/signature_config.cc +++ b/tink/signature/signature_config.cc @@ -28,6 +28,7 @@ #include "tink/signature/rsa_ssa_pkcs1_proto_serialization.h" #include "tink/signature/rsa_ssa_pkcs1_sign_key_manager.h" #include "tink/signature/rsa_ssa_pkcs1_verify_key_manager.h" +#include "tink/signature/rsa_ssa_pss_proto_serialization.h" #include "tink/signature/rsa_ssa_pss_sign_key_manager.h" #include "tink/signature/rsa_ssa_pss_verify_key_manager.h" #include "tink/util/status.h" @@ -61,6 +62,9 @@ util::Status SignatureConfig::Register() { absl::make_unique(), true); if (!status.ok()) return status; + status = RegisterRsaSsaPssProtoSerialization(); + if (!status.ok()) return status; + // RSA SSA PKCS1 status = Registry::RegisterAsymmetricKeyManagers( absl::make_unique(), diff --git a/tink/signature/signature_config_test.cc b/tink/signature/signature_config_test.cc index 605685a2..634c98cd 100644 --- a/tink/signature/signature_config_test.cc +++ b/tink/signature/signature_config_test.cc @@ -52,6 +52,9 @@ #include "tink/signature/rsa_ssa_pkcs1_parameters.h" #include "tink/signature/rsa_ssa_pkcs1_private_key.h" #include "tink/signature/rsa_ssa_pkcs1_public_key.h" +#include "tink/signature/rsa_ssa_pss_parameters.h" +#include "tink/signature/rsa_ssa_pss_private_key.h" +#include "tink/signature/rsa_ssa_pss_public_key.h" #include "tink/signature/rsa_ssa_pss_sign_key_manager.h" #include "tink/signature/rsa_ssa_pss_verify_key_manager.h" #include "tink/signature/signature_key_templates.h" @@ -491,6 +494,217 @@ TEST_F(SignatureConfigTest, RsaSsaPkcs1ProtoPrivateKeySerializationRegistered) { ASSERT_THAT(serialized_key2, IsOk()); } +TEST_F(SignatureConfigTest, RsaSsaPssProtoParamsSerializationRegistered) { + if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) { + GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is " + "not available"; + } + + util::StatusOr + proto_params_serialization = + internal::ProtoParametersSerialization::Create( + SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4()); + ASSERT_THAT(proto_params_serialization, IsOk()); + + util::StatusOr> parsed_params = + internal::MutableSerializationRegistry::GlobalInstance().ParseParameters( + *proto_params_serialization); + ASSERT_THAT(parsed_params.status(), StatusIs(absl::StatusCode::kNotFound)); + + util::StatusOr params = + RsaSsaPssParameters::Builder() + .SetVariant(RsaSsaPssParameters::Variant::kTink) + .SetSigHashType(RsaSsaPssParameters::HashType::kSha256) + .SetMgf1HashType(RsaSsaPssParameters::HashType::kSha256) + .SetSaltLengthInBytes(32) + .SetModulusSizeInBits(3072) + .Build(); + ASSERT_THAT(params, IsOk()); + + util::StatusOr> serialized_params = + internal::MutableSerializationRegistry::GlobalInstance() + .SerializeParameters(*params); + ASSERT_THAT(serialized_params.status(), + StatusIs(absl::StatusCode::kNotFound)); + + // Register serialization. + ASSERT_THAT(SignatureConfig::Register(), IsOk()); + + util::StatusOr> parsed_params2 = + internal::MutableSerializationRegistry::GlobalInstance().ParseParameters( + *proto_params_serialization); + ASSERT_THAT(parsed_params2, IsOk()); + + util::StatusOr> serialized_params2 = + internal::MutableSerializationRegistry::GlobalInstance() + .SerializeParameters(*params); + ASSERT_THAT(serialized_params2, IsOk()); +} + +TEST_F(SignatureConfigTest, RsaSsaPssProtoPublicKeySerializationRegistered) { + if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) { + GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is " + "not available"; + } + + RsaKeyValues key_values = GenerateRsaKeyValues(/*modulus_size_in_bits=*/2048); + + google::crypto::tink::RsaSsaPssParams params; + params.set_sig_hash(HashType::SHA256); + params.set_mgf1_hash(HashType::SHA256); + params.set_salt_length(32); + + google::crypto::tink::RsaSsaPssPublicKey key_proto; + key_proto.set_version(0); + key_proto.set_n(key_values.n); + key_proto.set_e(key_values.e); + *key_proto.mutable_params() = params; + + util::StatusOr proto_key_serialization = + internal::ProtoKeySerialization::Create( + "type.googleapis.com/google.crypto.tink.RsaSsaPkcs1PublicKey", + RestrictedData(key_proto.SerializeAsString(), + InsecureSecretKeyAccess::Get()), + KeyData::ASYMMETRIC_PUBLIC, OutputPrefixType::TINK, + /*id_requirement=*/123); + ASSERT_THAT(proto_key_serialization, IsOk()); + + util::StatusOr> parsed_key = + internal::MutableSerializationRegistry::GlobalInstance().ParseKey( + *proto_key_serialization, InsecureSecretKeyAccess::Get()); + ASSERT_THAT(parsed_key.status(), StatusIs(absl::StatusCode::kNotFound)); + + util::StatusOr parameters = + RsaSsaPssParameters::Builder() + .SetVariant(RsaSsaPssParameters::Variant::kTink) + .SetSigHashType(RsaSsaPssParameters::HashType::kSha256) + .SetMgf1HashType(RsaSsaPssParameters::HashType::kSha256) + .SetSaltLengthInBytes(32) + .SetModulusSizeInBits(2048) + .Build(); + ASSERT_THAT(parameters, IsOk()); + + util::StatusOr key = + RsaSsaPssPublicKey::Create(*parameters, BigInteger(key_values.n), + /*id_requirement=*/123, GetPartialKeyAccess()); + ASSERT_THAT(key, IsOk()); + + util::StatusOr> serialized_key = + internal::MutableSerializationRegistry::GlobalInstance() + .SerializeKey( + *key, InsecureSecretKeyAccess::Get()); + ASSERT_THAT(serialized_key.status(), StatusIs(absl::StatusCode::kNotFound)); + + // Register serialization. + ASSERT_THAT(SignatureConfig::Register(), IsOk()); + + util::StatusOr> parsed_key2 = + internal::MutableSerializationRegistry::GlobalInstance().ParseKey( + *proto_key_serialization, InsecureSecretKeyAccess::Get()); + ASSERT_THAT(parsed_key2, IsOk()); + + util::StatusOr> serialized_key2 = + internal::MutableSerializationRegistry::GlobalInstance() + .SerializeKey( + *key, InsecureSecretKeyAccess::Get()); + ASSERT_THAT(serialized_key2, IsOk()); +} + +TEST_F(SignatureConfigTest, RsaSsaPssProtoPrivateKeySerializationRegistered) { + if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) { + GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is " + "not available"; + } + + RsaKeyValues key_values = GenerateRsaKeyValues(/*modulus_size_in_bits=*/2048); + + google::crypto::tink::RsaSsaPssParams params; + params.set_sig_hash(HashType::SHA256); + params.set_mgf1_hash(HashType::SHA256); + params.set_salt_length(32); + + google::crypto::tink::RsaSsaPssPublicKey public_key_proto; + public_key_proto.set_version(0); + public_key_proto.set_n(key_values.n); + public_key_proto.set_e(key_values.e); + *public_key_proto.mutable_params() = params; + + google::crypto::tink::RsaSsaPssPrivateKey private_key_proto; + private_key_proto.set_version(0); + *private_key_proto.mutable_public_key() = public_key_proto; + private_key_proto.set_p(key_values.p); + private_key_proto.set_q(key_values.q); + private_key_proto.set_dp(key_values.dp); + private_key_proto.set_dq(key_values.dq); + private_key_proto.set_d(key_values.d); + private_key_proto.set_crt(key_values.q_inv); + + util::StatusOr proto_key_serialization = + internal::ProtoKeySerialization::Create( + "type.googleapis.com/google.crypto.tink.RsaSsaPssPrivateKey", + RestrictedData(private_key_proto.SerializeAsString(), + InsecureSecretKeyAccess::Get()), + KeyData::ASYMMETRIC_PRIVATE, OutputPrefixType::TINK, + /*id_requirement=*/123); + ASSERT_THAT(proto_key_serialization, IsOk()); + + util::StatusOr> parsed_key = + internal::MutableSerializationRegistry::GlobalInstance().ParseKey( + *proto_key_serialization, InsecureSecretKeyAccess::Get()); + ASSERT_THAT(parsed_key.status(), StatusIs(absl::StatusCode::kNotFound)); + + util::StatusOr parameters = + RsaSsaPssParameters::Builder() + .SetVariant(RsaSsaPssParameters::Variant::kTink) + .SetSigHashType(RsaSsaPssParameters::HashType::kSha256) + .SetMgf1HashType(RsaSsaPssParameters::HashType::kSha256) + .SetSaltLengthInBytes(32) + .SetModulusSizeInBits(2048) + .Build(); + ASSERT_THAT(parameters, IsOk()); + + util::StatusOr public_key = + RsaSsaPssPublicKey::Create(*parameters, BigInteger(key_values.n), + /*id_requirement=*/123, GetPartialKeyAccess()); + ASSERT_THAT(public_key, IsOk()); + + util::StatusOr private_key = + RsaSsaPssPrivateKey::Builder() + .SetPublicKey(*public_key) + .SetPrimeP(RestrictedBigInteger(key_values.p, + InsecureSecretKeyAccess::Get())) + .SetPrimeQ(RestrictedBigInteger(key_values.q, + InsecureSecretKeyAccess::Get())) + .SetPrimeExponentP(RestrictedBigInteger( + key_values.dp, InsecureSecretKeyAccess::Get())) + .SetPrimeExponentQ(RestrictedBigInteger( + key_values.dq, InsecureSecretKeyAccess::Get())) + .SetPrivateExponent(RestrictedBigInteger( + key_values.d, InsecureSecretKeyAccess::Get())) + .SetCrtCoefficient(RestrictedBigInteger( + key_values.q_inv, InsecureSecretKeyAccess::Get())) + .Build(GetPartialKeyAccess()); + + util::StatusOr> serialized_key = + internal::MutableSerializationRegistry::GlobalInstance() + .SerializeKey( + *private_key, InsecureSecretKeyAccess::Get()); + ASSERT_THAT(serialized_key.status(), StatusIs(absl::StatusCode::kNotFound)); + + ASSERT_THAT(SignatureConfig::Register(), IsOk()); + + util::StatusOr> parsed_key2 = + internal::MutableSerializationRegistry::GlobalInstance().ParseKey( + *proto_key_serialization, InsecureSecretKeyAccess::Get()); + ASSERT_THAT(parsed_key2, IsOk()); + + util::StatusOr> serialized_key2 = + internal::MutableSerializationRegistry::GlobalInstance() + .SerializeKey( + *private_key, InsecureSecretKeyAccess::Get()); + ASSERT_THAT(serialized_key2, IsOk()); +} + } // namespace } // namespace tink } // namespace crypto