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