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(®istry_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(®istry_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(®istry_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(®istry_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(®istry_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(®istry_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