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/registration_fetcher_param.h"
6
7 #include <optional>
8
9 #include "base/strings/strcat.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/test/bind.h"
12 #include "base/test/task_environment.h"
13 #include "crypto/signature_verifier.h"
14 #include "net/http/http_response_headers.h"
15 #include "net/http/structured_headers.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace net::device_bound_sessions {
20
21 namespace {
22
23 constexpr char kRegistrationHeader[] = "Sec-Session-Registration";
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,std::optional<std::string> authorization,scoped_refptr<net::HttpResponseHeaders> headers=nullptr)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::optional<std::string> authorization,
33 scoped_refptr<net::HttpResponseHeaders> headers = nullptr) {
34 const std::string algs_string = (algs && !algs->empty()) ? *algs : "()";
35 const std::string path_string =
36 path ? base::StrCat({";path=\"", *path, "\""}) : "";
37 const std::string challenge_string =
38 challenge ? base::StrCat({";challenge=\"", *challenge, "\""}) : "";
39 std::string authorization_string;
40 if (authorization) {
41 authorization_string =
42 base::StrCat({";authorization=\"", *authorization, "\""});
43 }
44 const std::string full_string = base::StrCat(
45 {algs_string, path_string, challenge_string, authorization_string});
46
47 if (!headers) {
48 headers = HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
49 }
50 headers->AddHeader(kRegistrationHeader, full_string);
51
52 return headers;
53 }
54
TEST(RegistrationFetcherParamTest,BasicValid)55 TEST(RegistrationFetcherParamTest, BasicValid) {
56 const GURL registration_request("https://www.example.com/registration");
57 scoped_refptr<net::HttpResponseHeaders> response_headers =
58 CreateHeaders("startsession", "(ES256 RS256)", "c1", "auth");
59 std::vector<RegistrationFetcherParam> params =
60 RegistrationFetcherParam::CreateIfValid(registration_request,
61 response_headers.get());
62 ASSERT_EQ(params.size(), 1U);
63 const auto& param = params[0];
64 EXPECT_EQ(param.registration_endpoint(),
65 GURL("https://www.example.com/startsession"));
66 EXPECT_THAT(param.supported_algos(),
67 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
68 EXPECT_EQ(param.challenge(), "c1");
69 EXPECT_EQ(param.authorization(), "auth");
70 }
71
TEST(RegistrationFetcherParamTest,ExtraUnrecognizedAlgorithm)72 TEST(RegistrationFetcherParamTest, ExtraUnrecognizedAlgorithm) {
73 const GURL registration_request("https://www.example.com/registration");
74 scoped_refptr<net::HttpResponseHeaders> response_headers =
75 CreateHeaders("startsession", "(ES256 bf512)", "c1", "auth");
76 std::vector<RegistrationFetcherParam> params =
77 RegistrationFetcherParam::CreateIfValid(registration_request,
78 response_headers.get());
79 ASSERT_EQ(params.size(), 1U);
80 const auto& param = params[0];
81 EXPECT_EQ(param.registration_endpoint(),
82 GURL("https://www.example.com/startsession"));
83 EXPECT_THAT(param.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
84 EXPECT_EQ(param.challenge(), "c1");
85 EXPECT_EQ(param.authorization(), "auth");
86 }
87
TEST(RegistrationFetcherParamTest,NoHeader)88 TEST(RegistrationFetcherParamTest, NoHeader) {
89 const GURL registration_request("https://www.example.com/registration");
90 scoped_refptr<net::HttpResponseHeaders> response_headers =
91 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
92 std::vector<RegistrationFetcherParam> params =
93 RegistrationFetcherParam::CreateIfValid(registration_request,
94 response_headers.get());
95 ASSERT_TRUE(params.empty());
96 }
97
TEST(RegistrationFetcherParamTest,ChallengeFirst)98 TEST(RegistrationFetcherParamTest, ChallengeFirst) {
99 const GURL registration_request("https://www.example.com/registration");
100 // Testing customized header.
101 scoped_refptr<net::HttpResponseHeaders> response_headers =
102 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
103 response_headers->SetHeader(
104 kRegistrationHeader,
105 "(RS256 ES256);challenge=\"challenge1\";path=\"first\"");
106
107 std::vector<RegistrationFetcherParam> params =
108 RegistrationFetcherParam::CreateIfValid(registration_request,
109 response_headers.get());
110 ASSERT_EQ(params.size(), 1U);
111 const auto& param = params[0];
112 EXPECT_EQ(param.registration_endpoint(),
113 GURL("https://www.example.com/first"));
114 EXPECT_THAT(param.supported_algos(),
115 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
116 EXPECT_EQ(param.challenge(), "challenge1");
117 }
118
TEST(RegistrationFetcherParamTest,NoSpaces)119 TEST(RegistrationFetcherParamTest, NoSpaces) {
120 const GURL registration_request("https://www.example.com/registration");
121 // Testing customized header.
122 scoped_refptr<net::HttpResponseHeaders> response_headers =
123 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
124 response_headers->SetHeader(
125 kRegistrationHeader,
126 "(RS256 ES256);path=\"startsession\";challenge=\"challenge1\"");
127 std::vector<RegistrationFetcherParam> params =
128 RegistrationFetcherParam::CreateIfValid(registration_request,
129 response_headers.get());
130 ASSERT_EQ(params.size(), 1U);
131 const auto& param = params[0];
132 EXPECT_EQ(param.registration_endpoint(),
133 GURL("https://www.example.com/startsession"));
134 EXPECT_THAT(param.supported_algos(),
135 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
136 EXPECT_EQ(param.challenge(), "challenge1");
137 }
138
TEST(RegistrationFetcherParamTest,TwoRegistrations)139 TEST(RegistrationFetcherParamTest, TwoRegistrations) {
140 const GURL registration_request("https://www.example.com/registration");
141 scoped_refptr<net::HttpResponseHeaders> response_headers =
142 CreateHeaders("/first", "(ES256 RS256)", "c1", "auth1");
143 CreateHeaders("/second", "(ES256)", "challenge2", "auth2", response_headers);
144 std::vector<RegistrationFetcherParam> params =
145 RegistrationFetcherParam::CreateIfValid(registration_request,
146 response_headers.get());
147 ASSERT_EQ(params.size(), 2U);
148 const auto& p1 = params[0];
149 EXPECT_EQ(p1.registration_endpoint(), GURL("https://www.example.com/first"));
150 EXPECT_THAT(p1.supported_algos(),
151 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
152 EXPECT_EQ(p1.challenge(), "c1");
153 EXPECT_EQ(p1.authorization(), "auth1");
154
155 const auto& p2 = params[1];
156 EXPECT_EQ(p2.registration_endpoint(), GURL("https://www.example.com/second"));
157 EXPECT_THAT(p2.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
158 EXPECT_EQ(p2.challenge(), "challenge2");
159 EXPECT_EQ(p2.authorization(), "auth2");
160 }
161
TEST(RegistrationFetcherParamTest,ValidInvalid)162 TEST(RegistrationFetcherParamTest, ValidInvalid) {
163 const GURL registration_request("https://www.example.com/registration");
164 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
165 "/first", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
166 CreateHeaders("/second", "(es256)", "challenge2", "auth2", response_headers);
167 std::vector<RegistrationFetcherParam> params =
168 RegistrationFetcherParam::CreateIfValid(registration_request,
169 response_headers.get());
170 ASSERT_EQ(params.size(), 1U);
171 const auto& p1 = params[0];
172 EXPECT_EQ(p1.registration_endpoint(), GURL("https://www.example.com/first"));
173 EXPECT_THAT(p1.supported_algos(),
174 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
175 EXPECT_EQ(p1.challenge(), "c1");
176 EXPECT_FALSE(p1.authorization());
177 }
178
TEST(RegistrationFetcherParamTest,AddedInvalidNonsenseCharacters)179 TEST(RegistrationFetcherParamTest, AddedInvalidNonsenseCharacters) {
180 const GURL registration_request("https://www.example.com/registration");
181 // Testing customized header.
182 scoped_refptr<net::HttpResponseHeaders> response_headers =
183 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
184 response_headers->AddHeader(kRegistrationHeader,
185 "(RS256);path=\"new\";challenge=\"test\";;=;");
186 std::vector<RegistrationFetcherParam> params =
187 RegistrationFetcherParam::CreateIfValid(registration_request,
188 response_headers.get());
189 ASSERT_TRUE(params.empty());
190 }
191
TEST(RegistrationFetcherParamTest,AddedValidNonsenseCharacters)192 TEST(RegistrationFetcherParamTest, AddedValidNonsenseCharacters) {
193 const GURL registration_request("https://www.example.com/registration");
194 // Testing customized header.
195 scoped_refptr<net::HttpResponseHeaders> response_headers =
196 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
197 response_headers->AddHeader(
198 kRegistrationHeader,
199 "(RS256);path=\"new\";challenge=\"test\";nonsense=\";';'\",OTHER");
200 std::vector<RegistrationFetcherParam> params =
201 RegistrationFetcherParam::CreateIfValid(registration_request,
202 response_headers.get());
203 ASSERT_EQ(params.size(), 1U);
204 const auto& p1 = params[0];
205 EXPECT_EQ(p1.registration_endpoint(), GURL("https://www.example.com/new"));
206 EXPECT_THAT(p1.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
207 EXPECT_EQ(p1.challenge(), "test");
208 }
209
TEST(RegistrationFetcherParamTest,AlgAsString)210 TEST(RegistrationFetcherParamTest, AlgAsString) {
211 const GURL registration_request("https://www.example.com/registration");
212 // Testing customized header.
213 scoped_refptr<net::HttpResponseHeaders> response_headers =
214 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
215 response_headers->AddHeader(kRegistrationHeader,
216 "(\"RS256\");path=\"new\";challenge=\"test\"");
217 std::vector<RegistrationFetcherParam> params =
218 RegistrationFetcherParam::CreateIfValid(registration_request,
219 response_headers.get());
220 ASSERT_TRUE(params.empty());
221 }
222
TEST(RegistrationFetcherParamTest,PathAsToken)223 TEST(RegistrationFetcherParamTest, PathAsToken) {
224 const GURL registration_request("https://www.example.com/registration");
225 // Testing customized header.
226 scoped_refptr<net::HttpResponseHeaders> response_headers =
227 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
228 response_headers->AddHeader(kRegistrationHeader,
229 "(RS256);path=new;challenge=\"test\"");
230 std::vector<RegistrationFetcherParam> params =
231 RegistrationFetcherParam::CreateIfValid(registration_request,
232 response_headers.get());
233 ASSERT_TRUE(params.empty());
234 }
235
TEST(RegistrationFetcherParamTest,ChallengeAsByteSequence)236 TEST(RegistrationFetcherParamTest, ChallengeAsByteSequence) {
237 const GURL registration_request("https://www.example.com/registration");
238 // Testing customized header.
239 scoped_refptr<net::HttpResponseHeaders> response_headers =
240 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
241 response_headers->AddHeader(kRegistrationHeader,
242 "(RS256);path=\"new\";challenge=:Y29kZWQ=:");
243 std::vector<RegistrationFetcherParam> params =
244 RegistrationFetcherParam::CreateIfValid(registration_request,
245 response_headers.get());
246 ASSERT_TRUE(params.empty());
247 }
248
TEST(RegistrationFetcherParamTest,ValidInvalidValid)249 TEST(RegistrationFetcherParamTest, ValidInvalidValid) {
250 const GURL registration_request("https://www.example.com/registration");
251 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
252 "/first", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
253 CreateHeaders("/second", "(es256)", "challenge2", "auth2", response_headers);
254 CreateHeaders("/third", "(ES256)", "challenge3", "auth3", response_headers);
255
256 std::vector<RegistrationFetcherParam> params =
257 RegistrationFetcherParam::CreateIfValid(registration_request,
258 response_headers.get());
259 ASSERT_EQ(params.size(), 2U);
260 const auto& p1 = params[0];
261 EXPECT_EQ(p1.registration_endpoint(), GURL("https://www.example.com/first"));
262 EXPECT_THAT(p1.supported_algos(),
263 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
264 EXPECT_EQ(p1.challenge(), "c1");
265 EXPECT_FALSE(p1.authorization());
266
267 const auto& p2 = params[1];
268 EXPECT_EQ(p2.registration_endpoint(), GURL("https://www.example.com/third"));
269 EXPECT_THAT(p2.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
270 EXPECT_EQ(p2.challenge(), "challenge3");
271 EXPECT_EQ(p2.authorization(), "auth3");
272 }
273
TEST(RegistrationFetcherParamTest,ThreeRegistrations)274 TEST(RegistrationFetcherParamTest, ThreeRegistrations) {
275 const GURL registration_request("https://www.example.com/registration");
276 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
277 "/startsession", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
278 CreateHeaders("/new", "(ES256)", "coded", "", response_headers);
279 CreateHeaders("/third", "(ES256)", "another", "auth", response_headers);
280
281 std::vector<RegistrationFetcherParam> params =
282 RegistrationFetcherParam::CreateIfValid(registration_request,
283 response_headers.get());
284 ASSERT_EQ(params.size(), 3U);
285 const auto& p1 = params[0];
286 EXPECT_EQ(p1.registration_endpoint(),
287 GURL("https://www.example.com/startsession"));
288 EXPECT_THAT(p1.supported_algos(),
289 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
290 EXPECT_EQ(p1.challenge(), "c1");
291 EXPECT_FALSE(p1.authorization());
292
293 const auto& p2 = params[1];
294 EXPECT_EQ(p2.registration_endpoint(), GURL("https://www.example.com/new"));
295 EXPECT_THAT(p2.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
296 EXPECT_EQ(p2.challenge(), "coded");
297 EXPECT_EQ(p2.authorization(), "");
298
299 const auto& p3 = params[2];
300 EXPECT_EQ(p3.registration_endpoint(), GURL("https://www.example.com/third"));
301 EXPECT_THAT(p3.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
302 EXPECT_EQ(p3.challenge(), "another");
303 EXPECT_EQ(p3.authorization(), "auth");
304 }
305
TEST(RegistrationFetcherParamTest,ThreeRegistrationsList)306 TEST(RegistrationFetcherParamTest, ThreeRegistrationsList) {
307 const GURL registration_request("https://www.example.com/registration");
308 // Testing customized header.
309 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
310 "/startsession", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
311 response_headers->AddHeader(kRegistrationHeader,
312 "(ES256);path=\"new\";challenge=\"coded\", "
313 "(ES256);path=\"third\";challenge=\"another\"");
314 std::vector<RegistrationFetcherParam> params =
315 RegistrationFetcherParam::CreateIfValid(registration_request,
316 response_headers.get());
317 ASSERT_EQ(params.size(), 3U);
318 const auto& p1 = params[0];
319 EXPECT_EQ(p1.registration_endpoint(),
320 GURL("https://www.example.com/startsession"));
321 EXPECT_THAT(p1.supported_algos(),
322 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
323 EXPECT_EQ(p1.challenge(), "c1");
324
325 const auto& p2 = params[1];
326 EXPECT_EQ(p2.registration_endpoint(), GURL("https://www.example.com/new"));
327 EXPECT_THAT(p2.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
328 EXPECT_EQ(p2.challenge(), "coded");
329
330 const auto& p3 = params[2];
331 EXPECT_EQ(p3.registration_endpoint(), GURL("https://www.example.com/third"));
332 EXPECT_THAT(p3.supported_algos(), UnorderedElementsAre(ECDSA_SHA256));
333 EXPECT_EQ(p3.challenge(), "another");
334 }
335
TEST(RegistrationFetcherParamTest,StartWithSlash)336 TEST(RegistrationFetcherParamTest, StartWithSlash) {
337 const GURL registration_request("https://www.example.com/registration");
338 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
339 "/startsession", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
340 std::vector<RegistrationFetcherParam> params =
341 RegistrationFetcherParam::CreateIfValid(registration_request,
342 response_headers.get());
343 ASSERT_EQ(params.size(), 1U);
344 const auto& param = params[0];
345 EXPECT_EQ(param.registration_endpoint(),
346 GURL("https://www.example.com/startsession"));
347 EXPECT_THAT(param.supported_algos(),
348 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
349 EXPECT_EQ(param.challenge(), "c1");
350 EXPECT_FALSE(param.authorization());
351 }
352
TEST(RegistrationFetcherParamTest,EscapeOnce)353 TEST(RegistrationFetcherParamTest, EscapeOnce) {
354 const GURL registration_request("https://www.example.com/registration");
355 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
356 "/%2561", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
357 std::vector<RegistrationFetcherParam> params =
358 RegistrationFetcherParam::CreateIfValid(registration_request,
359 response_headers.get());
360 ASSERT_EQ(params.size(), 1U);
361 const auto& param = params[0];
362 EXPECT_EQ(param.registration_endpoint(), GURL("https://www.example.com/%61"));
363 EXPECT_THAT(param.supported_algos(),
364 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
365 EXPECT_EQ(param.challenge(), "c1");
366 EXPECT_FALSE(param.authorization());
367 }
368
TEST(RegistrationFetcherParamTest,InvalidUrl)369 TEST(RegistrationFetcherParamTest, InvalidUrl) {
370 const GURL registration_request = GURL("https://[/");
371 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
372 "new", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
373 std::vector<RegistrationFetcherParam> params =
374 RegistrationFetcherParam::CreateIfValid(registration_request,
375 response_headers.get());
376 ASSERT_EQ(params.size(), 0U);
377 }
378
TEST(RegistrationFetcherParamTest,HasUrlEncoded)379 TEST(RegistrationFetcherParamTest, HasUrlEncoded) {
380 const GURL registration_request("https://www.example.com/registration");
381 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
382 "test%2Fstart", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
383 std::vector<RegistrationFetcherParam> params =
384 RegistrationFetcherParam::CreateIfValid(registration_request,
385 response_headers.get());
386 ASSERT_EQ(params.size(), 1U);
387 const auto& param = params[0];
388 EXPECT_EQ(param.registration_endpoint(),
389 GURL("https://www.example.com/test/start"));
390 EXPECT_THAT(param.supported_algos(),
391 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
392 EXPECT_EQ(param.challenge(), "c1");
393 EXPECT_FALSE(param.authorization());
394 }
395
TEST(RegistrationFetcherParamTest,FullUrl)396 TEST(RegistrationFetcherParamTest, FullUrl) {
397 const GURL registration_request("https://www.example.com/registration");
398 scoped_refptr<net::HttpResponseHeaders> response_headers =
399 CreateHeaders("https://accounts.example.com/startsession",
400 "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
401 std::vector<RegistrationFetcherParam> params =
402 RegistrationFetcherParam::CreateIfValid(registration_request,
403 response_headers.get());
404 ASSERT_EQ(params.size(), 1U);
405 const auto& param = params[0];
406 EXPECT_EQ(param.registration_endpoint(),
407 GURL("https://accounts.example.com/startsession"));
408 EXPECT_THAT(param.supported_algos(),
409 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
410 EXPECT_EQ(param.challenge(), "c1");
411 EXPECT_FALSE(param.authorization());
412 }
413
TEST(RegistrationFetcherParamTest,SwapAlgo)414 TEST(RegistrationFetcherParamTest, SwapAlgo) {
415 const GURL registration_request("https://www.example.com/registration");
416 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
417 "startsession", "(ES256 RS256)", "c1", /*authorization=*/std::nullopt);
418 std::vector<RegistrationFetcherParam> params =
419 RegistrationFetcherParam::CreateIfValid(registration_request,
420 response_headers.get());
421 ASSERT_EQ(params.size(), 1U);
422 const auto& param = params[0];
423 EXPECT_EQ(param.registration_endpoint(),
424 GURL("https://www.example.com/startsession"));
425 EXPECT_THAT(param.supported_algos(),
426 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
427 EXPECT_EQ(param.challenge(), "c1");
428 EXPECT_FALSE(param.authorization());
429 }
430
TEST(RegistrationFetcherParamTest,OneAlgo)431 TEST(RegistrationFetcherParamTest, OneAlgo) {
432 const GURL registration_request("https://www.example.com/registration");
433 scoped_refptr<net::HttpResponseHeaders> response_headers = CreateHeaders(
434 "startsession", "(RS256)", "c1", /*authorization=*/std::nullopt);
435 std::vector<RegistrationFetcherParam> params =
436 RegistrationFetcherParam::CreateIfValid(registration_request,
437 response_headers.get());
438 ASSERT_EQ(params.size(), 1U);
439 const auto& param = params[0];
440 EXPECT_EQ(param.registration_endpoint(),
441 GURL("https://www.example.com/startsession"));
442 ASSERT_THAT(param.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
443 EXPECT_EQ(param.challenge(), "c1");
444 EXPECT_FALSE(param.authorization());
445 }
446
TEST(RegistrationFetcherParamTest,InvalidParamIgnored)447 TEST(RegistrationFetcherParamTest, InvalidParamIgnored) {
448 const GURL registration_request("https://www.example.com/registration");
449 scoped_refptr<net::HttpResponseHeaders> response_headers =
450 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
451 response_headers->SetHeader(
452 kRegistrationHeader,
453 "(RS256);path=\"first\";challenge=\"c1\";another=true");
454 std::vector<RegistrationFetcherParam> params =
455 RegistrationFetcherParam::CreateIfValid(registration_request,
456 response_headers.get());
457 ASSERT_EQ(params.size(), 1U);
458 const auto& param = params[0];
459 EXPECT_EQ(param.registration_endpoint(),
460 GURL("https://www.example.com/first"));
461 ASSERT_THAT(param.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
462 EXPECT_EQ(param.challenge(), "c1");
463 EXPECT_FALSE(param.authorization());
464 }
465
TEST(RegistrationFetcherParamTest,InvalidInputs)466 TEST(RegistrationFetcherParamTest, InvalidInputs) {
467 struct Input {
468 std::string request_url;
469 std::optional<std::string> path;
470 std::optional<std::string> algos;
471 std::optional<std::string> challenge;
472 };
473
474 const Input kInvalidInputs[] = {
475 // All invalid
476 {"https://www.example.com/reg", "", "()", ""},
477 // All missing
478 {"https://www.example.com/reg", std::nullopt, std::nullopt, std::nullopt},
479 // All valid different Url
480 {"https://www.example.com/registration",
481 "https://accounts.different.url/startsession", "(RS256)", "c1"},
482 // Empty request Url
483 {"", "start", "(RS256)", "c1"},
484 // Empty algo
485 {"https://www.example.com/reg", "start", "()", "c1"},
486 // Missing algo
487 {"https://www.example.com/reg", "start", std::nullopt, "c1"},
488 // Missing registration
489 {"https://www.example.com/reg", std::nullopt, "(ES256 RS256)", "c1"},
490 // Missing challenge
491 {"https://www.example.com/reg", "start", "(ES256 RS256)", std::nullopt},
492 // Empty challenge
493 {"https://www.example.com/reg", "start", "(ES256 RS256)", ""},
494 // Challenge invalid utf8
495 {"https://www.example.com/reg", "start", "(ES256 RS256)", "ab\xC0\x80"}};
496
497 for (const auto& input : kInvalidInputs) {
498 const GURL registration_request = GURL(input.request_url);
499 scoped_refptr<net::HttpResponseHeaders> response_headers =
500 CreateHeaders(input.path, input.algos, input.challenge,
501 /*authorization=*/std::nullopt);
502 SCOPED_TRACE(registration_request.spec() + "; " +
503 response_headers->raw_headers());
504 std::vector<RegistrationFetcherParam> params =
505 RegistrationFetcherParam::CreateIfValid(registration_request,
506 response_headers.get());
507 EXPECT_TRUE(params.empty());
508 }
509 }
510
TEST(RegistrationFetcherParamTest,ValidAuthorization)511 TEST(RegistrationFetcherParamTest, ValidAuthorization) {
512 const GURL registration_request("https://www.example.com/registration");
513 scoped_refptr<net::HttpResponseHeaders> response_headers =
514 CreateHeaders("startsession", "(ES256 RS256)", "c1", "authcode");
515 std::vector<RegistrationFetcherParam> params =
516 RegistrationFetcherParam::CreateIfValid(registration_request,
517 response_headers.get());
518 ASSERT_EQ(params.size(), 1U);
519 const auto& param = params[0];
520 EXPECT_EQ(param.registration_endpoint(),
521 GURL("https://www.example.com/startsession"));
522 EXPECT_THAT(param.supported_algos(),
523 UnorderedElementsAre(ECDSA_SHA256, RSA_PKCS1_SHA256));
524 EXPECT_EQ(param.challenge(), "c1");
525 EXPECT_EQ(param.authorization(), "authcode");
526 }
527
TEST(RegistrationFetcherParamTest,InvalidAuthorizationIgnored)528 TEST(RegistrationFetcherParamTest, InvalidAuthorizationIgnored) {
529 const GURL registration_request("https://www.example.com/registration");
530 // Testing customized header.
531 scoped_refptr<net::HttpResponseHeaders> response_headers =
532 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
533 response_headers->AddHeader(
534 kRegistrationHeader,
535 "(RS256);path=\"startsession\";challenge=\"c1\";authorization=123");
536 std::vector<RegistrationFetcherParam> params =
537 RegistrationFetcherParam::CreateIfValid(registration_request,
538 response_headers.get());
539 ASSERT_EQ(params.size(), 1U);
540 const auto& param = params[0];
541 EXPECT_EQ(param.registration_endpoint(),
542 GURL("https://www.example.com/startsession"));
543 EXPECT_THAT(param.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
544 EXPECT_EQ(param.challenge(), "c1");
545 EXPECT_FALSE(param.authorization());
546 }
547
TEST(RegistrationFetcherParamTest,MultipleAuthorizationHeaders)548 TEST(RegistrationFetcherParamTest, MultipleAuthorizationHeaders) {
549 const GURL registration_request("https://www.example.com/registration");
550 // Testing customized header.
551 scoped_refptr<net::HttpResponseHeaders> response_headers =
552 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
553 response_headers->AddHeader(
554 kRegistrationHeader,
555 "(RS256);path=\"startsession\";challenge=\"c1\";"
556 "authorization=\"auth1\";authorization=\"auth2\"");
557 std::vector<RegistrationFetcherParam> params =
558 RegistrationFetcherParam::CreateIfValid(registration_request,
559 response_headers.get());
560 ASSERT_EQ(params.size(), 1U);
561 const auto& param = params[0];
562 EXPECT_EQ(param.registration_endpoint(),
563 GURL("https://www.example.com/startsession"));
564 EXPECT_THAT(param.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
565 EXPECT_EQ(param.challenge(), "c1");
566 EXPECT_EQ(param.authorization(), "auth2");
567 }
568
TEST(RegistrationFetcherParamTest,MultipleAuthorizationHeadersWithEmpty)569 TEST(RegistrationFetcherParamTest, MultipleAuthorizationHeadersWithEmpty) {
570 const GURL registration_request("https://www.example.com/registration");
571 // Testing customized header.
572 scoped_refptr<net::HttpResponseHeaders> response_headers =
573 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
574 response_headers->AddHeader(kRegistrationHeader,
575 "(RS256);path=\"startsession\";challenge=\"c1\";"
576 "authorization=\"auth1\";authorization=\"\"");
577 std::vector<RegistrationFetcherParam> params =
578 RegistrationFetcherParam::CreateIfValid(registration_request,
579 response_headers.get());
580 ASSERT_EQ(params.size(), 1U);
581 const auto& param = params[0];
582 EXPECT_EQ(param.registration_endpoint(),
583 GURL("https://www.example.com/startsession"));
584 EXPECT_THAT(param.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
585 EXPECT_EQ(param.challenge(), "c1");
586 EXPECT_EQ(param.authorization(), "");
587 }
588
TEST(RegistrationFetcherParamTest,EmptyStringAuthorization)589 TEST(RegistrationFetcherParamTest, EmptyStringAuthorization) {
590 const GURL registration_request("https://www.example.com/registration");
591 // Testing customized header.
592 scoped_refptr<net::HttpResponseHeaders> response_headers =
593 HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
594 response_headers->AddHeader(
595 kRegistrationHeader,
596 "(RS256);path=\"startsession\";challenge=\"c1\";authorization=\"\"");
597 std::vector<RegistrationFetcherParam> params =
598 RegistrationFetcherParam::CreateIfValid(registration_request,
599 response_headers.get());
600 ASSERT_EQ(params.size(), 1U);
601 const auto& param = params[0];
602 EXPECT_EQ(param.registration_endpoint(),
603 GURL("https://www.example.com/startsession"));
604 EXPECT_THAT(param.supported_algos(), UnorderedElementsAre(RSA_PKCS1_SHA256));
605 EXPECT_EQ(param.challenge(), "c1");
606 EXPECT_EQ(param.authorization(), "");
607 }
608
609 } // namespace
610
611 } // namespace net::device_bound_sessions
612