diff options
author | Thomas Holenstein <tholenst@google.com> | 2018-10-03 12:06:57 -0400 |
---|---|---|
committer | Tink Team <noreply@google.com> | 2018-10-04 11:47:15 -0700 |
commit | b5e9a88c31225ae777ecc0dace61ec3d3bff70dc (patch) | |
tree | 26e25a0c8aae0accee87f105448fc819e433b973 /cc/registry.h | |
parent | f6b8bf92a836fb84a8068b0ca5146a16b8b23011 (diff) | |
download | tink-b5e9a88c31225ae777ecc0dace61ec3d3bff70dc.tar.gz |
Project import generated by Copybara.
PiperOrigin-RevId: 215570590
GitOrigin-RevId: 7c887e67cb957d1fd7d608dd0910f3739d648c0b
Diffstat (limited to 'cc/registry.h')
-rw-r--r-- | cc/registry.h | 281 |
1 files changed, 39 insertions, 242 deletions
diff --git a/cc/registry.h b/cc/registry.h index 626731f5e..792fb2d5b 100644 --- a/cc/registry.h +++ b/cc/registry.h @@ -17,21 +17,12 @@ #ifndef TINK_REGISTRY_H_ #define TINK_REGISTRY_H_ -#include <mutex> // NOLINT(build/c++11) -#include <typeinfo> -#include <unordered_map> +#include <memory> +#include <string> -#include "absl/base/thread_annotations.h" -#include "absl/synchronization/mutex.h" -#include "tink/catalogue.h" -#include "tink/key_manager.h" -#include "tink/keyset_handle.h" -#include "tink/primitive_set.h" -#include "tink/util/errors.h" -#include "tink/util/protobuf_helper.h" +#include "tink/core/registry_impl.h" #include "tink/util/status.h" -#include "tink/util/validation.h" -#include "proto/tink.pb.h" +#include "tink/util/statusor.h" namespace crypto { namespace tink { @@ -64,7 +55,9 @@ class Registry { // see https://goo.gl/x0ymDz) template <class P> static crypto::tink::util::StatusOr<const Catalogue<P>*> get_catalogue( - const std::string& catalogue_name) LOCKS_EXCLUDED(maps_mutex_); + const std::string& catalogue_name) { + return RegistryImpl::GlobalInstance().get_catalogue<P>(catalogue_name); + } // Adds the given 'catalogue' under the specified 'catalogue_name', // to enable custom configuration of key types and key managers. @@ -77,20 +70,23 @@ class Registry { // (in case of failure, 'catalogue' is deleted). template <class P> static crypto::tink::util::Status AddCatalogue(const std::string& catalogue_name, - Catalogue<P>* catalogue) - LOCKS_EXCLUDED(maps_mutex_); + Catalogue<P>* catalogue) { + return RegistryImpl::GlobalInstance().AddCatalogue<P>(catalogue_name, + catalogue); + } // Registers the given 'manager' for the key type 'manager->get_key_type()'. // Takes ownership of 'manager', which must be non-nullptr. template <class P> static crypto::tink::util::Status RegisterKeyManager(KeyManager<P>* manager, - bool new_key_allowed) - LOCKS_EXCLUDED(maps_mutex_); + bool new_key_allowed) { + return RegistryImpl::GlobalInstance().RegisterKeyManager(manager, + new_key_allowed); + } template <class P> - static crypto::tink::util::Status RegisterKeyManager(KeyManager<P>* manager) - LOCKS_EXCLUDED(maps_mutex_) { - return RegisterKeyManager(manager, /* new_key_allowed= */ true); + static crypto::tink::util::Status RegisterKeyManager(KeyManager<P>* manager) { + return RegistryImpl::GlobalInstance().RegisterKeyManager(manager); } // Returns a key manager for the given type_url (if any found). @@ -101,23 +97,26 @@ class Registry { // see https://goo.gl/x0ymDz) template <class P> static crypto::tink::util::StatusOr<const KeyManager<P>*> get_key_manager( - const std::string& type_url) LOCKS_EXCLUDED(maps_mutex_); + const std::string& type_url) { + return RegistryImpl::GlobalInstance().get_key_manager<P>(type_url); + } // Convenience method for creating a new primitive for the key given // in 'key_data'. It looks up a KeyManager identified by key_data.type_url, // and calls manager's GetPrimitive(key_data)-method. template <class P> static crypto::tink::util::StatusOr<std::unique_ptr<P>> GetPrimitive( - const google::crypto::tink::KeyData& key_data) - LOCKS_EXCLUDED(maps_mutex_); - + const google::crypto::tink::KeyData& key_data) { + return RegistryImpl::GlobalInstance().GetPrimitive<P>(key_data); + } // Convenience method for creating a new primitive for the key given // in 'key'. It looks up a KeyManager identified by type_url, // and calls manager's GetPrimitive(key)-method. template <class P> static crypto::tink::util::StatusOr<std::unique_ptr<P>> GetPrimitive( - const std::string& type_url, const portable_proto::MessageLite& key) - LOCKS_EXCLUDED(maps_mutex_); + const std::string& type_url, const portable_proto::MessageLite& key) { + return RegistryImpl::GlobalInstance().GetPrimitive<P>(type_url, key); + } // Creates a set of primitives corresponding to the keys with // (status == ENABLED) in the keyset given in 'keyset_handle', @@ -129,8 +128,10 @@ class Registry { template <class P> static crypto::tink::util::StatusOr<std::unique_ptr<PrimitiveSet<P>>> GetPrimitives(const KeysetHandle& keyset_handle, - const KeyManager<P>* custom_manager) - LOCKS_EXCLUDED(maps_mutex_); + const KeyManager<P>* custom_manager) { + return RegistryImpl::GlobalInstance().GetPrimitives<P>(keyset_handle, + custom_manager); + } // Generates a new KeyData for the specified 'key_template'. // It looks up a KeyManager identified by key_template.type_url, @@ -138,8 +139,9 @@ class Registry { // This method should be used solely for key management. static crypto::tink::util::StatusOr< std::unique_ptr<google::crypto::tink::KeyData>> - NewKeyData(const google::crypto::tink::KeyTemplate& key_template) - LOCKS_EXCLUDED(maps_mutex_); + NewKeyData(const google::crypto::tink::KeyTemplate& key_template) { + return RegistryImpl::GlobalInstance().NewKeyData(key_template); + } // Convenience method for extracting the public key data from the // private key given in serialized_private_key. @@ -147,223 +149,18 @@ class Registry { // a PrivateKeyFactory, and calls PrivateKeyFactory::GetPublicKeyData. static crypto::tink::util::StatusOr< std::unique_ptr<google::crypto::tink::KeyData>> - GetPublicKeyData(const std::string& type_url, const std::string& serialized_private_key) - LOCKS_EXCLUDED(maps_mutex_); + GetPublicKeyData(const std::string& type_url, + const std::string& serialized_private_key) { + return RegistryImpl::GlobalInstance().GetPublicKeyData( + type_url, serialized_private_key); + } // Resets the registry. // After reset the registry is empty, i.e. it contains neither catalogues // nor key managers. This method is intended for testing only. - static void Reset() LOCKS_EXCLUDED(maps_mutex_); - - private: - typedef std::unordered_map<std::string, std::unique_ptr<void, void (*)(void*)>> - LabelToObjectMap; - typedef std::unordered_map<std::string, const char*> LabelToTypeNameMap; - typedef std::unordered_map<std::string, bool> LabelToBoolMap; - typedef std::unordered_map<std::string, const KeyFactory*> LabelToKeyFactoryMap; - - static absl::Mutex maps_mutex_; - // Maps for key manager data. - static LabelToObjectMap type_to_manager_map_ GUARDED_BY(maps_mutex_); - static LabelToTypeNameMap type_to_primitive_map_ GUARDED_BY(maps_mutex_); - static LabelToBoolMap type_to_new_key_allowed_map_ GUARDED_BY(maps_mutex_); - static LabelToKeyFactoryMap type_to_key_factory_map_ GUARDED_BY(maps_mutex_); - // Maps for catalogue-data. - static LabelToObjectMap name_to_catalogue_map_ GUARDED_BY(maps_mutex_); - static LabelToTypeNameMap name_to_primitive_map_ GUARDED_BY(maps_mutex_); - - static crypto::tink::util::StatusOr<bool> get_new_key_allowed( - const std::string& type_url) SHARED_LOCKS_REQUIRED(maps_mutex_); - static crypto::tink::util::StatusOr<const KeyFactory*> get_key_factory( - const std::string& type_url) SHARED_LOCKS_REQUIRED(maps_mutex_); + static void Reset() { return RegistryImpl::GlobalInstance().Reset(); } }; -/////////////////////////////////////////////////////////////////////////////// -// Implementation details. - -template <class P> -void delete_manager(void* t) { - delete static_cast<KeyManager<P>*>(t); -} - -template <class P> -void delete_catalogue(void* t) { - delete static_cast<Catalogue<P>*>(t); -} - -// static -template <class P> -crypto::tink::util::Status Registry::AddCatalogue( - const std::string& catalogue_name, Catalogue<P>* catalogue) { - if (catalogue == nullptr) { - return crypto::tink::util::Status( - crypto::tink::util::error::INVALID_ARGUMENT, - "Parameter 'catalogue' must be non-null."); - } - std::unique_ptr<void, void (*)(void*)> entry(catalogue, delete_catalogue<P>); - absl::MutexLock lock(&maps_mutex_); - auto curr_catalogue = name_to_catalogue_map_.find(catalogue_name); - if (curr_catalogue != name_to_catalogue_map_.end()) { - auto existing = static_cast<Catalogue<P>*>(curr_catalogue->second.get()); - if (typeid(*existing).name() != typeid(*catalogue).name()) { - return ToStatusF(crypto::tink::util::error::ALREADY_EXISTS, - "A catalogue named '%s' has been already added.", - catalogue_name.c_str()); - } - } else { - name_to_catalogue_map_.insert( - std::make_pair(catalogue_name, std::move(entry))); - name_to_primitive_map_.insert( - std::make_pair(catalogue_name, typeid(P).name())); - } - return crypto::tink::util::Status::OK; -} - -// static -template <class P> -crypto::tink::util::StatusOr<const Catalogue<P>*> Registry::get_catalogue( - const std::string& catalogue_name) { - absl::MutexLock lock(&maps_mutex_); - auto catalogue_entry = name_to_catalogue_map_.find(catalogue_name); - if (catalogue_entry == name_to_catalogue_map_.end()) { - return ToStatusF(crypto::tink::util::error::NOT_FOUND, - "No catalogue named '%s' has been added.", - catalogue_name.c_str()); - } - if (name_to_primitive_map_[catalogue_name] != typeid(P).name()) { - return ToStatusF(crypto::tink::util::error::INVALID_ARGUMENT, - "Wrong Primitive type for catalogue named '%s': " - "got '%s', expected '%s'", - catalogue_name.c_str(), typeid(P).name(), - name_to_primitive_map_[catalogue_name]); - } - return static_cast<Catalogue<P>*>(catalogue_entry->second.get()); -} - -// static -template <class P> -crypto::tink::util::Status Registry::RegisterKeyManager( - KeyManager<P>* manager, bool new_key_allowed) { - if (manager == nullptr) { - return crypto::tink::util::Status( - crypto::tink::util::error::INVALID_ARGUMENT, - "Parameter 'manager' must be non-null."); - } - std::string type_url = manager->get_key_type(); - std::unique_ptr<void, void (*)(void*)> entry(manager, delete_manager<P>); - if (!manager->DoesSupport(type_url)) { - return ToStatusF(crypto::tink::util::error::INVALID_ARGUMENT, - "The manager does not support type '%s'.", - type_url.c_str()); - } - absl::MutexLock lock(&maps_mutex_); - auto curr_manager = type_to_manager_map_.find(type_url); - if (curr_manager != type_to_manager_map_.end()) { - auto existing = static_cast<KeyManager<P>*>(curr_manager->second.get()); - if (typeid(*existing).name() != typeid(*manager).name()) { - return ToStatusF(crypto::tink::util::error::ALREADY_EXISTS, - "A manager for type '%s' has been already registered.", - type_url.c_str()); - } else { - auto curr_new_key_allowed = type_to_new_key_allowed_map_.find(type_url); - if (!curr_new_key_allowed->second && new_key_allowed) { - return ToStatusF(crypto::tink::util::error::ALREADY_EXISTS, - "A manager for type '%s' has been already registered " - "with forbidden new key operation.", - type_url.c_str()); - } else { - curr_new_key_allowed->second = new_key_allowed; - } - } - } else { - type_to_manager_map_.insert( - std::make_pair(type_url, std::move(entry))); - type_to_primitive_map_.insert( - std::make_pair(type_url, typeid(P).name())); - type_to_new_key_allowed_map_.insert( - std::make_pair(type_url, new_key_allowed)); - type_to_key_factory_map_.insert( - std::make_pair(type_url, &(manager->get_key_factory()))); - } - return crypto::tink::util::Status::OK; -} - -// static -template <class P> -crypto::tink::util::StatusOr<const KeyManager<P>*> Registry::get_key_manager( - const std::string& type_url) { - absl::MutexLock lock(&maps_mutex_); - auto manager_entry = type_to_manager_map_.find(type_url); - if (manager_entry == type_to_manager_map_.end()) { - return ToStatusF(crypto::tink::util::error::NOT_FOUND, - "No manager for type '%s' has been registered.", - type_url.c_str()); - } - if (type_to_primitive_map_[type_url] != typeid(P).name()) { - return ToStatusF(crypto::tink::util::error::INVALID_ARGUMENT, - "Wrong Primitive type for key type '%s': " - "got '%s', expected '%s'", - type_url.c_str(), typeid(P).name(), - type_to_primitive_map_[type_url]); - } - return static_cast<KeyManager<P>*>(manager_entry->second.get()); -} - -// static -template <class P> -crypto::tink::util::StatusOr<std::unique_ptr<P>> Registry::GetPrimitive( - const google::crypto::tink::KeyData& key_data) { - auto key_manager_result = get_key_manager<P>(key_data.type_url()); - if (key_manager_result.ok()) { - return key_manager_result.ValueOrDie()->GetPrimitive(key_data); - } - return key_manager_result.status(); -} - -// static -template <class P> -crypto::tink::util::StatusOr<std::unique_ptr<P>> Registry::GetPrimitive( - const std::string& type_url, const portable_proto::MessageLite& key) { - auto key_manager_result = get_key_manager<P>(type_url); - if (key_manager_result.ok()) { - return key_manager_result.ValueOrDie()->GetPrimitive(key); - } - return key_manager_result.status(); -} - -// static -template <class P> -crypto::tink::util::StatusOr<std::unique_ptr<PrimitiveSet<P>>> -Registry::GetPrimitives(const KeysetHandle& keyset_handle, - const KeyManager<P>* custom_manager) { - crypto::tink::util::Status status = - ValidateKeyset(keyset_handle.get_keyset()); - if (!status.ok()) return status; - std::unique_ptr<PrimitiveSet<P>> primitives(new PrimitiveSet<P>()); - for (const google::crypto::tink::Keyset::Key& key : - keyset_handle.get_keyset().key()) { - if (key.status() == google::crypto::tink::KeyStatusType::ENABLED) { - std::unique_ptr<P> primitive; - if (custom_manager != nullptr && - custom_manager->DoesSupport(key.key_data().type_url())) { - auto primitive_result = custom_manager->GetPrimitive(key.key_data()); - if (!primitive_result.ok()) return primitive_result.status(); - primitive = std::move(primitive_result.ValueOrDie()); - } else { - auto primitive_result = GetPrimitive<P>(key.key_data()); - if (!primitive_result.ok()) return primitive_result.status(); - primitive = std::move(primitive_result.ValueOrDie()); - } - auto entry_result = primitives->AddPrimitive(std::move(primitive), key); - if (!entry_result.ok()) return entry_result.status(); - if (key.key_id() == keyset_handle.get_keyset().primary_key_id()) { - primitives->set_primary(entry_result.ValueOrDie()); - } - } - } - return std::move(primitives); -} - } // namespace tink } // namespace crypto |