1 // Copyright 2023 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
17 #include "tink/internal/key_gen_configuration_impl.h"
18
19 #include <memory>
20 #include <string>
21
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "tink/aead/aead_key_templates.h"
25 #include "tink/key_gen_configuration.h"
26 #include "tink/util/test_matchers.h"
27 #include "tink/util/test_util.h"
28 #include "proto/aes_gcm.pb.h"
29 #include "proto/rsa_ssa_pss.pb.h"
30
31 namespace crypto {
32 namespace tink {
33 namespace internal {
34 namespace {
35
36 using ::crypto::tink::test::IsOk;
37 using ::crypto::tink::test::StatusIs;
38 using ::google::crypto::tink::AesGcmKey;
39 using ::google::crypto::tink::AesGcmKeyFormat;
40 using ::google::crypto::tink::KeyData;
41 using ::google::crypto::tink::RsaSsaPssKeyFormat;
42 using ::google::crypto::tink::RsaSsaPssParams;
43 using ::google::crypto::tink::RsaSsaPssPrivateKey;
44 using ::google::crypto::tink::RsaSsaPssPublicKey;
45
46 class FakePrimitive {
47 public:
FakePrimitive(std::string s)48 explicit FakePrimitive(std::string s) : s_(s) {}
get()49 std::string get() { return s_; }
50
51 private:
52 std::string s_;
53 };
54
55 class FakeKeyTypeManager
56 : public KeyTypeManager<AesGcmKey, AesGcmKeyFormat, List<FakePrimitive>> {
57 public:
58 class FakePrimitiveFactory : public PrimitiveFactory<FakePrimitive> {
59 public:
Create(const AesGcmKey & key) const60 util::StatusOr<std::unique_ptr<FakePrimitive>> Create(
61 const AesGcmKey& key) const override {
62 return absl::make_unique<FakePrimitive>(key.key_value());
63 }
64 };
65
FakeKeyTypeManager()66 FakeKeyTypeManager()
67 : KeyTypeManager(absl::make_unique<FakePrimitiveFactory>()) {}
68
key_material_type() const69 KeyData::KeyMaterialType key_material_type() const override {
70 return KeyData::SYMMETRIC;
71 }
72
get_version() const73 uint32_t get_version() const override { return 0; }
74
get_key_type() const75 const std::string& get_key_type() const override { return key_type_; }
76
ValidateKey(const AesGcmKey & key) const77 util::Status ValidateKey(const AesGcmKey& key) const override {
78 return util::OkStatus();
79 }
80
ValidateKeyFormat(const AesGcmKeyFormat & key_format) const81 util::Status ValidateKeyFormat(
82 const AesGcmKeyFormat& key_format) const override {
83 return util::OkStatus();
84 }
85
CreateKey(const AesGcmKeyFormat & key_format) const86 util::StatusOr<AesGcmKey> CreateKey(
87 const AesGcmKeyFormat& key_format) const override {
88 return AesGcmKey();
89 }
90
DeriveKey(const AesGcmKeyFormat & key_format,InputStream * input_stream) const91 util::StatusOr<AesGcmKey> DeriveKey(
92 const AesGcmKeyFormat& key_format,
93 InputStream* input_stream) const override {
94 return AesGcmKey();
95 }
96
97 private:
98 const std::string key_type_ =
99 "type.googleapis.com/google.crypto.tink.AesGcmKey";
100 };
101
TEST(KeyGenConfigurationImplTest,AddKeyTypeManager)102 TEST(KeyGenConfigurationImplTest, AddKeyTypeManager) {
103 KeyGenConfiguration config;
104 EXPECT_THAT(KeyGenConfigurationImpl::AddKeyTypeManager(
105 absl::make_unique<FakeKeyTypeManager>(), config),
106 IsOk());
107 }
108
TEST(KeyGenConfigurationImplTest,GetKeyTypeInfoStore)109 TEST(KeyGenConfigurationImplTest, GetKeyTypeInfoStore) {
110 KeyGenConfiguration config;
111 ASSERT_THAT(KeyGenConfigurationImpl::AddKeyTypeManager(
112 absl::make_unique<FakeKeyTypeManager>(), config),
113 IsOk());
114
115 std::string type_url = FakeKeyTypeManager().get_key_type();
116 util::StatusOr<const KeyTypeInfoStore*> store =
117 KeyGenConfigurationImpl::GetKeyTypeInfoStore(config);
118 ASSERT_THAT(store, IsOk());
119 util::StatusOr<const KeyTypeInfoStore::Info*> info = (*store)->Get(type_url);
120 ASSERT_THAT(info, IsOk());
121
122 util::StatusOr<const KeyManager<FakePrimitive>*> key_manager =
123 (*info)->get_key_manager<FakePrimitive>(type_url);
124 ASSERT_THAT(key_manager, IsOk());
125 EXPECT_EQ((*key_manager)->get_key_type(), type_url);
126 }
127
TEST(KeyGenConfigurationImplTest,GetKeyTypeInfoStoreMissingInfoFails)128 TEST(KeyGenConfigurationImplTest, GetKeyTypeInfoStoreMissingInfoFails) {
129 KeyGenConfiguration config;
130 util::StatusOr<const KeyTypeInfoStore*> store =
131 KeyGenConfigurationImpl::GetKeyTypeInfoStore(config);
132 ASSERT_THAT(store, IsOk());
133 EXPECT_THAT((*store)->Get("i.do.not.exist").status(),
134 StatusIs(absl::StatusCode::kNotFound));
135 }
136
137 class FakeSignKeyManager
138 : public PrivateKeyTypeManager<RsaSsaPssPrivateKey, RsaSsaPssKeyFormat,
139 RsaSsaPssPublicKey, List<PublicKeySign>> {
140 public:
141 class PublicKeySignFactory : public PrimitiveFactory<PublicKeySign> {
142 public:
Create(const RsaSsaPssPrivateKey & key) const143 util::StatusOr<std::unique_ptr<PublicKeySign>> Create(
144 const RsaSsaPssPrivateKey& key) const override {
145 return {absl::make_unique<test::DummyPublicKeySign>("a public key sign")};
146 }
147 };
148
FakeSignKeyManager()149 explicit FakeSignKeyManager()
150 : PrivateKeyTypeManager(absl::make_unique<PublicKeySignFactory>()) {}
151
key_material_type() const152 KeyData::KeyMaterialType key_material_type() const override {
153 return KeyData::ASYMMETRIC_PRIVATE;
154 }
155
get_version() const156 uint32_t get_version() const override { return 0; }
157
get_key_type() const158 const std::string& get_key_type() const override { return key_type_; }
159
ValidateKey(const RsaSsaPssPrivateKey & key) const160 util::Status ValidateKey(const RsaSsaPssPrivateKey& key) const override {
161 return util::OkStatus();
162 }
163
ValidateKeyFormat(const RsaSsaPssKeyFormat & key_format) const164 util::Status ValidateKeyFormat(
165 const RsaSsaPssKeyFormat& key_format) const override {
166 return util::OkStatus();
167 }
168
CreateKey(const RsaSsaPssKeyFormat & key_format) const169 util::StatusOr<RsaSsaPssPrivateKey> CreateKey(
170 const RsaSsaPssKeyFormat& key_format) const override {
171 return RsaSsaPssPrivateKey();
172 }
173
DeriveKey(const RsaSsaPssKeyFormat & key_format,InputStream * input_stream) const174 util::StatusOr<RsaSsaPssPrivateKey> DeriveKey(
175 const RsaSsaPssKeyFormat& key_format,
176 InputStream* input_stream) const override {
177 return RsaSsaPssPrivateKey();
178 }
179
GetPublicKey(const RsaSsaPssPrivateKey & private_key) const180 util::StatusOr<RsaSsaPssPublicKey> GetPublicKey(
181 const RsaSsaPssPrivateKey& private_key) const override {
182 return private_key.public_key();
183 }
184
185 private:
186 const std::string key_type_ = "some.sign.key.type";
187 };
188
189 class FakeVerifyKeyManager
190 : public KeyTypeManager<RsaSsaPssPublicKey, void, List<PublicKeyVerify>> {
191 public:
192 class PublicKeyVerifyFactory : public PrimitiveFactory<PublicKeyVerify> {
193 public:
Create(const RsaSsaPssPublicKey & key) const194 util::StatusOr<std::unique_ptr<PublicKeyVerify>> Create(
195 const RsaSsaPssPublicKey& key) const override {
196 return {
197 absl::make_unique<test::DummyPublicKeyVerify>("a public key verify")};
198 }
199 };
200
FakeVerifyKeyManager()201 explicit FakeVerifyKeyManager()
202 : KeyTypeManager(absl::make_unique<PublicKeyVerifyFactory>()) {}
203
key_material_type() const204 KeyData::KeyMaterialType key_material_type() const override {
205 return KeyData::ASYMMETRIC_PUBLIC;
206 }
207
get_version() const208 uint32_t get_version() const override { return 0; }
209
get_key_type() const210 const std::string& get_key_type() const override { return key_type_; }
211
ValidateKey(const RsaSsaPssPublicKey & key) const212 util::Status ValidateKey(const RsaSsaPssPublicKey& key) const override {
213 return util::OkStatus();
214 }
215
ValidateParams(const RsaSsaPssParams & params) const216 util::Status ValidateParams(const RsaSsaPssParams& params) const {
217 return util::OkStatus();
218 }
219
220 private:
221 const std::string key_type_ = "some.verify.key.type";
222 };
223
TEST(KeyGenConfigurationImplTest,AddAsymmetricKeyManagers)224 TEST(KeyGenConfigurationImplTest, AddAsymmetricKeyManagers) {
225 KeyGenConfiguration config;
226 EXPECT_THAT(KeyGenConfigurationImpl::AddAsymmetricKeyManagers(
227 absl::make_unique<FakeSignKeyManager>(),
228 absl::make_unique<FakeVerifyKeyManager>(), config),
229 IsOk());
230 }
231
TEST(KeyGenConfigurationImplTest,GetKeyTypeInfoStoreAsymmetric)232 TEST(KeyGenConfigurationImplTest, GetKeyTypeInfoStoreAsymmetric) {
233 KeyGenConfiguration config;
234 ASSERT_THAT(KeyGenConfigurationImpl::AddAsymmetricKeyManagers(
235 absl::make_unique<FakeSignKeyManager>(),
236 absl::make_unique<FakeVerifyKeyManager>(), config),
237 IsOk());
238
239 {
240 std::string type_url = FakeSignKeyManager().get_key_type();
241 util::StatusOr<const KeyTypeInfoStore*> store =
242 KeyGenConfigurationImpl::GetKeyTypeInfoStore(config);
243 ASSERT_THAT(store, IsOk());
244 util::StatusOr<const KeyTypeInfoStore::Info*> info =
245 (*store)->Get(type_url);
246 ASSERT_THAT(info, IsOk());
247
248 util::StatusOr<const KeyManager<PublicKeySign>*> key_manager =
249 (*info)->get_key_manager<PublicKeySign>(type_url);
250 ASSERT_THAT(key_manager, IsOk());
251 EXPECT_EQ((*key_manager)->get_key_type(), type_url);
252 }
253 {
254 std::string type_url = FakeVerifyKeyManager().get_key_type();
255 util::StatusOr<const KeyTypeInfoStore*> store =
256 KeyGenConfigurationImpl::GetKeyTypeInfoStore(config);
257 ASSERT_THAT(store, IsOk());
258 util::StatusOr<const KeyTypeInfoStore::Info*> info =
259 (*store)->Get(type_url);
260 ASSERT_THAT(info, IsOk());
261
262 util::StatusOr<const KeyManager<PublicKeyVerify>*> key_manager =
263 (*info)->get_key_manager<PublicKeyVerify>(type_url);
264 ASSERT_THAT(key_manager, IsOk());
265 EXPECT_EQ((*key_manager)->get_key_type(), type_url);
266 }
267 }
268
TEST(KeyGenConfigurationImplTest,GlobalRegistryMode)269 TEST(KeyGenConfigurationImplTest, GlobalRegistryMode) {
270 Registry::Reset();
271 KeyGenConfiguration config;
272 ASSERT_THAT(KeyGenConfigurationImpl::SetGlobalRegistryMode(config), IsOk());
273 EXPECT_TRUE(KeyGenConfigurationImpl::IsInGlobalRegistryMode(config));
274
275 // Check that KeyGenConfigurationImpl functions return kFailedPrecondition.
276 EXPECT_THAT(KeyGenConfigurationImpl::AddKeyTypeManager(
277 absl::make_unique<FakeKeyTypeManager>(), config),
278 StatusIs(absl::StatusCode::kFailedPrecondition));
279 EXPECT_THAT(KeyGenConfigurationImpl::AddAsymmetricKeyManagers(
280 absl::make_unique<FakeSignKeyManager>(),
281 absl::make_unique<FakeVerifyKeyManager>(), config),
282 StatusIs(absl::StatusCode::kFailedPrecondition));
283 EXPECT_THAT(KeyGenConfigurationImpl::GetKeyTypeInfoStore(config).status(),
284 StatusIs(absl::StatusCode::kFailedPrecondition));
285
286 // TODO(b/265705174): Replace with KeysetHandle::GenerateNew(config).
287 EXPECT_THAT(Registry::NewKeyData(AeadKeyTemplates::Aes256Gcm()).status(),
288 StatusIs(absl::StatusCode::kNotFound));
289
290 ASSERT_THAT(
291 Registry::RegisterKeyTypeManager(absl::make_unique<FakeKeyTypeManager>(),
292 /*new_key_allowed=*/true),
293 IsOk());
294 // TODO(b/265705174): Replace with KeysetHandle::GenerateNew(config) once
295 // implemented.
296 EXPECT_THAT(Registry::NewKeyData(AeadKeyTemplates::Aes256Gcm()), IsOk());
297 }
298
TEST(KeyGenConfigurationImplTest,GlobalRegistryModeWithNonEmptyConfigFails)299 TEST(KeyGenConfigurationImplTest, GlobalRegistryModeWithNonEmptyConfigFails) {
300 KeyGenConfiguration config;
301 ASSERT_THAT(KeyGenConfigurationImpl::AddKeyTypeManager(
302 absl::make_unique<FakeKeyTypeManager>(), config),
303 IsOk());
304 EXPECT_THAT(KeyGenConfigurationImpl::SetGlobalRegistryMode(config),
305 StatusIs(absl::StatusCode::kFailedPrecondition));
306 EXPECT_FALSE(KeyGenConfigurationImpl::IsInGlobalRegistryMode(config));
307 }
308
309 } // namespace
310 } // namespace internal
311 } // namespace tink
312 } // namespace crypto
313