From 8bb2995fb415d7a39342e6be83c0468d2b498cf9 Mon Sep 17 00:00:00 2001 From: William Conner Date: Mon, 18 Nov 2024 07:26:38 -0800 Subject: [PATCH] Add global immutable serialization registry. More key types will be registered in the future as we add support for registering those key types with immutable serialization registries. PiperOrigin-RevId: 697619164 Change-Id: Ibab04b04e398abe48b0f47e42a01db588593da4a --- tink/internal/BUILD.bazel | 51 ++++++ tink/internal/CMakeLists.txt | 50 +++++ .../internal/global_serialization_registry.cc | 76 ++++++++ tink/internal/global_serialization_registry.h | 33 ++++ .../global_serialization_registry_test.cc | 173 ++++++++++++++++++ 5 files changed, 383 insertions(+) create mode 100644 tink/internal/global_serialization_registry.cc create mode 100644 tink/internal/global_serialization_registry.h create mode 100644 tink/internal/global_serialization_registry_test.cc diff --git a/tink/internal/BUILD.bazel b/tink/internal/BUILD.bazel index c8d8f599..c4ea0738 100644 --- a/tink/internal/BUILD.bazel +++ b/tink/internal/BUILD.bazel @@ -1842,3 +1842,54 @@ cc_library( "//tink:secret_key_access_token", ], ) + +cc_library( + name = "global_serialization_registry", + srcs = ["global_serialization_registry.cc"], + hdrs = ["global_serialization_registry.h"], + include_prefix = "tink/internal", + deps = [ + ":serialization_registry", + "//tink/aead/internal:chacha20_poly1305_proto_serialization_impl", + "//tink/aead/internal:legacy_kms_aead_proto_serialization_impl", + "//tink/aead/internal:x_aes_gcm_proto_serialization_impl", + "//tink/aead/internal:xchacha20_poly1305_proto_serialization_impl", + "//tink/prf/internal:aes_cmac_prf_proto_serialization_impl", + "//tink/prf/internal:hkdf_prf_proto_serialization_impl", + "//tink/prf/internal:hmac_prf_proto_serialization_impl", + "@com_google_absl//absl/log:check", + ], +) + +cc_test( + name = "global_serialization_registry_test", + srcs = ["global_serialization_registry_test.cc"], + deps = [ + ":global_serialization_registry", + ":internal_insecure_secret_key_access", + ":proto_key_serialization", + ":serialization", + "//tink:key", + "//tink:partial_key_access", + "//tink:restricted_data", + "//tink/aead:chacha20_poly1305_key", + "//tink/aead:chacha20_poly1305_parameters", + "//tink/aead:legacy_kms_aead_key", + "//tink/aead:legacy_kms_aead_parameters", + "//tink/aead:x_aes_gcm_key", + "//tink/aead:x_aes_gcm_parameters", + "//tink/aead:xchacha20_poly1305_key", + "//tink/aead:xchacha20_poly1305_parameters", + "//tink/prf:aes_cmac_prf_key", + "//tink/prf:hkdf_prf_key", + "//tink/prf:hkdf_prf_parameters", + "//tink/prf:hmac_prf_key", + "//tink/prf:hmac_prf_parameters", + "//tink/util:statusor", + "//tink/util:test_matchers", + "@com_google_absl//absl/log:check", + "@com_google_absl//absl/memory", + "@com_google_absl//absl/types:optional", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/tink/internal/CMakeLists.txt b/tink/internal/CMakeLists.txt index 23f67bab..77ebe9ad 100644 --- a/tink/internal/CMakeLists.txt +++ b/tink/internal/CMakeLists.txt @@ -1772,3 +1772,53 @@ tink_cc_library( tink::core::insecure_secret_key_access tink::core::secret_key_access_token ) + +tink_cc_library( + NAME global_serialization_registry + SRCS + global_serialization_registry.cc + global_serialization_registry.h + DEPS + tink::internal::serialization_registry + absl::check + tink::aead::internal::chacha20_poly1305_proto_serialization_impl + tink::aead::internal::legacy_kms_aead_proto_serialization_impl + tink::aead::internal::x_aes_gcm_proto_serialization_impl + tink::aead::internal::xchacha20_poly1305_proto_serialization_impl + tink::prf::internal::aes_cmac_prf_proto_serialization_impl + tink::prf::internal::hkdf_prf_proto_serialization_impl + tink::prf::internal::hmac_prf_proto_serialization_impl +) + +tink_cc_test( + NAME global_serialization_registry_test + SRCS + global_serialization_registry_test.cc + DEPS + tink::internal::global_serialization_registry + tink::internal::internal_insecure_secret_key_access + tink::internal::proto_key_serialization + tink::internal::serialization + gmock + absl::check + absl::memory + absl::optional + tink::core::key + tink::core::partial_key_access + tink::core::restricted_data + tink::aead::chacha20_poly1305_key + tink::aead::chacha20_poly1305_parameters + tink::aead::legacy_kms_aead_key + tink::aead::legacy_kms_aead_parameters + tink::aead::x_aes_gcm_key + tink::aead::x_aes_gcm_parameters + tink::aead::xchacha20_poly1305_key + tink::aead::xchacha20_poly1305_parameters + tink::prf::aes_cmac_prf_key + tink::prf::hkdf_prf_key + tink::prf::hkdf_prf_parameters + tink::prf::hmac_prf_key + tink::prf::hmac_prf_parameters + tink::util::statusor + tink::util::test_matchers +) diff --git a/tink/internal/global_serialization_registry.cc b/tink/internal/global_serialization_registry.cc new file mode 100644 index 00000000..3664de75 --- /dev/null +++ b/tink/internal/global_serialization_registry.cc @@ -0,0 +1,76 @@ +// Copyright 2024 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/internal/global_serialization_registry.h" + +#include + +#include "absl/log/check.h" +#include "tink/aead/internal/chacha20_poly1305_proto_serialization_impl.h" +#include "tink/aead/internal/legacy_kms_aead_proto_serialization_impl.h" +#include "tink/aead/internal/x_aes_gcm_proto_serialization_impl.h" +#include "tink/aead/internal/xchacha20_poly1305_proto_serialization_impl.h" +#include "tink/internal/serialization_registry.h" +#include "tink/prf/internal/aes_cmac_prf_proto_serialization_impl.h" +#include "tink/prf/internal/hkdf_prf_proto_serialization_impl.h" +#include "tink/prf/internal/hmac_prf_proto_serialization_impl.h" + +namespace crypto { +namespace tink { +namespace internal { + +const SerializationRegistry& GlobalSerializationRegistry() { + static const SerializationRegistry* instance = [] { + SerializationRegistry::Builder builder; + + // AEAD + CHECK_OK( + RegisterChaCha20Poly1305ProtoSerializationWithRegistryBuilder(builder)); + CHECK_OK( + RegisterLegacyKmsAeadProtoSerializationWithRegistryBuilder(builder)); + CHECK_OK(RegisterXAesGcmProtoSerializationWithRegistryBuilder(builder)); + CHECK_OK(RegisterXChaCha20Poly1305ProtoSerializationWithRegistryBuilder( + builder)); + + // Deterministic AEAD + + // Hybrid + + // JWT + + // Key derivation + + // MAC + + // PRF + CHECK_OK(RegisterAesCmacPrfProtoSerializationWithRegistryBuilder(builder)); + CHECK_OK(RegisterHkdfPrfProtoSerializationWithRegistryBuilder(builder)); + CHECK_OK(RegisterHmacPrfProtoSerializationWithRegistryBuilder(builder)); + + // Signature + + // Streaming AEAD + + static SerializationRegistry* registry = + new SerializationRegistry(std::move(builder).Build()); + return registry; + }(); + return *instance; +} + +} // namespace internal +} // namespace tink +} // namespace crypto diff --git a/tink/internal/global_serialization_registry.h b/tink/internal/global_serialization_registry.h new file mode 100644 index 00000000..37c2a03b --- /dev/null +++ b/tink/internal/global_serialization_registry.h @@ -0,0 +1,33 @@ +// Copyright 2024 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_INTERNAL_GLOBAL_SERIALIZATION_REGISTRY_H_ +#define TINK_INTERNAL_GLOBAL_SERIALIZATION_REGISTRY_H_ + +#include "tink/internal/serialization_registry.h" + +namespace crypto { +namespace tink { +namespace internal { + +// Returns the global immutable serialization registry. +const SerializationRegistry& GlobalSerializationRegistry(); + +} // namespace internal +} // namespace tink +} // namespace crypto + +#endif // TINK_INTERNAL_GLOBAL_SERIALIZATION_REGISTRY_H_ diff --git a/tink/internal/global_serialization_registry_test.cc b/tink/internal/global_serialization_registry_test.cc new file mode 100644 index 00000000..d7107947 --- /dev/null +++ b/tink/internal/global_serialization_registry_test.cc @@ -0,0 +1,173 @@ +// Copyright 2024 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/internal/global_serialization_registry.h" + +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/log/check.h" +#include "absl/memory/memory.h" +#include "absl/types/optional.h" +#include "tink/aead/chacha20_poly1305_key.h" +#include "tink/aead/chacha20_poly1305_parameters.h" +#include "tink/aead/legacy_kms_aead_key.h" +#include "tink/aead/legacy_kms_aead_parameters.h" +#include "tink/aead/x_aes_gcm_key.h" +#include "tink/aead/x_aes_gcm_parameters.h" +#include "tink/aead/xchacha20_poly1305_key.h" +#include "tink/aead/xchacha20_poly1305_parameters.h" +#include "tink/internal/internal_insecure_secret_key_access.h" +#include "tink/internal/proto_key_serialization.h" +#include "tink/internal/serialization.h" +#include "tink/key.h" +#include "tink/partial_key_access.h" +#include "tink/prf/aes_cmac_prf_key.h" +#include "tink/prf/hkdf_prf_key.h" +#include "tink/prf/hkdf_prf_parameters.h" +#include "tink/prf/hmac_prf_key.h" +#include "tink/prf/hmac_prf_parameters.h" +#include "tink/restricted_data.h" +#include "tink/util/statusor.h" +#include "tink/util/test_matchers.h" + +namespace crypto { +namespace tink { +namespace internal { +namespace { + +using ::crypto::tink::test::IsOk; +using ::testing::TestWithParam; +using ::testing::Values; + +struct KeyTestVector { + std::shared_ptr key; +}; + +std::unique_ptr CreateAesCmacPrfKey() { + util::StatusOr key = AesCmacPrfKey::Create( + RestrictedData(/*num_random_bytes=*/32), GetPartialKeyAccess()); + CHECK_OK(key); + + return absl::make_unique(*key); +} + +std::unique_ptr CreateChaCha20Poly1305Key() { + util::StatusOr key = ChaCha20Poly1305Key::Create( + ChaCha20Poly1305Parameters::Variant::kTink, + RestrictedData(/*num_random_bytes=*/32), /*id_requirement=*/123, + GetPartialKeyAccess()); + CHECK_OK(key); + + return absl::make_unique(*key); +} + +std::unique_ptr CreateHkdfPrfKey() { + util::StatusOr parameters = HkdfPrfParameters::Create( + /*key_size_in_bytes=*/16, HkdfPrfParameters::HashType::kSha256, + /*salt=*/absl::nullopt); + CHECK_OK(parameters); + + util::StatusOr key = + HkdfPrfKey::Create(*parameters, RestrictedData(/*num_random_bytes=*/16), + GetPartialKeyAccess()); + CHECK_OK(key); + + return absl::make_unique(*key); +} + +std::unique_ptr CreateHmacPrfKey() { + util::StatusOr parameters = HmacPrfParameters::Create( + /*key_size_in_bytes=*/16, HmacPrfParameters::HashType::kSha256); + CHECK_OK(parameters); + + util::StatusOr key = + HmacPrfKey::Create(*parameters, RestrictedData(/*num_random_bytes=*/16), + GetPartialKeyAccess()); + CHECK_OK(key); + + return absl::make_unique(*key); +} + +std::unique_ptr CreateLegacyKmsAeadKey() { + util::StatusOr parameters = + LegacyKmsAeadParameters::Create("key_uri", + LegacyKmsAeadParameters::Variant::kTink); + CHECK_OK(parameters); + + util::StatusOr key = + LegacyKmsAeadKey::Create(*parameters, /*id_requirement=*/123); + CHECK_OK(key); + + return absl::make_unique(*key); +} + +std::unique_ptr CreateXAesGcmKey() { + util::StatusOr parameters = XAesGcmParameters::Create( + XAesGcmParameters::Variant::kTink, /*salt_size_bytes=*/12); + CHECK_OK(parameters); + + util::StatusOr key = + XAesGcmKey::Create(*parameters, RestrictedData(/*num_random_bytes=*/32), + /*id_requirement=*/123, GetPartialKeyAccess()); + CHECK_OK(key); + + return absl::make_unique(*key); +} + +std::unique_ptr CreateXChaCha20Poly1305Key() { + util::StatusOr key = XChaCha20Poly1305Key::Create( + XChaCha20Poly1305Parameters::Variant::kTink, + RestrictedData(/*num_random_bytes=*/32), /*id_requirement=*/123, + GetPartialKeyAccess()); + CHECK_OK(key); + + return absl::make_unique(*key); +} + +using GlobalSerializationRegistryTest = TestWithParam; + +INSTANTIATE_TEST_SUITE_P(GlobalSerializationRegistryTests, + GlobalSerializationRegistryTest, + Values(KeyTestVector{CreateAesCmacPrfKey()}, + KeyTestVector{CreateChaCha20Poly1305Key()}, + KeyTestVector{CreateHkdfPrfKey()}, + KeyTestVector{CreateHmacPrfKey()}, + KeyTestVector{CreateLegacyKmsAeadKey()}, + KeyTestVector{CreateXAesGcmKey()}, + KeyTestVector{CreateXChaCha20Poly1305Key()})); + +TEST_P(GlobalSerializationRegistryTest, SerializeAndParse) { + const KeyTestVector& test_case = GetParam(); + + util::StatusOr> serialization = + GlobalSerializationRegistry().SerializeKey( + *test_case.key, GetInsecureSecretKeyAccessInternal()); + ASSERT_THAT(serialization, IsOk()); + + util::StatusOr> parsed_key = + GlobalSerializationRegistry().ParseKey( + **serialization, GetInsecureSecretKeyAccessInternal()); + ASSERT_THAT(parsed_key, IsOk()); + + EXPECT_TRUE(**parsed_key == *test_case.key); +} + +} // namespace +} // namespace internal +} // namespace tink +} // namespace crypto