blob: c1ec40d5158690a3b17e47c520647ba16a7ffc08 [file] [log] [blame]
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
#include "tink/core/registry_impl.h"
#include "tink/util/errors.h"
#include "tink/util/statusor.h"
#include "proto/tink.pb.h"
using crypto::tink::util::StatusOr;
using google::crypto::tink::KeyData;
using google::crypto::tink::KeyTemplate;
namespace crypto {
namespace tink {
StatusOr<std::unique_ptr<KeyData>> RegistryImpl::NewKeyData(
const KeyTemplate& key_template) const {
absl::MutexLock lock(&maps_mutex_);
const std::string& type_url = key_template.type_url();
auto it = type_url_to_info_.find(type_url);
if (it == type_url_to_info_.end()) {
return ToStatusF(util::error::NOT_FOUND,
"No manager for type '%s' has been registered.",
type_url.c_str());
}
if (!it->second.new_key_allowed()) {
return ToStatusF(util::error::INVALID_ARGUMENT,
"KeyManager for type '%s' does not allow "
"for creation of new keys.",
type_url.c_str());
}
return it->second.key_factory().NewKeyData(key_template.value());
}
StatusOr<std::unique_ptr<KeyData>> RegistryImpl::GetPublicKeyData(
const std::string& type_url, const std::string& serialized_private_key) const {
absl::MutexLock lock(&maps_mutex_);
auto it = type_url_to_info_.find(type_url);
if (it == type_url_to_info_.end()) {
return ToStatusF(util::error::INTERNAL, "No Key type '%s' registered.",
type_url.c_str());
}
auto factory =
dynamic_cast<const PrivateKeyFactory*>(&it->second.key_factory());
if (factory == nullptr) {
return ToStatusF(util::error::INVALID_ARGUMENT,
"KeyManager for type '%s' does not have "
"a PrivateKeyFactory.", type_url.c_str());
}
auto result = factory->GetPublicKeyData(serialized_private_key);
return result;
}
crypto::tink::util::Status RegistryImpl::CheckInsertable(
const std::string& type_url, const std::type_index& key_manager_type_index,
bool new_key_allowed) const {
auto it = type_url_to_info_.find(type_url);
if (it == type_url_to_info_.end()) {
return crypto::tink::util::Status::OK;
}
if (it->second.key_manager_type_index() != key_manager_type_index) {
return ToStatusF(crypto::tink::util::error::ALREADY_EXISTS,
"A manager for type '%s' has been already registered.",
type_url.c_str());
}
if (!it->second.new_key_allowed() && 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());
}
return crypto::tink::util::Status::OK;
}
void RegistryImpl::Reset() {
absl::MutexLock lock(&maps_mutex_);
type_url_to_info_.clear();
name_to_catalogue_map_.clear();
primitive_to_wrapper_.clear();
}
} // namespace tink
} // namespace crypto