xref: /aosp_15_r20/external/tink/cc/signature/signature_config_test.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/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