xref: /aosp_15_r20/external/tink/cc/signature/public_key_verify_wrapper_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/public_key_verify_wrapper.h"
18 
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include "gtest/gtest.h"
24 #include "tink/primitive_set.h"
25 #include "tink/public_key_verify.h"
26 #include "tink/internal/registry_impl.h"
27 #include "tink/monitoring/monitoring.h"
28 #include "tink/monitoring/monitoring_client_mocks.h"
29 #include "tink/signature/failing_signature.h"
30 #include "tink/util/status.h"
31 #include "tink/util/test_matchers.h"
32 #include "tink/util/test_util.h"
33 
34 namespace crypto {
35 namespace tink {
36 namespace {
37 
38 using ::crypto::tink::test::DummyPublicKeySign;
39 using ::crypto::tink::test::DummyPublicKeyVerify;
40 using ::crypto::tink::test::IsOk;
41 using ::crypto::tink::test::IsOkAndHolds;
42 using ::crypto::tink::test::StatusIs;
43 using ::google::crypto::tink::KeysetInfo;
44 using ::google::crypto::tink::KeyStatusType;
45 using ::google::crypto::tink::OutputPrefixType;
46 using ::testing::_;
47 using ::testing::ByMove;
48 using ::testing::IsNull;
49 using ::testing::StrictMock;
50 using ::testing::Not;
51 using ::testing::NotNull;
52 using ::testing::Return;
53 using ::testing::Test;
54 
55 class PublicKeyVerifySetWrapperTest : public ::testing::Test {
56  protected:
SetUp()57   void SetUp() override {
58   }
TearDown()59   void TearDown() override {
60   }
61 };
62 
TEST_F(PublicKeyVerifySetWrapperTest,testBasic)63 TEST_F(PublicKeyVerifySetWrapperTest, testBasic) {
64   { // pk_verify_set is nullptr.
65     auto pk_verify_result = PublicKeyVerifyWrapper().Wrap(nullptr);
66     EXPECT_FALSE(pk_verify_result.ok());
67     EXPECT_EQ(absl::StatusCode::kInternal, pk_verify_result.status().code());
68     EXPECT_PRED_FORMAT2(testing::IsSubstring, "non-NULL",
69                         std::string(pk_verify_result.status().message()));
70   }
71 
72   { // pk_verify_set has no primary primitive.
73     std::unique_ptr<PrimitiveSet<PublicKeyVerify>>
74         pk_verify_set(new PrimitiveSet<PublicKeyVerify>());
75     auto pk_verify_result =
76         PublicKeyVerifyWrapper().Wrap(std::move(pk_verify_set));
77     EXPECT_FALSE(pk_verify_result.ok());
78     EXPECT_EQ(absl::StatusCode::kInvalidArgument,
79         pk_verify_result.status().code());
80     EXPECT_PRED_FORMAT2(testing::IsSubstring, "no primary",
81                         std::string(pk_verify_result.status().message()));
82   }
83 
84   { // Correct pk_verify_set;
85     KeysetInfo::KeyInfo* key_info;
86     KeysetInfo keyset_info;
87 
88     uint32_t key_id_0 = 1234543;
89     key_info = keyset_info.add_key_info();
90     key_info->set_output_prefix_type(OutputPrefixType::RAW);
91     key_info->set_key_id(key_id_0);
92     key_info->set_status(KeyStatusType::ENABLED);
93 
94     uint32_t key_id_1 = 726329;
95     key_info = keyset_info.add_key_info();
96     key_info->set_output_prefix_type(OutputPrefixType::LEGACY);
97     key_info->set_key_id(key_id_1);
98     key_info->set_status(KeyStatusType::ENABLED);
99 
100     uint32_t key_id_2 = 7213743;
101     key_info = keyset_info.add_key_info();
102     key_info->set_output_prefix_type(OutputPrefixType::TINK);
103     key_info->set_key_id(key_id_2);
104     key_info->set_status(KeyStatusType::ENABLED);
105 
106     std::string signature_name_0 = "signature_0";
107     std::string signature_name_1 = "signature_1";
108     std::string signature_name_2 = "signature_2";
109     std::unique_ptr<PrimitiveSet<PublicKeyVerify>> pk_verify_set(
110         new PrimitiveSet<PublicKeyVerify>());
111 
112     std::unique_ptr<PublicKeyVerify> pk_verify(
113         new DummyPublicKeyVerify(signature_name_0));
114     auto entry_result = pk_verify_set->AddPrimitive(std::move(pk_verify),
115                                                     keyset_info.key_info(0));
116     ASSERT_TRUE(entry_result.ok());
117 
118     pk_verify = std::make_unique<DummyPublicKeyVerify>(signature_name_1);
119     entry_result = pk_verify_set->AddPrimitive(std::move(pk_verify),
120                                                keyset_info.key_info(1));
121     ASSERT_TRUE(entry_result.ok());
122 
123     pk_verify = std::make_unique<DummyPublicKeyVerify>(signature_name_2);
124     entry_result = pk_verify_set->AddPrimitive(std::move(pk_verify),
125                                                keyset_info.key_info(2));
126     ASSERT_TRUE(entry_result.ok());
127 
128     // The last key is the primary.
129     ASSERT_THAT(pk_verify_set->set_primary(entry_result.value()), IsOk());
130 
131     // Wrap pk_verify_set and test the resulting PublicKeyVerify.
132     auto pk_verify_result =
133         PublicKeyVerifyWrapper().Wrap(std::move(pk_verify_set));
134     EXPECT_TRUE(pk_verify_result.ok()) << pk_verify_result.status();
135     pk_verify = std::move(pk_verify_result.value());
136     std::string data = "some data to sign";
137     std::unique_ptr<PublicKeySign> pk_sign(
138         new DummyPublicKeySign(signature_name_0));
139     std::string signature = pk_sign->Sign(data).value();
140     util::Status status = pk_verify->Verify(signature, data);
141     EXPECT_TRUE(status.ok()) << status;
142   }
143 }
144 
PopulateKeyInfo(uint32_t key_id,OutputPrefixType out_prefix_type,KeyStatusType status)145 KeysetInfo::KeyInfo PopulateKeyInfo(uint32_t key_id,
146                                     OutputPrefixType out_prefix_type,
147                                     KeyStatusType status) {
148   KeysetInfo::KeyInfo key_info;
149   key_info.set_output_prefix_type(out_prefix_type);
150   key_info.set_key_id(key_id);
151   key_info.set_status(status);
152   return key_info;
153 }
154 
155 // Creates a test keyset info object.
CreateTestKeysetInfo()156 KeysetInfo CreateTestKeysetInfo() {
157   KeysetInfo keyset_info;
158   *keyset_info.add_key_info() =
159       PopulateKeyInfo(/*key_id=*/1234543, OutputPrefixType::TINK,
160                       /*status=*/KeyStatusType::ENABLED);
161   *keyset_info.add_key_info() =
162       PopulateKeyInfo(/*key_id=*/726329, OutputPrefixType::LEGACY,
163                       /*status=*/KeyStatusType::ENABLED);
164   *keyset_info.add_key_info() =
165       PopulateKeyInfo(/*key_id=*/7213743, OutputPrefixType::TINK,
166                       /*status=*/KeyStatusType::ENABLED);
167   return keyset_info;
168 }
169 
170 // Tests for the monitoring behavior.
171 class PublicKeyVerifySetWrapperWithMonitoringTest : public Test {
172  protected:
173   // Perform some common initialization: reset the global registry, set expected
174   // calls for the mock monitoring factory and the returned clients.
SetUp()175   void SetUp() override {
176     Registry::Reset();
177 
178     // Setup mocks for catching Monitoring calls.
179     auto monitoring_client_factory =
180         absl::make_unique<MockMonitoringClientFactory>();
181     auto verify_monitoring_client =
182         absl::make_unique<StrictMock<MockMonitoringClient>>();
183     verify_monitoring_client_ = verify_monitoring_client.get();
184 
185     // Monitoring tests expect that the client factory will create the
186     // corresponding MockMonitoringClients.
187     EXPECT_CALL(*monitoring_client_factory, New(_))
188         .WillOnce(
189             Return(ByMove(util::StatusOr<std::unique_ptr<MonitoringClient>>(
190                 std::move(verify_monitoring_client)))));
191 
192     ASSERT_THAT(internal::RegistryImpl::GlobalInstance()
193                     .RegisterMonitoringClientFactory(
194                         std::move(monitoring_client_factory)),
195                 IsOk());
196     ASSERT_THAT(
197         internal::RegistryImpl::GlobalInstance().GetMonitoringClientFactory(),
198         Not(IsNull()));
199   }
200 
201   // Cleanup the registry to avoid mock leaks.
~PublicKeyVerifySetWrapperWithMonitoringTest()202   ~PublicKeyVerifySetWrapperWithMonitoringTest() override { Registry::Reset(); }
203 
204   MockMonitoringClient* verify_monitoring_client_;
205 };
206 
207 // Test that successful sign operations are logged.
TEST_F(PublicKeyVerifySetWrapperWithMonitoringTest,WrapKeysetWithMonitoringVerifySuccess)208 TEST_F(PublicKeyVerifySetWrapperWithMonitoringTest,
209        WrapKeysetWithMonitoringVerifySuccess) {
210   // Create a primitive set and fill it with some entries
211   KeysetInfo keyset_info = CreateTestKeysetInfo();
212   const absl::flat_hash_map<std::string, std::string> kAnnotations = {
213       {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
214   auto public_key_verify_primitive_set =
215       absl::make_unique<PrimitiveSet<PublicKeyVerify>>(kAnnotations);
216   ASSERT_THAT(
217       public_key_verify_primitive_set
218           ->AddPrimitive(absl::make_unique<DummyPublicKeyVerify>("verify0"),
219                          keyset_info.key_info(0))
220           .status(),
221       IsOk());
222   ASSERT_THAT(
223       public_key_verify_primitive_set
224           ->AddPrimitive(absl::make_unique<DummyPublicKeyVerify>("sign1"),
225                          keyset_info.key_info(1))
226           .status(),
227       IsOk());
228   // Set the last as primary.
229   util::StatusOr<PrimitiveSet<PublicKeyVerify>::Entry<PublicKeyVerify>*> last =
230       public_key_verify_primitive_set->AddPrimitive(
231           absl::make_unique<DummyPublicKeyVerify>("sign2"),
232           keyset_info.key_info(2));
233   ASSERT_THAT(last.status(), IsOk());
234   ASSERT_THAT(public_key_verify_primitive_set->set_primary(*last), IsOk());
235   // Record the ID of the primary key.
236   const uint32_t primary_key_id = keyset_info.key_info(2).key_id();
237 
238   // Create a PublicKeyVerify primitive to verify a signature.
239   util::StatusOr<std::unique_ptr<PublicKeyVerify>> public_key_verify =
240       PublicKeyVerifyWrapper().Wrap(std::move(public_key_verify_primitive_set));
241   ASSERT_THAT(public_key_verify, IsOkAndHolds(NotNull()));
242 
243   // Create a PublicKeySign primitive and sign some data we can verify.
244   constexpr absl::string_view message = "This is some message!";
245   std::string signature =
246       absl::StrCat((*last)->get_identifier(),
247                    DummyPublicKeySign("sign2").Sign(message).value());
248 
249   // Check that calling Verify triggers a Log() call.
250   EXPECT_CALL(*verify_monitoring_client_, Log(primary_key_id, message.size()));
251   EXPECT_THAT((*public_key_verify)->Verify(signature, message), IsOk());
252 }
253 
TEST_F(PublicKeyVerifySetWrapperWithMonitoringTest,WrapKeysetWithMonitoringVerifyFailures)254 TEST_F(PublicKeyVerifySetWrapperWithMonitoringTest,
255        WrapKeysetWithMonitoringVerifyFailures) {
256   // Create a primitive set and fill it with some entries
257   KeysetInfo keyset_info = CreateTestKeysetInfo();
258   const absl::flat_hash_map<std::string, std::string> kAnnotations = {
259       {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
260   auto public_key_verify_primitive_set =
261       absl::make_unique<PrimitiveSet<PublicKeyVerify>>(kAnnotations);
262   ASSERT_THAT(public_key_verify_primitive_set
263                   ->AddPrimitive(CreateAlwaysFailingPublicKeyVerify("sign0"),
264                                  keyset_info.key_info(0))
265                   .status(),
266               IsOk());
267   ASSERT_THAT(public_key_verify_primitive_set
268                   ->AddPrimitive(CreateAlwaysFailingPublicKeyVerify("sign1"),
269                                  keyset_info.key_info(1))
270                   .status(),
271               IsOk());
272   // Set the last as primary.
273   util::StatusOr<PrimitiveSet<PublicKeyVerify>::Entry<PublicKeyVerify>*> last =
274       public_key_verify_primitive_set->AddPrimitive(
275           CreateAlwaysFailingPublicKeyVerify("sign2"), keyset_info.key_info(2));
276   ASSERT_THAT(last.status(), IsOk());
277   ASSERT_THAT(public_key_verify_primitive_set->set_primary(*last), IsOk());
278 
279   // Create a PublicKeySign and sign some data we can verify.
280   util::StatusOr<std::unique_ptr<PublicKeyVerify>> public_key_verify =
281       PublicKeyVerifyWrapper().Wrap(std::move(public_key_verify_primitive_set));
282   ASSERT_THAT(public_key_verify, IsOkAndHolds(NotNull()));
283 
284   constexpr absl::string_view message = "This is some message!";
285   constexpr absl::string_view signature = "This is some invalid signature!";
286 
287   // Check that calling Verify triggers a LogFailure() call.
288   EXPECT_CALL(*verify_monitoring_client_, LogFailure());
289   EXPECT_THAT((*public_key_verify)->Verify(signature, message),
290               StatusIs(absl::StatusCode::kInvalidArgument));
291 }
292 
293 }  // namespace
294 }  // namespace tink
295 }  // namespace crypto
296