1*e7b1675dSTing-Kang Chang // Copyright 2023 Google LLC 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_INTERNAL_CONFIGURATION_IMPL_H_ 18*e7b1675dSTing-Kang Chang #define TINK_INTERNAL_CONFIGURATION_IMPL_H_ 19*e7b1675dSTing-Kang Chang 20*e7b1675dSTing-Kang Chang #include "tink/configuration.h" 21*e7b1675dSTing-Kang Chang #include "tink/internal/key_type_info_store.h" 22*e7b1675dSTing-Kang Chang #include "tink/internal/keyset_wrapper_store.h" 23*e7b1675dSTing-Kang Chang 24*e7b1675dSTing-Kang Chang namespace crypto { 25*e7b1675dSTing-Kang Chang namespace tink { 26*e7b1675dSTing-Kang Chang namespace internal { 27*e7b1675dSTing-Kang Chang 28*e7b1675dSTing-Kang Chang constexpr absl::string_view kConfigurationImplErr = 29*e7b1675dSTing-Kang Chang "Use crypto::tink::Registry instead when in global registry mode."; 30*e7b1675dSTing-Kang Chang 31*e7b1675dSTing-Kang Chang class ConfigurationImpl { 32*e7b1675dSTing-Kang Chang public: 33*e7b1675dSTing-Kang Chang template <class PW> AddPrimitiveWrapper(std::unique_ptr<PW> wrapper,crypto::tink::Configuration & config)34*e7b1675dSTing-Kang Chang static crypto::tink::util::Status AddPrimitiveWrapper( 35*e7b1675dSTing-Kang Chang std::unique_ptr<PW> wrapper, crypto::tink::Configuration& config) { 36*e7b1675dSTing-Kang Chang if (config.global_registry_mode_) { 37*e7b1675dSTing-Kang Chang return crypto::tink::util::Status(absl::StatusCode::kFailedPrecondition, 38*e7b1675dSTing-Kang Chang kConfigurationImplErr); 39*e7b1675dSTing-Kang Chang } 40*e7b1675dSTing-Kang Chang 41*e7b1675dSTing-Kang Chang // Function `primitive_getter` must be defined here, since 42*e7b1675dSTing-Kang Chang // PW::InputPrimitive is not accessible later. 43*e7b1675dSTing-Kang Chang // TODO(b/284084337): Move primitive getter out of key manager. 44*e7b1675dSTing-Kang Chang std::function<crypto::tink::util::StatusOr< 45*e7b1675dSTing-Kang Chang std::unique_ptr<typename PW::InputPrimitive>>( 46*e7b1675dSTing-Kang Chang const google::crypto::tink::KeyData& key_data)> 47*e7b1675dSTing-Kang Chang primitive_getter = 48*e7b1675dSTing-Kang Chang [&config](const google::crypto::tink::KeyData& key_data) 49*e7b1675dSTing-Kang Chang -> crypto::tink::util::StatusOr< 50*e7b1675dSTing-Kang Chang std::unique_ptr<typename PW::InputPrimitive>> { 51*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr< 52*e7b1675dSTing-Kang Chang const crypto::tink::internal::KeyTypeInfoStore::Info*> 53*e7b1675dSTing-Kang Chang info = config.key_type_info_store_.Get(key_data.type_url()); 54*e7b1675dSTing-Kang Chang if (!info.ok()) { 55*e7b1675dSTing-Kang Chang return info.status(); 56*e7b1675dSTing-Kang Chang } 57*e7b1675dSTing-Kang Chang 58*e7b1675dSTing-Kang Chang crypto::tink::util::StatusOr< 59*e7b1675dSTing-Kang Chang const crypto::tink::KeyManager<typename PW::InputPrimitive>*> 60*e7b1675dSTing-Kang Chang key_manager = (*info)->get_key_manager<typename PW::InputPrimitive>( 61*e7b1675dSTing-Kang Chang key_data.type_url()); 62*e7b1675dSTing-Kang Chang if (!key_manager.ok()) { 63*e7b1675dSTing-Kang Chang return key_manager.status(); 64*e7b1675dSTing-Kang Chang } 65*e7b1675dSTing-Kang Chang 66*e7b1675dSTing-Kang Chang return (*key_manager)->GetPrimitive(key_data); 67*e7b1675dSTing-Kang Chang }; 68*e7b1675dSTing-Kang Chang 69*e7b1675dSTing-Kang Chang return config.keyset_wrapper_store_ 70*e7b1675dSTing-Kang Chang .Add<typename PW::InputPrimitive, typename PW::Primitive>( 71*e7b1675dSTing-Kang Chang std::move(wrapper), primitive_getter); 72*e7b1675dSTing-Kang Chang } 73*e7b1675dSTing-Kang Chang 74*e7b1675dSTing-Kang Chang template <class KM> AddKeyTypeManager(std::unique_ptr<KM> key_manager,crypto::tink::Configuration & config)75*e7b1675dSTing-Kang Chang static crypto::tink::util::Status AddKeyTypeManager( 76*e7b1675dSTing-Kang Chang std::unique_ptr<KM> key_manager, crypto::tink::Configuration& config) { 77*e7b1675dSTing-Kang Chang if (config.global_registry_mode_) { 78*e7b1675dSTing-Kang Chang return crypto::tink::util::Status(absl::StatusCode::kFailedPrecondition, 79*e7b1675dSTing-Kang Chang kConfigurationImplErr); 80*e7b1675dSTing-Kang Chang } 81*e7b1675dSTing-Kang Chang return config.key_type_info_store_.AddKeyTypeManager( 82*e7b1675dSTing-Kang Chang std::move(key_manager), /*new_key_allowed=*/true); 83*e7b1675dSTing-Kang Chang } 84*e7b1675dSTing-Kang Chang 85*e7b1675dSTing-Kang Chang template <class PrivateKM, class PublicKM> AddAsymmetricKeyManagers(std::unique_ptr<PrivateKM> private_key_manager,std::unique_ptr<PublicKM> public_key_manager,crypto::tink::Configuration & config)86*e7b1675dSTing-Kang Chang static crypto::tink::util::Status AddAsymmetricKeyManagers( 87*e7b1675dSTing-Kang Chang std::unique_ptr<PrivateKM> private_key_manager, 88*e7b1675dSTing-Kang Chang std::unique_ptr<PublicKM> public_key_manager, 89*e7b1675dSTing-Kang Chang crypto::tink::Configuration& config) { 90*e7b1675dSTing-Kang Chang if (config.global_registry_mode_) { 91*e7b1675dSTing-Kang Chang return crypto::tink::util::Status(absl::StatusCode::kFailedPrecondition, 92*e7b1675dSTing-Kang Chang kConfigurationImplErr); 93*e7b1675dSTing-Kang Chang } 94*e7b1675dSTing-Kang Chang return config.key_type_info_store_.AddAsymmetricKeyTypeManagers( 95*e7b1675dSTing-Kang Chang std::move(private_key_manager), std::move(public_key_manager), 96*e7b1675dSTing-Kang Chang /*new_key_allowed=*/true); 97*e7b1675dSTing-Kang Chang } 98*e7b1675dSTing-Kang Chang 99*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr< 100*e7b1675dSTing-Kang Chang const crypto::tink::internal::KeyTypeInfoStore*> GetKeyTypeInfoStore(const crypto::tink::Configuration & config)101*e7b1675dSTing-Kang Chang GetKeyTypeInfoStore(const crypto::tink::Configuration& config) { 102*e7b1675dSTing-Kang Chang if (config.global_registry_mode_) { 103*e7b1675dSTing-Kang Chang return crypto::tink::util::Status(absl::StatusCode::kFailedPrecondition, 104*e7b1675dSTing-Kang Chang kConfigurationImplErr); 105*e7b1675dSTing-Kang Chang } 106*e7b1675dSTing-Kang Chang return &config.key_type_info_store_; 107*e7b1675dSTing-Kang Chang } 108*e7b1675dSTing-Kang Chang 109*e7b1675dSTing-Kang Chang static crypto::tink::util::StatusOr< 110*e7b1675dSTing-Kang Chang const crypto::tink::internal::KeysetWrapperStore*> GetKeysetWrapperStore(const crypto::tink::Configuration & config)111*e7b1675dSTing-Kang Chang GetKeysetWrapperStore(const crypto::tink::Configuration& config) { 112*e7b1675dSTing-Kang Chang if (config.global_registry_mode_) { 113*e7b1675dSTing-Kang Chang return crypto::tink::util::Status(absl::StatusCode::kFailedPrecondition, 114*e7b1675dSTing-Kang Chang kConfigurationImplErr); 115*e7b1675dSTing-Kang Chang } 116*e7b1675dSTing-Kang Chang return &config.keyset_wrapper_store_; 117*e7b1675dSTing-Kang Chang } 118*e7b1675dSTing-Kang Chang 119*e7b1675dSTing-Kang Chang // `config` can be set to global registry mode only if empty. SetGlobalRegistryMode(crypto::tink::Configuration & config)120*e7b1675dSTing-Kang Chang static crypto::tink::util::Status SetGlobalRegistryMode( 121*e7b1675dSTing-Kang Chang crypto::tink::Configuration& config) { 122*e7b1675dSTing-Kang Chang if (!config.key_type_info_store_.IsEmpty() || 123*e7b1675dSTing-Kang Chang !config.keyset_wrapper_store_.IsEmpty()) { 124*e7b1675dSTing-Kang Chang return crypto::tink::util::Status(absl::StatusCode::kFailedPrecondition, 125*e7b1675dSTing-Kang Chang "Using the global registry is only " 126*e7b1675dSTing-Kang Chang "allowed when Configuration is empty."); 127*e7b1675dSTing-Kang Chang } 128*e7b1675dSTing-Kang Chang config.global_registry_mode_ = true; 129*e7b1675dSTing-Kang Chang return crypto::tink::util::OkStatus(); 130*e7b1675dSTing-Kang Chang } 131*e7b1675dSTing-Kang Chang IsInGlobalRegistryMode(const crypto::tink::Configuration & config)132*e7b1675dSTing-Kang Chang static bool IsInGlobalRegistryMode( 133*e7b1675dSTing-Kang Chang const crypto::tink::Configuration& config) { 134*e7b1675dSTing-Kang Chang return config.global_registry_mode_; 135*e7b1675dSTing-Kang Chang } 136*e7b1675dSTing-Kang Chang }; 137*e7b1675dSTing-Kang Chang 138*e7b1675dSTing-Kang Chang } // namespace internal 139*e7b1675dSTing-Kang Chang } // namespace tink 140*e7b1675dSTing-Kang Chang } // namespace crypto 141*e7b1675dSTing-Kang Chang 142*e7b1675dSTing-Kang Chang #endif // TINK_INTERNAL_CONFIGURATION_IMPL_H_ 143