xref: /aosp_15_r20/external/tink/cc/core/keyset_manager.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16 
17 #include "tink/keyset_manager.h"
18 
19 #include <memory>
20 #include <utility>
21 
22 #include "absl/memory/memory.h"
23 #include "absl/status/status.h"
24 #include "tink/internal/key_gen_configuration_impl.h"
25 #include "tink/key_gen_configuration.h"
26 #include "tink/keyset_handle.h"
27 #include "tink/util/enums.h"
28 #include "tink/util/errors.h"
29 #include "tink/util/status.h"
30 #include "tink/util/statusor.h"
31 #include "proto/tink.pb.h"
32 
33 namespace crypto {
34 namespace tink {
35 
36 using ::crypto::tink::util::Enums;
37 using ::crypto::tink::util::Status;
38 using ::crypto::tink::util::StatusOr;
39 using google::crypto::tink::Keyset;
40 using google::crypto::tink::KeyStatusType;
41 using google::crypto::tink::KeyTemplate;
42 
43 // static
New(const KeyTemplate & key_template)44 StatusOr<std::unique_ptr<KeysetManager>> KeysetManager::New(
45     const KeyTemplate& key_template) {
46   auto manager = absl::make_unique<KeysetManager>();
47   auto rotate_result = manager->Rotate(key_template);
48   if (!rotate_result.ok()) return rotate_result.status();
49   return std::move(manager);
50 }
51 
52 // static
New(const KeysetHandle & keyset_handle)53 StatusOr<std::unique_ptr<KeysetManager>> KeysetManager::New(
54     const KeysetHandle& keyset_handle) {
55   auto manager = absl::make_unique<KeysetManager>();
56   absl::MutexLock lock(&manager->keyset_mutex_);
57   manager->keyset_ = keyset_handle.get_keyset();
58   return std::move(manager);
59 }
60 
GetKeysetHandle()61 std::unique_ptr<KeysetHandle> KeysetManager::GetKeysetHandle() {
62   absl::MutexLock lock(&keyset_mutex_);
63   std::unique_ptr<Keyset> keyset_copy(new Keyset(keyset_));
64   std::unique_ptr<KeysetHandle> handle(
65       new KeysetHandle(std::move(keyset_copy)));
66   return handle;
67 }
68 
Add(const KeyTemplate & key_template)69 StatusOr<uint32_t> KeysetManager::Add(const KeyTemplate& key_template) {
70   return Add(key_template, false);
71 }
72 
Add(const google::crypto::tink::KeyTemplate & key_template,bool as_primary)73 StatusOr<uint32_t> KeysetManager::Add(
74     const google::crypto::tink::KeyTemplate& key_template, bool as_primary) {
75   KeyGenConfiguration config;
76   Status status =
77       internal::KeyGenConfigurationImpl::SetGlobalRegistryMode(config);
78   if (!status.ok()) {
79     return status;
80   }
81   absl::MutexLock lock(&keyset_mutex_);
82   return KeysetHandle::AddToKeyset(key_template, as_primary, config, &keyset_);
83 }
84 
Rotate(const KeyTemplate & key_template)85 StatusOr<uint32_t> KeysetManager::Rotate(const KeyTemplate& key_template) {
86   return Add(key_template, true);
87 }
88 
Enable(uint32_t key_id)89 Status KeysetManager::Enable(uint32_t key_id) {
90   absl::MutexLock lock(&keyset_mutex_);
91   for (auto& key : *(keyset_.mutable_key())) {
92     if (key.key_id() == key_id) {
93       if (key.status() != KeyStatusType::DISABLED &&
94           key.status() != KeyStatusType::ENABLED) {
95         return ToStatusF(absl::StatusCode::kInvalidArgument,
96                          "Cannot enable key with key_id %u and status %s.",
97                          key_id, Enums::KeyStatusName(key.status()));
98       }
99       key.set_status(KeyStatusType::ENABLED);
100       return util::OkStatus();
101     }
102   }
103   return ToStatusF(absl::StatusCode::kNotFound,
104                    "No key with key_id %u found in the keyset.", key_id);
105 }
106 
Disable(uint32_t key_id)107 Status KeysetManager::Disable(uint32_t key_id) {
108   absl::MutexLock lock(&keyset_mutex_);
109   if (keyset_.primary_key_id() == key_id) {
110     return ToStatusF(absl::StatusCode::kInvalidArgument,
111                      "Cannot disable primary key (key_id %u).", key_id);
112   }
113   for (auto& key : *(keyset_.mutable_key())) {
114     if (key.key_id() == key_id) {
115       if (key.status() != KeyStatusType::DISABLED &&
116           key.status() != KeyStatusType::ENABLED) {
117         return ToStatusF(absl::StatusCode::kInvalidArgument,
118                          "Cannot disable key with key_id %u and status %s.",
119                          key_id, Enums::KeyStatusName(key.status()));
120       }
121       key.set_status(KeyStatusType::DISABLED);
122       return util::OkStatus();
123     }
124   }
125   return ToStatusF(absl::StatusCode::kNotFound,
126                    "No key with key_id %u found in the keyset.", key_id);
127 }
128 
Delete(uint32_t key_id)129 Status KeysetManager::Delete(uint32_t key_id) {
130   absl::MutexLock lock(&keyset_mutex_);
131   if (keyset_.primary_key_id() == key_id) {
132     return ToStatusF(absl::StatusCode::kInvalidArgument,
133                      "Cannot delete primary key (key_id %u).", key_id);
134   }
135   auto key_field = keyset_.mutable_key();
136   for (auto key_iter = key_field->begin(); key_iter != key_field->end();
137        key_iter++) {
138     auto key = *key_iter;
139     if (key.key_id() == key_id) {
140       keyset_.mutable_key()->erase(key_iter);
141       return util::OkStatus();
142     }
143   }
144   return ToStatusF(absl::StatusCode::kNotFound,
145                    "No key with key_id %u found in the keyset.", key_id);
146 }
147 
Destroy(uint32_t key_id)148 Status KeysetManager::Destroy(uint32_t key_id) {
149   absl::MutexLock lock(&keyset_mutex_);
150   if (keyset_.primary_key_id() == key_id) {
151     return ToStatusF(absl::StatusCode::kInvalidArgument,
152                      "Cannot destroy primary key (key_id %u).", key_id);
153   }
154   for (auto& key : *(keyset_.mutable_key())) {
155     if (key.key_id() == key_id) {
156       if (key.status() != KeyStatusType::DISABLED &&
157           key.status() != KeyStatusType::DESTROYED &&
158           key.status() != KeyStatusType::ENABLED) {
159         return ToStatusF(absl::StatusCode::kInvalidArgument,
160                          "Cannot destroy key with key_id %u and status %s.",
161                          key_id, Enums::KeyStatusName(key.status()));
162       }
163       key.clear_key_data();
164       key.set_status(KeyStatusType::DESTROYED);
165       return util::OkStatus();
166     }
167   }
168   return ToStatusF(absl::StatusCode::kNotFound,
169                    "No key with key_id %u found in the keyset.", key_id);
170 }
171 
SetPrimary(uint32_t key_id)172 Status KeysetManager::SetPrimary(uint32_t key_id) {
173   absl::MutexLock lock(&keyset_mutex_);
174   for (auto& key : keyset_.key()) {
175     if (key.key_id() == key_id) {
176       if (key.status() != KeyStatusType::ENABLED) {
177         return ToStatusF(absl::StatusCode::kInvalidArgument,
178                          "The candidate for the primary key must be ENABLED"
179                          " (key_id %u).",
180                          key_id);
181       }
182       keyset_.set_primary_key_id(key_id);
183       return util::OkStatus();
184     }
185   }
186   return ToStatusF(absl::StatusCode::kNotFound,
187                    "No key with key_id %u found in the keyset.", key_id);
188 }
189 
KeyCount() const190 int KeysetManager::KeyCount() const {
191   absl::MutexLock lock(&keyset_mutex_);
192   return keyset_.key_size();
193 }
194 
195 }  // namespace tink
196 }  // namespace crypto
197