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/signature/signature_config.h"
18
19 #include <list>
20 #include <memory>
21 #include <string>
22 #include <utility>
23
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "absl/memory/memory.h"
27 #include "absl/status/status.h"
28 #include "openssl/crypto.h"
29 #include "tink/insecure_secret_key_access.h"
30 #include "tink/internal/ec_util.h"
31 #include "tink/internal/fips_utils.h"
32 #include "tink/internal/mutable_serialization_registry.h"
33 #include "tink/internal/proto_key_serialization.h"
34 #include "tink/internal/proto_parameters_serialization.h"
35 #include "tink/internal/serialization.h"
36 #include "tink/key.h"
37 #include "tink/keyset_handle.h"
38 #include "tink/parameters.h"
39 #include "tink/partial_key_access.h"
40 #include "tink/public_key_sign.h"
41 #include "tink/public_key_verify.h"
42 #include "tink/registry.h"
43 #include "tink/restricted_data.h"
44 #include "tink/signature/ed25519_parameters.h"
45 #include "tink/signature/ed25519_private_key.h"
46 #include "tink/signature/ed25519_public_key.h"
47 #include "tink/signature/rsa_ssa_pss_sign_key_manager.h"
48 #include "tink/signature/rsa_ssa_pss_verify_key_manager.h"
49 #include "tink/signature/signature_key_templates.h"
50 #include "tink/subtle/random.h"
51 #include "tink/util/status.h"
52 #include "tink/util/statusor.h"
53 #include "tink/util/test_matchers.h"
54 #include "tink/util/test_util.h"
55 #include "proto/ed25519.pb.h"
56 #include "proto/tink.pb.h"
57
58 namespace crypto {
59 namespace tink {
60 namespace {
61
62 using ::crypto::tink::test::DummyPublicKeySign;
63 using ::crypto::tink::test::DummyPublicKeyVerify;
64 using ::crypto::tink::test::IsOk;
65 using ::crypto::tink::test::StatusIs;
66 using ::google::crypto::tink::KeyData;
67 using ::google::crypto::tink::OutputPrefixType;
68 using ::testing::Not;
69
70 class SignatureConfigTest : public ::testing::Test {
71 protected:
SetUp()72 void SetUp() override {
73 Registry::Reset();
74 internal::MutableSerializationRegistry::GlobalInstance().Reset();
75 }
76 };
77
TEST_F(SignatureConfigTest,testBasic)78 TEST_F(SignatureConfigTest, testBasic) {
79 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
80 GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
81 "not available";
82 }
83
84 EXPECT_THAT(Registry::get_key_manager<PublicKeySign>(
85 RsaSsaPssSignKeyManager().get_key_type())
86 .status(),
87 StatusIs(absl::StatusCode::kNotFound));
88 EXPECT_THAT(Registry::get_key_manager<PublicKeyVerify>(
89 RsaSsaPssVerifyKeyManager().get_key_type())
90 .status(),
91 StatusIs(absl::StatusCode::kNotFound));
92 EXPECT_THAT(SignatureConfig::Register(), IsOk());
93 EXPECT_THAT(Registry::get_key_manager<PublicKeySign>(
94 RsaSsaPssSignKeyManager().get_key_type())
95 .status(),
96 IsOk());
97 EXPECT_THAT(Registry::get_key_manager<PublicKeyVerify>(
98 RsaSsaPssVerifyKeyManager().get_key_type())
99 .status(),
100 IsOk());
101 }
102
103 // Tests that the PublicKeySignWrapper has been properly registered and we
104 // can wrap primitives.
TEST_F(SignatureConfigTest,PublicKeySignWrapperRegistered)105 TEST_F(SignatureConfigTest, PublicKeySignWrapperRegistered) {
106 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
107 GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
108 "not available";
109 }
110
111 ASSERT_TRUE(SignatureConfig::Register().ok());
112
113 google::crypto::tink::KeysetInfo::KeyInfo key_info;
114 key_info.set_status(google::crypto::tink::KeyStatusType::ENABLED);
115 key_info.set_key_id(1234);
116 key_info.set_output_prefix_type(google::crypto::tink::OutputPrefixType::TINK);
117 auto primitive_set = absl::make_unique<PrimitiveSet<PublicKeySign>>();
118 ASSERT_THAT(
119 primitive_set->set_primary(
120 primitive_set
121 ->AddPrimitive(absl::make_unique<DummyPublicKeySign>("dummy"),
122 key_info)
123 .value()),
124 IsOk());
125
126 auto wrapped = Registry::Wrap(std::move(primitive_set));
127
128 ASSERT_TRUE(wrapped.ok()) << wrapped.status();
129 auto signature_result = wrapped.value()->Sign("message");
130 ASSERT_TRUE(signature_result.ok());
131
132 std::string prefix = CryptoFormat::GetOutputPrefix(key_info).value();
133 EXPECT_EQ(signature_result.value(),
134 absl::StrCat(prefix,
135 DummyPublicKeySign("dummy").Sign("message").value()));
136 }
137
138
139 // Tests that the PublicKeyVerifyWrapper has been properly registered and we
140 // can wrap primitives.
TEST_F(SignatureConfigTest,PublicKeyVerifyWrapperRegistered)141 TEST_F(SignatureConfigTest, PublicKeyVerifyWrapperRegistered) {
142 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
143 GTEST_SKIP() << "Not supported if FIPS-mode is used and BoringCrypto is "
144 "not available";
145 }
146
147 ASSERT_TRUE(SignatureConfig::Register().ok());
148
149 google::crypto::tink::KeysetInfo::KeyInfo key_info;
150 key_info.set_status(google::crypto::tink::KeyStatusType::ENABLED);
151 key_info.set_key_id(1234);
152 key_info.set_output_prefix_type(google::crypto::tink::OutputPrefixType::TINK);
153 auto primitive_set = absl::make_unique<PrimitiveSet<PublicKeyVerify>>();
154 ASSERT_THAT(
155 primitive_set->set_primary(
156 primitive_set
157 ->AddPrimitive(absl::make_unique<DummyPublicKeyVerify>("dummy"),
158 key_info)
159 .value()),
160 IsOk());
161 std::string prefix = CryptoFormat::GetOutputPrefix(key_info).value();
162 std::string signature = DummyPublicKeySign("dummy").Sign("message").value();
163
164 auto wrapped = Registry::Wrap(std::move(primitive_set));
165
166 ASSERT_TRUE(wrapped.ok()) << wrapped.status();
167 ASSERT_TRUE(
168 wrapped.value()->Verify(absl::StrCat(prefix, signature), "message").ok());
169 }
170
171 // FIPS-only mode tests
TEST_F(SignatureConfigTest,RegisterNonFipsTemplates)172 TEST_F(SignatureConfigTest, RegisterNonFipsTemplates) {
173 if (!internal::IsFipsModeEnabled() || !internal::IsFipsEnabledInSsl()) {
174 GTEST_SKIP() << "Only supported in FIPS-only mode with BoringCrypto.";
175 }
176
177 EXPECT_THAT(SignatureConfig::Register(), IsOk());
178
179 std::list<google::crypto::tink::KeyTemplate> non_fips_key_templates;
180 non_fips_key_templates.push_back(SignatureKeyTemplates::Ed25519());
181 non_fips_key_templates.push_back(
182 SignatureKeyTemplates::Ed25519WithRawOutput());
183 // 4096-bit RSA is not validated.
184 non_fips_key_templates.push_back(
185 SignatureKeyTemplates::RsaSsaPkcs14096Sha512F4());
186 non_fips_key_templates.push_back(
187 SignatureKeyTemplates::RsaSsaPss4096Sha384Sha384F4());
188 non_fips_key_templates.push_back(
189 SignatureKeyTemplates::RsaSsaPss4096Sha512Sha512F4());
190
191 for (auto key_template : non_fips_key_templates) {
192 EXPECT_THAT(KeysetHandle::GenerateNew(key_template).status(),
193 Not(IsOk()));
194 }
195 }
196
TEST_F(SignatureConfigTest,RegisterFipsValidTemplates)197 TEST_F(SignatureConfigTest, RegisterFipsValidTemplates) {
198 if (!internal::IsFipsModeEnabled() || !internal::IsFipsEnabledInSsl()) {
199 GTEST_SKIP() << "Only supported in FIPS-only mode with BoringCrypto.";
200 }
201
202 EXPECT_THAT(SignatureConfig::Register(), IsOk());
203
204 std::list<google::crypto::tink::KeyTemplate> fips_key_templates;
205 fips_key_templates.push_back(SignatureKeyTemplates::EcdsaP256());
206 fips_key_templates.push_back(SignatureKeyTemplates::EcdsaP256Ieee());
207 fips_key_templates.push_back(SignatureKeyTemplates::EcdsaP384Sha384());
208 fips_key_templates.push_back(SignatureKeyTemplates::EcdsaP384Sha512());
209 fips_key_templates.push_back(SignatureKeyTemplates::EcdsaP384Ieee());
210 fips_key_templates.push_back(SignatureKeyTemplates::EcdsaP521());
211 fips_key_templates.push_back(SignatureKeyTemplates::EcdsaP521Ieee());
212 fips_key_templates.push_back(
213 SignatureKeyTemplates::RsaSsaPkcs13072Sha256F4());
214 fips_key_templates.push_back(
215 SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4());
216
217 for (auto key_template : fips_key_templates) {
218 EXPECT_THAT(KeysetHandle::GenerateNew(key_template), IsOk());
219 }
220 }
221
TEST_F(SignatureConfigTest,Ed25519ProtoParamsSerializationRegistered)222 TEST_F(SignatureConfigTest, Ed25519ProtoParamsSerializationRegistered) {
223 if (internal::IsFipsModeEnabled()) {
224 GTEST_SKIP() << "Not supported in FIPS-only mode";
225 }
226
227 util::StatusOr<internal::ProtoParametersSerialization>
228 proto_params_serialization =
229 internal::ProtoParametersSerialization::Create(
230 SignatureKeyTemplates::Ed25519());
231 ASSERT_THAT(proto_params_serialization, IsOk());
232
233 util::StatusOr<std::unique_ptr<Parameters>> parsed_params =
234 internal::MutableSerializationRegistry::GlobalInstance().ParseParameters(
235 *proto_params_serialization);
236 ASSERT_THAT(parsed_params.status(), StatusIs(absl::StatusCode::kNotFound));
237
238 util::StatusOr<Ed25519Parameters> params =
239 Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
240 ASSERT_THAT(params, IsOk());
241
242 util::StatusOr<std::unique_ptr<Serialization>> serialized_params =
243 internal::MutableSerializationRegistry::GlobalInstance()
244 .SerializeParameters<internal::ProtoParametersSerialization>(*params);
245 ASSERT_THAT(serialized_params.status(),
246 StatusIs(absl::StatusCode::kNotFound));
247
248 ASSERT_THAT(SignatureConfig::Register(), IsOk());
249
250 util::StatusOr<std::unique_ptr<Parameters>> parsed_params2 =
251 internal::MutableSerializationRegistry::GlobalInstance().ParseParameters(
252 *proto_params_serialization);
253 ASSERT_THAT(parsed_params2, IsOk());
254
255 util::StatusOr<std::unique_ptr<Serialization>> serialized_params2 =
256 internal::MutableSerializationRegistry::GlobalInstance()
257 .SerializeParameters<internal::ProtoParametersSerialization>(*params);
258 ASSERT_THAT(serialized_params2, IsOk());
259 }
260
TEST_F(SignatureConfigTest,Ed25519ProtoPublicKeySerializationRegistered)261 TEST_F(SignatureConfigTest, Ed25519ProtoPublicKeySerializationRegistered) {
262 if (internal::IsFipsModeEnabled()) {
263 GTEST_SKIP() << "Not supported in FIPS-only mode";
264 }
265
266 const std::string raw_key = subtle::Random::GetRandomBytes(32);
267
268 google::crypto::tink::Ed25519PublicKey key_proto;
269 key_proto.set_version(0);
270 key_proto.set_key_value(raw_key);
271
272 util::StatusOr<internal::ProtoKeySerialization> proto_key_serialization =
273 internal::ProtoKeySerialization::Create(
274 "type.googleapis.com/google.crypto.tink.Ed25519PublicKey",
275 RestrictedData(key_proto.SerializeAsString(),
276 InsecureSecretKeyAccess::Get()),
277 KeyData::ASYMMETRIC_PUBLIC, OutputPrefixType::TINK,
278 /*id_requirement=*/123);
279 ASSERT_THAT(proto_key_serialization, IsOk());
280
281 util::StatusOr<std::unique_ptr<Key>> parsed_key =
282 internal::MutableSerializationRegistry::GlobalInstance().ParseKey(
283 *proto_key_serialization, InsecureSecretKeyAccess::Get());
284 ASSERT_THAT(parsed_key.status(), StatusIs(absl::StatusCode::kNotFound));
285
286 util::StatusOr<Ed25519Parameters> params =
287 Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
288 ASSERT_THAT(params, IsOk());
289
290 util::StatusOr<Ed25519PublicKey> key =
291 Ed25519PublicKey::Create(*params, raw_key,
292 /*id_requirement=*/123, GetPartialKeyAccess());
293 ASSERT_THAT(key, IsOk());
294
295 util::StatusOr<std::unique_ptr<Serialization>> serialized_key =
296 internal::MutableSerializationRegistry::GlobalInstance()
297 .SerializeKey<internal::ProtoKeySerialization>(
298 *key, InsecureSecretKeyAccess::Get());
299 ASSERT_THAT(serialized_key.status(), StatusIs(absl::StatusCode::kNotFound));
300
301 ASSERT_THAT(SignatureConfig::Register(), IsOk());
302
303 util::StatusOr<std::unique_ptr<Key>> parsed_key2 =
304 internal::MutableSerializationRegistry::GlobalInstance().ParseKey(
305 *proto_key_serialization, InsecureSecretKeyAccess::Get());
306 ASSERT_THAT(parsed_key2, IsOk());
307
308 util::StatusOr<std::unique_ptr<Serialization>> serialized_key2 =
309 internal::MutableSerializationRegistry::GlobalInstance()
310 .SerializeKey<internal::ProtoKeySerialization>(
311 *key, InsecureSecretKeyAccess::Get());
312 ASSERT_THAT(serialized_key2, IsOk());
313 }
314
TEST_F(SignatureConfigTest,Ed25519ProtoPrivateKeySerializationRegistered)315 TEST_F(SignatureConfigTest, Ed25519ProtoPrivateKeySerializationRegistered) {
316 if (internal::IsFipsModeEnabled()) {
317 GTEST_SKIP() << "Not supported in FIPS-only mode";
318 }
319
320 util::StatusOr<std::unique_ptr<internal::Ed25519Key>> key_pair =
321 internal::NewEd25519Key();
322 ASSERT_THAT(key_pair, IsOk());
323
324 google::crypto::tink::Ed25519PublicKey public_key_proto;
325 public_key_proto.set_version(0);
326 public_key_proto.set_key_value((*key_pair)->public_key);
327
328 google::crypto::tink::Ed25519PrivateKey private_key_proto;
329 private_key_proto.set_version(0);
330 private_key_proto.set_key_value((*key_pair)->private_key);
331 *private_key_proto.mutable_public_key() = public_key_proto;
332
333 util::StatusOr<internal::ProtoKeySerialization> proto_key_serialization =
334 internal::ProtoKeySerialization::Create(
335 "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey",
336 RestrictedData(private_key_proto.SerializeAsString(),
337 InsecureSecretKeyAccess::Get()),
338 KeyData::ASYMMETRIC_PRIVATE, OutputPrefixType::TINK,
339 /*id_requirement=*/123);
340 ASSERT_THAT(proto_key_serialization, IsOk());
341
342 util::StatusOr<std::unique_ptr<Key>> parsed_key =
343 internal::MutableSerializationRegistry::GlobalInstance().ParseKey(
344 *proto_key_serialization, InsecureSecretKeyAccess::Get());
345 ASSERT_THAT(parsed_key.status(), StatusIs(absl::StatusCode::kNotFound));
346
347 util::StatusOr<Ed25519Parameters> params =
348 Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
349 ASSERT_THAT(params, IsOk());
350
351 util::StatusOr<Ed25519PublicKey> public_key =
352 Ed25519PublicKey::Create(*params, (*key_pair)->public_key,
353 /*id_requirement=*/123, GetPartialKeyAccess());
354 ASSERT_THAT(public_key, IsOk());
355
356 RestrictedData private_key_bytes =
357 RestrictedData((*key_pair)->private_key, InsecureSecretKeyAccess::Get());
358
359 util::StatusOr<Ed25519PrivateKey> private_key = Ed25519PrivateKey::Create(
360 *public_key, private_key_bytes, GetPartialKeyAccess());
361 ASSERT_THAT(private_key, IsOk());
362
363 util::StatusOr<std::unique_ptr<Serialization>> serialized_key =
364 internal::MutableSerializationRegistry::GlobalInstance()
365 .SerializeKey<internal::ProtoKeySerialization>(
366 *private_key, InsecureSecretKeyAccess::Get());
367 ASSERT_THAT(serialized_key.status(), StatusIs(absl::StatusCode::kNotFound));
368
369 ASSERT_THAT(SignatureConfig::Register(), IsOk());
370
371 util::StatusOr<std::unique_ptr<Key>> parsed_key2 =
372 internal::MutableSerializationRegistry::GlobalInstance().ParseKey(
373 *proto_key_serialization, InsecureSecretKeyAccess::Get());
374 ASSERT_THAT(parsed_key2, IsOk());
375
376 util::StatusOr<std::unique_ptr<Serialization>> serialized_key2 =
377 internal::MutableSerializationRegistry::GlobalInstance()
378 .SerializeKey<internal::ProtoKeySerialization>(
379 *private_key, InsecureSecretKeyAccess::Get());
380 ASSERT_THAT(serialized_key2, IsOk());
381 }
382
383 } // namespace
384 } // namespace tink
385 } // namespace crypto
386