xref: /aosp_15_r20/external/tink/cc/internal/registry_impl.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2018 Google Inc.
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/registry_impl.h"
18 
19 #include <functional>
20 #include <memory>
21 #include <utility>
22 
23 #include "absl/status/status.h"
24 #include "absl/strings/str_cat.h"
25 #include "absl/strings/string_view.h"
26 #include "absl/synchronization/mutex.h"
27 #include "tink/input_stream.h"
28 #include "tink/internal/keyset_wrapper_store.h"
29 #include "tink/key_manager.h"
30 #include "tink/monitoring/monitoring.h"
31 #include "tink/util/errors.h"
32 #include "tink/util/status.h"
33 #include "tink/util/statusor.h"
34 #include "proto/tink.pb.h"
35 
36 namespace crypto {
37 namespace tink {
38 namespace internal {
39 
40 using ::crypto::tink::MonitoringClientFactory;
41 using ::google::crypto::tink::KeyData;
42 using ::google::crypto::tink::KeyTemplate;
43 
get_key_type_info(absl::string_view type_url) const44 util::StatusOr<const KeyTypeInfoStore::Info*> RegistryImpl::get_key_type_info(
45     absl::string_view type_url) const {
46   absl::MutexLock lock(&maps_mutex_);
47   return key_type_info_store_.Get(type_url);
48 }
49 
NewKeyData(const KeyTemplate & key_template) const50 util::StatusOr<std::unique_ptr<KeyData>> RegistryImpl::NewKeyData(
51     const KeyTemplate& key_template) const {
52   util::StatusOr<const internal::KeyTypeInfoStore::Info*> info =
53       get_key_type_info(key_template.type_url());
54   if (!info.ok()) {
55     return info.status();
56   }
57   if (!(*info)->new_key_allowed()) {
58     return crypto::tink::util::Status(
59         absl::StatusCode::kInvalidArgument,
60         absl::StrCat("KeyManager for type ", key_template.type_url(),
61                      " does not allow for creation of new keys."));
62   }
63   return (*info)->key_factory().NewKeyData(key_template.value());
64 }
65 
GetPublicKeyData(absl::string_view type_url,absl::string_view serialized_private_key) const66 util::StatusOr<std::unique_ptr<KeyData>> RegistryImpl::GetPublicKeyData(
67     absl::string_view type_url,
68     absl::string_view serialized_private_key) const {
69   util::StatusOr<const internal::KeyTypeInfoStore::Info*> info =
70       get_key_type_info(type_url);
71   if (!info.ok()) {
72     return info.status();
73   }
74   auto factory =
75       dynamic_cast<const PrivateKeyFactory*>(&(*info)->key_factory());
76   if (factory == nullptr) {
77     return ToStatusF(absl::StatusCode::kInvalidArgument,
78                      "KeyManager for type '%s' does not have "
79                      "a PrivateKeyFactory.",
80                      type_url);
81   }
82   auto result = factory->GetPublicKeyData(serialized_private_key);
83   return result;
84 }
85 
DeriveKey(const KeyTemplate & key_template,InputStream * randomness) const86 util::StatusOr<KeyData> RegistryImpl::DeriveKey(const KeyTemplate& key_template,
87                                                 InputStream* randomness) const {
88   util::StatusOr<const internal::KeyTypeInfoStore::Info*> info =
89       get_key_type_info(key_template.type_url());
90   if (!info.ok()) {
91     return info.status();
92   }
93   if (!(*info)->key_deriver()) {
94     return crypto::tink::util::Status(
95         absl::StatusCode::kInvalidArgument,
96         absl::StrCat("Manager for type '", key_template.type_url(),
97                      "' cannot derive keys."));
98   }
99   return (*info)->key_deriver()(key_template.value(), randomness);
100 }
101 
RegisterMonitoringClientFactory(std::unique_ptr<MonitoringClientFactory> factory)102 util::Status RegistryImpl::RegisterMonitoringClientFactory(
103     std::unique_ptr<MonitoringClientFactory> factory) {
104   absl::MutexLock lock(&monitoring_factory_mutex_);
105   if (monitoring_factory_ != nullptr) {
106     return util::Status(absl::StatusCode::kAlreadyExists,
107                         "A monitoring factory is already registered");
108   }
109   monitoring_factory_ = std::move(factory);
110   return util::OkStatus();
111 }
112 
Reset()113 void RegistryImpl::Reset() {
114   {
115     absl::MutexLock lock(&maps_mutex_);
116     key_type_info_store_ = KeyTypeInfoStore();
117     keyset_wrapper_store_ = KeysetWrapperStore();
118   }
119   {
120     absl::MutexLock lock(&monitoring_factory_mutex_);
121     monitoring_factory_.reset();
122   }
123 }
124 
125 }  // namespace internal
126 }  // namespace tink
127 }  // namespace crypto
128