xref: /aosp_15_r20/external/tink/cc/registry.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2017 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 #ifndef TINK_REGISTRY_H_
18 #define TINK_REGISTRY_H_
19 
20 #include <memory>
21 #include <string>
22 
23 #include "absl/strings/string_view.h"
24 #include "tink/internal/registry_impl.h"
25 #include "tink/util/status.h"
26 #include "tink/util/statusor.h"
27 
28 namespace crypto {
29 namespace tink {
30 
31 // Registry for KeyMangers and PrimitiveWrappers.
32 //
33 // It is essentially a big container (map) that for each supported key type
34 // holds a corresponding KeyManager object, which "understands" the key type
35 // (i.e. the KeyManager can instantiate the primitive corresponding to given
36 // key, or can generate new keys of the supported key type).  It holds also
37 // a so-called PrimitiveWrapper for each supported primitive, so that it can
38 // wrap a set of primitives (corresponding to a keyset) into a single primitive.
39 //
40 // Registry is initialized at startup, and is later used to instantiate
41 // primitives for given keys or keysets.  Keeping KeyManagers for all primitives
42 // in a single Registry (rather than having a separate KeyManager per primitive)
43 // enables modular construction of compound primitives from "simple" ones, e.g.,
44 // AES-CTR-HMAC AEAD encryption uses IND-CPA encryption and a MAC.
45 //
46 // Note that regular users will usually not work directly with Registry, but
47 // rather via KeysetHandle::GetPrimitive()-methods, which in the background
48 // query the Registry for specific KeyManagers and PrimitiveWrappers.
49 // Registry is public though, to enable configurations with custom primitives
50 // and KeyManagers.
51 class Registry {
52  public:
53   // Registers the given 'manager' for the key type 'manager->get_key_type()'.
54   template <class ConcreteKeyManager>
RegisterKeyManager(std::unique_ptr<ConcreteKeyManager> manager,bool new_key_allowed)55   static crypto::tink::util::Status RegisterKeyManager(
56       std::unique_ptr<ConcreteKeyManager> manager, bool new_key_allowed) {
57     return internal::RegistryImpl::GlobalInstance().RegisterKeyManager(
58         manager.release(), new_key_allowed);
59   }
60 
61   template <class KTManager>
RegisterKeyTypeManager(std::unique_ptr<KTManager> manager,bool new_key_allowed)62   static crypto::tink::util::Status RegisterKeyTypeManager(
63       std::unique_ptr<KTManager> manager, bool new_key_allowed) {
64     return internal::RegistryImpl::GlobalInstance()
65         .RegisterKeyTypeManager<typename KTManager::KeyProto,
66                                 typename KTManager::KeyFormatProto,
67                                 typename KTManager::PrimitiveList>(
68             std::move(manager), new_key_allowed);
69   }
70 
71   template <class PrivateKeyTypeManager, class KeyTypeManager>
RegisterAsymmetricKeyManagers(std::unique_ptr<PrivateKeyTypeManager> private_key_manager,std::unique_ptr<KeyTypeManager> public_key_manager,bool new_key_allowed)72   static crypto::tink::util::Status RegisterAsymmetricKeyManagers(
73       std::unique_ptr<PrivateKeyTypeManager> private_key_manager,
74       std::unique_ptr<KeyTypeManager> public_key_manager,
75       bool new_key_allowed) {
76     return internal::RegistryImpl::GlobalInstance()
77         .RegisterAsymmetricKeyManagers(private_key_manager.release(),
78                                        public_key_manager.release(),
79                                        new_key_allowed);
80   }
81 
82   template <class ConcretePrimitiveWrapper>
RegisterPrimitiveWrapper(std::unique_ptr<ConcretePrimitiveWrapper> wrapper)83   static crypto::tink::util::Status RegisterPrimitiveWrapper(
84       std::unique_ptr<ConcretePrimitiveWrapper> wrapper) {
85     return internal::RegistryImpl::GlobalInstance().RegisterPrimitiveWrapper(
86         wrapper.release());
87   }
88 
89   // Returns a key manager for the given type_url (if any found).
90   // Keeps the ownership of the manager. Returned key_managers are guaranteed
91   // to stay valid for the lifetime of the binary (with the exception of a user
92   // calling Reset()).
93   // TODO(tholenst): Remove Reset() from the interface, as it could violate this
94   // but should be test only anyhow.
95   template <class P>
get_key_manager(absl::string_view type_url)96   static crypto::tink::util::StatusOr<const KeyManager<P>*> get_key_manager(
97       absl::string_view type_url) {
98     return internal::RegistryImpl::GlobalInstance().get_key_manager<P>(
99         type_url);
100   }
101 
102   // Convenience method for creating a new primitive for the key given
103   // in 'key_data'.  It looks up a KeyManager identified by key_data.type_url,
104   // and calls manager's GetPrimitive(key_data)-method.
105   template <class P>
GetPrimitive(const google::crypto::tink::KeyData & key_data)106   static crypto::tink::util::StatusOr<std::unique_ptr<P>> GetPrimitive(
107       const google::crypto::tink::KeyData& key_data) {
108     return internal::RegistryImpl::GlobalInstance().GetPrimitive<P>(key_data);
109   }
110 
111   // Generates a new KeyData for the specified 'key_template'.
112   // It looks up a KeyManager identified by key_template.type_url,
113   // and calls KeyManager::NewKeyData.
114   // This method should be used solely for key management.
115   static crypto::tink::util::StatusOr<
116       std::unique_ptr<google::crypto::tink::KeyData>>
NewKeyData(const google::crypto::tink::KeyTemplate & key_template)117   NewKeyData(const google::crypto::tink::KeyTemplate& key_template) {
118     return internal::RegistryImpl::GlobalInstance().NewKeyData(key_template);
119   }
120 
121   // Convenience method for extracting the public key data from the
122   // private key given in serialized_private_key.
123   // It looks up a KeyManager identified by type_url, whose KeyFactory must be
124   // a PrivateKeyFactory, and calls PrivateKeyFactory::GetPublicKeyData.
125   static crypto::tink::util::StatusOr<
126       std::unique_ptr<google::crypto::tink::KeyData>>
GetPublicKeyData(absl::string_view type_url,absl::string_view serialized_private_key)127   GetPublicKeyData(absl::string_view type_url,
128                    absl::string_view serialized_private_key) {
129     return internal::RegistryImpl::GlobalInstance().GetPublicKeyData(
130         type_url, serialized_private_key);
131   }
132 
133   // Looks up the globally registered PrimitiveWrapper for this primitive
134   // and wraps the given PrimitiveSet with it.
135   template <class P>
Wrap(std::unique_ptr<PrimitiveSet<P>> primitive_set)136   static crypto::tink::util::StatusOr<std::unique_ptr<P>> Wrap(
137       std::unique_ptr<PrimitiveSet<P>> primitive_set) {
138     return internal::RegistryImpl::GlobalInstance().Wrap<P>(
139         std::move(primitive_set));
140   }
141 
142   // Resets the registry.
143   // After reset the registry is empty, i.e. it contains neither catalogues
144   // nor key managers. This method is intended for testing only.
Reset()145   static void Reset() {
146     return internal::RegistryImpl::GlobalInstance().Reset();
147   }
148 };
149 
150 }  // namespace tink
151 }  // namespace crypto
152 
153 #endif  // TINK_REGISTRY_H_
154