1 // Copyright 2017 Google LLC
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 #include "tink/keyset_manager.h"
17
18 #include <utility>
19
20 #include "gtest/gtest.h"
21 #include "tink/aead/aead_config.h"
22 #include "tink/aead/aes_gcm_key_manager.h"
23 #include "tink/keyset_handle.h"
24 #include "tink/util/test_keyset_handle.h"
25 #include "proto/aes_gcm.pb.h"
26 #include "proto/tink.pb.h"
27
28 using google::crypto::tink::AesGcmKeyFormat;
29 using google::crypto::tink::KeyData;
30 using google::crypto::tink::KeyStatusType;
31 using google::crypto::tink::KeyTemplate;
32 using google::crypto::tink::OutputPrefixType;
33
34 namespace crypto {
35 namespace tink {
36
37 class KeysetManagerTest : public ::testing::Test {
38 protected:
SetUp()39 void SetUp() override {
40 auto status = AeadConfig::Register();
41 ASSERT_TRUE(status.ok()) << status;
42 }
TearDown()43 void TearDown() override {}
44 };
45
TEST_F(KeysetManagerTest,testBasicOperations)46 TEST_F(KeysetManagerTest, testBasicOperations) {
47 AesGcmKeyFormat key_format;
48 key_format.set_key_size(16);
49 KeyTemplate key_template;
50 key_template.set_type_url(AesGcmKeyManager().get_key_type());
51 key_template.set_output_prefix_type(OutputPrefixType::TINK);
52 key_template.set_value(key_format.SerializeAsString());
53
54 // Create a keyset manager with a single key.
55 auto new_result = KeysetManager::New(key_template);
56 EXPECT_TRUE(new_result.ok()) << new_result.status();
57 auto keyset_manager = std::move(new_result.value());
58 EXPECT_EQ(1, keyset_manager->KeyCount());
59
60 // Verify the keyset.
61 auto keyset =
62 TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
63 EXPECT_EQ(1, keyset.key().size());
64 auto key_id_0 = keyset.key(0).key_id();
65 EXPECT_EQ(key_id_0, keyset.primary_key_id());
66 EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(0).status());
67 EXPECT_EQ(OutputPrefixType::TINK, keyset.key(0).output_prefix_type());
68 EXPECT_EQ(AesGcmKeyManager().get_key_type(),
69 keyset.key(0).key_data().type_url());
70 EXPECT_EQ(KeyData::SYMMETRIC, keyset.key(0).key_data().key_material_type());
71
72 // Add another key.
73 key_template.set_output_prefix_type(OutputPrefixType::RAW);
74 auto add_result = keyset_manager->Add(key_template);
75 EXPECT_TRUE(add_result.ok()) << add_result.status();
76 EXPECT_EQ(2, keyset_manager->KeyCount());
77 auto key_id_1 = add_result.value();
78 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
79 EXPECT_EQ(2, keyset.key().size());
80 EXPECT_EQ(key_id_0, keyset.primary_key_id());
81 EXPECT_FALSE(keyset.key(0).key_data().value() ==
82 keyset.key(1).key_data().value());
83 EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(1).status());
84 EXPECT_EQ(OutputPrefixType::RAW, keyset.key(1).output_prefix_type());
85 EXPECT_EQ(AesGcmKeyManager().get_key_type(),
86 keyset.key(1).key_data().type_url());
87 EXPECT_EQ(KeyData::SYMMETRIC, keyset.key(1).key_data().key_material_type());
88
89 // And another one, via rotation.
90 key_template.set_output_prefix_type(OutputPrefixType::LEGACY);
91 auto rotate_result = keyset_manager->Rotate(key_template);
92 EXPECT_TRUE(rotate_result.ok()) << add_result.status();
93 EXPECT_EQ(3, keyset_manager->KeyCount());
94 auto key_id_2 = rotate_result.value();
95 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
96 EXPECT_EQ(3, keyset.key().size());
97 EXPECT_EQ(key_id_2, keyset.primary_key_id());
98 EXPECT_FALSE(keyset.key(0).key_data().value() ==
99 keyset.key(2).key_data().value());
100 EXPECT_FALSE(keyset.key(1).key_data().value() ==
101 keyset.key(2).key_data().value());
102 EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(2).status());
103 EXPECT_EQ(OutputPrefixType::LEGACY, keyset.key(2).output_prefix_type());
104 EXPECT_EQ(AesGcmKeyManager().get_key_type(),
105 keyset.key(2).key_data().type_url());
106 EXPECT_EQ(KeyData::SYMMETRIC, keyset.key(2).key_data().key_material_type());
107
108 // Change the primary.
109 auto status = keyset_manager->SetPrimary(key_id_1);
110 EXPECT_TRUE(status.ok()) << status;
111 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
112 EXPECT_EQ(3, keyset.key().size());
113 EXPECT_EQ(3, keyset_manager->KeyCount());
114 EXPECT_EQ(key_id_1, keyset.primary_key_id());
115
116 // Clone a keyset via the manager, and check equality.
117 auto keyset_manager_2 =
118 std::move(KeysetManager::New(*keyset_manager->GetKeysetHandle()).value());
119 auto keyset_2 =
120 TestKeysetHandle::GetKeyset(*(keyset_manager_2->GetKeysetHandle()));
121 EXPECT_EQ(keyset.SerializeAsString(), keyset_2.SerializeAsString());
122
123 // Disable a key, and try to set it as primary.
124 EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(2).status());
125 status = keyset_manager->Disable(key_id_2);
126 EXPECT_TRUE(status.ok()) << status;
127 EXPECT_EQ(3, keyset_manager->KeyCount());
128 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
129 EXPECT_EQ(KeyStatusType::DISABLED, keyset.key(2).status());
130
131 status = keyset_manager->SetPrimary(key_id_2);
132 EXPECT_FALSE(status.ok());
133 EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
134 EXPECT_PRED_FORMAT2(testing::IsSubstring, "must be ENABLED",
135 std::string(status.message()));
136 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
137 EXPECT_EQ(key_id_1, keyset.primary_key_id());
138
139 // Enable ENABLED key, disable a DISABLED one.
140 EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(1).status());
141 status = keyset_manager->Enable(key_id_1);
142 EXPECT_TRUE(status.ok()) << status;
143 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
144 EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(1).status());
145
146 EXPECT_EQ(KeyStatusType::DISABLED, keyset.key(2).status());
147 status = keyset_manager->Disable(key_id_2);
148 EXPECT_TRUE(status.ok()) << status;
149 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
150 EXPECT_EQ(KeyStatusType::DISABLED, keyset.key(2).status());
151
152 // Enable the disabled key, then destroy it, and try to re-enable.
153 EXPECT_EQ(KeyStatusType::DISABLED, keyset.key(2).status());
154 status = keyset_manager->Enable(key_id_2);
155 EXPECT_TRUE(status.ok()) << status;
156 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
157 EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(2).status());
158 EXPECT_TRUE(keyset.key(2).has_key_data());
159
160 status = keyset_manager->Destroy(key_id_2);
161 EXPECT_TRUE(status.ok()) << status;
162 EXPECT_EQ(3, keyset_manager->KeyCount());
163 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
164 EXPECT_EQ(KeyStatusType::DESTROYED, keyset.key(2).status());
165 EXPECT_FALSE(keyset.key(2).has_key_data());
166
167 status = keyset_manager->Enable(key_id_2);
168 EXPECT_FALSE(status.ok());
169 EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
170 EXPECT_PRED_FORMAT2(testing::IsSubstring, "Cannot enable",
171 std::string(status.message()));
172 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
173 EXPECT_EQ(KeyStatusType::DESTROYED, keyset.key(2).status());
174 EXPECT_EQ(key_id_1, keyset.primary_key_id());
175
176 // Delete the destroyed key, then try to destroy and delete it again.
177 status = keyset_manager->Delete(key_id_2);
178 EXPECT_TRUE(status.ok()) << status;
179 EXPECT_EQ(2, keyset_manager->KeyCount());
180 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
181
182 EXPECT_EQ(2, keyset.key().size());
183
184 status = keyset_manager->Destroy(key_id_2);
185 EXPECT_EQ(absl::StatusCode::kNotFound, status.code());
186 EXPECT_PRED_FORMAT2(testing::IsSubstring, "No key with key_id",
187 std::string(status.message()));
188
189 status = keyset_manager->Delete(key_id_2);
190 EXPECT_EQ(absl::StatusCode::kNotFound, status.code());
191 EXPECT_PRED_FORMAT2(testing::IsSubstring, "No key with key_id",
192 std::string(status.message()));
193
194 // Try disabling/destroying/deleting the primary key.
195 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
196
197 EXPECT_EQ(key_id_1, keyset.primary_key_id());
198
199 status = keyset_manager->Disable(key_id_1);
200 EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
201 EXPECT_PRED_FORMAT2(testing::IsSubstring, "Cannot disable primary",
202 std::string(status.message()));
203
204 status = keyset_manager->Destroy(key_id_1);
205 EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
206 EXPECT_PRED_FORMAT2(testing::IsSubstring, "Cannot destroy primary",
207 std::string(status.message()));
208
209 status = keyset_manager->Delete(key_id_1);
210 EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
211 EXPECT_PRED_FORMAT2(testing::IsSubstring, "Cannot delete primary",
212 std::string(status.message()));
213
214 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
215 EXPECT_EQ(key_id_1, keyset.primary_key_id());
216
217 // Delete the first key, then try to set it as primary.
218 status = keyset_manager->Delete(key_id_0);
219 EXPECT_TRUE(status.ok()) << status;
220 keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
221 EXPECT_EQ(1, keyset.key().size());
222 EXPECT_EQ(key_id_1, keyset.key(0).key_id());
223
224 status = keyset_manager->SetPrimary(key_id_0);
225 EXPECT_FALSE(status.ok());
226 EXPECT_EQ(absl::StatusCode::kNotFound, status.code());
227 EXPECT_PRED_FORMAT2(testing::IsSubstring, "No key with key_id",
228 std::string(status.message()));
229 EXPECT_EQ(1, keyset_manager->KeyCount());
230 }
231
232 } // namespace tink
233 } // namespace crypto
234