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