Skip to content

Commit

Permalink
Add RsaSsaPkcs1 proto parser and serializer for the parameters objects.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 577220674
Change-Id: I77558b6de4b917299d58177bbf4426103ad05509
  • Loading branch information
ioannanedelcu authored and Copybara-Service committed Oct 27, 2023
1 parent bd7ac23 commit 6ab4705
Show file tree
Hide file tree
Showing 5 changed files with 630 additions and 0 deletions.
46 changes: 46 additions & 0 deletions tink/signature/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,29 @@ cc_library(
],
)

cc_library(
name = "rsa_ssa_pkcs1_proto_serialization",
srcs = ["rsa_ssa_pkcs1_proto_serialization.cc"],
hdrs = ["rsa_ssa_pkcs1_proto_serialization.h"],
include_prefix = "tink/signature",
deps = [
":rsa_ssa_pkcs1_parameters",
"//tink:big_integer",
"//tink/internal:mutable_serialization_registry",
"//tink/internal:parameters_parser",
"//tink/internal:parameters_serializer",
"//tink/internal:proto_parameters_serialization",
"//proto:common_cc_proto",
"//proto:rsa_ssa_pkcs1_cc_proto",
"//proto:tink_cc_proto",
"//tink/util:status",
"//tink/util:statusor",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
],
)

# tests

cc_test(
Expand Down Expand Up @@ -1115,3 +1138,26 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "rsa_ssa_pkcs1_proto_serialization_test",
srcs = ["rsa_ssa_pkcs1_proto_serialization_test.cc"],
deps = [
":rsa_ssa_pkcs1_parameters",
":rsa_ssa_pkcs1_proto_serialization",
"//tink:big_integer",
"//tink:parameters",
"//tink/internal:mutable_serialization_registry",
"//tink/internal:proto_parameters_serialization",
"//tink/internal:serialization",
"//proto:common_cc_proto",
"//proto:rsa_ssa_pkcs1_cc_proto",
"//proto:tink_cc_proto",
"//tink/util:statusor",
"//tink/util:test_matchers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
"@com_google_absl//absl/types:optional",
"@com_google_googletest//:gtest_main",
],
)
45 changes: 45 additions & 0 deletions tink/signature/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,28 @@ tink_cc_library(
tink::signature::internal::key_gen_config_v0
)

tink_cc_library(
NAME rsa_ssa_pkcs1_proto_serialization
SRCS
rsa_ssa_pkcs1_proto_serialization.cc
rsa_ssa_pkcs1_proto_serialization.h
DEPS
tink::signature::rsa_ssa_pkcs1_parameters
absl::core_headers
absl::status
absl::string_view
tink::core::big_integer
tink::internal::mutable_serialization_registry
tink::internal::parameters_parser
tink::internal::parameters_serializer
tink::internal::proto_parameters_serialization
tink::util::status
tink::util::statusor
tink::proto::common_cc_proto
tink::proto::rsa_ssa_pkcs1_cc_proto
tink::proto::tink_cc_proto
)

# tests

tink_cc_test(
Expand Down Expand Up @@ -1070,3 +1092,26 @@ tink_cc_test(
tink::util::test_matchers
tink::proto::tink_cc_proto
)

tink_cc_test(
NAME rsa_ssa_pkcs1_proto_serialization_test
SRCS
rsa_ssa_pkcs1_proto_serialization_test.cc
DEPS
tink::signature::rsa_ssa_pkcs1_parameters
tink::signature::rsa_ssa_pkcs1_proto_serialization
gmock
absl::status
absl::string_view
absl::optional
tink::core::big_integer
tink::core::parameters
tink::internal::mutable_serialization_registry
tink::internal::proto_parameters_serialization
tink::internal::serialization
tink::util::statusor
tink::util::test_matchers
tink::proto::common_cc_proto
tink::proto::rsa_ssa_pkcs1_cc_proto
tink::proto::tink_cc_proto
)
210 changes: 210 additions & 0 deletions tink/signature/rsa_ssa_pkcs1_proto_serialization.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

#include "tink/signature/rsa_ssa_pkcs1_proto_serialization.h"
#include <string>

#include "absl/base/attributes.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "tink/big_integer.h"
#include "tink/internal/mutable_serialization_registry.h"
#include "tink/internal/parameters_parser.h"
#include "tink/internal/parameters_serializer.h"
#include "tink/internal/proto_parameters_serialization.h"
#include "tink/signature/rsa_ssa_pkcs1_parameters.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"
#include "proto/common.pb.h"
#include "proto/rsa_ssa_pkcs1.pb.h"
#include "proto/tink.pb.h"

namespace crypto {
namespace tink {
namespace {

using ::google::crypto::tink::HashType;
using ::google::crypto::tink::OutputPrefixType;
using ::google::crypto::tink::RsaSsaPkcs1KeyFormat;
using ::google::crypto::tink::RsaSsaPkcs1Params;

using RsaSsaPkcs1ProtoParametersParserImpl =
internal::ParametersParserImpl<internal::ProtoParametersSerialization,
RsaSsaPkcs1Parameters>;
using RsaSsaPkcs1ProtoParametersSerializerImpl =
internal::ParametersSerializerImpl<RsaSsaPkcs1Parameters,
internal::ProtoParametersSerialization>;

const absl::string_view kPrivateTypeUrl =
"type.googleapis.com/google.crypto.tink.RsaSsaPkcs1PrivateKey";

util::StatusOr<RsaSsaPkcs1Parameters::Variant> ToVariant(
OutputPrefixType output_prefix_type) {
switch (output_prefix_type) {
case OutputPrefixType::LEGACY:
ABSL_FALLTHROUGH_INTENDED; // Parse LEGACY output prefix as CRUNCHY.
case OutputPrefixType::CRUNCHY:
return RsaSsaPkcs1Parameters::Variant::kCrunchy;
case OutputPrefixType::RAW:
return RsaSsaPkcs1Parameters::Variant::kNoPrefix;
case OutputPrefixType::TINK:
return RsaSsaPkcs1Parameters::Variant::kTink;
default:
return util::Status(absl::StatusCode::kInvalidArgument,
"Could not determine RsaSsaPkcs1Parameters::Variant");
}
}

util::StatusOr<OutputPrefixType> ToOutputPrefixType(
RsaSsaPkcs1Parameters::Variant variant) {
switch (variant) {
case RsaSsaPkcs1Parameters::Variant::kCrunchy:
return OutputPrefixType::CRUNCHY;
case RsaSsaPkcs1Parameters::Variant::kNoPrefix:
return OutputPrefixType::RAW;
case RsaSsaPkcs1Parameters::Variant::kTink:
return OutputPrefixType::TINK;
default:
return util::Status(absl::StatusCode::kInvalidArgument,
"Could not determine output prefix type.");
}
}

util::StatusOr<RsaSsaPkcs1Parameters::HashType> ToEnumHashType(
HashType hash_type) {
switch (hash_type) {
case HashType::SHA256:
return RsaSsaPkcs1Parameters::HashType::kSha256;
case HashType::SHA384:
return RsaSsaPkcs1Parameters::HashType::kSha384;
case HashType::SHA512:
return RsaSsaPkcs1Parameters::HashType::kSha512;
default:
return util::Status(absl::StatusCode::kInvalidArgument,
"Could not determine HashType");
}
}

util::StatusOr<HashType> ToProtoHashType(
RsaSsaPkcs1Parameters::HashType hash_type) {
switch (hash_type) {
case RsaSsaPkcs1Parameters::HashType::kSha256:
return HashType::SHA256;
case RsaSsaPkcs1Parameters::HashType::kSha384:
return HashType::SHA384;
case RsaSsaPkcs1Parameters::HashType::kSha512:
return HashType::SHA512;
default:
return util::Status(
absl::StatusCode::kInvalidArgument,
"Could not determine RsaSsaPkcs1Parameters::HashType");
}
}

util::StatusOr<RsaSsaPkcs1Parameters> ParseParameters(
const internal::ProtoParametersSerialization& serialization) {
if (serialization.GetKeyTemplate().type_url() != kPrivateTypeUrl) {
return util::Status(absl::StatusCode::kInvalidArgument,
"Wrong type URL when parsing RsaSsaPkcs1Parameters.");
}

RsaSsaPkcs1KeyFormat proto_key_format;
if (!proto_key_format.ParseFromString(
serialization.GetKeyTemplate().value())) {
return util::Status(absl::StatusCode::kInvalidArgument,
"Failed to parse RsaSsaPkcs1KeyFormat proto");
}
if (!proto_key_format.has_params()) {
return util::Status(absl::StatusCode::kInvalidArgument,
"RsaSsaPkcs1KeyFormat proto is missing params field.");
}

util::StatusOr<RsaSsaPkcs1Parameters::Variant> variant =
ToVariant(serialization.GetKeyTemplate().output_prefix_type());
if (!variant.ok()) {
return variant.status();
}

util::StatusOr<RsaSsaPkcs1Parameters::HashType> hash_type =
ToEnumHashType(proto_key_format.params().hash_type());
if (!hash_type.ok()) {
return hash_type.status();
}

return RsaSsaPkcs1Parameters::Builder()
.SetVariant(*variant)
.SetHashType(*hash_type)
.SetModulusSizeInBits(proto_key_format.modulus_size_in_bits())
.SetPublicExponent(BigInteger(proto_key_format.public_exponent()))
.Build();
}

util::StatusOr<internal::ProtoParametersSerialization> SerializeParameters(
const RsaSsaPkcs1Parameters& parameters) {
util::StatusOr<OutputPrefixType> output_prefix_type =
ToOutputPrefixType(parameters.GetVariant());
if (!output_prefix_type.ok()) {
return output_prefix_type.status();
}

util::StatusOr<HashType> hash_type =
ToProtoHashType(parameters.GetHashType());
if (!hash_type.ok()) {
return hash_type.status();
}

RsaSsaPkcs1Params params;
params.set_hash_type(*hash_type);
RsaSsaPkcs1KeyFormat proto_key_format;
proto_key_format.set_modulus_size_in_bits(parameters.GetModulusSizeInBits());
proto_key_format.set_public_exponent(
std::string(parameters.GetPublicExponent().GetValue()));
*proto_key_format.mutable_params() = params;

return internal::ProtoParametersSerialization::Create(
kPrivateTypeUrl, *output_prefix_type,
proto_key_format.SerializeAsString());
}

RsaSsaPkcs1ProtoParametersParserImpl* RsaSsaPkcs1ProtoParametersParser() {
static auto* parser = new RsaSsaPkcs1ProtoParametersParserImpl(
kPrivateTypeUrl, ParseParameters);
return parser;
}

RsaSsaPkcs1ProtoParametersSerializerImpl*
RsaSsaPkcs1ProtoParametersSerializer() {
static auto* serializer = new RsaSsaPkcs1ProtoParametersSerializerImpl(
kPrivateTypeUrl, SerializeParameters);
return serializer;
}

} // namespace

util::Status RegisterRsaSsaPkcs1ProtoSerialization() {
util::Status status =
internal::MutableSerializationRegistry::GlobalInstance()
.RegisterParametersParser(RsaSsaPkcs1ProtoParametersParser());
if (!status.ok()) {
return status;
}

return internal::MutableSerializationRegistry::GlobalInstance()
.RegisterParametersSerializer(RsaSsaPkcs1ProtoParametersSerializer());
}

} // namespace tink
} // namespace crypto
31 changes: 31 additions & 0 deletions tink/signature/rsa_ssa_pkcs1_proto_serialization.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

#ifndef TINK_SIGNATURE_RSA_SSA_PKCS1_PROTO_SERIALIZATION_H_
#define TINK_SIGNATURE_RSA_SSA_PKCS1_PROTO_SERIALIZATION_H_

#include "tink/util/status.h"

namespace crypto {
namespace tink {

// Registers proto parsers and serializers for RsaSsaPkcs1 parameters and keys.
crypto::tink::util::Status RegisterRsaSsaPkcs1ProtoSerialization();

} // namespace tink
} // namespace crypto

#endif // TINK_SIGNATURE_RSA_SSA_PKCS1_PROTO_SERIALIZATION_H_
Loading

0 comments on commit 6ab4705

Please sign in to comment.