1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/device_bound_sessions/device_bound_session_registration_fetcher_param.h"
6
7 #include <optional>
8
9 #include "base/strings/strcat.h"
10 #include "base/test/bind.h"
11 #include "base/test/task_environment.h"
12 #include "crypto/signature_verifier.h"
13 #include "net/http/http_response_headers.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 #include "net/http/structured_headers.h"
18
19 namespace net {
20 namespace {
21
22 constexpr char kChallenge[] = ":Y2hhbGxlbmdl:";
23 constexpr char kDecodedChallenge[] = "challenge";
24 using crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256;
25 using crypto::SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256;
26 using ::testing::UnorderedElementsAre;
27
CreateHeaders(std::optional<std::string> path,std::optional<std::string> algs,std::optional<std::string> challenge)28 scoped_refptr<net::HttpResponseHeaders> CreateHeaders(
29 std::optional<std::string> path,
30 std::optional<std::string> algs,
31 std::optional<std::string> challenge) {
32 std::string path_string = path ? base::StrCat({"\"", *path, "\"", "; "}) : "";
33 std::string algs_string =
34 (algs && !algs->empty()) ? base::StrCat({*algs, "; "}) : "";
35 std::string challenge_string =
36 challenge ? base::StrCat({"challenge=", *challenge}) : "";
37 std::string full_string =
38 base::StrCat({path_string, algs_string, challenge_string});
39 return HttpResponseHeaders::Builder({1, 1}, "200 OK")
40 .AddHeader("Sec-Session-Registration", full_string)
41 .Build();
42 }
43
TEST(DeviceBoundSessionRegistrationFetcherParamTest,BasicValid)44 TEST(DeviceBoundSessionRegistrationFetcherParamTest, BasicValid) {
45 GURL registration_request = GURL("https://www.example.com/registration");
46 scoped_refptr<net::HttpResponseHeaders> response_headers =
47 CreateHeaders("startsession", "es256;rs256", kChallenge);
48 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
49 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
50 registration_request, response_headers.get());
51 ASSERT_EQ(params.size(), 1U);
52 auto param = std::move(params[0]);
53 EXPECT_EQ(param.registration_endpoint(),
54 GURL("https://www.example.com/startsession"));
55 EXPECT_THAT(param.supported_algos(),
56 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
57 EXPECT_EQ(param.challenge(), kDecodedChallenge);
58 }
59
TEST(DeviceBoundSessionRegistrationFetcherParamTest,ExtraUnrecognizedAlgorithm)60 TEST(DeviceBoundSessionRegistrationFetcherParamTest,
61 ExtraUnrecognizedAlgorithm) {
62 GURL registration_request = GURL("https://www.example.com/registration");
63 scoped_refptr<net::HttpResponseHeaders> response_headers =
64 CreateHeaders("startsession", "es256;bf512", kChallenge);
65 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
66 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
67 registration_request, response_headers.get());
68 ASSERT_EQ(params.size(), 1U);
69 auto param = std::move(params[0]);
70 EXPECT_EQ(param.registration_endpoint(),
71 GURL("https://www.example.com/startsession"));
72 EXPECT_THAT(param.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
73 EXPECT_EQ(param.challenge(), kDecodedChallenge);
74 }
75
TEST(DeviceBoundSessionRegistrationFetcherParamTest,NoHeader)76 TEST(DeviceBoundSessionRegistrationFetcherParamTest, NoHeader) {
77 GURL registration_request = GURL("https://www.example.com/registration");
78 scoped_refptr<net::HttpResponseHeaders> response_headers =
79 base::MakeRefCounted<net::HttpResponseHeaders>("");
80 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
81 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
82 registration_request, response_headers.get());
83 ASSERT_TRUE(params.empty());
84 }
85
TEST(DeviceBoundSessionRegistrationFetcherParamTest,ChallengeFirst)86 TEST(DeviceBoundSessionRegistrationFetcherParamTest, ChallengeFirst) {
87 GURL registration_request = GURL("https://www.example.com/registration");
88 scoped_refptr<net::HttpResponseHeaders> response_headers =
89 base::MakeRefCounted<net::HttpResponseHeaders>("");
90 response_headers->SetHeader("Sec-Session-Registration",
91 base::StrCat({"\"startsession\";", "challenge=",
92 kChallenge, "; ", "rs256;es256"}));
93 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
94 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
95 registration_request, response_headers.get());
96 ASSERT_EQ(params.size(), 1U);
97 auto param = std::move(params[0]);
98 EXPECT_EQ(param.registration_endpoint(),
99 GURL("https://www.example.com/startsession"));
100 EXPECT_THAT(param.supported_algos(),
101 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
102 EXPECT_EQ(param.challenge(), kDecodedChallenge);
103 }
104
TEST(DeviceBoundSessionRegistrationFetcherParamTest,NoSpaces)105 TEST(DeviceBoundSessionRegistrationFetcherParamTest, NoSpaces) {
106 GURL registration_request = GURL("https://www.example.com/registration");
107 scoped_refptr<net::HttpResponseHeaders> response_headers =
108 base::MakeRefCounted<net::HttpResponseHeaders>("");
109 response_headers->SetHeader("Sec-Session-Registration",
110 base::StrCat({"\"startsession\";challenge=",
111 kChallenge, ";rs256;es256"}));
112 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
113 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
114 registration_request, response_headers.get());
115 ASSERT_EQ(params.size(), 1U);
116 auto param = std::move(params[0]);
117 EXPECT_EQ(param.registration_endpoint(),
118 GURL("https://www.example.com/startsession"));
119 EXPECT_THAT(param.supported_algos(),
120 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
121 EXPECT_EQ(param.challenge(), kDecodedChallenge);
122 }
123
TEST(DeviceBoundSessionRegistrationFetcherParamTest,TwoRegistrations)124 TEST(DeviceBoundSessionRegistrationFetcherParamTest, TwoRegistrations) {
125 GURL registration_request = GURL("https://www.example.com/registration");
126 scoped_refptr<net::HttpResponseHeaders> response_headers =
127 base::MakeRefCounted<net::HttpResponseHeaders>("");
128 response_headers->SetHeader("Sec-Session-Registration",
129 base::StrCat({"\"startsession\";challenge=",
130 kChallenge, ";rs256;es256"}));
131 response_headers->AddHeader("Sec-Session-Registration",
132 "\"new\";challenge=:Y29kZWQ=:;es256");
133 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
134 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
135 registration_request, response_headers.get());
136 ASSERT_EQ(params.size(), 2U);
137 auto p1 = std::move(params[0]);
138 EXPECT_EQ(p1.registration_endpoint(),
139 GURL("https://www.example.com/startsession"));
140 EXPECT_THAT(p1.supported_algos(),
141 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
142 EXPECT_EQ(p1.challenge(), kDecodedChallenge);
143
144 auto p2 = std::move(params[1]);
145 EXPECT_EQ(p2.registration_endpoint(), GURL("https://www.example.com/new"));
146 EXPECT_THAT(p2.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
147 EXPECT_EQ(p2.challenge(), "coded");
148 }
149
TEST(DeviceBoundSessionRegistrationFetcherParamTest,ValidInvalid)150 TEST(DeviceBoundSessionRegistrationFetcherParamTest, ValidInvalid) {
151 GURL registration_request = GURL("https://www.example.com/registration");
152 scoped_refptr<net::HttpResponseHeaders> response_headers =
153 base::MakeRefCounted<net::HttpResponseHeaders>("");
154 response_headers->SetHeader("Sec-Session-Registration",
155 base::StrCat({"\"startsession\";challenge=",
156 kChallenge, ";rs256;es256"}));
157 response_headers->AddHeader("Sec-Session-Registration",
158 "\"new\";challenge=:Y29kZWQ=:");
159 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
160 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
161 registration_request, response_headers.get());
162 ASSERT_EQ(params.size(), 1U);
163 auto p1 = std::move(params[0]);
164 EXPECT_EQ(p1.registration_endpoint(),
165 GURL("https://www.example.com/startsession"));
166 EXPECT_THAT(p1.supported_algos(),
167 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
168 EXPECT_EQ(p1.challenge(), kDecodedChallenge);
169 }
170
TEST(DeviceBoundSessionRegistrationFetcherParamTest,AddedNonsenseCharacters)171 TEST(DeviceBoundSessionRegistrationFetcherParamTest, AddedNonsenseCharacters) {
172 GURL registration_request = GURL("https://www.example.com/registration");
173 scoped_refptr<net::HttpResponseHeaders> response_headers =
174 base::MakeRefCounted<net::HttpResponseHeaders>("");
175 response_headers->AddHeader("Sec-Session-Registration",
176 "\"new\";challenge=:Y29kZWQ=:;rs256;;=;");
177 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
178 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
179 registration_request, response_headers.get());
180 ASSERT_TRUE(params.empty());
181 }
182
TEST(DeviceBoundSessionRegistrationFetcherParamTest,AlgAsString)183 TEST(DeviceBoundSessionRegistrationFetcherParamTest, AlgAsString) {
184 GURL registration_request = GURL("https://www.example.com/registration");
185 scoped_refptr<net::HttpResponseHeaders> response_headers =
186 base::MakeRefCounted<net::HttpResponseHeaders>("");
187 response_headers->AddHeader("Sec-Session-Registration",
188 "\"new\";challenge=:Y29kZWQ=:;\"rs256\"");
189 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
190 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
191 registration_request, response_headers.get());
192 ASSERT_TRUE(params.empty());
193 }
194
TEST(DeviceBoundSessionRegistrationFetcherParamTest,ChallengeAsString)195 TEST(DeviceBoundSessionRegistrationFetcherParamTest, ChallengeAsString) {
196 GURL registration_request = GURL("https://www.example.com/registration");
197 scoped_refptr<net::HttpResponseHeaders> response_headers =
198 base::MakeRefCounted<net::HttpResponseHeaders>("");
199 response_headers->AddHeader("Sec-Session-Registration",
200 "\"new\";challenge=\"Y29kZWQ=\";rs256");
201 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
202 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
203 registration_request, response_headers.get());
204 ASSERT_TRUE(params.empty());
205 }
206
TEST(DeviceBoundSessionRegistrationFetcherParamTest,ValidInvalidValid)207 TEST(DeviceBoundSessionRegistrationFetcherParamTest, ValidInvalidValid) {
208 GURL registration_request = GURL("https://www.example.com/registration");
209 scoped_refptr<net::HttpResponseHeaders> response_headers =
210 base::MakeRefCounted<net::HttpResponseHeaders>("");
211 response_headers->SetHeader("Sec-Session-Registration",
212 base::StrCat({"\"startsession\";challenge=",
213 kChallenge, ";rs256;es256"}));
214 response_headers->AddHeader("Sec-Session-Registration",
215 "\"new\";challenge=:Y29kZWQ=:");
216 response_headers->AddHeader("Sec-Session-Registration",
217 "\"new\";challenge=:Y29kZWQ=:;es256");
218 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
219 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
220 registration_request, response_headers.get());
221 ASSERT_EQ(params.size(), 2U);
222 auto p1 = std::move(params[0]);
223 EXPECT_EQ(p1.registration_endpoint(),
224 GURL("https://www.example.com/startsession"));
225 EXPECT_THAT(p1.supported_algos(),
226 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
227 EXPECT_EQ(p1.challenge(), kDecodedChallenge);
228
229 auto p2 = std::move(params[1]);
230 EXPECT_EQ(p2.registration_endpoint(), GURL("https://www.example.com/new"));
231 EXPECT_THAT(p2.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
232 EXPECT_EQ(p2.challenge(), "coded");
233 }
234
TEST(DeviceBoundSessionRegistrationFetcherParamTest,ThreeRegistrations)235 TEST(DeviceBoundSessionRegistrationFetcherParamTest, ThreeRegistrations) {
236 GURL registration_request = GURL("https://www.example.com/registration");
237 scoped_refptr<net::HttpResponseHeaders> response_headers =
238 base::MakeRefCounted<net::HttpResponseHeaders>("");
239 response_headers->SetHeader("Sec-Session-Registration",
240 base::StrCat({"\"startsession\";challenge=",
241 kChallenge, ";rs256;es256"}));
242 response_headers->AddHeader("Sec-Session-Registration",
243 "\"new\";challenge=:Y29kZWQ=:;es256");
244 response_headers->AddHeader("Sec-Session-Registration",
245 "\"third\";challenge=:YW5vdGhlcg==:;es256");
246 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
247 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
248 registration_request, response_headers.get());
249 ASSERT_EQ(params.size(), 3U);
250 auto p1 = std::move(params[0]);
251 EXPECT_EQ(p1.registration_endpoint(),
252 GURL("https://www.example.com/startsession"));
253 EXPECT_THAT(p1.supported_algos(),
254 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
255 EXPECT_EQ(p1.challenge(), kDecodedChallenge);
256
257 auto p2 = std::move(params[1]);
258 EXPECT_EQ(p2.registration_endpoint(), GURL("https://www.example.com/new"));
259 EXPECT_THAT(p2.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
260 EXPECT_EQ(p2.challenge(), "coded");
261
262 auto p3 = std::move(params[2]);
263 EXPECT_EQ(p3.registration_endpoint(), GURL("https://www.example.com/third"));
264 EXPECT_THAT(p3.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
265 EXPECT_EQ(p3.challenge(), "another");
266 }
267
TEST(DeviceBoundSessionRegistrationFetcherParamTest,ThreeRegistrationsList)268 TEST(DeviceBoundSessionRegistrationFetcherParamTest, ThreeRegistrationsList) {
269 GURL registration_request = GURL("https://www.example.com/registration");
270 scoped_refptr<net::HttpResponseHeaders> response_headers =
271 base::MakeRefCounted<net::HttpResponseHeaders>("");
272 response_headers->SetHeader("Sec-Session-Registration",
273 base::StrCat({"\"startsession\";challenge=",
274 kChallenge, ";rs256;es256"}));
275 response_headers->AddHeader("Sec-Session-Registration",
276 "\"new\";challenge=:Y29kZWQ=:;es256, "
277 "\"third\";challenge=:YW5vdGhlcg==:;es256");
278 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
279 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
280 registration_request, response_headers.get());
281 ASSERT_EQ(params.size(), 3U);
282 auto p1 = std::move(params[0]);
283 EXPECT_EQ(p1.registration_endpoint(),
284 GURL("https://www.example.com/startsession"));
285 EXPECT_THAT(p1.supported_algos(),
286 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
287 EXPECT_EQ(p1.challenge(), kDecodedChallenge);
288
289 auto p2 = std::move(params[1]);
290 EXPECT_EQ(p2.registration_endpoint(), GURL("https://www.example.com/new"));
291 EXPECT_THAT(p2.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
292 EXPECT_EQ(p2.challenge(), "coded");
293
294 auto p3 = std::move(params[2]);
295 EXPECT_EQ(p3.registration_endpoint(), GURL("https://www.example.com/third"));
296 EXPECT_THAT(p3.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
297 EXPECT_EQ(p3.challenge(), "another");
298 }
299
TEST(DeviceBoundSessionRegistrationFetcherParamTest,StartWithSlash)300 TEST(DeviceBoundSessionRegistrationFetcherParamTest, StartWithSlash) {
301 GURL registration_request = GURL("https://www.example.com/registration");
302 scoped_refptr<net::HttpResponseHeaders> response_headers =
303 CreateHeaders("/startsession", "es256;rs256", kChallenge);
304 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
305 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
306 registration_request, response_headers.get());
307 ASSERT_EQ(params.size(), 1U);
308 auto param = std::move(params[0]);
309 EXPECT_EQ(param.registration_endpoint(),
310 GURL("https://www.example.com/startsession"));
311 EXPECT_THAT(param.supported_algos(),
312 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
313 EXPECT_EQ(param.challenge(), kDecodedChallenge);
314 }
315
TEST(DeviceBoundSessionRegistrationFetcherParamTest,EscapeOnce)316 TEST(DeviceBoundSessionRegistrationFetcherParamTest, EscapeOnce) {
317 GURL registration_request = GURL("https://www.example.com/registration");
318 scoped_refptr<net::HttpResponseHeaders> response_headers =
319 CreateHeaders("/%2561", "es256;rs256", kChallenge);
320 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
321 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
322 registration_request, response_headers.get());
323 ASSERT_EQ(params.size(), 1U);
324 auto param = std::move(params[0]);
325 EXPECT_EQ(param.registration_endpoint(), GURL("https://www.example.com/%61"));
326 EXPECT_THAT(param.supported_algos(),
327 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
328 EXPECT_EQ(param.challenge(), kDecodedChallenge);
329 }
330
TEST(DeviceBoundSessionRegistrationFetcherParamTest,InvalidUrl)331 TEST(DeviceBoundSessionRegistrationFetcherParamTest, InvalidUrl) {
332 GURL registration_request = GURL("https://[/");
333 scoped_refptr<net::HttpResponseHeaders> response_headers =
334 CreateHeaders("[", "es256;rs256", kChallenge);
335 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
336 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
337 registration_request, response_headers.get());
338 ASSERT_EQ(params.size(), 0U);
339 }
340
TEST(DeviceBoundSessionRegistrationFetcherParamTest,HasUrlEncoded)341 TEST(DeviceBoundSessionRegistrationFetcherParamTest, HasUrlEncoded) {
342 GURL registration_request = GURL("https://www.example.com/registration");
343 scoped_refptr<net::HttpResponseHeaders> response_headers =
344 CreateHeaders("test%2Fstart", "es256;rs256", kChallenge);
345 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
346 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
347 registration_request, response_headers.get());
348 ASSERT_EQ(params.size(), 1U);
349 auto param = std::move(params[0]);
350 EXPECT_EQ(param.registration_endpoint(),
351 GURL("https://www.example.com/test/start"));
352 EXPECT_THAT(param.supported_algos(),
353 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
354 EXPECT_EQ(param.challenge(), kDecodedChallenge);
355 }
356
TEST(DeviceBoundSessionRegistrationFetcherParamTest,FullUrl)357 TEST(DeviceBoundSessionRegistrationFetcherParamTest, FullUrl) {
358 GURL registration_request = GURL("https://www.example.com/registration");
359 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
360 "https://accounts.example.com/startsession", "es256;rs256", kChallenge);
361 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
362 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
363 registration_request, response_headers.get());
364 ASSERT_EQ(params.size(), 1U);
365 auto param = std::move(params[0]);
366 EXPECT_EQ(param.registration_endpoint(),
367 GURL("https://accounts.example.com/startsession"));
368 EXPECT_THAT(param.supported_algos(),
369 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
370 EXPECT_EQ(param.challenge(), kDecodedChallenge);
371 }
372
TEST(DeviceBoundSessionRegistrationFetcherParamTest,SwapAlgo)373 TEST(DeviceBoundSessionRegistrationFetcherParamTest, SwapAlgo) {
374 GURL registration_request = GURL("https://www.example.com/registration");
375 scoped_refptr<net::HttpResponseHeaders> response_headers =
376 CreateHeaders("startsession", "es256;rs256", kChallenge);
377 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
378 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
379 registration_request, response_headers.get());
380 ASSERT_EQ(params.size(), 1U);
381 auto param = std::move(params[0]);
382 EXPECT_EQ(param.registration_endpoint(),
383 GURL("https://www.example.com/startsession"));
384 EXPECT_THAT(param.supported_algos(),
385 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
386 EXPECT_EQ(param.challenge(), kDecodedChallenge);
387 }
388
TEST(DeviceBoundSessionRegistrationFetcherParamTest,OneAlgo)389 TEST(DeviceBoundSessionRegistrationFetcherParamTest, OneAlgo) {
390 GURL registration_request = GURL("https://www.example.com/registration");
391 scoped_refptr<net::HttpResponseHeaders> response_headers =
392 CreateHeaders("startsession", "rs256", kChallenge);
393 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
394 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
395 registration_request, response_headers.get());
396 ASSERT_EQ(params.size(), 1U);
397 auto param = std::move(params[0]);
398 EXPECT_EQ(param.registration_endpoint(),
399 GURL("https://www.example.com/startsession"));
400 ASSERT_THAT(param.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
401 EXPECT_EQ(param.challenge(), kDecodedChallenge);
402 }
403
TEST(DeviceBoundSessionRegistrationFetcherParamTest,AddedParameter)404 TEST(DeviceBoundSessionRegistrationFetcherParamTest, AddedParameter) {
405 GURL registration_request = GURL("https://www.example.com/registration");
406 scoped_refptr<net::HttpResponseHeaders> response_headers =
407 CreateHeaders("startsession", "rs256;lolcat", kChallenge);
408 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
409 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
410 registration_request, response_headers.get());
411 ASSERT_EQ(params.size(), 1U);
412 auto param = std::move(params[0]);
413 EXPECT_EQ(param.registration_endpoint(),
414 GURL("https://www.example.com/startsession"));
415 ASSERT_THAT(param.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
416 EXPECT_EQ(param.challenge(), kDecodedChallenge);
417 }
418
TEST(DeviceBoundSessionRegistrationFetcherParamTest,InvalidInputs)419 TEST(DeviceBoundSessionRegistrationFetcherParamTest, InvalidInputs) {
420 struct Input {
421 std::string request_url;
422 std::optional<std::string> path;
423 std::optional<std::string> algos;
424 std::optional<std::string> challenge;
425 };
426
427 const Input kInvalidInputs[] = {
428 // All invalid
429 {"https://www.example.com/reg", "", "", ""},
430 // All missing
431 {"https://www.example.com/reg", std::nullopt, std::nullopt, std::nullopt},
432 // All valid different Url
433 {"https://www.example.com/registration",
434 "https://accounts.different.url/startsession", "rs256", kChallenge},
435 // Empty request Url
436 {"", "start", "rs256", kChallenge},
437 // Empty algo
438 {"https://www.example.com/reg", "start", "", kChallenge},
439 // Missing algo
440 {"https://www.example.com/reg", "start", std::nullopt, kChallenge},
441 // Missing registration
442 {"https://www.example.com/reg", std::nullopt, "es256;rs256", kChallenge},
443 // Missing challenge
444 {"https://www.example.com/reg", "start", "es256;rs256", std::nullopt},
445 // Empty challenge
446 {"https://www.example.com/reg", "start", "es256;rs256", ""},
447 // Challenge invalid utf8
448 {"https://www.example.com/reg", "start", "es256;rs256", "ab\xC0\x80"}};
449
450 for (const auto& input : kInvalidInputs) {
451 GURL registration_request = GURL(input.request_url);
452 scoped_refptr<net::HttpResponseHeaders> response_headers =
453 CreateHeaders(input.path, input.algos, input.challenge);
454 SCOPED_TRACE(registration_request.spec() + "; " +
455 response_headers->raw_headers());
456 std::vector<DeviceBoundSessionRegistrationFetcherParam> params =
457 DeviceBoundSessionRegistrationFetcherParam::CreateIfValid(
458 registration_request, response_headers.get());
459 EXPECT_TRUE(params.empty());
460 }
461 }
462
463 } // namespace
464 } // namespace net
465