xref: /aosp_15_r20/external/tink/cc/internal/registry_impl.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang // Copyright 2018 Google Inc.
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang //     http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ///////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang 
17*e7b1675dSTing-Kang Chang #ifndef TINK_INTERNAL_REGISTRY_IMPL_H_
18*e7b1675dSTing-Kang Chang #define TINK_INTERNAL_REGISTRY_IMPL_H_
19*e7b1675dSTing-Kang Chang 
20*e7b1675dSTing-Kang Chang #include <algorithm>
21*e7b1675dSTing-Kang Chang #include <memory>
22*e7b1675dSTing-Kang Chang #include <string>
23*e7b1675dSTing-Kang Chang #include <utility>
24*e7b1675dSTing-Kang Chang 
25*e7b1675dSTing-Kang Chang #include "absl/base/thread_annotations.h"
26*e7b1675dSTing-Kang Chang #include "absl/container/flat_hash_map.h"
27*e7b1675dSTing-Kang Chang #include "absl/functional/any_invocable.h"
28*e7b1675dSTing-Kang Chang #include "absl/memory/memory.h"
29*e7b1675dSTing-Kang Chang #include "absl/status/status.h"
30*e7b1675dSTing-Kang Chang #include "absl/strings/string_view.h"
31*e7b1675dSTing-Kang Chang #include "absl/synchronization/mutex.h"
32*e7b1675dSTing-Kang Chang #include "tink/core/key_type_manager.h"
33*e7b1675dSTing-Kang Chang #include "tink/core/private_key_type_manager.h"
34*e7b1675dSTing-Kang Chang #include "tink/input_stream.h"
35*e7b1675dSTing-Kang Chang #include "tink/internal/fips_utils.h"
36*e7b1675dSTing-Kang Chang #include "tink/internal/key_type_info_store.h"
37*e7b1675dSTing-Kang Chang #include "tink/internal/keyset_wrapper.h"
38*e7b1675dSTing-Kang Chang #include "tink/internal/keyset_wrapper_store.h"
39*e7b1675dSTing-Kang Chang #include "tink/key_manager.h"
40*e7b1675dSTing-Kang Chang #include "tink/monitoring/monitoring.h"
41*e7b1675dSTing-Kang Chang #include "tink/primitive_set.h"
42*e7b1675dSTing-Kang Chang #include "tink/primitive_wrapper.h"
43*e7b1675dSTing-Kang Chang #include "tink/util/status.h"
44*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
45*e7b1675dSTing-Kang Chang #include "proto/tink.pb.h"
46*e7b1675dSTing-Kang Chang 
47*e7b1675dSTing-Kang Chang namespace crypto {
48*e7b1675dSTing-Kang Chang namespace tink {
49*e7b1675dSTing-Kang Chang namespace internal {
50*e7b1675dSTing-Kang Chang 
51*e7b1675dSTing-Kang Chang class RegistryImpl {
52*e7b1675dSTing-Kang Chang  public:
GlobalInstance()53*e7b1675dSTing-Kang Chang   static RegistryImpl& GlobalInstance() {
54*e7b1675dSTing-Kang Chang     static RegistryImpl* instance = new RegistryImpl();
55*e7b1675dSTing-Kang Chang     return *instance;
56*e7b1675dSTing-Kang Chang   }
57*e7b1675dSTing-Kang Chang 
58*e7b1675dSTing-Kang Chang   RegistryImpl() = default;
59*e7b1675dSTing-Kang Chang   RegistryImpl(const RegistryImpl&) = delete;
60*e7b1675dSTing-Kang Chang   RegistryImpl& operator=(const RegistryImpl&) = delete;
61*e7b1675dSTing-Kang Chang 
62*e7b1675dSTing-Kang Chang   // Registers the given 'manager' for the key type 'manager->get_key_type()'.
63*e7b1675dSTing-Kang Chang   // Takes ownership of 'manager', which must be non-nullptr. KeyManager is the
64*e7b1675dSTing-Kang Chang   // legacy/internal version of KeyTypeManager.
65*e7b1675dSTing-Kang Chang   template <class P>
66*e7b1675dSTing-Kang Chang   crypto::tink::util::Status RegisterKeyManager(KeyManager<P>* manager,
67*e7b1675dSTing-Kang Chang                                                 bool new_key_allowed = true)
68*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(maps_mutex_);
69*e7b1675dSTing-Kang Chang 
70*e7b1675dSTing-Kang Chang   // Takes ownership of 'manager', which must be non-nullptr.
71*e7b1675dSTing-Kang Chang   template <class KeyProto, class KeyFormatProto, class PrimitiveList>
72*e7b1675dSTing-Kang Chang   crypto::tink::util::Status RegisterKeyTypeManager(
73*e7b1675dSTing-Kang Chang       std::unique_ptr<KeyTypeManager<KeyProto, KeyFormatProto, PrimitiveList>>
74*e7b1675dSTing-Kang Chang           manager,
75*e7b1675dSTing-Kang Chang       bool new_key_allowed) ABSL_LOCKS_EXCLUDED(maps_mutex_);
76*e7b1675dSTing-Kang Chang 
77*e7b1675dSTing-Kang Chang   // Takes ownership of 'private_manager' and 'public_manager'. Both must be
78*e7b1675dSTing-Kang Chang   // non-nullptr.
79*e7b1675dSTing-Kang Chang   template <class PrivateKeyProto, class KeyFormatProto, class PublicKeyProto,
80*e7b1675dSTing-Kang Chang             class PrivatePrimitivesList, class PublicPrimitivesList>
81*e7b1675dSTing-Kang Chang   crypto::tink::util::Status RegisterAsymmetricKeyManagers(
82*e7b1675dSTing-Kang Chang       PrivateKeyTypeManager<PrivateKeyProto, KeyFormatProto, PublicKeyProto,
83*e7b1675dSTing-Kang Chang                             PrivatePrimitivesList>* private_manager,
84*e7b1675dSTing-Kang Chang       KeyTypeManager<PublicKeyProto, void, PublicPrimitivesList>*
85*e7b1675dSTing-Kang Chang           public_manager,
86*e7b1675dSTing-Kang Chang       bool new_key_allowed) ABSL_LOCKS_EXCLUDED(maps_mutex_);
87*e7b1675dSTing-Kang Chang 
88*e7b1675dSTing-Kang Chang   template <class P>
89*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<const KeyManager<P>*> get_key_manager(
90*e7b1675dSTing-Kang Chang       absl::string_view type_url) const ABSL_LOCKS_EXCLUDED(maps_mutex_);
91*e7b1675dSTing-Kang Chang 
92*e7b1675dSTing-Kang Chang   // Takes ownership of 'wrapper', which must be non-nullptr.
93*e7b1675dSTing-Kang Chang   template <class P, class Q>
94*e7b1675dSTing-Kang Chang   crypto::tink::util::Status RegisterPrimitiveWrapper(
95*e7b1675dSTing-Kang Chang       PrimitiveWrapper<P, Q>* wrapper) ABSL_LOCKS_EXCLUDED(maps_mutex_);
96*e7b1675dSTing-Kang Chang 
97*e7b1675dSTing-Kang Chang   template <class P>
98*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<std::unique_ptr<P>> GetPrimitive(
99*e7b1675dSTing-Kang Chang       const google::crypto::tink::KeyData& key_data) const
100*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(maps_mutex_);
101*e7b1675dSTing-Kang Chang 
102*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<std::unique_ptr<google::crypto::tink::KeyData>>
103*e7b1675dSTing-Kang Chang   NewKeyData(const google::crypto::tink::KeyTemplate& key_template) const
104*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(maps_mutex_);
105*e7b1675dSTing-Kang Chang 
106*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<std::unique_ptr<google::crypto::tink::KeyData>>
107*e7b1675dSTing-Kang Chang   GetPublicKeyData(absl::string_view type_url,
108*e7b1675dSTing-Kang Chang                    absl::string_view serialized_private_key) const
109*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(maps_mutex_);
110*e7b1675dSTing-Kang Chang 
111*e7b1675dSTing-Kang Chang   template <class P>
112*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<std::unique_ptr<P>> Wrap(
113*e7b1675dSTing-Kang Chang       std::unique_ptr<PrimitiveSet<P>> primitive_set) const
114*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(maps_mutex_);
115*e7b1675dSTing-Kang Chang 
116*e7b1675dSTing-Kang Chang   // Wraps a `keyset` and annotates it with `annotations`.
117*e7b1675dSTing-Kang Chang   template <class P>
118*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<std::unique_ptr<P>> WrapKeyset(
119*e7b1675dSTing-Kang Chang       const google::crypto::tink::Keyset& keyset,
120*e7b1675dSTing-Kang Chang       const absl::flat_hash_map<std::string, std::string>& annotations) const
121*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(maps_mutex_);
122*e7b1675dSTing-Kang Chang 
123*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<google::crypto::tink::KeyData> DeriveKey(
124*e7b1675dSTing-Kang Chang       const google::crypto::tink::KeyTemplate& key_template,
125*e7b1675dSTing-Kang Chang       InputStream* randomness) const ABSL_LOCKS_EXCLUDED(maps_mutex_);
126*e7b1675dSTing-Kang Chang 
127*e7b1675dSTing-Kang Chang   void Reset() ABSL_LOCKS_EXCLUDED(maps_mutex_, monitoring_factory_mutex_);
128*e7b1675dSTing-Kang Chang 
129*e7b1675dSTing-Kang Chang   crypto::tink::util::Status RestrictToFipsIfEmpty() const
130*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(maps_mutex_);
131*e7b1675dSTing-Kang Chang 
132*e7b1675dSTing-Kang Chang   // Registers a `monitoring_factory`. Only one factory can be registered,
133*e7b1675dSTing-Kang Chang   // subsequent calls to this method will return a kAlreadyExists error.
134*e7b1675dSTing-Kang Chang   crypto::tink::util::Status RegisterMonitoringClientFactory(
135*e7b1675dSTing-Kang Chang       std::unique_ptr<crypto::tink::MonitoringClientFactory> monitoring_factory)
136*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(monitoring_factory_mutex_);
137*e7b1675dSTing-Kang Chang 
138*e7b1675dSTing-Kang Chang   // Returns a pointer to the registered monitoring factory if any, and nullptr
139*e7b1675dSTing-Kang Chang   // otherwise.
GetMonitoringClientFactory()140*e7b1675dSTing-Kang Chang   crypto::tink::MonitoringClientFactory* GetMonitoringClientFactory() const
141*e7b1675dSTing-Kang Chang       ABSL_LOCKS_EXCLUDED(monitoring_factory_mutex_) {
142*e7b1675dSTing-Kang Chang     absl::MutexLock lock(&monitoring_factory_mutex_);
143*e7b1675dSTing-Kang Chang     return monitoring_factory_.get();
144*e7b1675dSTing-Kang Chang   }
145*e7b1675dSTing-Kang Chang 
146*e7b1675dSTing-Kang Chang  private:
147*e7b1675dSTing-Kang Chang   // Returns the key type info for a given type URL. Since we never replace
148*e7b1675dSTing-Kang Chang   // key type infos, the pointers will stay valid for the lifetime of the
149*e7b1675dSTing-Kang Chang   // binary.
150*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<const KeyTypeInfoStore::Info*> get_key_type_info(
151*e7b1675dSTing-Kang Chang       absl::string_view type_url) const ABSL_LOCKS_EXCLUDED(maps_mutex_);
152*e7b1675dSTing-Kang Chang 
153*e7b1675dSTing-Kang Chang   mutable absl::Mutex maps_mutex_;
154*e7b1675dSTing-Kang Chang   // Stores information about key types constructed from their KeyTypeManager or
155*e7b1675dSTing-Kang Chang   // KeyManager.
156*e7b1675dSTing-Kang Chang   // Once inserted, KeyTypeInfoStore::Info objects must remain valid for the
157*e7b1675dSTing-Kang Chang   // lifetime of the binary, and the Info object's pointer stability is
158*e7b1675dSTing-Kang Chang   // required. Elements in Info, which include the KeyTypeManager or KeyManager,
159*e7b1675dSTing-Kang Chang   // must not be replaced.
160*e7b1675dSTing-Kang Chang   KeyTypeInfoStore key_type_info_store_ ABSL_GUARDED_BY(maps_mutex_);
161*e7b1675dSTing-Kang Chang   // Stores information about keyset wrappers constructed from their
162*e7b1675dSTing-Kang Chang   // PrimitiveWrapper.
163*e7b1675dSTing-Kang Chang   KeysetWrapperStore keyset_wrapper_store_ ABSL_GUARDED_BY(maps_mutex_);
164*e7b1675dSTing-Kang Chang 
165*e7b1675dSTing-Kang Chang   mutable absl::Mutex monitoring_factory_mutex_;
166*e7b1675dSTing-Kang Chang   std::unique_ptr<crypto::tink::MonitoringClientFactory> monitoring_factory_
167*e7b1675dSTing-Kang Chang       ABSL_GUARDED_BY(monitoring_factory_mutex_);
168*e7b1675dSTing-Kang Chang };
169*e7b1675dSTing-Kang Chang 
170*e7b1675dSTing-Kang Chang template <class P>
RegisterKeyManager(KeyManager<P> * manager,bool new_key_allowed)171*e7b1675dSTing-Kang Chang crypto::tink::util::Status RegistryImpl::RegisterKeyManager(
172*e7b1675dSTing-Kang Chang     KeyManager<P>* manager, bool new_key_allowed) {
173*e7b1675dSTing-Kang Chang   auto owned_manager = absl::WrapUnique(manager);
174*e7b1675dSTing-Kang Chang   if (manager == nullptr) {
175*e7b1675dSTing-Kang Chang     return crypto::tink::util::Status(absl::StatusCode::kInvalidArgument,
176*e7b1675dSTing-Kang Chang                                       "Parameter 'manager' must be non-null.");
177*e7b1675dSTing-Kang Chang   }
178*e7b1675dSTing-Kang Chang   absl::MutexLock lock(&maps_mutex_);
179*e7b1675dSTing-Kang Chang   return key_type_info_store_.AddKeyManager(std::move(owned_manager),
180*e7b1675dSTing-Kang Chang                                             new_key_allowed);
181*e7b1675dSTing-Kang Chang }
182*e7b1675dSTing-Kang Chang 
183*e7b1675dSTing-Kang Chang template <class KeyProto, class KeyFormatProto, class PrimitiveList>
RegisterKeyTypeManager(std::unique_ptr<KeyTypeManager<KeyProto,KeyFormatProto,PrimitiveList>> manager,bool new_key_allowed)184*e7b1675dSTing-Kang Chang crypto::tink::util::Status RegistryImpl::RegisterKeyTypeManager(
185*e7b1675dSTing-Kang Chang     std::unique_ptr<KeyTypeManager<KeyProto, KeyFormatProto, PrimitiveList>>
186*e7b1675dSTing-Kang Chang         manager,
187*e7b1675dSTing-Kang Chang     bool new_key_allowed) {
188*e7b1675dSTing-Kang Chang   if (manager == nullptr) {
189*e7b1675dSTing-Kang Chang     return crypto::tink::util::Status(absl::StatusCode::kInvalidArgument,
190*e7b1675dSTing-Kang Chang                                       "Parameter 'manager' must be non-null.");
191*e7b1675dSTing-Kang Chang   }
192*e7b1675dSTing-Kang Chang   absl::MutexLock lock(&maps_mutex_);
193*e7b1675dSTing-Kang Chang   return key_type_info_store_.AddKeyTypeManager(std::move(manager),
194*e7b1675dSTing-Kang Chang                                                 new_key_allowed);
195*e7b1675dSTing-Kang Chang }
196*e7b1675dSTing-Kang Chang 
197*e7b1675dSTing-Kang Chang template <class PrivateKeyProto, class KeyFormatProto, class PublicKeyProto,
198*e7b1675dSTing-Kang Chang           class PrivatePrimitivesList, class PublicPrimitivesList>
RegisterAsymmetricKeyManagers(PrivateKeyTypeManager<PrivateKeyProto,KeyFormatProto,PublicKeyProto,PrivatePrimitivesList> * private_manager,KeyTypeManager<PublicKeyProto,void,PublicPrimitivesList> * public_manager,bool new_key_allowed)199*e7b1675dSTing-Kang Chang crypto::tink::util::Status RegistryImpl::RegisterAsymmetricKeyManagers(
200*e7b1675dSTing-Kang Chang     PrivateKeyTypeManager<PrivateKeyProto, KeyFormatProto, PublicKeyProto,
201*e7b1675dSTing-Kang Chang                           PrivatePrimitivesList>* private_manager,
202*e7b1675dSTing-Kang Chang     KeyTypeManager<PublicKeyProto, void, PublicPrimitivesList>* public_manager,
203*e7b1675dSTing-Kang Chang     bool new_key_allowed) ABSL_LOCKS_EXCLUDED(maps_mutex_) {
204*e7b1675dSTing-Kang Chang   auto owned_private_manager = absl::WrapUnique(private_manager);
205*e7b1675dSTing-Kang Chang   auto owned_public_manager = absl::WrapUnique(public_manager);
206*e7b1675dSTing-Kang Chang 
207*e7b1675dSTing-Kang Chang   if (private_manager == nullptr) {
208*e7b1675dSTing-Kang Chang     return crypto::tink::util::Status(
209*e7b1675dSTing-Kang Chang         absl::StatusCode::kInvalidArgument,
210*e7b1675dSTing-Kang Chang         "Parameter 'private_manager' must be non-null.");
211*e7b1675dSTing-Kang Chang   }
212*e7b1675dSTing-Kang Chang   if (public_manager == nullptr) {
213*e7b1675dSTing-Kang Chang     return crypto::tink::util::Status(
214*e7b1675dSTing-Kang Chang         absl::StatusCode::kInvalidArgument,
215*e7b1675dSTing-Kang Chang         "Parameter 'public_manager' must be non-null.");
216*e7b1675dSTing-Kang Chang   }
217*e7b1675dSTing-Kang Chang 
218*e7b1675dSTing-Kang Chang   absl::MutexLock lock(&maps_mutex_);
219*e7b1675dSTing-Kang Chang   return key_type_info_store_.AddAsymmetricKeyTypeManagers(
220*e7b1675dSTing-Kang Chang       std::move(owned_private_manager), std::move(owned_public_manager),
221*e7b1675dSTing-Kang Chang       new_key_allowed);
222*e7b1675dSTing-Kang Chang }
223*e7b1675dSTing-Kang Chang 
224*e7b1675dSTing-Kang Chang template <class P, class Q>
RegisterPrimitiveWrapper(PrimitiveWrapper<P,Q> * wrapper)225*e7b1675dSTing-Kang Chang crypto::tink::util::Status RegistryImpl::RegisterPrimitiveWrapper(
226*e7b1675dSTing-Kang Chang     PrimitiveWrapper<P, Q>* wrapper) {
227*e7b1675dSTing-Kang Chang   if (wrapper == nullptr) {
228*e7b1675dSTing-Kang Chang     return crypto::tink::util::Status(absl::StatusCode::kInvalidArgument,
229*e7b1675dSTing-Kang Chang                                       "Parameter 'wrapper' must be non-null.");
230*e7b1675dSTing-Kang Chang   }
231*e7b1675dSTing-Kang Chang   std::unique_ptr<PrimitiveWrapper<P, Q>> owned_wrapper(wrapper);
232*e7b1675dSTing-Kang Chang 
233*e7b1675dSTing-Kang Chang   absl::MutexLock lock(&maps_mutex_);
234*e7b1675dSTing-Kang Chang   absl::AnyInvocable<crypto::tink::util::StatusOr<std::unique_ptr<P>>(
235*e7b1675dSTing-Kang Chang       const google::crypto::tink::KeyData& key_data) const>
236*e7b1675dSTing-Kang Chang       primitive_getter = [this](const google::crypto::tink::KeyData& key_data) {
237*e7b1675dSTing-Kang Chang         return this->GetPrimitive<P>(key_data);
238*e7b1675dSTing-Kang Chang       };
239*e7b1675dSTing-Kang Chang   return keyset_wrapper_store_.Add(std::move(owned_wrapper),
240*e7b1675dSTing-Kang Chang                                    std::move(primitive_getter));
241*e7b1675dSTing-Kang Chang }
242*e7b1675dSTing-Kang Chang 
243*e7b1675dSTing-Kang Chang template <class P>
244*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<const KeyManager<P>*>
get_key_manager(absl::string_view type_url)245*e7b1675dSTing-Kang Chang RegistryImpl::get_key_manager(absl::string_view type_url) const {
246*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<
247*e7b1675dSTing-Kang Chang       const crypto::tink::internal::KeyTypeInfoStore::Info*>
248*e7b1675dSTing-Kang Chang       info = get_key_type_info(type_url);
249*e7b1675dSTing-Kang Chang   if (!info.ok()) {
250*e7b1675dSTing-Kang Chang     return info.status();
251*e7b1675dSTing-Kang Chang   }
252*e7b1675dSTing-Kang Chang   return (*info)->get_key_manager<P>(type_url);
253*e7b1675dSTing-Kang Chang }
254*e7b1675dSTing-Kang Chang 
255*e7b1675dSTing-Kang Chang template <class P>
GetPrimitive(const google::crypto::tink::KeyData & key_data)256*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> RegistryImpl::GetPrimitive(
257*e7b1675dSTing-Kang Chang     const google::crypto::tink::KeyData& key_data) const {
258*e7b1675dSTing-Kang Chang   auto key_manager_result = get_key_manager<P>(key_data.type_url());
259*e7b1675dSTing-Kang Chang   if (key_manager_result.ok()) {
260*e7b1675dSTing-Kang Chang     return key_manager_result.value()->GetPrimitive(key_data);
261*e7b1675dSTing-Kang Chang   }
262*e7b1675dSTing-Kang Chang   return key_manager_result.status();
263*e7b1675dSTing-Kang Chang }
264*e7b1675dSTing-Kang Chang 
265*e7b1675dSTing-Kang Chang template <class P>
Wrap(std::unique_ptr<PrimitiveSet<P>> primitive_set)266*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> RegistryImpl::Wrap(
267*e7b1675dSTing-Kang Chang     std::unique_ptr<PrimitiveSet<P>> primitive_set) const {
268*e7b1675dSTing-Kang Chang   if (primitive_set == nullptr) {
269*e7b1675dSTing-Kang Chang     return crypto::tink::util::Status(
270*e7b1675dSTing-Kang Chang         absl::StatusCode::kInvalidArgument,
271*e7b1675dSTing-Kang Chang         "Parameter 'primitive_set' must be non-null.");
272*e7b1675dSTing-Kang Chang   }
273*e7b1675dSTing-Kang Chang   const PrimitiveWrapper<P, P>* wrapper = nullptr;
274*e7b1675dSTing-Kang Chang   {
275*e7b1675dSTing-Kang Chang     absl::MutexLock lock(&maps_mutex_);
276*e7b1675dSTing-Kang Chang     crypto::tink::util::StatusOr<const PrimitiveWrapper<P, P>*> wrapper_status =
277*e7b1675dSTing-Kang Chang         keyset_wrapper_store_.GetPrimitiveWrapper<P>();
278*e7b1675dSTing-Kang Chang     if (!wrapper_status.ok()) {
279*e7b1675dSTing-Kang Chang       return wrapper_status.status();
280*e7b1675dSTing-Kang Chang     }
281*e7b1675dSTing-Kang Chang     wrapper = *wrapper_status;
282*e7b1675dSTing-Kang Chang   }
283*e7b1675dSTing-Kang Chang   return wrapper->Wrap(std::move(primitive_set));
284*e7b1675dSTing-Kang Chang }
285*e7b1675dSTing-Kang Chang 
286*e7b1675dSTing-Kang Chang template <class P>
WrapKeyset(const google::crypto::tink::Keyset & keyset,const absl::flat_hash_map<std::string,std::string> & annotations)287*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr<std::unique_ptr<P>> RegistryImpl::WrapKeyset(
288*e7b1675dSTing-Kang Chang     const google::crypto::tink::Keyset& keyset,
289*e7b1675dSTing-Kang Chang     const absl::flat_hash_map<std::string, std::string>& annotations) const {
290*e7b1675dSTing-Kang Chang   const KeysetWrapper<P>* keyset_wrapper = nullptr;
291*e7b1675dSTing-Kang Chang   {
292*e7b1675dSTing-Kang Chang     absl::MutexLock lock(&maps_mutex_);
293*e7b1675dSTing-Kang Chang     crypto::tink::util::StatusOr<const KeysetWrapper<P>*>
294*e7b1675dSTing-Kang Chang         keyset_wrapper_status = keyset_wrapper_store_.Get<P>();
295*e7b1675dSTing-Kang Chang     if (!keyset_wrapper_status.ok()) {
296*e7b1675dSTing-Kang Chang       return keyset_wrapper_status.status();
297*e7b1675dSTing-Kang Chang     }
298*e7b1675dSTing-Kang Chang     keyset_wrapper = *keyset_wrapper_status;
299*e7b1675dSTing-Kang Chang   }
300*e7b1675dSTing-Kang Chang   // `maps_mutex_` must be released before calling Wrap or this will deadlock,
301*e7b1675dSTing-Kang Chang   // as Wrap calls get_key_manager.
302*e7b1675dSTing-Kang Chang   return keyset_wrapper->Wrap(keyset, annotations);
303*e7b1675dSTing-Kang Chang }
304*e7b1675dSTing-Kang Chang 
RestrictToFipsIfEmpty()305*e7b1675dSTing-Kang Chang inline crypto::tink::util::Status RegistryImpl::RestrictToFipsIfEmpty() const {
306*e7b1675dSTing-Kang Chang   absl::MutexLock lock(&maps_mutex_);
307*e7b1675dSTing-Kang Chang   // If we are already in FIPS mode, then do nothing..
308*e7b1675dSTing-Kang Chang   if (IsFipsModeEnabled()) {
309*e7b1675dSTing-Kang Chang     return util::OkStatus();
310*e7b1675dSTing-Kang Chang   }
311*e7b1675dSTing-Kang Chang   if (key_type_info_store_.IsEmpty()) {
312*e7b1675dSTing-Kang Chang     SetFipsRestricted();
313*e7b1675dSTing-Kang Chang     return util::OkStatus();
314*e7b1675dSTing-Kang Chang   }
315*e7b1675dSTing-Kang Chang   return util::Status(absl::StatusCode::kInternal,
316*e7b1675dSTing-Kang Chang                       "Could not set FIPS only mode. Registry is not empty.");
317*e7b1675dSTing-Kang Chang }
318*e7b1675dSTing-Kang Chang 
319*e7b1675dSTing-Kang Chang }  // namespace internal
320*e7b1675dSTing-Kang Chang }  // namespace tink
321*e7b1675dSTing-Kang Chang }  // namespace crypto
322*e7b1675dSTing-Kang Chang 
323*e7b1675dSTing-Kang Chang #endif  // TINK_INTERNAL_REGISTRY_IMPL_H_
324