xref: /aosp_15_r20/external/tink/cc/mac/mac_wrapper_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang // Copyright 2017 Google Inc.
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang //     http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ////////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang 
17*e7b1675dSTing-Kang Chang #include "tink/mac/mac_wrapper.h"
18*e7b1675dSTing-Kang Chang 
19*e7b1675dSTing-Kang Chang #include <memory>
20*e7b1675dSTing-Kang Chang #include <string>
21*e7b1675dSTing-Kang Chang #include <utility>
22*e7b1675dSTing-Kang Chang 
23*e7b1675dSTing-Kang Chang #include "gtest/gtest.h"
24*e7b1675dSTing-Kang Chang #include "absl/strings/str_cat.h"
25*e7b1675dSTing-Kang Chang #include "tink/crypto_format.h"
26*e7b1675dSTing-Kang Chang #include "tink/internal/registry_impl.h"
27*e7b1675dSTing-Kang Chang #include "tink/mac.h"
28*e7b1675dSTing-Kang Chang #include "tink/mac/failing_mac.h"
29*e7b1675dSTing-Kang Chang #include "tink/monitoring/monitoring.h"
30*e7b1675dSTing-Kang Chang #include "tink/monitoring/monitoring_client_mocks.h"
31*e7b1675dSTing-Kang Chang #include "tink/primitive_set.h"
32*e7b1675dSTing-Kang Chang #include "tink/util/status.h"
33*e7b1675dSTing-Kang Chang #include "tink/util/test_matchers.h"
34*e7b1675dSTing-Kang Chang #include "tink/util/test_util.h"
35*e7b1675dSTing-Kang Chang #include "proto/tink.pb.h"
36*e7b1675dSTing-Kang Chang 
37*e7b1675dSTing-Kang Chang namespace crypto {
38*e7b1675dSTing-Kang Chang namespace tink {
39*e7b1675dSTing-Kang Chang namespace {
40*e7b1675dSTing-Kang Chang 
41*e7b1675dSTing-Kang Chang using ::crypto::tink::test::DummyMac;
42*e7b1675dSTing-Kang Chang using ::crypto::tink::test::IsOk;
43*e7b1675dSTing-Kang Chang using ::crypto::tink::test::IsOkAndHolds;
44*e7b1675dSTing-Kang Chang using ::crypto::tink::test::StatusIs;
45*e7b1675dSTing-Kang Chang using ::google::crypto::tink::KeysetInfo;
46*e7b1675dSTing-Kang Chang using ::google::crypto::tink::KeyStatusType;
47*e7b1675dSTing-Kang Chang using ::google::crypto::tink::OutputPrefixType;
48*e7b1675dSTing-Kang Chang using ::testing::_;
49*e7b1675dSTing-Kang Chang using ::testing::ByMove;
50*e7b1675dSTing-Kang Chang using ::testing::IsNull;
51*e7b1675dSTing-Kang Chang using ::testing::NiceMock;
52*e7b1675dSTing-Kang Chang using ::testing::Not;
53*e7b1675dSTing-Kang Chang using ::testing::NotNull;
54*e7b1675dSTing-Kang Chang using ::testing::Return;
55*e7b1675dSTing-Kang Chang using ::testing::Test;
56*e7b1675dSTing-Kang Chang 
TEST(MacWrapperTest,WrapNullptr)57*e7b1675dSTing-Kang Chang TEST(MacWrapperTest, WrapNullptr) {
58*e7b1675dSTing-Kang Chang   auto mac_result = MacWrapper().Wrap(nullptr);
59*e7b1675dSTing-Kang Chang   EXPECT_FALSE(mac_result.ok());
60*e7b1675dSTing-Kang Chang   EXPECT_EQ(absl::StatusCode::kInternal, mac_result.status().code());
61*e7b1675dSTing-Kang Chang   EXPECT_PRED_FORMAT2(testing::IsSubstring, "non-NULL",
62*e7b1675dSTing-Kang Chang                       std::string(mac_result.status().message()));
63*e7b1675dSTing-Kang Chang }
64*e7b1675dSTing-Kang Chang 
TEST(MacWrapperTest,WrapEmpty)65*e7b1675dSTing-Kang Chang TEST(MacWrapperTest, WrapEmpty) {
66*e7b1675dSTing-Kang Chang   std::unique_ptr<PrimitiveSet<Mac>> mac_set(new PrimitiveSet<Mac>());
67*e7b1675dSTing-Kang Chang   auto mac_result = MacWrapper().Wrap(std::move(mac_set));
68*e7b1675dSTing-Kang Chang   EXPECT_FALSE(mac_result.ok());
69*e7b1675dSTing-Kang Chang   EXPECT_EQ(absl::StatusCode::kInvalidArgument, mac_result.status().code());
70*e7b1675dSTing-Kang Chang   EXPECT_PRED_FORMAT2(testing::IsSubstring, "no primary",
71*e7b1675dSTing-Kang Chang                       std::string(mac_result.status().message()));
72*e7b1675dSTing-Kang Chang }
73*e7b1675dSTing-Kang Chang 
TEST(MacWrapperTest,Basic)74*e7b1675dSTing-Kang Chang TEST(MacWrapperTest, Basic) {
75*e7b1675dSTing-Kang Chang   KeysetInfo::KeyInfo* key_info;
76*e7b1675dSTing-Kang Chang   KeysetInfo keyset_info;
77*e7b1675dSTing-Kang Chang 
78*e7b1675dSTing-Kang Chang   uint32_t key_id_0 = 1234543;
79*e7b1675dSTing-Kang Chang   key_info = keyset_info.add_key_info();
80*e7b1675dSTing-Kang Chang   key_info->set_output_prefix_type(OutputPrefixType::TINK);
81*e7b1675dSTing-Kang Chang   key_info->set_key_id(key_id_0);
82*e7b1675dSTing-Kang Chang   key_info->set_status(KeyStatusType::ENABLED);
83*e7b1675dSTing-Kang Chang 
84*e7b1675dSTing-Kang Chang   uint32_t key_id_1 = 726329;
85*e7b1675dSTing-Kang Chang   key_info = keyset_info.add_key_info();
86*e7b1675dSTing-Kang Chang   key_info->set_output_prefix_type(OutputPrefixType::LEGACY);
87*e7b1675dSTing-Kang Chang   key_info->set_key_id(key_id_1);
88*e7b1675dSTing-Kang Chang   key_info->set_status(KeyStatusType::ENABLED);
89*e7b1675dSTing-Kang Chang 
90*e7b1675dSTing-Kang Chang   uint32_t key_id_2 = 7213743;
91*e7b1675dSTing-Kang Chang   key_info = keyset_info.add_key_info();
92*e7b1675dSTing-Kang Chang   key_info->set_output_prefix_type(OutputPrefixType::TINK);
93*e7b1675dSTing-Kang Chang   key_info->set_key_id(key_id_2);
94*e7b1675dSTing-Kang Chang   key_info->set_status(KeyStatusType::ENABLED);
95*e7b1675dSTing-Kang Chang 
96*e7b1675dSTing-Kang Chang   std::string mac_name_0 = "mac0";
97*e7b1675dSTing-Kang Chang   std::string mac_name_1 = "mac1";
98*e7b1675dSTing-Kang Chang   std::string mac_name_2 = "mac2";
99*e7b1675dSTing-Kang Chang   std::unique_ptr<PrimitiveSet<Mac>> mac_set(new PrimitiveSet<Mac>());
100*e7b1675dSTing-Kang Chang   auto entry_result = mac_set->AddPrimitive(
101*e7b1675dSTing-Kang Chang       absl::make_unique<DummyMac>(mac_name_0), keyset_info.key_info(0));
102*e7b1675dSTing-Kang Chang   ASSERT_TRUE(entry_result.ok());
103*e7b1675dSTing-Kang Chang   entry_result = mac_set->AddPrimitive(absl::make_unique<DummyMac>(mac_name_1),
104*e7b1675dSTing-Kang Chang                                        keyset_info.key_info(1));
105*e7b1675dSTing-Kang Chang   ASSERT_TRUE(entry_result.ok());
106*e7b1675dSTing-Kang Chang   entry_result = mac_set->AddPrimitive(absl::make_unique<DummyMac>(mac_name_2),
107*e7b1675dSTing-Kang Chang                                        keyset_info.key_info(2));
108*e7b1675dSTing-Kang Chang   ASSERT_TRUE(entry_result.ok());
109*e7b1675dSTing-Kang Chang   // The last key is the primary.
110*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_set->set_primary(entry_result.value()), IsOk());
111*e7b1675dSTing-Kang Chang 
112*e7b1675dSTing-Kang Chang   // Wrap mac_set and test the resulting Mac.
113*e7b1675dSTing-Kang Chang   auto mac_result = MacWrapper().Wrap(std::move(mac_set));
114*e7b1675dSTing-Kang Chang   EXPECT_TRUE(mac_result.ok()) << mac_result.status();
115*e7b1675dSTing-Kang Chang   std::unique_ptr<Mac> mac = std::move(mac_result.value());
116*e7b1675dSTing-Kang Chang   std::string data = "some_data_for_mac";
117*e7b1675dSTing-Kang Chang 
118*e7b1675dSTing-Kang Chang   auto compute_mac_result = mac->ComputeMac(data);
119*e7b1675dSTing-Kang Chang   EXPECT_TRUE(compute_mac_result.ok()) << compute_mac_result.status();
120*e7b1675dSTing-Kang Chang   std::string mac_value = compute_mac_result.value();
121*e7b1675dSTing-Kang Chang   EXPECT_PRED_FORMAT2(testing::IsSubstring, mac_name_2, mac_value);
122*e7b1675dSTing-Kang Chang 
123*e7b1675dSTing-Kang Chang   util::Status status = mac->VerifyMac(mac_value, data);
124*e7b1675dSTing-Kang Chang   EXPECT_TRUE(status.ok()) << status;
125*e7b1675dSTing-Kang Chang 
126*e7b1675dSTing-Kang Chang   status = mac->VerifyMac("some bad mac", data);
127*e7b1675dSTing-Kang Chang   EXPECT_FALSE(status.ok());
128*e7b1675dSTing-Kang Chang   EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
129*e7b1675dSTing-Kang Chang   EXPECT_PRED_FORMAT2(testing::IsSubstring, "verification failed",
130*e7b1675dSTing-Kang Chang                       std::string(status.message()));
131*e7b1675dSTing-Kang Chang }
132*e7b1675dSTing-Kang Chang 
TEST(MacWrapperTest,testLegacyAuthentication)133*e7b1675dSTing-Kang Chang TEST(MacWrapperTest, testLegacyAuthentication) {
134*e7b1675dSTing-Kang Chang   // Prepare a set for the wrapper.
135*e7b1675dSTing-Kang Chang   KeysetInfo::KeyInfo key_info;
136*e7b1675dSTing-Kang Chang   uint32_t key_id = 1234543;
137*e7b1675dSTing-Kang Chang   key_info.set_output_prefix_type(OutputPrefixType::LEGACY);
138*e7b1675dSTing-Kang Chang   key_info.set_key_id(key_id);
139*e7b1675dSTing-Kang Chang   key_info.set_status(KeyStatusType::ENABLED);
140*e7b1675dSTing-Kang Chang   std::string mac_name = "SomeLegacyMac";
141*e7b1675dSTing-Kang Chang 
142*e7b1675dSTing-Kang Chang   std::unique_ptr<PrimitiveSet<Mac>> mac_set(new PrimitiveSet<Mac>());
143*e7b1675dSTing-Kang Chang   std::unique_ptr<Mac> mac(new DummyMac(mac_name));
144*e7b1675dSTing-Kang Chang   auto entry_result = mac_set->AddPrimitive(std::move(mac), key_info);
145*e7b1675dSTing-Kang Chang   ASSERT_TRUE(entry_result.ok());
146*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_set->set_primary(entry_result.value()), IsOk());
147*e7b1675dSTing-Kang Chang 
148*e7b1675dSTing-Kang Chang   // Wrap mac_set and test the resulting Mac.
149*e7b1675dSTing-Kang Chang   auto mac_result = MacWrapper().Wrap(std::move(mac_set));
150*e7b1675dSTing-Kang Chang   EXPECT_TRUE(mac_result.ok()) << mac_result.status();
151*e7b1675dSTing-Kang Chang   mac = std::move(mac_result.value());
152*e7b1675dSTing-Kang Chang   std::string data = "Some data to authenticate";
153*e7b1675dSTing-Kang Chang 
154*e7b1675dSTing-Kang Chang   // Compute and verify MAC via wrapper.
155*e7b1675dSTing-Kang Chang   auto compute_mac_result = mac->ComputeMac(data);
156*e7b1675dSTing-Kang Chang   EXPECT_TRUE(compute_mac_result.ok()) << compute_mac_result.status();
157*e7b1675dSTing-Kang Chang   std::string mac_value = compute_mac_result.value();
158*e7b1675dSTing-Kang Chang   EXPECT_PRED_FORMAT2(testing::IsSubstring, mac_name, mac_value);
159*e7b1675dSTing-Kang Chang   auto status = mac->VerifyMac(mac_value, data);
160*e7b1675dSTing-Kang Chang   EXPECT_TRUE(status.ok()) << status;
161*e7b1675dSTing-Kang Chang 
162*e7b1675dSTing-Kang Chang   // Try verifying on raw Mac-primitive using original data.
163*e7b1675dSTing-Kang Chang   std::unique_ptr<Mac> raw_mac(new DummyMac(mac_name));  // same as in wrapper
164*e7b1675dSTing-Kang Chang   std::string raw_mac_value = mac_value.substr(CryptoFormat::kNonRawPrefixSize);
165*e7b1675dSTing-Kang Chang   status = raw_mac->VerifyMac(raw_mac_value, data);
166*e7b1675dSTing-Kang Chang   EXPECT_FALSE(status.ok());
167*e7b1675dSTing-Kang Chang   EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
168*e7b1675dSTing-Kang Chang 
169*e7b1675dSTing-Kang Chang   // Verify on raw Mac-primitive using legacy-formatted data.
170*e7b1675dSTing-Kang Chang   std::string legacy_data = data;
171*e7b1675dSTing-Kang Chang   legacy_data.append(1, CryptoFormat::kLegacyStartByte);
172*e7b1675dSTing-Kang Chang   status = raw_mac->VerifyMac(raw_mac_value, legacy_data);
173*e7b1675dSTing-Kang Chang   EXPECT_TRUE(status.ok()) << status;
174*e7b1675dSTing-Kang Chang }
175*e7b1675dSTing-Kang Chang 
176*e7b1675dSTing-Kang Chang // Produces a mac which starts in the same way as a legacy non-raw signature.
177*e7b1675dSTing-Kang Chang class TryBreakLegacyMac : public Mac {
178*e7b1675dSTing-Kang Chang  public:
ComputeMac(absl::string_view data) const179*e7b1675dSTing-Kang Chang   crypto::tink::util::StatusOr<std::string> ComputeMac(
180*e7b1675dSTing-Kang Chang       absl::string_view data) const override {
181*e7b1675dSTing-Kang Chang     return absl::StrCat(std::string("\x00", 1), "\xff\xff\xff\xff", data);
182*e7b1675dSTing-Kang Chang   }
183*e7b1675dSTing-Kang Chang 
VerifyMac(absl::string_view mac,absl::string_view data) const184*e7b1675dSTing-Kang Chang   crypto::tink::util::Status VerifyMac(absl::string_view mac,
185*e7b1675dSTing-Kang Chang                                        absl::string_view data) const override {
186*e7b1675dSTing-Kang Chang     if (mac != ComputeMac(data).value()) {
187*e7b1675dSTing-Kang Chang       return absl::InvalidArgumentError("Wrong mac");
188*e7b1675dSTing-Kang Chang     }
189*e7b1675dSTing-Kang Chang     return util::OkStatus();
190*e7b1675dSTing-Kang Chang   }
191*e7b1675dSTing-Kang Chang };
192*e7b1675dSTing-Kang Chang 
193*e7b1675dSTing-Kang Chang // Checks that a raw tag can be verified after a legacy tag is verified with
194*e7b1675dSTing-Kang Chang // the same output prefix. (To prevent regression of b/173013224).
TEST(MacWrapperTest,VerifyRawAfterLegacy)195*e7b1675dSTing-Kang Chang TEST(MacWrapperTest, VerifyRawAfterLegacy) {
196*e7b1675dSTing-Kang Chang   std::unique_ptr<PrimitiveSet<Mac>> mac_set(new PrimitiveSet<Mac>());
197*e7b1675dSTing-Kang Chang 
198*e7b1675dSTing-Kang Chang   KeysetInfo::KeyInfo key_info_0;
199*e7b1675dSTing-Kang Chang   key_info_0.set_output_prefix_type(OutputPrefixType::RAW);
200*e7b1675dSTing-Kang Chang   key_info_0.set_key_id(1234);
201*e7b1675dSTing-Kang Chang   key_info_0.set_status(KeyStatusType::ENABLED);
202*e7b1675dSTing-Kang Chang   ASSERT_THAT(
203*e7b1675dSTing-Kang Chang       mac_set->AddPrimitive(absl::make_unique<TryBreakLegacyMac>(), key_info_0)
204*e7b1675dSTing-Kang Chang           .status(),
205*e7b1675dSTing-Kang Chang       IsOk());
206*e7b1675dSTing-Kang Chang 
207*e7b1675dSTing-Kang Chang   KeysetInfo::KeyInfo key_info_1;
208*e7b1675dSTing-Kang Chang   key_info_1.set_output_prefix_type(OutputPrefixType::LEGACY);
209*e7b1675dSTing-Kang Chang   key_info_1.set_key_id(0xffffffff);
210*e7b1675dSTing-Kang Chang   key_info_1.set_status(KeyStatusType::ENABLED);
211*e7b1675dSTing-Kang Chang 
212*e7b1675dSTing-Kang Chang   auto entry1 =
213*e7b1675dSTing-Kang Chang       mac_set->AddPrimitive(absl::make_unique<DummyMac>(""), key_info_1);
214*e7b1675dSTing-Kang Chang   ASSERT_THAT(entry1, IsOk());
215*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_set->set_primary(entry1.value()), IsOk());
216*e7b1675dSTing-Kang Chang 
217*e7b1675dSTing-Kang Chang   // Wrap mac_set and test the resulting Mac.
218*e7b1675dSTing-Kang Chang   auto wrapped_mac = MacWrapper().Wrap(std::move(mac_set));
219*e7b1675dSTing-Kang Chang   EXPECT_THAT(wrapped_mac, IsOk());
220*e7b1675dSTing-Kang Chang 
221*e7b1675dSTing-Kang Chang   std::string data = "some data";
222*e7b1675dSTing-Kang Chang   std::string mac_tag = TryBreakLegacyMac().ComputeMac(data).value();
223*e7b1675dSTing-Kang Chang   EXPECT_THAT(wrapped_mac.value()->VerifyMac(mac_tag, data), IsOk());
224*e7b1675dSTing-Kang Chang }
225*e7b1675dSTing-Kang Chang 
PopulateKeyInfo(uint32_t key_id,OutputPrefixType out_prefix_type,KeyStatusType status)226*e7b1675dSTing-Kang Chang KeysetInfo::KeyInfo PopulateKeyInfo(uint32_t key_id,
227*e7b1675dSTing-Kang Chang                                     OutputPrefixType out_prefix_type,
228*e7b1675dSTing-Kang Chang                                     KeyStatusType status) {
229*e7b1675dSTing-Kang Chang   KeysetInfo::KeyInfo key_info;
230*e7b1675dSTing-Kang Chang   key_info.set_output_prefix_type(out_prefix_type);
231*e7b1675dSTing-Kang Chang   key_info.set_key_id(key_id);
232*e7b1675dSTing-Kang Chang   key_info.set_status(status);
233*e7b1675dSTing-Kang Chang   return key_info;
234*e7b1675dSTing-Kang Chang }
235*e7b1675dSTing-Kang Chang 
236*e7b1675dSTing-Kang Chang // Creates a test keyset info object.
CreateTestKeysetInfo()237*e7b1675dSTing-Kang Chang KeysetInfo CreateTestKeysetInfo() {
238*e7b1675dSTing-Kang Chang   KeysetInfo keyset_info;
239*e7b1675dSTing-Kang Chang   *keyset_info.add_key_info() =
240*e7b1675dSTing-Kang Chang       PopulateKeyInfo(/*key_id=*/1234543, OutputPrefixType::TINK,
241*e7b1675dSTing-Kang Chang                       /*status=*/KeyStatusType::ENABLED);
242*e7b1675dSTing-Kang Chang   *keyset_info.add_key_info() =
243*e7b1675dSTing-Kang Chang       PopulateKeyInfo(/*key_id=*/726329, OutputPrefixType::LEGACY,
244*e7b1675dSTing-Kang Chang                       /*status=*/KeyStatusType::ENABLED);
245*e7b1675dSTing-Kang Chang   *keyset_info.add_key_info() =
246*e7b1675dSTing-Kang Chang       PopulateKeyInfo(/*key_id=*/7213743, OutputPrefixType::TINK,
247*e7b1675dSTing-Kang Chang                       /*status=*/KeyStatusType::ENABLED);
248*e7b1675dSTing-Kang Chang   return keyset_info;
249*e7b1675dSTing-Kang Chang }
250*e7b1675dSTing-Kang Chang 
251*e7b1675dSTing-Kang Chang // Tests for the monitoring behavior.
252*e7b1675dSTing-Kang Chang class MacSetWrapperWithMonitoringTest : public Test {
253*e7b1675dSTing-Kang Chang  protected:
254*e7b1675dSTing-Kang Chang   // Perform some common initialization: reset the global registry, set expected
255*e7b1675dSTing-Kang Chang   // calls for the mock monitoring factory and the returned clients.
SetUp()256*e7b1675dSTing-Kang Chang   void SetUp() override {
257*e7b1675dSTing-Kang Chang     Registry::Reset();
258*e7b1675dSTing-Kang Chang 
259*e7b1675dSTing-Kang Chang     // Setup mocks for catching Monitoring calls.
260*e7b1675dSTing-Kang Chang     auto monitoring_client_factory =
261*e7b1675dSTing-Kang Chang         absl::make_unique<MockMonitoringClientFactory>();
262*e7b1675dSTing-Kang Chang     auto compute_monitoring_client =
263*e7b1675dSTing-Kang Chang         absl::make_unique<NiceMock<MockMonitoringClient>>();
264*e7b1675dSTing-Kang Chang     compute_monitoring_client_ = compute_monitoring_client.get();
265*e7b1675dSTing-Kang Chang     auto verify_monitoring_client =
266*e7b1675dSTing-Kang Chang         absl::make_unique<NiceMock<MockMonitoringClient>>();
267*e7b1675dSTing-Kang Chang     verify_monitoring_client_ = verify_monitoring_client.get();
268*e7b1675dSTing-Kang Chang 
269*e7b1675dSTing-Kang Chang     // Monitoring tests expect that the client factory will create the
270*e7b1675dSTing-Kang Chang     // corresponding MockMonitoringClients.
271*e7b1675dSTing-Kang Chang     EXPECT_CALL(*monitoring_client_factory, New(_))
272*e7b1675dSTing-Kang Chang         .WillOnce(
273*e7b1675dSTing-Kang Chang             Return(ByMove(util::StatusOr<std::unique_ptr<MonitoringClient>>(
274*e7b1675dSTing-Kang Chang                 std::move(compute_monitoring_client)))))
275*e7b1675dSTing-Kang Chang         .WillOnce(
276*e7b1675dSTing-Kang Chang             Return(ByMove(util::StatusOr<std::unique_ptr<MonitoringClient>>(
277*e7b1675dSTing-Kang Chang                 std::move(verify_monitoring_client)))));
278*e7b1675dSTing-Kang Chang 
279*e7b1675dSTing-Kang Chang     ASSERT_THAT(internal::RegistryImpl::GlobalInstance()
280*e7b1675dSTing-Kang Chang                     .RegisterMonitoringClientFactory(
281*e7b1675dSTing-Kang Chang                         std::move(monitoring_client_factory)),
282*e7b1675dSTing-Kang Chang                 IsOk());
283*e7b1675dSTing-Kang Chang     ASSERT_THAT(
284*e7b1675dSTing-Kang Chang         internal::RegistryImpl::GlobalInstance().GetMonitoringClientFactory(),
285*e7b1675dSTing-Kang Chang         Not(IsNull()));
286*e7b1675dSTing-Kang Chang   }
287*e7b1675dSTing-Kang Chang 
288*e7b1675dSTing-Kang Chang   // Cleanup the registry to avoid mock leaks.
~MacSetWrapperWithMonitoringTest()289*e7b1675dSTing-Kang Chang   ~MacSetWrapperWithMonitoringTest() override { Registry::Reset(); }
290*e7b1675dSTing-Kang Chang 
291*e7b1675dSTing-Kang Chang   MockMonitoringClient* compute_monitoring_client_;
292*e7b1675dSTing-Kang Chang   MockMonitoringClient* verify_monitoring_client_;
293*e7b1675dSTing-Kang Chang };
294*e7b1675dSTing-Kang Chang 
295*e7b1675dSTing-Kang Chang // Tests that successful ComputeMac operations are logged.
TEST_F(MacSetWrapperWithMonitoringTest,WrapKeysetWithMonitoringComputeSuccess)296*e7b1675dSTing-Kang Chang TEST_F(MacSetWrapperWithMonitoringTest,
297*e7b1675dSTing-Kang Chang        WrapKeysetWithMonitoringComputeSuccess) {
298*e7b1675dSTing-Kang Chang   // Create a primitive set and fill it with some entries
299*e7b1675dSTing-Kang Chang   KeysetInfo keyset_info = CreateTestKeysetInfo();
300*e7b1675dSTing-Kang Chang   const absl::flat_hash_map<std::string, std::string> annotations = {
301*e7b1675dSTing-Kang Chang       {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
302*e7b1675dSTing-Kang Chang   auto mac_primitive_set = absl::make_unique<PrimitiveSet<Mac>>(annotations);
303*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set
304*e7b1675dSTing-Kang Chang                   ->AddPrimitive(absl::make_unique<DummyMac>("mac0"),
305*e7b1675dSTing-Kang Chang                                  keyset_info.key_info(0))
306*e7b1675dSTing-Kang Chang                   .status(),
307*e7b1675dSTing-Kang Chang               IsOk());
308*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set
309*e7b1675dSTing-Kang Chang                   ->AddPrimitive(absl::make_unique<DummyMac>("mac1"),
310*e7b1675dSTing-Kang Chang                                  keyset_info.key_info(1))
311*e7b1675dSTing-Kang Chang                   .status(),
312*e7b1675dSTing-Kang Chang               IsOk());
313*e7b1675dSTing-Kang Chang   // Set the last as primary.
314*e7b1675dSTing-Kang Chang   util::StatusOr<PrimitiveSet<Mac>::Entry<Mac>*> last =
315*e7b1675dSTing-Kang Chang       mac_primitive_set->AddPrimitive(absl::make_unique<DummyMac>("mac2"),
316*e7b1675dSTing-Kang Chang                                       keyset_info.key_info(2));
317*e7b1675dSTing-Kang Chang   ASSERT_THAT(last.status(), IsOk());
318*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set->set_primary(*last), IsOk());
319*e7b1675dSTing-Kang Chang   // Record the ID of the primary key.
320*e7b1675dSTing-Kang Chang   const uint32_t primary_key_id = keyset_info.key_info(2).key_id();
321*e7b1675dSTing-Kang Chang 
322*e7b1675dSTing-Kang Chang   // Create a MAC and compute an authentication tag
323*e7b1675dSTing-Kang Chang   util::StatusOr<std::unique_ptr<Mac>> mac =
324*e7b1675dSTing-Kang Chang       MacWrapper().Wrap(std::move(mac_primitive_set));
325*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac, IsOkAndHolds(NotNull()));
326*e7b1675dSTing-Kang Chang 
327*e7b1675dSTing-Kang Chang   constexpr absl::string_view message = "This is some message!";
328*e7b1675dSTing-Kang Chang 
329*e7b1675dSTing-Kang Chang   // Check that calling ComputeMac triggers a Log() call.
330*e7b1675dSTing-Kang Chang   EXPECT_CALL(*compute_monitoring_client_, Log(primary_key_id, message.size()));
331*e7b1675dSTing-Kang Chang   EXPECT_THAT((*mac)->ComputeMac(message).status(), IsOk());
332*e7b1675dSTing-Kang Chang }
333*e7b1675dSTing-Kang Chang 
334*e7b1675dSTing-Kang Chang // Test that successful VerifyMac operations are logged.
TEST_F(MacSetWrapperWithMonitoringTest,WrapKeysetWithMonitoringVerifySuccess)335*e7b1675dSTing-Kang Chang TEST_F(MacSetWrapperWithMonitoringTest,
336*e7b1675dSTing-Kang Chang        WrapKeysetWithMonitoringVerifySuccess) {
337*e7b1675dSTing-Kang Chang   // Create a primitive set and fill it with some entries
338*e7b1675dSTing-Kang Chang   KeysetInfo keyset_info = CreateTestKeysetInfo();
339*e7b1675dSTing-Kang Chang   const absl::flat_hash_map<std::string, std::string> annotations = {
340*e7b1675dSTing-Kang Chang       {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
341*e7b1675dSTing-Kang Chang   auto mac_primitive_set = absl::make_unique<PrimitiveSet<Mac>>(annotations);
342*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set
343*e7b1675dSTing-Kang Chang                   ->AddPrimitive(absl::make_unique<DummyMac>("mac0"),
344*e7b1675dSTing-Kang Chang                                  keyset_info.key_info(0))
345*e7b1675dSTing-Kang Chang                   .status(),
346*e7b1675dSTing-Kang Chang               IsOk());
347*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set
348*e7b1675dSTing-Kang Chang                   ->AddPrimitive(absl::make_unique<DummyMac>("mac1"),
349*e7b1675dSTing-Kang Chang                                  keyset_info.key_info(1))
350*e7b1675dSTing-Kang Chang                   .status(),
351*e7b1675dSTing-Kang Chang               IsOk());
352*e7b1675dSTing-Kang Chang   // Set the last as primary.
353*e7b1675dSTing-Kang Chang   util::StatusOr<PrimitiveSet<Mac>::Entry<Mac>*> last =
354*e7b1675dSTing-Kang Chang       mac_primitive_set->AddPrimitive(absl::make_unique<DummyMac>("mac2"),
355*e7b1675dSTing-Kang Chang                                       keyset_info.key_info(2));
356*e7b1675dSTing-Kang Chang   ASSERT_THAT(last.status(), IsOk());
357*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set->set_primary(*last), IsOk());
358*e7b1675dSTing-Kang Chang   // Record the ID of the primary key.
359*e7b1675dSTing-Kang Chang   const uint32_t primary_key_id = keyset_info.key_info(2).key_id();
360*e7b1675dSTing-Kang Chang 
361*e7b1675dSTing-Kang Chang   // Create a MAC, compute a Mac and verify it.
362*e7b1675dSTing-Kang Chang   util::StatusOr<std::unique_ptr<Mac>> mac =
363*e7b1675dSTing-Kang Chang       MacWrapper().Wrap(std::move(mac_primitive_set));
364*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac, IsOkAndHolds(NotNull()));
365*e7b1675dSTing-Kang Chang 
366*e7b1675dSTing-Kang Chang   constexpr absl::string_view message = "This is some message!";
367*e7b1675dSTing-Kang Chang 
368*e7b1675dSTing-Kang Chang   // Check that calling VerifyMac triggers a Log() call.
369*e7b1675dSTing-Kang Chang   util::StatusOr<std::string> tag = (*mac)->ComputeMac(message);
370*e7b1675dSTing-Kang Chang   EXPECT_THAT(tag.status(), IsOk());
371*e7b1675dSTing-Kang Chang 
372*e7b1675dSTing-Kang Chang   // In the log expect the size of the message without the non-raw prefix.
373*e7b1675dSTing-Kang Chang   EXPECT_CALL(*verify_monitoring_client_, Log(primary_key_id, message.size()));
374*e7b1675dSTing-Kang Chang   EXPECT_THAT((*mac)->VerifyMac(*tag, message), IsOk());
375*e7b1675dSTing-Kang Chang }
376*e7b1675dSTing-Kang Chang 
TEST_F(MacSetWrapperWithMonitoringTest,WrapKeysetWithMonitoringComputeFailures)377*e7b1675dSTing-Kang Chang TEST_F(MacSetWrapperWithMonitoringTest,
378*e7b1675dSTing-Kang Chang        WrapKeysetWithMonitoringComputeFailures) {
379*e7b1675dSTing-Kang Chang   // Create a primitive set and fill it with some entries.
380*e7b1675dSTing-Kang Chang   KeysetInfo keyset_info = CreateTestKeysetInfo();
381*e7b1675dSTing-Kang Chang   const absl::flat_hash_map<std::string, std::string> annotations = {
382*e7b1675dSTing-Kang Chang       {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
383*e7b1675dSTing-Kang Chang   auto mac_primitive_set = absl::make_unique<PrimitiveSet<Mac>>(annotations);
384*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set
385*e7b1675dSTing-Kang Chang                   ->AddPrimitive(CreateAlwaysFailingMac("mac "),
386*e7b1675dSTing-Kang Chang                                  keyset_info.key_info(0))
387*e7b1675dSTing-Kang Chang                   .status(),
388*e7b1675dSTing-Kang Chang               IsOk());
389*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set
390*e7b1675dSTing-Kang Chang                   ->AddPrimitive(CreateAlwaysFailingMac("mac "),
391*e7b1675dSTing-Kang Chang                                  keyset_info.key_info(1))
392*e7b1675dSTing-Kang Chang                   .status(),
393*e7b1675dSTing-Kang Chang               IsOk());
394*e7b1675dSTing-Kang Chang   // Set the last as primary.
395*e7b1675dSTing-Kang Chang   util::StatusOr<PrimitiveSet<Mac>::Entry<Mac>*> last =
396*e7b1675dSTing-Kang Chang       mac_primitive_set->AddPrimitive(CreateAlwaysFailingMac("mac "),
397*e7b1675dSTing-Kang Chang                                       keyset_info.key_info(2));
398*e7b1675dSTing-Kang Chang   ASSERT_THAT(last.status(), IsOk());
399*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set->set_primary(*last), IsOk());
400*e7b1675dSTing-Kang Chang 
401*e7b1675dSTing-Kang Chang   // Create a MAC and compute a tag.
402*e7b1675dSTing-Kang Chang   util::StatusOr<std::unique_ptr<Mac>> mac =
403*e7b1675dSTing-Kang Chang       MacWrapper().Wrap(std::move(mac_primitive_set));
404*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac, IsOkAndHolds(NotNull()));
405*e7b1675dSTing-Kang Chang 
406*e7b1675dSTing-Kang Chang   constexpr absl::string_view message = "This is some message!";
407*e7b1675dSTing-Kang Chang 
408*e7b1675dSTing-Kang Chang   // Check that calling ComputeMac triggers a LogFailure() call.
409*e7b1675dSTing-Kang Chang   EXPECT_CALL(*compute_monitoring_client_, LogFailure());
410*e7b1675dSTing-Kang Chang   EXPECT_THAT((*mac)->ComputeMac(message).status(),
411*e7b1675dSTing-Kang Chang               StatusIs(absl::StatusCode::kInternal));
412*e7b1675dSTing-Kang Chang }
413*e7b1675dSTing-Kang Chang 
414*e7b1675dSTing-Kang Chang // Test that monitoring logs verify failures correctly.
TEST_F(MacSetWrapperWithMonitoringTest,WrapKeysetWithMonitoringVerifyFailures)415*e7b1675dSTing-Kang Chang TEST_F(MacSetWrapperWithMonitoringTest,
416*e7b1675dSTing-Kang Chang        WrapKeysetWithMonitoringVerifyFailures) {
417*e7b1675dSTing-Kang Chang   // Create a primitive set and fill it with some entries.
418*e7b1675dSTing-Kang Chang   KeysetInfo keyset_info = CreateTestKeysetInfo();
419*e7b1675dSTing-Kang Chang   const absl::flat_hash_map<std::string, std::string> annotations = {
420*e7b1675dSTing-Kang Chang       {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
421*e7b1675dSTing-Kang Chang   auto mac_primitive_set = absl::make_unique<PrimitiveSet<Mac>>(annotations);
422*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set
423*e7b1675dSTing-Kang Chang                   ->AddPrimitive(CreateAlwaysFailingMac("mac "),
424*e7b1675dSTing-Kang Chang                                  keyset_info.key_info(0))
425*e7b1675dSTing-Kang Chang                   .status(),
426*e7b1675dSTing-Kang Chang               IsOk());
427*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set
428*e7b1675dSTing-Kang Chang                   ->AddPrimitive(CreateAlwaysFailingMac("mac "),
429*e7b1675dSTing-Kang Chang                                  keyset_info.key_info(1))
430*e7b1675dSTing-Kang Chang                   .status(),
431*e7b1675dSTing-Kang Chang               IsOk());
432*e7b1675dSTing-Kang Chang   // Set the last as primary.
433*e7b1675dSTing-Kang Chang   util::StatusOr<PrimitiveSet<Mac>::Entry<Mac>*> last =
434*e7b1675dSTing-Kang Chang       mac_primitive_set->AddPrimitive(CreateAlwaysFailingMac("mac "),
435*e7b1675dSTing-Kang Chang                                       keyset_info.key_info(2));
436*e7b1675dSTing-Kang Chang   ASSERT_THAT(last.status(), IsOk());
437*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac_primitive_set->set_primary(*last), IsOk());
438*e7b1675dSTing-Kang Chang 
439*e7b1675dSTing-Kang Chang   // Create a MAC and verify a tag.
440*e7b1675dSTing-Kang Chang   util::StatusOr<std::unique_ptr<Mac>> mac =
441*e7b1675dSTing-Kang Chang       MacWrapper().Wrap(std::move(mac_primitive_set));
442*e7b1675dSTing-Kang Chang   ASSERT_THAT(mac, IsOkAndHolds(NotNull()));
443*e7b1675dSTing-Kang Chang 
444*e7b1675dSTing-Kang Chang   constexpr absl::string_view message = "This is some message!";
445*e7b1675dSTing-Kang Chang   constexpr absl::string_view tag = "some invalid tag!";
446*e7b1675dSTing-Kang Chang 
447*e7b1675dSTing-Kang Chang   // Check that calling VerifyMac triggers a LogFailure() call.
448*e7b1675dSTing-Kang Chang   EXPECT_CALL(*verify_monitoring_client_, LogFailure());
449*e7b1675dSTing-Kang Chang   EXPECT_THAT((*mac)->VerifyMac(tag, message),
450*e7b1675dSTing-Kang Chang               StatusIs(absl::StatusCode::kInvalidArgument));
451*e7b1675dSTing-Kang Chang }
452*e7b1675dSTing-Kang Chang 
453*e7b1675dSTing-Kang Chang }  // namespace
454*e7b1675dSTing-Kang Chang }  // namespace tink
455*e7b1675dSTing-Kang Chang }  // namespace crypto
456