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 // https://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 #include "anonymous_tokens/cpp/privacy_pass/token_encodings.h"
16
17 #include <cstdint>
18 #include <string>
19 #include <utility>
20 #include <vector>
21
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include "absl/status/status.h"
25 #include "absl/status/statusor.h"
26 #include "absl/strings/escaping.h"
27 #include "absl/time/clock.h"
28 #include "absl/time/time.h"
29 #include "absl/types/span.h"
30 #include "anonymous_tokens/cpp/testing/utils.h"
31
32 namespace anonymous_tokens {
33 namespace {
34
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,EmptyAuthenticatorInputTest)35 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
36 EmptyAuthenticatorInputTest) {
37 Token token;
38 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string authenticator_input,
39 AuthenticatorInput(token));
40
41 std::string expected_authenticator_input_encoding;
42 ASSERT_TRUE(
43 absl::HexStringToBytes("DA7A", &expected_authenticator_input_encoding));
44
45 EXPECT_EQ(authenticator_input, expected_authenticator_input_encoding);
46 }
47
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,AuthenticatorInputTest)48 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, AuthenticatorInputTest) {
49 std::string token_key_id;
50 ASSERT_TRUE(absl::HexStringToBytes(
51 "ca572f8982a9ca248a3056186322d93ca147266121ddeb5632c07f1f71cd2708",
52 &token_key_id));
53 std::string nonce;
54 ASSERT_TRUE(absl::HexStringToBytes(
55 "5f5e46604255ac6a8ae0820f5b20c236118d97d917509ccbc96b5a82ae40ebeb",
56 &nonce));
57 std::string context;
58 ASSERT_TRUE(absl::HexStringToBytes(
59 "11e15c91a7c2ad02abd66645802373db1d823bea80f08d452541fb2b62b5898b",
60 &context));
61 Token token = {/*token_type=*/0XDA7A, std::move(token_key_id),
62 std::move(nonce), std::move(context)};
63
64 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string authenticator_input,
65 AuthenticatorInput(token));
66
67 std::string expected_authenticator_input_encoding;
68 ASSERT_TRUE(absl::HexStringToBytes(
69 "DA7A5f5e46604255ac6a8ae0820f5b20c236118d97d917509ccbc96b5a82ae40ebeb11e1"
70 "5c91a7c2ad02abd66645802373db1d823bea80f08d452541fb2b62b5898bca572f8982a9"
71 "ca248a3056186322d93ca147266121ddeb5632c07f1f71cd2708",
72 &expected_authenticator_input_encoding));
73 EXPECT_EQ(authenticator_input, expected_authenticator_input_encoding);
74 }
75
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,EmptyMarshalTokenTest)76 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, EmptyMarshalTokenTest) {
77 Token token;
78 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_token,
79 MarshalToken(token));
80 std::string expected_token_encoding;
81 ASSERT_TRUE(absl::HexStringToBytes("DA7A", &expected_token_encoding));
82
83 EXPECT_EQ(encoded_token, expected_token_encoding);
84 }
85
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,MarshalTokenTest)86 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, MarshalTokenTest) {
87 std::string token_key_id;
88 ASSERT_TRUE(absl::HexStringToBytes(
89 "ca572f8982a9ca248a3056186322d93ca147266121ddeb5632c07f1f71cd2708",
90 &token_key_id));
91 std::string nonce;
92 ASSERT_TRUE(absl::HexStringToBytes(
93 "5f5e46604255ac6a8ae0820f5b20c236118d97d917509ccbc96b5a82ae40ebeb",
94 &nonce));
95 std::string context;
96 ASSERT_TRUE(absl::HexStringToBytes(
97 "11e15c91a7c2ad02abd66645802373db1d823bea80f08d452541fb2b62b5898b",
98 &context));
99 std::string authenticator;
100 ASSERT_TRUE(absl::HexStringToBytes(
101 "4ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560568620"
102 "0d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129"
103 "b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881f5e156"
104 "68e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d59402a8"
105 "7e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f5c27d0"
106 "1ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac1f8f61"
107 "1029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000ae10548"
108 "3941652e",
109 &authenticator));
110 Token token = {/*token_type=*/0XDA7A, std::move(token_key_id),
111 std::move(nonce), std::move(context),
112 std::move(authenticator)};
113
114 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_token,
115 MarshalToken(token));
116
117 std::string expected_token_encoding;
118 ASSERT_TRUE(absl::HexStringToBytes(
119 "DA7A5f5e46604255ac6a8ae0820f5b20c236118d97d917509ccbc96b5a82ae40ebeb11e1"
120 "5c91a7c2ad02abd66645802373db1d823bea80f08d452541fb2b62b5898bca572f8982a9"
121 "ca248a3056186322d93ca147266121ddeb5632c07f1f71cd27084ed3f2a25ec528543d9a"
122 "83c850d12b3036b518fafec080df3efcd9693b944d05605686200d6500f249475737ea92"
123 "46a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129b88c92ad61c08a9fe416"
124 "29a642263e4857e428a706ba87659361fed38087c0e881f5e15668e0701d7edd63be98fc"
125 "c7415819d466c61341de03d7e2a24181d7b9321b0826d59402a87e08514f36cc45b0f7aa"
126 "c0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f5c27d01ad42119953c5987b05c"
127 "9ae2ca04b12838e641b4b1aac21e36f18573f603735fac1f8f611029e4cb76c8a5cc6f2c"
128 "4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000ae105483941652e",
129 &expected_token_encoding));
130 EXPECT_EQ(encoded_token, expected_token_encoding);
131
132 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Token token2,
133 UnmarshalToken(encoded_token));
134 EXPECT_EQ(token.token_type, token2.token_type);
135 EXPECT_EQ(token.token_key_id, token2.token_key_id);
136 EXPECT_EQ(token.context, token2.context);
137 EXPECT_EQ(token.nonce, token2.nonce);
138 EXPECT_EQ(token.authenticator, token2.authenticator);
139 }
140
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,UnmarshalTooShort)141 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, UnmarshalTooShort) {
142 std::string short_token;
143 ASSERT_TRUE(absl::HexStringToBytes("DA7A5f5e466042", &short_token));
144 EXPECT_FALSE(UnmarshalToken(short_token).ok());
145 }
146
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,UnmarshalTooLong)147 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, UnmarshalTooLong) {
148 std::string long_token;
149 ASSERT_TRUE(absl::HexStringToBytes(
150 "DA7A5f5e46604255ac6a8ae0820f5b20c236118d97d917509ccbc96b5a82ae40ebeb11e1"
151 "5c91a7c2ad02abd66645802373db1d823bea80f08d452541fb2b62b5898bca572f8982a9"
152 "ca248a3056186322d93ca147266121ddeb5632c07f1f71cd27084ed3f2a25ec528543d9a"
153 "83c850d12b3036b518fafec080df3efcd9693b944d05605686200d6500f249475737ea92"
154 "46a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129b88c92ad61c08a9fe416"
155 "29a642263e4857e428a706ba87659361fed38087c0e881f5e15668e0701d7edd63be98fc"
156 "c7415819d466c61341de03d7e2a24181d7b9321b0826d59402a87e08514f36cc45b0f7aa"
157 "c0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f5c27d01ad42119953c5987b05c"
158 "9ae2ca04b12838e641b4b1aac21e36f18573f603735fac1f8f611029e4cb76c8a5cc6f2c"
159 "4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000ae105483941652e9ae2ca04",
160 &long_token));
161 EXPECT_FALSE(UnmarshalToken(long_token).ok());
162 }
163
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,UnmarshalWrongType)164 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, UnmarshalWrongType) {
165 std::string token;
166 ASSERT_TRUE(absl::HexStringToBytes(
167 "DA7B5f5e46604255ac6a8ae0820f5b20c236118d97d917509ccbc96b5a82ae40ebeb11e1"
168 "5c91a7c2ad02abd66645802373db1d823bea80f08d452541fb2b62b5898bca572f8982a9"
169 "ca248a3056186322d93ca147266121ddeb5632c07f1f71cd27084ed3f2a25ec528543d9a"
170 "83c850d12b3036b518fafec080df3efcd9693b944d05605686200d6500f249475737ea92"
171 "46a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129b88c92ad61c08a9fe416"
172 "29a642263e4857e428a706ba87659361fed38087c0e881f5e15668e0701d7edd63be98fc"
173 "c7415819d466c61341de03d7e2a24181d7b9321b0826d59402a87e08514f36cc45b0f7aa"
174 "c0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f5c27d01ad42119953c5987b05c"
175 "9ae2ca04b12838e641b4b1aac21e36f18573f603735fac1f8f611029e4cb76c8a5cc6f2c"
176 "4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000ae105483941652e",
177 &token));
178 EXPECT_FALSE(UnmarshalToken(token).ok());
179 }
180
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,EmptyExtensionTest)181 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, EmptyExtensionTest) {
182 Extension extension;
183 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_extension,
184 EncodeExtension(extension));
185
186 std::string expected_extension_encoding;
187 ASSERT_TRUE(absl::HexStringToBytes("00010000", &expected_extension_encoding));
188 EXPECT_EQ(encoded_extension, expected_extension_encoding);
189 }
190
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,ExtensionValueSizeOfMoreThanTwoBytes)191 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
192 ExtensionValueSizeOfMoreThanTwoBytes) {
193 // Input string of size more than 2 bytes.
194 std::string large_test_value = std::string(65536, 'a');
195 // Random hex number to populate the uint16_t extension_type.
196 Extension extension = {/*extension_type=*/0x5E6D,
197 /*extension_value=*/large_test_value};
198 absl::StatusOr<std::string> encoded_extension = EncodeExtension(extension);
199
200 EXPECT_EQ(encoded_extension.status().code(),
201 absl::StatusCode::kInvalidArgument);
202 EXPECT_THAT(encoded_extension.status().message(),
203 ::testing::HasSubstr("Failed to generate extension encoding"));
204 }
205
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,ExtensionEncodingSuccess)206 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, ExtensionEncodingSuccess) {
207 std::string extension_value;
208 ASSERT_TRUE(absl::HexStringToBytes(
209 "46a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129b88c92ad61c08a9fe416"
210 "29a642263e4857e428a706ba87659361fed38087c0e881f5e15668e0701d7edd63be98fc"
211 "c7415819d466c61341de03d7e2a24181d7b9321b0826d59402a87e08514f36cc45b0f7a"
212 "a",
213 &extension_value));
214 Extension extension = {
215 // Random hex number to populate the uint16_t extension_type.
216 /*extension_type=*/0x5E6D,
217 // Random hex string to populate extension_value.
218 std::move(extension_value)};
219 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_extension,
220 EncodeExtension(extension));
221 // The first 2 bytes of the expected_extension_encoding store the
222 // extension_type. The next two bytes store the number of bytes needed for the
223 // extension_value. These 4 bytes are then prefixed to the extension_value.
224 std::string expected_extension_encoding;
225 ASSERT_TRUE(absl::HexStringToBytes(
226 "5e6d006c46a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129b88c92ad61c0"
227 "8a9fe41629a642263e4857e428a706ba87659361fed38087c0e881f5e15668e0701d7edd"
228 "63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d59402a87e08514f36cc"
229 "45b0f7aa",
230 &expected_extension_encoding));
231 EXPECT_EQ(encoded_extension, expected_extension_encoding);
232 }
233
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,EmptyExtensionsTest)234 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, EmptyExtensionsTest) {
235 Extensions extensions;
236 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_extensions,
237 EncodeExtensions(extensions));
238
239 std::string expected_extensions_encoding;
240 ASSERT_TRUE(absl::HexStringToBytes("0000", &expected_extensions_encoding));
241 EXPECT_EQ(encoded_extensions, expected_extensions_encoding);
242 }
243
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,ExtensionsListSizeOfMoreThanTwoBytes)244 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
245 ExtensionsListSizeOfMoreThanTwoBytes) {
246 std::string large_test_value = std::string(65532, 'a');
247 Extensions extensions;
248 extensions.extensions.push_back(
249 {// Random hex number to populate the uint16_t extension_type.
250 /*extension_type=*/0x5E6D,
251 /*extension_value=*/large_test_value});
252 absl::StatusOr<std::string> encoded_extensions = EncodeExtensions(extensions);
253 // The string encoding of this extensions struct will take at least 65536
254 // bytes. This length is not be storable in 2 bytes.
255 EXPECT_EQ(encoded_extensions.status().code(),
256 absl::StatusCode::kInvalidArgument);
257 EXPECT_THAT(
258 encoded_extensions.status().message(),
259 ::testing::HasSubstr("Failed to generate encoded extensions list"));
260 }
261
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,SingleExtensionInExtensionsSuccess)262 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
263 SingleExtensionInExtensionsSuccess) {
264 std::string extension_value;
265 ASSERT_TRUE(absl::HexStringToBytes(
266 "46a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129b88c92ad61c08a9fe416"
267 "29a642263e4857e428a706ba87659361fed38087c0e881f5e15668e0701d7edd63be98fc"
268 "c7415819d466c61341de03d7e2a24181d7b9321b0826d59402a87e08514f36cc45b0f7a"
269 "a",
270 &extension_value));
271 Extensions extensions;
272 extensions.extensions.push_back(Extension{
273 // Random hex number to populate the uint16_t extension_type.
274 /*extension_type=*/0x5E6D,
275 // Random hex string to populate extension_value.
276 std::move(extension_value)});
277 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_extensions,
278 EncodeExtensions(extensions));
279 // The first 2 bytes of the expected_extensions_encoding store the length of
280 // the rest of the string. The rest of the string is the concatenation
281 // of individually encoded extensions.
282 std::string expected_extensions_encoding;
283 ASSERT_TRUE(absl::HexStringToBytes(
284 "00705e6d006c46a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129b88c92ad"
285 "61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881f5e15668e0701d"
286 "7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d59402a87e08514f"
287 "36cc45b0f7aa",
288 &expected_extensions_encoding));
289 EXPECT_EQ(encoded_extensions, expected_extensions_encoding);
290 }
291
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,MultipleExtensionsEncodingSuccess)292 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
293 MultipleExtensionsEncodingSuccess) {
294 std::string extension_value_1;
295 ASSERT_TRUE(absl::HexStringToBytes("01", &extension_value_1));
296 std::string extension_value_2;
297 ASSERT_TRUE(absl::HexStringToBytes("0202", &extension_value_2));
298 Extensions extensions;
299 extensions.extensions.push_back(
300 Extension{/*extension_type=*/0x0001, std::move(extension_value_1)});
301 extensions.extensions.push_back(
302 Extension{/*extension_type=*/0x0002, std::move(extension_value_2)});
303 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string encoded_extensions,
304 EncodeExtensions(extensions));
305 // The first 2 bytes of the expected_extensions_encoding store the length of
306 // the rest of the string. The rest of the string is the concatenation
307 // of individually encoded extensions.
308 std::string expected_extensions_encoding;
309 ASSERT_TRUE(absl::HexStringToBytes("000b0001000101000200020202",
310 &expected_extensions_encoding));
311 EXPECT_EQ(encoded_extensions, expected_extensions_encoding);
312 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extensions extensions2,
313 DecodeExtensions(encoded_extensions));
314 EXPECT_EQ(extensions2.extensions.size(), extensions.extensions.size());
315 for (size_t i = 0; i < extensions.extensions.size(); ++i) {
316 EXPECT_EQ(extensions2.extensions[i].extension_type,
317 extensions.extensions[i].extension_type);
318 EXPECT_EQ(extensions2.extensions[i].extension_value,
319 extensions.extensions[i].extension_value);
320 }
321 }
322
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,ExpirationTimestampRoundTrip)323 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
324 ExpirationTimestampRoundTrip) {
325 ExpirationTimestamp et{.timestamp_precision = 3600, .timestamp = 1688583600};
326 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, et.AsExtension());
327 EXPECT_EQ(ext.extension_type, 0x0001);
328 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const ExpirationTimestamp et2,
329 ExpirationTimestamp::FromExtension(ext));
330 EXPECT_EQ(et.timestamp_precision, et2.timestamp_precision);
331 EXPECT_EQ(et.timestamp, et2.timestamp);
332 }
333
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,ExpirationTimestampWrongType)334 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
335 ExpirationTimestampWrongType) {
336 const Extension ext = {.extension_type = 0x0002, .extension_value = ""};
337 EXPECT_FALSE(ExpirationTimestamp::FromExtension(ext).ok());
338 }
339
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,DecodeExtensions)340 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, DecodeExtensions) {
341 std::string encoded_extensions;
342 ASSERT_TRUE(absl::HexStringToBytes(
343 "0014000100100000000000000E100000000064A5BDB0", &encoded_extensions));
344 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extensions extensions,
345 DecodeExtensions(encoded_extensions));
346 EXPECT_EQ(extensions.extensions.size(), 1u);
347 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
348 const ExpirationTimestamp et,
349 ExpirationTimestamp::FromExtension(extensions.extensions[0]));
350 EXPECT_EQ(et.timestamp_precision, 3600u);
351 EXPECT_EQ(et.timestamp, 1688583600u);
352 Extensions extensions2;
353 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext2, et.AsExtension());
354 extensions2.extensions.push_back(ext2);
355 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string encoded_extensions2,
356 EncodeExtensions(extensions2));
357 EXPECT_EQ(absl::BytesToHexString(encoded_extensions2),
358 absl::BytesToHexString(encoded_extensions));
359 }
360
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,DecodeTooShort)361 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, DecodeTooShort) {
362 std::string encoded_extensions;
363 ASSERT_TRUE(absl::HexStringToBytes("00140001001000", &encoded_extensions));
364 const absl::StatusOr<Extensions> extensions =
365 DecodeExtensions(encoded_extensions);
366 EXPECT_FALSE(extensions.ok()) << extensions.status();
367 }
368
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,DecodeTooLong)369 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, DecodeTooLong) {
370 std::string encoded_extensions;
371 ASSERT_TRUE(absl::HexStringToBytes(
372 "0014000100100000000000000E100000000064A5BDB0123456",
373 &encoded_extensions));
374 const absl::StatusOr<Extensions> extensions =
375 DecodeExtensions(encoded_extensions);
376 EXPECT_FALSE(extensions.ok());
377 }
378
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,GeoHintRoundTrip)379 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, GeoHintRoundTrip) {
380 GeoHint gh{.geo_hint = "US,US-AL,ALABASTER"};
381 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, gh.AsExtension());
382 EXPECT_EQ(ext.extension_type, 0x0002);
383 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const GeoHint gh2,
384 GeoHint::FromExtension(ext));
385 EXPECT_EQ(gh.geo_hint, gh2.geo_hint);
386 EXPECT_EQ(gh2.country_code, "US");
387 EXPECT_EQ(gh2.region, "US-AL");
388 EXPECT_EQ(gh2.city, "ALABASTER");
389 }
390
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,GeoHintNoPostal)391 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, GeoHintNoPostal) {
392 GeoHint gh{.geo_hint = "US,US-AL,ALABASTER,FOO"};
393 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, gh.AsExtension());
394 EXPECT_FALSE(GeoHint::FromExtension(ext).ok());
395 }
396
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,GeoHintNoLowercase)397 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, GeoHintNoLowercase) {
398 GeoHint gh{.geo_hint = "US,US-AL,Alabaster"};
399 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, gh.AsExtension());
400 EXPECT_FALSE(GeoHint::FromExtension(ext).ok());
401 }
402
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,GeoHintTooShort)403 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, GeoHintTooShort) {
404 GeoHint gh{.geo_hint = "US,US-AL"};
405 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, gh.AsExtension());
406 EXPECT_FALSE(GeoHint::FromExtension(ext).ok());
407 }
408
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,GeoHintEmptyOk)409 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, GeoHintEmptyOk) {
410 GeoHint gh{.geo_hint = "US,,"};
411 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, gh.AsExtension());
412 EXPECT_TRUE(GeoHint::FromExtension(ext).ok());
413 }
414
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,ServiceTypeRoundTrip)415 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, ServiceTypeRoundTrip) {
416 ServiceType st{.service_type_id = 0x01};
417 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, st.AsExtension());
418 EXPECT_EQ(ext.extension_type, 0xF001);
419 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const ServiceType st2,
420 ServiceType::FromExtension(ext));
421 EXPECT_EQ(st.service_type_id, st2.service_type_id);
422 EXPECT_EQ(st2.service_type, "chromeipblinding");
423 }
424
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,WrongExtId)425 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, WrongExtId) {
426 ServiceType st{.service_type_id = 0x01};
427 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, st.AsExtension());
428 ext.extension_type = 0xF002;
429 EXPECT_FALSE(ServiceType::FromExtension(ext).ok());
430 }
431
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,WrongServiceTypeId)432 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, WrongServiceTypeId) {
433 ServiceType st{.service_type_id = 0x02};
434 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, st.AsExtension());
435 EXPECT_EQ(ext.extension_type, 0xF001);
436 EXPECT_FALSE(ServiceType::FromExtension(ext).ok());
437 }
438
TEST(AnonymousTokensDebugMode,RoundTrip)439 TEST(AnonymousTokensDebugMode, RoundTrip) {
440 DebugMode dm{.mode = DebugMode::kProd};
441 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, dm.AsExtension());
442 EXPECT_EQ(ext.extension_type, 0xF002);
443 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const DebugMode dm2,
444 DebugMode::FromExtension(ext));
445 EXPECT_EQ(dm.mode, dm2.mode);
446 }
447
TEST(AnonymousTokensDebugMode,WrongExtId)448 TEST(AnonymousTokensDebugMode, WrongExtId) {
449 DebugMode dm{.mode = DebugMode::kProd};
450 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, dm.AsExtension());
451 ext.extension_type = 0xF003;
452 EXPECT_FALSE(ServiceType::FromExtension(ext).ok());
453 }
454
TEST(AnonymousTokensDebugMode,InvalidMode)455 TEST(AnonymousTokensDebugMode, InvalidMode) {
456 DebugMode dm{.mode = DebugMode::kProd};
457 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, dm.AsExtension());
458 EXPECT_EQ(ext.extension_type, 0xF002);
459 ext.extension_value = std::string("~");
460 EXPECT_FALSE(DebugMode::FromExtension(ext).ok());
461 }
462
TEST(AnonymousTokensProxyLayer,RoundTripProxyA)463 TEST(AnonymousTokensProxyLayer, RoundTripProxyA) {
464 ProxyLayer pl{.layer = ProxyLayer::kProxyA};
465 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, pl.AsExtension());
466 EXPECT_EQ(ext.extension_type, 0xF003);
467 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const ProxyLayer pl2,
468 ProxyLayer::FromExtension(ext));
469 EXPECT_EQ(pl.layer, pl2.layer);
470 }
471
TEST(AnonymousTokensProxyLayer,RoundTripProxyB)472 TEST(AnonymousTokensProxyLayer, RoundTripProxyB) {
473 ProxyLayer pl{.layer = ProxyLayer::kProxyB};
474 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const Extension ext, pl.AsExtension());
475 EXPECT_EQ(ext.extension_type, 0xF003);
476 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const ProxyLayer pl2,
477 ProxyLayer::FromExtension(ext));
478 EXPECT_EQ(pl.layer, pl2.layer);
479 }
480
TEST(AnonymousTokensProxyLayer,WrongExtId)481 TEST(AnonymousTokensProxyLayer, WrongExtId) {
482 ProxyLayer pl{.layer = ProxyLayer::kProxyA};
483 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, pl.AsExtension());
484 ext.extension_type = 0xF004;
485 EXPECT_FALSE(ProxyLayer::FromExtension(ext).ok());
486 }
487
TEST(AnonymousTokensProxyLayer,InvalidLayer)488 TEST(AnonymousTokensProxyLayer, InvalidLayer) {
489 ProxyLayer pl{.layer = ProxyLayer::kProxyA};
490 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, pl.AsExtension());
491 EXPECT_EQ(ext.extension_type, 0xF003);
492 ext.extension_value = std::string("~");
493 EXPECT_FALSE(ProxyLayer::FromExtension(ext).ok());
494 }
495
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,EmptyMarshalTokenChallengeTest)496 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
497 EmptyMarshalTokenChallengeTest) {
498 TokenChallenge token_challenge;
499 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_token,
500 MarshalTokenChallenge(token_challenge));
501
502 std::string expected_token_encoding;
503 ASSERT_TRUE(absl::HexStringToBytes("DA7A0000", &expected_token_encoding));
504
505 EXPECT_EQ(encoded_token, expected_token_encoding);
506 }
507
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,MarshalTokenChallengeTest)508 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest, MarshalTokenChallengeTest) {
509 TokenChallenge token_challenge;
510 token_challenge.issuer_name = "issuer.google.com";
511 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_token,
512 MarshalTokenChallenge(token_challenge));
513
514 std::string expected_token_encoding;
515 ASSERT_TRUE(absl::HexStringToBytes(
516 "da7a00116973737565722e676f6f676c652e636f6d", &expected_token_encoding));
517
518 EXPECT_EQ(encoded_token, expected_token_encoding);
519 }
520
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,UnMarshalTokenRequestWrongTokenType)521 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
522 UnMarshalTokenRequestWrongTokenType) {
523 std::string token_request_encoding;
524 ASSERT_TRUE(absl::HexStringToBytes(
525 "1234124ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560"
526 "5686200d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bb"
527 "ae7129b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881"
528 "f5e15668e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d5"
529 "9402a87e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f"
530 "5c27d01ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac"
531 "1f8f611029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000a"
532 "e105483941652e",
533 &token_request_encoding));
534 absl::StatusOr<TokenRequest> token_request =
535 UnmarshalTokenRequest(token_request_encoding);
536
537 EXPECT_EQ(token_request.status().code(), absl::StatusCode::kInvalidArgument);
538 EXPECT_THAT(token_request.status().message(),
539 ::testing::HasSubstr("unsupported token type"));
540 }
541
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,UnMarshalTokenRequestBlindedRequestTooShort)542 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
543 UnMarshalTokenRequestBlindedRequestTooShort) {
544 std::string token_request_encoding;
545 ASSERT_TRUE(absl::HexStringToBytes(
546 "DA7A124ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560"
547 "5686200d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bb"
548 "ae7129b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881"
549 "f5e15668e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d5"
550 "9402a87e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f"
551 "5c27d01ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac"
552 "1f8f611029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000"
553 "a",
554 &token_request_encoding));
555 absl::StatusOr<TokenRequest> token_request =
556 UnmarshalTokenRequest(token_request_encoding);
557
558 EXPECT_EQ(token_request.status().code(), absl::StatusCode::kInvalidArgument);
559 EXPECT_THAT(token_request.status().message(),
560 ::testing::HasSubstr("failed to read blinded_token_request"));
561 }
562
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,UnMarshalTokenRequestBlindedRequestTooLong)563 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
564 UnMarshalTokenRequestBlindedRequestTooLong) {
565 std::string token_request_encoding;
566 ASSERT_TRUE(absl::HexStringToBytes(
567 "DA7A124ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560"
568 "5686200d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bb"
569 "ae7129b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881"
570 "f5e15668e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d5"
571 "9402a87e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f"
572 "5c27d01ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac"
573 "1f8f611029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000a"
574 "e105483941652ea5cc6f2c4143474e458c8d2ca8e9aa",
575 &token_request_encoding));
576 absl::StatusOr<TokenRequest> token_request =
577 UnmarshalTokenRequest(token_request_encoding);
578
579 EXPECT_EQ(token_request.status().code(), absl::StatusCode::kInvalidArgument);
580 EXPECT_THAT(token_request.status().message(),
581 ::testing::HasSubstr("token request had extra bytes"));
582 }
583
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,MarshalAndUnmarshalTokenRequest)584 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
585 MarshalAndUnmarshalTokenRequest) {
586 std::string blinded_token_request;
587 ASSERT_TRUE(absl::HexStringToBytes(
588 "4ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560568620"
589 "0d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129"
590 "b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881f5e156"
591 "68e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d59402a8"
592 "7e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f5c27d0"
593 "1ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac1f8f61"
594 "1029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000ae10548"
595 "3941652e",
596 &blinded_token_request));
597 TokenRequest token_request{
598 .token_type = 0xDA7A,
599 .truncated_token_key_id = 0x12,
600 .blinded_token_request = std::move(blinded_token_request)};
601 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string encoded_token_request,
602 MarshalTokenRequest(token_request));
603
604 std::string expected_token_request_encoding;
605 ASSERT_TRUE(absl::HexStringToBytes(
606 "DA7A124ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560"
607 "5686200d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bb"
608 "ae7129b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881"
609 "f5e15668e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d5"
610 "9402a87e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f"
611 "5c27d01ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac"
612 "1f8f611029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000a"
613 "e105483941652e",
614 &expected_token_request_encoding));
615
616 EXPECT_EQ(encoded_token_request, expected_token_request_encoding);
617
618 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
619 TokenRequest decoded_token_request,
620 UnmarshalTokenRequest(encoded_token_request));
621
622 EXPECT_EQ(decoded_token_request.token_type, token_request.token_type);
623 EXPECT_EQ(decoded_token_request.truncated_token_key_id,
624 token_request.truncated_token_key_id);
625 EXPECT_EQ(decoded_token_request.blinded_token_request,
626 token_request.blinded_token_request);
627 }
628
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,UnmarshalExtendedTokenRequestTooShort)629 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
630 UnmarshalExtendedTokenRequestTooShort) {
631 std::string extended_token_request_encoding_1;
632 ASSERT_TRUE(absl::HexStringToBytes(
633 "DA7A124ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560"
634 "5686200d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bb"
635 "ae7129b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881"
636 "f5e15668e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d5"
637 "9402a87e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f"
638 "5c27d01ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac"
639 "1f8f611029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000a"
640 "e10548394165",
641 &extended_token_request_encoding_1));
642 std::string extended_token_request_encoding_2;
643 ASSERT_TRUE(absl::HexStringToBytes(
644 "DA7A124ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560"
645 "5686200d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bb"
646 "ae7129b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881"
647 "f5e15668e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d5"
648 "9402a87e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f"
649 "5c27d01ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac"
650 "1f8f611029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000a"
651 "e105483941652e",
652 &extended_token_request_encoding_2));
653
654 absl::StatusOr<ExtendedTokenRequest> decoded_extended_token_request_1 =
655 UnmarshalExtendedTokenRequest(extended_token_request_encoding_1);
656 absl::StatusOr<ExtendedTokenRequest> decoded_extended_token_request_2 =
657 UnmarshalExtendedTokenRequest(extended_token_request_encoding_2);
658
659 EXPECT_EQ(decoded_extended_token_request_1.status().code(),
660 absl::StatusCode::kInvalidArgument);
661 EXPECT_THAT(decoded_extended_token_request_1.status().message(),
662 ::testing::HasSubstr("failed to read encoded_token_request"));
663 EXPECT_EQ(decoded_extended_token_request_2.status().code(),
664 absl::StatusCode::kInvalidArgument);
665 EXPECT_THAT(decoded_extended_token_request_2.status().message(),
666 ::testing::HasSubstr("failed to read extensions."));
667 }
668
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,UnmarshalExtendedTokenRequestTooLong)669 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
670 UnmarshalExtendedTokenRequestTooLong) {
671 std::string extended_token_request_encoding;
672 ASSERT_TRUE(absl::HexStringToBytes(
673 "DA7A124ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560"
674 "5686200d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bb"
675 "ae7129b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881"
676 "f5e15668e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d5"
677 "9402a87e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f"
678 "5c27d01ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac"
679 "1f8f611029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000a"
680 "e105483941652e000b0001000101000200020202DA",
681 &extended_token_request_encoding));
682
683 absl::StatusOr<ExtendedTokenRequest> decoded_extended_token_request =
684 UnmarshalExtendedTokenRequest(extended_token_request_encoding);
685
686 EXPECT_EQ(decoded_extended_token_request.status().code(),
687 absl::StatusCode::kInvalidArgument);
688 EXPECT_THAT(decoded_extended_token_request.status().message(),
689 ::testing::HasSubstr("no data after extensions is allowed"));
690 }
691
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,MarshalAndUnmarshalExtendedTokenRequest)692 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
693 MarshalAndUnmarshalExtendedTokenRequest) {
694 std::string blinded_token_request;
695 ASSERT_TRUE(absl::HexStringToBytes(
696 "4ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560568620"
697 "0d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bbae7129"
698 "b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881f5e156"
699 "68e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d59402a8"
700 "7e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f5c27d0"
701 "1ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac1f8f61"
702 "1029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000ae10548"
703 "3941652e",
704 &blinded_token_request));
705 TokenRequest token_request{
706 .token_type = 0xDA7A,
707 .truncated_token_key_id = 0x12,
708 .blinded_token_request = std::move(blinded_token_request)};
709 std::string extension_value_1;
710 ASSERT_TRUE(absl::HexStringToBytes("01", &extension_value_1));
711 std::string extension_value_2;
712 ASSERT_TRUE(absl::HexStringToBytes("0202", &extension_value_2));
713 Extensions extensions;
714 extensions.extensions.push_back(
715 Extension{/*extension_type=*/0x0001, std::move(extension_value_1)});
716 extensions.extensions.push_back(
717 Extension{/*extension_type=*/0x0002, std::move(extension_value_2)});
718 ExtendedTokenRequest extended_token_request{token_request, extensions};
719
720 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
721 std::string encoded_extended_token_request,
722 MarshalExtendedTokenRequest(extended_token_request));
723
724 std::string expected_extended_token_request_encoding;
725 ASSERT_TRUE(absl::HexStringToBytes(
726 "DA7A124ed3f2a25ec528543d9a83c850d12b3036b518fafec080df3efcd9693b944d0560"
727 "5686200d6500f249475737ea9246a70c3c2a1ff280663e46c792a8ae0d9a6877d1b427bb"
728 "ae7129b88c92ad61c08a9fe41629a642263e4857e428a706ba87659361fed38087c0e881"
729 "f5e15668e0701d7edd63be98fcc7415819d466c61341de03d7e2a24181d7b9321b0826d5"
730 "9402a87e08514f36cc45b0f7aac0e9a6578ddb0534c8ebe528c693b6efb54e76a5a8056f"
731 "5c27d01ad42119953c5987b05c9ae2ca04b12838e641b4b1aac21e36f18573f603735fac"
732 "1f8f611029e4cb76c8a5cc6f2c4143474e458c8d2ca8e9a71f01d90e0d2d784874ff000a"
733 "e105483941652e000b0001000101000200020202",
734 &expected_extended_token_request_encoding));
735
736 EXPECT_EQ(encoded_extended_token_request,
737 expected_extended_token_request_encoding);
738
739 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
740 ExtendedTokenRequest decoded_extended_token_request,
741 UnmarshalExtendedTokenRequest(encoded_extended_token_request));
742
743 EXPECT_EQ(decoded_extended_token_request.request.token_type,
744 token_request.token_type);
745 EXPECT_EQ(decoded_extended_token_request.request.truncated_token_key_id,
746 token_request.truncated_token_key_id);
747 EXPECT_EQ(decoded_extended_token_request.request.blinded_token_request,
748 token_request.blinded_token_request);
749 EXPECT_EQ(decoded_extended_token_request.extensions.extensions.size(),
750 extensions.extensions.size());
751 for (size_t i = 0; i < extensions.extensions.size(); ++i) {
752 EXPECT_EQ(
753 decoded_extended_token_request.extensions.extensions[i].extension_type,
754 extensions.extensions[i].extension_type);
755 EXPECT_EQ(
756 decoded_extended_token_request.extensions.extensions[i].extension_value,
757 extensions.extensions[i].extension_value);
758 }
759 }
760
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,ValidateExtensionsValuesTest)761 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
762 ValidateExtensionsValuesTest) {
763 Extensions extensions;
764 EXPECT_TRUE(ValidateExtensionsValues(extensions, absl::Now()).ok());
765
766 ExpirationTimestamp et;
767 absl::Time one_day_away = absl::Now() + absl::Hours(24);
768 et.timestamp = absl::ToUnixSeconds(one_day_away);
769 et.timestamp -= et.timestamp % 900;
770 et.timestamp_precision = 900;
771 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, et.AsExtension());
772 extensions.extensions.push_back(ext);
773 EXPECT_TRUE(ValidateExtensionsValues(extensions, absl::Now()).ok());
774
775 GeoHint gh;
776 gh.geo_hint = "US,US-AL,ALABASTER";
777 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(ext, gh.AsExtension());
778 extensions.extensions.push_back(ext);
779 EXPECT_TRUE(ValidateExtensionsValues(extensions, absl::Now()).ok());
780
781 ServiceType svc;
782 svc.service_type_id = ServiceType::kChromeIpBlinding;
783 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(ext, svc.AsExtension());
784 extensions.extensions.push_back(ext);
785 EXPECT_TRUE(ValidateExtensionsValues(extensions, absl::Now()).ok());
786
787 DebugMode debug;
788 debug.mode = DebugMode::kDebug;
789 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(ext, debug.AsExtension());
790 extensions.extensions.push_back(ext);
791 EXPECT_TRUE(ValidateExtensionsValues(extensions, absl::Now()).ok());
792
793 ProxyLayer proxy_layer;
794 proxy_layer.layer = ProxyLayer::kProxyA;
795 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(ext, proxy_layer.AsExtension());
796 extensions.extensions.push_back(ext);
797 EXPECT_TRUE(ValidateExtensionsValues(extensions, absl::Now()).ok());
798 }
799
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,NotRoundedExpirationExtensionValidationTest)800 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
801 NotRoundedExpirationExtensionValidationTest) {
802 Extensions extensions;
803 EXPECT_TRUE(ValidateExtensionsValues(extensions, absl::Now()).ok());
804
805 ExpirationTimestamp et;
806 absl::Time one_day_away = absl::Now() + absl::Hours(24);
807 et.timestamp = absl::ToUnixSeconds(one_day_away);
808 et.timestamp -= et.timestamp % 900;
809 et.timestamp += 17;
810 et.timestamp_precision = 900;
811 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, et.AsExtension());
812 extensions.extensions.push_back(ext);
813 EXPECT_EQ(ValidateExtensionsValues(extensions, absl::Now()).code(),
814 absl::StatusCode::kInvalidArgument);
815 }
816
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,BadPrecisionExpirationExtensionValidationTest)817 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
818 BadPrecisionExpirationExtensionValidationTest) {
819 Extensions extensions;
820 EXPECT_TRUE(ValidateExtensionsValues(extensions, absl::Now()).ok());
821
822 ExpirationTimestamp et;
823 absl::Time one_day_away = absl::Now() + absl::Hours(24);
824 et.timestamp = absl::ToUnixSeconds(one_day_away);
825 et.timestamp -= et.timestamp % 2;
826 et.timestamp_precision = 2;
827 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, et.AsExtension());
828 extensions.extensions.push_back(ext);
829 EXPECT_EQ(ValidateExtensionsValues(extensions, absl::Now()).code(),
830 absl::StatusCode::kInvalidArgument);
831 }
832
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,MissingCountryGeoHintExtensionValidationTest)833 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
834 MissingCountryGeoHintExtensionValidationTest) {
835 Extensions extensions;
836 GeoHint gh;
837 gh.geo_hint = "US-AL,ALABASTER";
838 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, gh.AsExtension());
839 extensions.extensions.push_back(ext);
840 EXPECT_EQ(ValidateExtensionsValues(extensions, absl::Now()).code(),
841 absl::StatusCode::kInvalidArgument);
842 }
843
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,CountryLowercaseGeoHintExtensionValidationTest)844 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
845 CountryLowercaseGeoHintExtensionValidationTest) {
846 Extensions extensions;
847 GeoHint gh;
848 gh.geo_hint = "us,US-AL,ALABASTER";
849 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, gh.AsExtension());
850 extensions.extensions.push_back(ext);
851 EXPECT_EQ(ValidateExtensionsValues(extensions, absl::Now()).code(),
852 absl::StatusCode::kInvalidArgument);
853 }
854
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,NotCountryCodeGeoHintExtensionValidationTest)855 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
856 NotCountryCodeGeoHintExtensionValidationTest) {
857 Extensions extensions;
858 GeoHint gh;
859 gh.geo_hint = "USA,US-AL,ALABASTER";
860 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, gh.AsExtension());
861 extensions.extensions.push_back(ext);
862 EXPECT_EQ(ValidateExtensionsValues(extensions, absl::Now()).code(),
863 absl::StatusCode::kInvalidArgument);
864 }
865
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,RegionLowercaseGeoHintExtensionValidationTest)866 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
867 RegionLowercaseGeoHintExtensionValidationTest) {
868 Extensions extensions;
869 GeoHint gh;
870 gh.geo_hint = "US,US-al,ALABASTER";
871 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, gh.AsExtension());
872 extensions.extensions.push_back(ext);
873 EXPECT_EQ(ValidateExtensionsValues(extensions, absl::Now()).code(),
874 absl::StatusCode::kInvalidArgument);
875 }
876
TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,ValidateExtensionsOrderAndValuesTest)877 TEST(AnonymousTokensPrivacyPassTokenEncodingsTest,
878 ValidateExtensionsOrderAndValuesTest) {
879 Extensions extensions;
880 std::vector<uint16_t> expected_types;
881 EXPECT_TRUE(ValidateExtensionsOrderAndValues(
882 extensions, absl::MakeSpan(expected_types), absl::Now())
883 .ok());
884
885 ExpirationTimestamp et;
886 absl::Time one_day_away = absl::Now() + absl::Hours(24);
887 et.timestamp = absl::ToUnixSeconds(one_day_away);
888 et.timestamp -= et.timestamp % 900;
889 et.timestamp_precision = 900;
890 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(Extension ext, et.AsExtension());
891 extensions.extensions.push_back(ext);
892 expected_types.push_back(0x0001);
893 EXPECT_TRUE(ValidateExtensionsOrderAndValues(
894 extensions, absl::MakeSpan(expected_types), absl::Now())
895 .ok());
896
897 expected_types.push_back(0x0002);
898 EXPECT_FALSE(ValidateExtensionsOrderAndValues(
899 extensions, absl::MakeSpan(expected_types), absl::Now())
900 .ok());
901
902 GeoHint gh;
903 gh.geo_hint = "US,US-AL,ALABASTER";
904 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(ext, gh.AsExtension());
905 extensions.extensions.push_back(ext);
906 EXPECT_TRUE(ValidateExtensionsOrderAndValues(
907 extensions, absl::MakeSpan(expected_types), absl::Now())
908 .ok());
909
910 expected_types.clear();
911 EXPECT_FALSE(ValidateExtensionsOrderAndValues(
912 extensions, absl::MakeSpan(expected_types), absl::Now())
913 .ok());
914
915 expected_types.push_back(0x0002);
916 expected_types.push_back(0x0001);
917 EXPECT_FALSE(ValidateExtensionsOrderAndValues(
918 extensions, absl::MakeSpan(expected_types), absl::Now())
919 .ok());
920 }
921
922 } // namespace
923 } // namespace anonymous_tokens
924