aboutsummaryrefslogtreecommitdiff
path: root/cc/registry.h
diff options
context:
space:
mode:
authorThomas Holenstein <tholenst@google.com>2018-10-03 12:06:57 -0400
committerTink Team <noreply@google.com>2018-10-04 11:47:15 -0700
commitb5e9a88c31225ae777ecc0dace61ec3d3bff70dc (patch)
tree26e25a0c8aae0accee87f105448fc819e433b973 /cc/registry.h
parentf6b8bf92a836fb84a8068b0ca5146a16b8b23011 (diff)
downloadtink-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.h281
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