xref: /aosp_15_r20/external/tink/cc/internal/mutable_serialization_registry.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 #include "tink/internal/mutable_serialization_registry.h"
18 
19 #include <memory>
20 
21 #include "absl/memory/memory.h"
22 #include "absl/status/status.h"
23 #include "absl/synchronization/mutex.h"
24 #include "tink/insecure_secret_key_access.h"
25 #include "tink/internal/key_parser.h"
26 #include "tink/internal/key_serializer.h"
27 #include "tink/internal/legacy_proto_key.h"
28 #include "tink/internal/parameters_parser.h"
29 #include "tink/internal/parameters_serializer.h"
30 #include "tink/internal/proto_key_serialization.h"
31 #include "tink/internal/serialization.h"
32 #include "tink/internal/serialization_registry.h"
33 #include "tink/key.h"
34 #include "tink/parameters.h"
35 #include "tink/secret_key_access_token.h"
36 #include "tink/util/status.h"
37 #include "tink/util/statusor.h"
38 
39 namespace crypto {
40 namespace tink {
41 namespace internal {
42 
GlobalInstance()43 MutableSerializationRegistry& MutableSerializationRegistry::GlobalInstance() {
44   static MutableSerializationRegistry* instance =
45       new MutableSerializationRegistry();
46   return *instance;
47 }
48 
RegisterParametersParser(ParametersParser * parser)49 util::Status MutableSerializationRegistry::RegisterParametersParser(
50     ParametersParser* parser) {
51   absl::WriterMutexLock lock(&registry_mutex_);
52   SerializationRegistry::Builder builder(registry_);
53   util::Status status = builder.RegisterParametersParser(parser);
54   if (!status.ok()) return status;
55   registry_ = builder.Build();
56   return util::OkStatus();
57 }
58 
RegisterParametersSerializer(ParametersSerializer * serializer)59 util::Status MutableSerializationRegistry::RegisterParametersSerializer(
60     ParametersSerializer* serializer) {
61   absl::WriterMutexLock lock(&registry_mutex_);
62   SerializationRegistry::Builder builder(registry_);
63   util::Status status = builder.RegisterParametersSerializer(serializer);
64   if (!status.ok()) return status;
65   registry_ = builder.Build();
66   return util::OkStatus();
67 }
68 
RegisterKeyParser(KeyParser * parser)69 util::Status MutableSerializationRegistry::RegisterKeyParser(
70     KeyParser* parser) {
71   absl::WriterMutexLock lock(&registry_mutex_);
72   SerializationRegistry::Builder builder(registry_);
73   util::Status status = builder.RegisterKeyParser(parser);
74   if (!status.ok()) return status;
75   registry_ = builder.Build();
76   return util::OkStatus();
77 }
78 
RegisterKeySerializer(KeySerializer * serializer)79 util::Status MutableSerializationRegistry::RegisterKeySerializer(
80     KeySerializer* serializer) {
81   absl::WriterMutexLock lock(&registry_mutex_);
82   SerializationRegistry::Builder builder(registry_);
83   util::Status status = builder.RegisterKeySerializer(serializer);
84   if (!status.ok()) return status;
85   registry_ = builder.Build();
86   return util::OkStatus();
87 }
88 
89 util::StatusOr<std::unique_ptr<Parameters>>
ParseParameters(const Serialization & serialization)90 MutableSerializationRegistry::ParseParameters(
91     const Serialization& serialization) {
92   absl::ReaderMutexLock lock(&registry_mutex_);
93   return registry_.ParseParameters(serialization);
94 }
95 
ParseKey(const Serialization & serialization,absl::optional<SecretKeyAccessToken> token)96 util::StatusOr<std::unique_ptr<Key>> MutableSerializationRegistry::ParseKey(
97     const Serialization& serialization,
98     absl::optional<SecretKeyAccessToken> token) {
99   absl::ReaderMutexLock lock(&registry_mutex_);
100   return registry_.ParseKey(serialization, token);
101 }
102 
103 util::StatusOr<std::unique_ptr<Key>>
ParseKeyWithLegacyFallback(const Serialization & serialization,SecretKeyAccessToken token)104 MutableSerializationRegistry::ParseKeyWithLegacyFallback(
105     const Serialization& serialization, SecretKeyAccessToken token) {
106   util::StatusOr<std::unique_ptr<Key>> key = ParseKey(serialization, token);
107   if (key.status().code() == absl::StatusCode::kNotFound) {
108     const ProtoKeySerialization* proto_serialization =
109         dynamic_cast<const ProtoKeySerialization*>(&serialization);
110     util::StatusOr<LegacyProtoKey> proto_key = internal::LegacyProtoKey::Create(
111         *proto_serialization, InsecureSecretKeyAccess::Get());
112     if (!proto_key.ok()) return proto_key.status();
113     return {absl::make_unique<LegacyProtoKey>(*proto_key)};
114   }
115   if (!key.ok()) return key.status();
116   return key;
117 }
118 
119 }  // namespace internal
120 }  // namespace tink
121 }  // namespace crypto
122