xref: /aosp_15_r20/external/tink/cc/internal/configuration_impl.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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