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/socket/connect_job_params_factory.h"
6
7 #include <ostream>
8 #include <tuple>
9
10 #include "base/containers/flat_set.h"
11 #include "base/memory/scoped_refptr.h"
12 #include "base/strings/strcat.h"
13 #include "base/test/scoped_feature_list.h"
14 #include "net/base/features.h"
15 #include "net/base/host_port_pair.h"
16 #include "net/base/network_anonymization_key.h"
17 #include "net/base/privacy_mode.h"
18 #include "net/base/proxy_chain.h"
19 #include "net/base/proxy_server.h"
20 #include "net/base/schemeful_site.h"
21 #include "net/dns/public/secure_dns_policy.h"
22 #include "net/http/http_proxy_connect_job.h"
23 #include "net/socket/connect_job_factory.h"
24 #include "net/socket/next_proto.h"
25 #include "net/socket/socks_connect_job.h"
26 #include "net/socket/ssl_connect_job.h"
27 #include "net/socket/transport_connect_job.h"
28 #include "net/ssl/ssl_config.h"
29 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "third_party/abseil-cpp/absl/types/variant.h"
32 #include "url/gurl.h"
33 #include "url/scheme_host_port.h"
34
35 namespace net {
36
37 namespace {
38
39 struct TestParams {
40 using ParamTuple = std::tuple<bool,
41 PrivacyMode,
42 SecureDnsPolicy,
43 ConnectJobFactory::AlpnMode,
44 bool,
45 bool>;
46
TestParamsnet::__anon236921ea0111::TestParams47 explicit TestParams(ParamTuple tup)
48 : disable_cert_network_fetches(std::get<0>(tup)),
49 privacy_mode(std::get<1>(tup)),
50 secure_dns_policy(std::get<2>(tup)),
51 alpn_mode(std::get<3>(tup)),
52 enable_early_data(std::get<4>(tup)),
53 partition_proxy_chains(std::get<5>(tup)) {}
54
55 bool disable_cert_network_fetches;
56 PrivacyMode privacy_mode;
57 SecureDnsPolicy secure_dns_policy;
58 ConnectJobFactory::AlpnMode alpn_mode;
59 bool enable_early_data;
60 bool partition_proxy_chains;
61 };
62
operator <<(std::ostream & os,const TestParams & test_params)63 std::ostream& operator<<(std::ostream& os, const TestParams& test_params) {
64 os << "TestParams {.disable_cert_network_fetches="
65 << test_params.disable_cert_network_fetches;
66 os << ", .privacy_mode=" << test_params.privacy_mode;
67 os << ", .secure_dns_policy="
68 << (test_params.secure_dns_policy == SecureDnsPolicy::kAllow ? "kAllow"
69 : "kDisable");
70 os << ", .alpn_mode="
71 << (test_params.alpn_mode == ConnectJobFactory::AlpnMode::kDisabled
72 ? "kDisabled"
73 : test_params.alpn_mode == ConnectJobFactory::AlpnMode::kHttp11Only
74 ? "kHttp11Only"
75 : "kHttpAll");
76 os << ", .enable_early_data=" << test_params.enable_early_data;
77 os << ", .partition_proxy_chains=" << test_params.partition_proxy_chains;
78 os << "}";
79 return os;
80 }
81
82 // Get a string describing the params variant.
ParamsName(ConnectJobParams & params)83 const char* ParamsName(ConnectJobParams& params) {
84 if (params.is_http_proxy()) {
85 return "HttpProxySocketParams";
86 }
87 if (params.is_socks()) {
88 return "SOCKSSocketParams";
89 }
90 if (params.is_ssl()) {
91 return "SSLSocketParams";
92 }
93 if (params.is_transport()) {
94 return "TransportSocketParams";
95 }
96 return "Unknown";
97 }
98
ExpectHttpProxySocketParams(ConnectJobParams params)99 scoped_refptr<HttpProxySocketParams> ExpectHttpProxySocketParams(
100 ConnectJobParams params) {
101 EXPECT_TRUE(params.is_http_proxy())
102 << "Expected HttpProxySocketParams, got " << ParamsName(params);
103 return params.take_http_proxy();
104 }
105
VerifyHttpProxySocketParams(scoped_refptr<HttpProxySocketParams> params,const char * description,std::optional<SSLConfig> quic_ssl_config,const HostPortPair & endpoint,const ProxyChain & proxy_chain,size_t proxy_chain_index,bool tunnel,const NetworkAnonymizationKey & network_anonymization_key,const SecureDnsPolicy secure_dns_policy)106 void VerifyHttpProxySocketParams(
107 scoped_refptr<HttpProxySocketParams> params,
108 const char* description,
109 // Only QUIC proxies have a quic_ssl_config.
110 std::optional<SSLConfig> quic_ssl_config,
111 const HostPortPair& endpoint,
112 const ProxyChain& proxy_chain,
113 size_t proxy_chain_index,
114 bool tunnel,
115 const NetworkAnonymizationKey& network_anonymization_key,
116 const SecureDnsPolicy secure_dns_policy) {
117 SCOPED_TRACE(testing::Message() << "Verifying " << description);
118 if (quic_ssl_config) {
119 // Only examine the values used for QUIC connections.
120 ASSERT_TRUE(params->quic_ssl_config().has_value());
121 EXPECT_EQ(params->quic_ssl_config()->privacy_mode,
122 quic_ssl_config->privacy_mode);
123 EXPECT_EQ(params->quic_ssl_config()->GetCertVerifyFlags(),
124 quic_ssl_config->GetCertVerifyFlags());
125 } else {
126 EXPECT_FALSE(params->quic_ssl_config().has_value());
127 }
128 EXPECT_EQ(params->endpoint(), endpoint);
129 EXPECT_EQ(params->proxy_chain(), proxy_chain);
130 EXPECT_EQ(params->proxy_chain_index(), proxy_chain_index);
131 EXPECT_EQ(params->tunnel(), tunnel);
132 EXPECT_EQ(params->network_anonymization_key(), network_anonymization_key);
133 EXPECT_EQ(params->secure_dns_policy(), secure_dns_policy);
134 }
135
ExpectSOCKSSocketParams(ConnectJobParams params)136 scoped_refptr<SOCKSSocketParams> ExpectSOCKSSocketParams(
137 ConnectJobParams params) {
138 EXPECT_TRUE(params.is_socks())
139 << "Expected SOCKSSocketParams, got " << ParamsName(params);
140 return params.take_socks();
141 }
142
143 // Verify the properties of SOCKSSocketParams.
VerifySOCKSSocketParams(scoped_refptr<SOCKSSocketParams> & params,const char * description,bool is_socks_v5,const HostPortPair & destination,const NetworkAnonymizationKey & network_anonymization_key)144 void VerifySOCKSSocketParams(
145 scoped_refptr<SOCKSSocketParams>& params,
146 const char* description,
147 bool is_socks_v5,
148 const HostPortPair& destination,
149 const NetworkAnonymizationKey& network_anonymization_key) {
150 SCOPED_TRACE(testing::Message() << "Verifying " << description);
151 EXPECT_EQ(params->is_socks_v5(), is_socks_v5);
152 EXPECT_EQ(params->destination(), destination);
153 EXPECT_EQ(params->network_anonymization_key(), network_anonymization_key);
154 }
155
156 // Assert that the params are TransportSocketParams and return them.
ExpectTransportSocketParams(ConnectJobParams params)157 scoped_refptr<TransportSocketParams> ExpectTransportSocketParams(
158 ConnectJobParams params) {
159 EXPECT_TRUE(params.is_transport())
160 << "Expected TransportSocketParams, got " << ParamsName(params);
161 return params.take_transport();
162 }
163
164 // Verify the properties of TransportSocketParams.
VerifyTransportSocketParams(scoped_refptr<TransportSocketParams> & params,const char * description,const TransportSocketParams::Endpoint destination,const SecureDnsPolicy secure_dns_policy,const NetworkAnonymizationKey & network_anonymization_key,const base::flat_set<std::string> & supported_alpns)165 void VerifyTransportSocketParams(
166 scoped_refptr<TransportSocketParams>& params,
167 const char* description,
168 const TransportSocketParams::Endpoint destination,
169 const SecureDnsPolicy secure_dns_policy,
170 const NetworkAnonymizationKey& network_anonymization_key,
171 const base::flat_set<std::string>& supported_alpns) {
172 SCOPED_TRACE(testing::Message() << "Verifying " << description);
173 EXPECT_EQ(params->destination(), destination);
174 EXPECT_EQ(params->secure_dns_policy(), secure_dns_policy);
175 EXPECT_EQ(params->network_anonymization_key(), network_anonymization_key);
176 EXPECT_EQ(params->supported_alpns(), supported_alpns);
177 }
178
179 // Assert that the params are SSLSocketParams and return them.
ExpectSSLSocketParams(ConnectJobParams params)180 scoped_refptr<SSLSocketParams> ExpectSSLSocketParams(ConnectJobParams params) {
181 EXPECT_TRUE(params.is_ssl())
182 << "Expected SSLSocketParams, got " << ParamsName(params);
183 return params.take_ssl();
184 }
185
186 // Verify the properties of SSLSocketParams.
VerifySSLSocketParams(scoped_refptr<SSLSocketParams> & params,const char * description,const HostPortPair & host_and_port,const SSLConfig & ssl_config,PrivacyMode privacy_mode,const NetworkAnonymizationKey & network_anonymization_key)187 void VerifySSLSocketParams(
188 scoped_refptr<SSLSocketParams>& params,
189 const char* description,
190 const HostPortPair& host_and_port,
191 const SSLConfig& ssl_config,
192 PrivacyMode privacy_mode,
193 const NetworkAnonymizationKey& network_anonymization_key) {
194 SCOPED_TRACE(testing::Message() << "Verifying " << description);
195 EXPECT_EQ(params->host_and_port(), host_and_port);
196 // SSLConfig doesn't implement operator==, so just check the properties the
197 // factory uses.
198 EXPECT_EQ(params->ssl_config().disable_cert_verification_network_fetches,
199 ssl_config.disable_cert_verification_network_fetches);
200 EXPECT_EQ(params->ssl_config().alpn_protos, ssl_config.alpn_protos);
201 EXPECT_EQ(params->ssl_config().application_settings,
202 ssl_config.application_settings);
203 EXPECT_EQ(params->ssl_config().renego_allowed_default,
204 ssl_config.renego_allowed_default);
205 EXPECT_EQ(params->ssl_config().renego_allowed_for_protos,
206 ssl_config.renego_allowed_for_protos);
207 EXPECT_EQ(params->ssl_config().privacy_mode, privacy_mode);
208 EXPECT_EQ(params->network_anonymization_key(), network_anonymization_key);
209 }
210
211 // Calculate the ALPN protocols for the given ALPN mode.
AlpnProtoStringsForMode(ConnectJobFactory::AlpnMode alpn_mode)212 base::flat_set<std::string> AlpnProtoStringsForMode(
213 ConnectJobFactory::AlpnMode alpn_mode) {
214 switch (alpn_mode) {
215 case ConnectJobFactory::AlpnMode::kDisabled:
216 return {};
217 case ConnectJobFactory::AlpnMode::kHttp11Only:
218 return {"http/1.1"};
219 case ConnectJobFactory::AlpnMode::kHttpAll:
220 return {"h2", "http/1.1"};
221 }
222 }
223
224 class ConnectJobParamsFactoryTest : public testing::TestWithParam<TestParams> {
225 public:
ConnectJobParamsFactoryTest()226 ConnectJobParamsFactoryTest() {
227 if (partition_proxy_chains()) {
228 scoped_feature_list_.InitAndEnableFeature(
229 net::features::kPartitionProxyChains);
230 } else {
231 scoped_feature_list_.InitAndDisableFeature(
232 net::features::kPartitionProxyChains);
233 }
234
235 early_data_enabled_ = enable_early_data();
236 switch (alpn_mode()) {
237 case ConnectJobFactory::AlpnMode::kDisabled:
238 alpn_protos_ = {};
239 application_settings_ = {};
240 break;
241 case ConnectJobFactory::AlpnMode::kHttp11Only:
242 alpn_protos_ = {kProtoHTTP11};
243 application_settings_ = {};
244 break;
245 case ConnectJobFactory::AlpnMode::kHttpAll:
246 alpn_protos_ = {kProtoHTTP2, kProtoHTTP11};
247 application_settings_ = {{kProtoHTTP2, {}}};
248 break;
249 }
250 }
251
252 protected:
253 // Parameter accessors.
disable_cert_network_fetches() const254 bool disable_cert_network_fetches() const {
255 return GetParam().disable_cert_network_fetches;
256 }
privacy_mode() const257 PrivacyMode privacy_mode() const { return GetParam().privacy_mode; }
secure_dns_policy() const258 SecureDnsPolicy secure_dns_policy() const {
259 return GetParam().secure_dns_policy;
260 }
alpn_mode() const261 ConnectJobFactory::AlpnMode alpn_mode() const { return GetParam().alpn_mode; }
enable_early_data() const262 bool enable_early_data() const { return GetParam().enable_early_data; }
partition_proxy_chains() const263 bool partition_proxy_chains() const {
264 return GetParam().partition_proxy_chains;
265 }
266
267 // Create an SSL config for connection to the endpoint, based on the test
268 // parameters.
SSLConfigForEndpoint() const269 SSLConfig SSLConfigForEndpoint() const {
270 SSLConfig endpoint_ssl_config;
271 endpoint_ssl_config.disable_cert_verification_network_fetches =
272 disable_cert_network_fetches();
273 endpoint_ssl_config.early_data_enabled = enable_early_data();
274 switch (alpn_mode()) {
275 case ConnectJobFactory::AlpnMode::kDisabled:
276 endpoint_ssl_config.alpn_protos = {};
277 endpoint_ssl_config.application_settings = {};
278 endpoint_ssl_config.renego_allowed_default = false;
279 endpoint_ssl_config.renego_allowed_for_protos = {};
280 break;
281 case ConnectJobFactory::AlpnMode::kHttp11Only:
282 endpoint_ssl_config.alpn_protos = {kProtoHTTP11};
283 endpoint_ssl_config.application_settings = {};
284 endpoint_ssl_config.renego_allowed_default = true;
285 endpoint_ssl_config.renego_allowed_for_protos = {kProtoHTTP11};
286 break;
287 case ConnectJobFactory::AlpnMode::kHttpAll:
288 endpoint_ssl_config.alpn_protos = {kProtoHTTP2, kProtoHTTP11};
289 endpoint_ssl_config.application_settings = {{kProtoHTTP2, {}}};
290 endpoint_ssl_config.renego_allowed_default = true;
291 endpoint_ssl_config.renego_allowed_for_protos = {kProtoHTTP11};
292 break;
293 }
294 return endpoint_ssl_config;
295 }
296
297 // Create an SSL config for connection to an HTTPS proxy, based on the test
298 // parameters.
SSLConfigForProxy() const299 SSLConfig SSLConfigForProxy() const {
300 SSLConfig proxy_ssl_config;
301 proxy_ssl_config.disable_cert_verification_network_fetches = true;
302 proxy_ssl_config.early_data_enabled = true;
303 proxy_ssl_config.renego_allowed_default = false;
304 proxy_ssl_config.renego_allowed_for_protos = {};
305 switch (alpn_mode()) {
306 case ConnectJobFactory::AlpnMode::kDisabled:
307 proxy_ssl_config.alpn_protos = {};
308 proxy_ssl_config.application_settings = {};
309 break;
310 case ConnectJobFactory::AlpnMode::kHttp11Only:
311 proxy_ssl_config.alpn_protos = {kProtoHTTP11};
312 proxy_ssl_config.application_settings = {};
313 break;
314 case ConnectJobFactory::AlpnMode::kHttpAll:
315 proxy_ssl_config.alpn_protos = {kProtoHTTP2, kProtoHTTP11};
316 proxy_ssl_config.application_settings = {{kProtoHTTP2, {}}};
317 break;
318 }
319 return proxy_ssl_config;
320 }
321
322 base::test::ScopedFeatureList scoped_feature_list_;
323 NextProtoVector alpn_protos_;
324 SSLConfig::ApplicationSettings application_settings_;
325 bool early_data_enabled_;
326 const CommonConnectJobParams common_connect_job_params_{
327 /*client_socket_factory=*/nullptr,
328 /*host_resolver=*/nullptr,
329 /*http_auth_cache=*/nullptr,
330 /*http_auth_handler_factory=*/nullptr,
331 /*spdy_session_pool=*/nullptr,
332 /*quic_supported_versions=*/nullptr,
333 /*quic_session_pool=*/nullptr,
334 /*proxy_delegate=*/nullptr,
335 /*http_user_agent_settings=*/nullptr,
336 /*ssl_client_context=*/nullptr,
337 /*socket_performance_watcher_factory=*/nullptr,
338 /*network_quality_estimator=*/nullptr,
339 /*net_log=*/nullptr,
340 /*websocket_endpoint_lock_manager=*/nullptr,
341 /*http_server_properties=*/nullptr,
342 &alpn_protos_,
343 &application_settings_,
344 /*ignore_certificate_errors=*/nullptr,
345 &early_data_enabled_};
346
347 const NetworkAnonymizationKey kEndpointNak =
348 NetworkAnonymizationKey::CreateSameSite(
349 net::SchemefulSite(GURL("http://test")));
350 const NetworkAnonymizationKey kProxyDnsNak =
351 NetworkAnonymizationKey::CreateSameSite(
352 net::SchemefulSite(GURL("http://example-dns.test")));
353 };
354
355 // A connect to a simple HTTP endpoint produces just transport params.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpoint)356 TEST_P(ConnectJobParamsFactoryTest, HttpEndpoint) {
357 const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
358 ConnectJobParams params = ConstructConnectJobParams(
359 kEndpoint, ProxyChain::Direct(),
360 /*proxy_annotation_tag=*/std::nullopt,
361 /*allowed_bad_certs=*/{}, alpn_mode(),
362 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
363 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
364 &common_connect_job_params_, kProxyDnsNak);
365
366 scoped_refptr<TransportSocketParams> transport_socket_params =
367 ExpectTransportSocketParams(params);
368 VerifyTransportSocketParams(
369 transport_socket_params, "transport_socket_params", kEndpoint,
370 secure_dns_policy(), kEndpointNak, base::flat_set<std::string>());
371 }
372
373 // A connect to a endpoint without SSL, specified as a `SchemelessEndpoint`,
374 // produces just transport params.
TEST_P(ConnectJobParamsFactoryTest,UnencryptedEndpointWithoutScheme)375 TEST_P(ConnectJobParamsFactoryTest, UnencryptedEndpointWithoutScheme) {
376 const ConnectJobFactory::SchemelessEndpoint kEndpoint{
377 /*using_ssl=*/false, HostPortPair("test", 82)};
378 ConnectJobParams params = ConstructConnectJobParams(
379 kEndpoint, ProxyChain::Direct(),
380 /*proxy_annotation_tag=*/std::nullopt,
381 /*allowed_bad_certs=*/{}, alpn_mode(),
382 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
383 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
384 &common_connect_job_params_, kProxyDnsNak);
385
386 scoped_refptr<TransportSocketParams> transport_socket_params =
387 ExpectTransportSocketParams(params);
388 VerifyTransportSocketParams(transport_socket_params,
389 "transport_socket_params",
390 HostPortPair("test", 82), secure_dns_policy(),
391 kEndpointNak, base::flat_set<std::string>());
392 }
393
394 // A connect to a simple HTTPS endpoint produces SSL params wrapping transport
395 // params.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpoint)396 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpoint) {
397 // HTTPS endpoints are not supported without ALPN.
398 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
399 return;
400 }
401
402 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
403 ConnectJobParams params = ConstructConnectJobParams(
404 kEndpoint, ProxyChain::Direct(), TRAFFIC_ANNOTATION_FOR_TESTS,
405 /*allowed_bad_certs=*/{}, alpn_mode(),
406 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
407 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
408 &common_connect_job_params_, kProxyDnsNak);
409
410 scoped_refptr<SSLSocketParams> ssl_socket_params =
411 ExpectSSLSocketParams(params);
412 SSLConfig ssl_config = SSLConfigForEndpoint();
413 VerifySSLSocketParams(ssl_socket_params, "ssl_socket_params",
414 HostPortPair::FromSchemeHostPort(kEndpoint), ssl_config,
415 privacy_mode(), kEndpointNak);
416 scoped_refptr<TransportSocketParams> transport_socket_params =
417 ssl_socket_params->GetDirectConnectionParams();
418 VerifyTransportSocketParams(
419 transport_socket_params, "transport_socket_params", kEndpoint,
420 secure_dns_policy(), kEndpointNak, AlpnProtoStringsForMode(alpn_mode()));
421 }
422
423 // A connect to a endpoint SSL, specified as a `SchemelessEndpoint`,
424 // produces just transport params.
TEST_P(ConnectJobParamsFactoryTest,EncryptedEndpointWithoutScheme)425 TEST_P(ConnectJobParamsFactoryTest, EncryptedEndpointWithoutScheme) {
426 // Encrypted endpoints without scheme are only supported without ALPN.
427 if (alpn_mode() != ConnectJobFactory::AlpnMode::kDisabled) {
428 return;
429 }
430
431 const ConnectJobFactory::SchemelessEndpoint kEndpoint{
432 /*using_ssl=*/true, HostPortPair("test", 4433)};
433 ConnectJobParams params = ConstructConnectJobParams(
434 kEndpoint, ProxyChain::Direct(), TRAFFIC_ANNOTATION_FOR_TESTS,
435 /*allowed_bad_certs=*/{}, alpn_mode(),
436 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
437 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
438 &common_connect_job_params_, kProxyDnsNak);
439
440 scoped_refptr<SSLSocketParams> ssl_socket_params =
441 ExpectSSLSocketParams(params);
442 SSLConfig ssl_config = SSLConfigForEndpoint();
443 VerifySSLSocketParams(ssl_socket_params, "ssl_socket_params",
444 HostPortPair("test", 4433), ssl_config, privacy_mode(),
445 kEndpointNak);
446 scoped_refptr<TransportSocketParams> transport_socket_params =
447 ssl_socket_params->GetDirectConnectionParams();
448 VerifyTransportSocketParams(
449 transport_socket_params, "transport_socket_params",
450 HostPortPair("test", 4433), secure_dns_policy(), kEndpointNak,
451 AlpnProtoStringsForMode(alpn_mode()));
452 }
453
454 // A connection to an HTTP endpoint via an HTTPS proxy, without forcing a
455 // tunnel, sets up an HttpProxySocketParams, wrapping SSLSocketParams wrapping
456 // TransportSocketParams, intending to use GET to the proxy. This is not
457 // tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpointViaHttpsProxy)458 TEST_P(ConnectJobParamsFactoryTest, HttpEndpointViaHttpsProxy) {
459 const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
460 ProxyChain proxy_chain = ProxyChain::FromSchemeHostAndPort(
461 ProxyServer::SCHEME_HTTPS, "proxy", 443);
462 ConnectJobParams params = ConstructConnectJobParams(
463 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
464 /*allowed_bad_certs=*/{}, alpn_mode(),
465 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
466 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
467 &common_connect_job_params_, kProxyDnsNak);
468
469 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params =
470 ExpectHttpProxySocketParams(params);
471 VerifyHttpProxySocketParams(
472 http_proxy_socket_params, "http_proxy_socket_params",
473 /*quic_ssl_config=*/std::nullopt,
474 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
475 /*proxy_chain_index=*/0,
476 /*tunnel=*/false, kEndpointNak, secure_dns_policy());
477
478 scoped_refptr<SSLSocketParams> ssl_socket_params =
479 http_proxy_socket_params->ssl_params();
480 ASSERT_TRUE(ssl_socket_params);
481 SSLConfig ssl_config = SSLConfigForProxy();
482 VerifySSLSocketParams(ssl_socket_params, "ssl_socket_params",
483 HostPortPair::FromString("proxy:443"), ssl_config,
484 PrivacyMode::PRIVACY_MODE_DISABLED, kEndpointNak);
485
486 scoped_refptr<TransportSocketParams> transport_socket_params =
487 ssl_socket_params->GetDirectConnectionParams();
488 VerifyTransportSocketParams(
489 transport_socket_params, "transport_socket_params",
490 HostPortPair("proxy", 443), secure_dns_policy(), kProxyDnsNak,
491 AlpnProtoStringsForMode(alpn_mode()));
492 }
493
494 // A connection to an HTTP endpoint via an QUIC proxy sets up an
495 // HttpProxySocketParams, wrapping almost-unused SSLSocketParams, intending to
496 // use GET to the proxy. This is not tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpointViaQuicProxy)497 TEST_P(ConnectJobParamsFactoryTest, HttpEndpointViaQuicProxy) {
498 const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
499 ProxyChain proxy_chain = ProxyChain::ForIpProtection({
500 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxy",
501 443),
502 });
503 ConnectJobParams params = ConstructConnectJobParams(
504 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
505 /*allowed_bad_certs=*/{}, alpn_mode(),
506 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
507 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
508 &common_connect_job_params_, kProxyDnsNak);
509
510 auto http_proxy_socket_params = ExpectHttpProxySocketParams(params);
511 SSLConfig quic_ssl_config = SSLConfigForProxy();
512 // Traffic always tunnels over QUIC proxies.
513 const bool tunnel = true;
514 VerifyHttpProxySocketParams(
515 http_proxy_socket_params, "http_proxy_socket_params", quic_ssl_config,
516 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
517 /*proxy_chain_index=*/0, tunnel, kEndpointNak, secure_dns_policy());
518 }
519
520 // A connection to an HTTPS endpoint via an HTTPS proxy,
521 // sets up an SSLSocketParams, wrapping HttpProxySocketParams, wrapping
522 // SSLSocketParams, wrapping TransportSocketParams. This is always tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaHttpsProxy)523 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaHttpsProxy) {
524 // HTTPS endpoints are not supported without ALPN.
525 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
526 return;
527 }
528
529 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
530 ProxyChain proxy_chain = ProxyChain::FromSchemeHostAndPort(
531 ProxyServer::SCHEME_HTTPS, "proxy", 443);
532 ConnectJobParams params = ConstructConnectJobParams(
533 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
534 /*allowed_bad_certs=*/{}, alpn_mode(),
535 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
536 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
537 &common_connect_job_params_, kProxyDnsNak);
538
539 scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
540 ExpectSSLSocketParams(params);
541 SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
542 VerifySSLSocketParams(endpoint_ssl_socket_params,
543 "endpoint_ssl_socket_params",
544 HostPortPair::FromSchemeHostPort(kEndpoint),
545 endpoint_ssl_config, privacy_mode(), kEndpointNak);
546
547 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params =
548 endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
549 VerifyHttpProxySocketParams(
550 http_proxy_socket_params, "http_proxy_socket_params",
551 /*quic_ssl_config=*/std::nullopt,
552 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
553 /*proxy_chain_index=*/0,
554 /*tunnel=*/true, kEndpointNak, secure_dns_policy());
555
556 scoped_refptr<SSLSocketParams> proxy_ssl_socket_params =
557 http_proxy_socket_params->ssl_params();
558 ASSERT_TRUE(proxy_ssl_socket_params);
559 SSLConfig proxy_ssl_config = SSLConfigForProxy();
560 VerifySSLSocketParams(proxy_ssl_socket_params, "proxy_ssl_socket_params",
561 HostPortPair::FromString("proxy:443"), proxy_ssl_config,
562 PrivacyMode::PRIVACY_MODE_DISABLED, kEndpointNak);
563
564 scoped_refptr<TransportSocketParams> transport_socket_params =
565 proxy_ssl_socket_params->GetDirectConnectionParams();
566 VerifyTransportSocketParams(
567 transport_socket_params, "transport_socket_params",
568 HostPortPair("proxy", 443), secure_dns_policy(), kProxyDnsNak,
569 AlpnProtoStringsForMode(alpn_mode()));
570 }
571
572 // A connection to an HTTPS endpoint via a QUIC proxy,
573 // sets up an SSLSocketParams, wrapping HttpProxySocketParams, wrapping
574 // SSLSocketParams. This is always tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaQuicProxy)575 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaQuicProxy) {
576 // HTTPS endpoints are not supported without ALPN.
577 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
578 return;
579 }
580
581 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
582 ProxyChain proxy_chain = ProxyChain::ForIpProtection({
583 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxy",
584 443),
585 });
586 ConnectJobParams params = ConstructConnectJobParams(
587 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
588 /*allowed_bad_certs=*/{}, alpn_mode(),
589 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
590 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
591 &common_connect_job_params_, kProxyDnsNak);
592
593 auto endpoint_ssl_socket_params = ExpectSSLSocketParams(params);
594 SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
595 VerifySSLSocketParams(endpoint_ssl_socket_params,
596 "endpoint_ssl_socket_params",
597 HostPortPair::FromSchemeHostPort(kEndpoint),
598 endpoint_ssl_config, privacy_mode(), kEndpointNak);
599
600 auto http_proxy_socket_params =
601 endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
602 SSLConfig quic_ssl_config = SSLConfigForProxy();
603 VerifyHttpProxySocketParams(
604 http_proxy_socket_params, "http_proxy_socket_params", quic_ssl_config,
605 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
606 /*proxy_chain_index=*/0,
607 /*tunnel=*/true, kEndpointNak, secure_dns_policy());
608 }
609
610 // A connection to an HTTPS endpoint via an HTTP proxy
611 // sets up an SSLSocketParams, wrapping HttpProxySocketParams, wrapping
612 // TransportSocketParams. This is always tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaHttpProxy)613 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaHttpProxy) {
614 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
615 return;
616 }
617
618 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
619 ProxyChain proxy_chain =
620 ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP, "proxy", 80);
621 ConnectJobParams params = ConstructConnectJobParams(
622 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
623 /*allowed_bad_certs=*/{}, alpn_mode(),
624 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
625 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
626 &common_connect_job_params_, kProxyDnsNak);
627
628 scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
629 ExpectSSLSocketParams(params);
630 SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
631 VerifySSLSocketParams(endpoint_ssl_socket_params,
632 "endpoint_ssl_socket_params",
633 HostPortPair::FromSchemeHostPort(kEndpoint),
634 endpoint_ssl_config, privacy_mode(), kEndpointNak);
635
636 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params =
637 endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
638 VerifyHttpProxySocketParams(
639 http_proxy_socket_params, "http_proxy_socket_params",
640 /*quic_ssl_config=*/std::nullopt,
641 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
642 /*proxy_chain_index=*/0,
643 /*tunnel=*/true, kEndpointNak, secure_dns_policy());
644
645 scoped_refptr<TransportSocketParams> transport_socket_params =
646 http_proxy_socket_params->transport_params();
647 ASSERT_TRUE(transport_socket_params);
648 VerifyTransportSocketParams(transport_socket_params,
649 "transport_socket_params",
650 HostPortPair("proxy", 80), secure_dns_policy(),
651 kProxyDnsNak, base::flat_set<std::string>({}));
652 }
653
654 // A connection to an HTTP endpoint via a SOCKS proxy,
655 // sets up an SOCKSSocketParams wrapping TransportSocketParams.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpointViaSOCKSProxy)656 TEST_P(ConnectJobParamsFactoryTest, HttpEndpointViaSOCKSProxy) {
657 const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
658 ProxyChain proxy_chain = ProxyChain::FromSchemeHostAndPort(
659 ProxyServer::SCHEME_SOCKS4, "proxy", 999);
660 ConnectJobParams params = ConstructConnectJobParams(
661 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
662 /*allowed_bad_certs=*/{}, alpn_mode(),
663 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
664 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
665 &common_connect_job_params_, kProxyDnsNak);
666
667 scoped_refptr<SOCKSSocketParams> socks_socket_params =
668 ExpectSOCKSSocketParams(params);
669 VerifySOCKSSocketParams(socks_socket_params, "socks_socket_params",
670 /*is_socks_v5=*/false,
671 HostPortPair::FromSchemeHostPort(kEndpoint),
672 kEndpointNak);
673
674 scoped_refptr<TransportSocketParams> transport_socket_params =
675 socks_socket_params->transport_params();
676 VerifyTransportSocketParams(
677 transport_socket_params, "transport_socket_params",
678 HostPortPair("proxy", 999), secure_dns_policy(), kProxyDnsNak, {});
679 }
680
681 // A connection to an HTTPS endpoint via a SOCKS proxy,
682 // sets up an SSLSocketParams wrapping SOCKSSocketParams wrapping
683 // TransportSocketParams.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaSOCKSProxy)684 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaSOCKSProxy) {
685 // HTTPS endpoints are not supported without ALPN.
686 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
687 return;
688 }
689
690 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
691 ProxyChain proxy_chain = ProxyChain::FromSchemeHostAndPort(
692 ProxyServer::SCHEME_SOCKS5, "proxy", 999);
693 ConnectJobParams params = ConstructConnectJobParams(
694 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
695 /*allowed_bad_certs=*/{}, alpn_mode(),
696 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
697 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
698 &common_connect_job_params_, kProxyDnsNak);
699
700 scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
701 ExpectSSLSocketParams(params);
702 SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
703 VerifySSLSocketParams(endpoint_ssl_socket_params,
704 "endpoint_ssl_socket_params",
705 HostPortPair::FromSchemeHostPort(kEndpoint),
706 endpoint_ssl_config, privacy_mode(), kEndpointNak);
707
708 scoped_refptr<SOCKSSocketParams> socks_socket_params =
709 endpoint_ssl_socket_params->GetSocksProxyConnectionParams();
710 VerifySOCKSSocketParams(socks_socket_params, "socks_socket_params",
711 /*is_socks_v5=*/true,
712 HostPortPair::FromSchemeHostPort(kEndpoint),
713 kEndpointNak);
714
715 scoped_refptr<TransportSocketParams> transport_socket_params =
716 socks_socket_params->transport_params();
717 VerifyTransportSocketParams(
718 transport_socket_params, "transport_socket_params",
719 HostPortPair("proxy", 999), secure_dns_policy(), kProxyDnsNak, {});
720 }
721
722 // A connection to an HTTP endpoint via a two-proxy HTTPS chain
723 // sets up the required parameters.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpointViaHttpsProxyViaHttpsProxy)724 TEST_P(ConnectJobParamsFactoryTest, HttpEndpointViaHttpsProxyViaHttpsProxy) {
725 const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
726 ProxyChain proxy_chain = ProxyChain::ForIpProtection({
727 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxya",
728 443),
729 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyb",
730 443),
731 });
732 ConnectJobParams params = ConstructConnectJobParams(
733 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
734 /*allowed_bad_certs=*/{}, alpn_mode(),
735 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
736 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
737 &common_connect_job_params_, kProxyDnsNak);
738
739 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_b =
740 ExpectHttpProxySocketParams(params);
741 VerifyHttpProxySocketParams(
742 http_proxy_socket_params_b, "http_proxy_socket_params_b",
743 /*quic_ssl_config=*/std::nullopt,
744 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
745 /*proxy_chain_index=*/1,
746 /*tunnel=*/true, kEndpointNak, secure_dns_policy());
747
748 scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_b =
749 http_proxy_socket_params_b->ssl_params();
750 ASSERT_TRUE(proxy_ssl_socket_params_b);
751 SSLConfig proxy_ssl_config = SSLConfigForProxy();
752 VerifySSLSocketParams(proxy_ssl_socket_params_b, "proxy_ssl_socket_params_b",
753 HostPortPair::FromString("proxyb:443"),
754 proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
755 kEndpointNak);
756
757 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_a =
758 proxy_ssl_socket_params_b->GetHttpProxyConnectionParams();
759 VerifyHttpProxySocketParams(
760 http_proxy_socket_params_a, "http_proxy_socket_params_a",
761 /*quic_ssl_config=*/std::nullopt, HostPortPair("proxyb", 443),
762 proxy_chain,
763 /*proxy_chain_index=*/0,
764 /*tunnel=*/true,
765 partition_proxy_chains() ? kEndpointNak : NetworkAnonymizationKey(),
766 secure_dns_policy());
767
768 scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_a =
769 http_proxy_socket_params_a->ssl_params();
770 ASSERT_TRUE(proxy_ssl_socket_params_a);
771 VerifySSLSocketParams(
772 proxy_ssl_socket_params_a, "proxy_ssl_socket_params_a",
773 HostPortPair::FromString("proxya:443"), proxy_ssl_config,
774 PrivacyMode::PRIVACY_MODE_DISABLED,
775 partition_proxy_chains() ? kEndpointNak : NetworkAnonymizationKey());
776
777 scoped_refptr<TransportSocketParams> transport_socket_params =
778 proxy_ssl_socket_params_a->GetDirectConnectionParams();
779 VerifyTransportSocketParams(
780 transport_socket_params, "transport_socket_params",
781 HostPortPair("proxya", 443), secure_dns_policy(), kProxyDnsNak,
782 AlpnProtoStringsForMode(alpn_mode()));
783 }
784
785 // A connection to an HTTPS endpoint via a two-proxy HTTPS chain
786 // sets up the required parameters.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaHttpsProxyViaHttpsProxy)787 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaHttpsProxyViaHttpsProxy) {
788 // HTTPS endpoints are not supported without ALPN.
789 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
790 return;
791 }
792
793 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
794 ProxyChain proxy_chain = ProxyChain::ForIpProtection({
795 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxya",
796 443),
797 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyb",
798 443),
799 });
800 ConnectJobParams params = ConstructConnectJobParams(
801 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
802 /*allowed_bad_certs=*/{}, alpn_mode(),
803 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
804 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
805 &common_connect_job_params_, kProxyDnsNak);
806
807 scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
808 ExpectSSLSocketParams(params);
809 SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
810 VerifySSLSocketParams(endpoint_ssl_socket_params,
811 "endpoint_ssl_socket_params",
812 HostPortPair::FromSchemeHostPort(kEndpoint),
813 endpoint_ssl_config, privacy_mode(), kEndpointNak);
814
815 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_b =
816 endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
817 VerifyHttpProxySocketParams(
818 http_proxy_socket_params_b, "http_proxy_socket_params_b",
819 /*quic_ssl_config=*/std::nullopt,
820 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
821 /*proxy_chain_index=*/1,
822 /*tunnel=*/true, kEndpointNak, secure_dns_policy());
823
824 scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_b =
825 http_proxy_socket_params_b->ssl_params();
826 ASSERT_TRUE(proxy_ssl_socket_params_b);
827 SSLConfig proxy_ssl_config = SSLConfigForProxy();
828 VerifySSLSocketParams(proxy_ssl_socket_params_b, "proxy_ssl_socket_params_b",
829 HostPortPair::FromString("proxyb:443"),
830 proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
831 kEndpointNak);
832
833 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_a =
834 proxy_ssl_socket_params_b->GetHttpProxyConnectionParams();
835 VerifyHttpProxySocketParams(
836 http_proxy_socket_params_a, "http_proxy_socket_params_a",
837 /*quic_ssl_config=*/std::nullopt, HostPortPair("proxyb", 443),
838 proxy_chain,
839 /*proxy_chain_index=*/0,
840 /*tunnel=*/true,
841 partition_proxy_chains() ? kEndpointNak : NetworkAnonymizationKey(),
842 secure_dns_policy());
843
844 scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_a =
845 http_proxy_socket_params_a->ssl_params();
846 ASSERT_TRUE(proxy_ssl_socket_params_a);
847 VerifySSLSocketParams(
848 proxy_ssl_socket_params_a, "proxy_ssl_socket_params_a",
849 HostPortPair::FromString("proxya:443"), proxy_ssl_config,
850 PrivacyMode::PRIVACY_MODE_DISABLED,
851 partition_proxy_chains() ? kEndpointNak : NetworkAnonymizationKey());
852
853 scoped_refptr<TransportSocketParams> transport_socket_params =
854 proxy_ssl_socket_params_a->GetDirectConnectionParams();
855 VerifyTransportSocketParams(
856 transport_socket_params, "transport_socket_params",
857 HostPortPair("proxya", 443), secure_dns_policy(), kProxyDnsNak,
858 AlpnProtoStringsForMode(alpn_mode()));
859 }
860
861 // A connection to an HTTPS endpoint via a two-proxy chain mixing QUIC and HTTPS
862 // sets up the required parameters.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaHttpsProxyViaQuicProxy)863 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaHttpsProxyViaQuicProxy) {
864 // HTTPS endpoints are not supported without ALPN.
865 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
866 return;
867 }
868
869 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
870 ProxyChain proxy_chain = ProxyChain::ForIpProtection({
871 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxya",
872 443),
873 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyb",
874 443),
875 });
876 ConnectJobParams params = ConstructConnectJobParams(
877 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
878 /*allowed_bad_certs=*/{}, alpn_mode(),
879 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
880 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
881 &common_connect_job_params_, kProxyDnsNak);
882
883 scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
884 ExpectSSLSocketParams(params);
885 SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
886 VerifySSLSocketParams(endpoint_ssl_socket_params,
887 "endpoint_ssl_socket_params",
888 HostPortPair::FromSchemeHostPort(kEndpoint),
889 endpoint_ssl_config, privacy_mode(), kEndpointNak);
890
891 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_b =
892 endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
893 VerifyHttpProxySocketParams(
894 http_proxy_socket_params_b, "http_proxy_socket_params_b",
895 /*quic_ssl_config=*/std::nullopt,
896 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
897 /*proxy_chain_index=*/1,
898 /*tunnel=*/true, kEndpointNak, secure_dns_policy());
899
900 scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_b =
901 http_proxy_socket_params_b->ssl_params();
902 ASSERT_TRUE(proxy_ssl_socket_params_b);
903 SSLConfig proxy_ssl_config = SSLConfigForProxy();
904 VerifySSLSocketParams(proxy_ssl_socket_params_b, "proxy_ssl_socket_params_b",
905 HostPortPair::FromString("proxyb:443"),
906 proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
907 kEndpointNak);
908
909 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_a =
910 proxy_ssl_socket_params_b->GetHttpProxyConnectionParams();
911 SSLConfig quic_ssl_config = SSLConfigForProxy();
912 VerifyHttpProxySocketParams(
913 http_proxy_socket_params_a, "http_proxy_socket_params_a", quic_ssl_config,
914 HostPortPair("proxyb", 443), proxy_chain,
915 /*proxy_chain_index=*/0,
916 /*tunnel=*/true,
917 partition_proxy_chains() ? kEndpointNak : NetworkAnonymizationKey(),
918 secure_dns_policy());
919 }
920
921 // A connection to an HTTPS endpoint via a two-proxy QUIC chain
922 // sets up the required parameters.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaQuicProxyViaQuicProxy)923 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaQuicProxyViaQuicProxy) {
924 // HTTPS endpoints are not supported without ALPN.
925 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
926 return;
927 }
928
929 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
930 ProxyChain proxy_chain = ProxyChain::ForIpProtection({
931 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxya",
932 443),
933 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxyb",
934 443),
935 });
936 ConnectJobParams params = ConstructConnectJobParams(
937 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
938 /*allowed_bad_certs=*/{}, alpn_mode(),
939 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
940 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
941 &common_connect_job_params_, kProxyDnsNak);
942
943 auto endpoint_ssl_socket_params = ExpectSSLSocketParams(params);
944 SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
945 VerifySSLSocketParams(endpoint_ssl_socket_params,
946 "endpoint_ssl_socket_params",
947 HostPortPair::FromSchemeHostPort(kEndpoint),
948 endpoint_ssl_config, privacy_mode(), kEndpointNak);
949
950 auto http_proxy_socket_params_b =
951 endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
952 SSLConfig quic_ssl_config_b = SSLConfigForProxy();
953 VerifyHttpProxySocketParams(
954 http_proxy_socket_params_b, "http_proxy_socket_params_b",
955 quic_ssl_config_b, HostPortPair::FromSchemeHostPort(kEndpoint),
956 proxy_chain,
957 /*proxy_chain_index=*/1,
958 /*tunnel=*/true, kEndpointNak, secure_dns_policy());
959 }
960
961 // A connection to an HTTPS endpoint via a proxy chain with two HTTPS proxies
962 // and two QUIC proxies.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaMixedProxyChain)963 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaMixedProxyChain) {
964 // HTTPS endpoints are not supported without ALPN.
965 if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
966 return;
967 }
968
969 const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
970 ProxyChain proxy_chain = ProxyChain::ForIpProtection({
971 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxya",
972 443),
973 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxyb",
974 443),
975 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyc",
976 443),
977 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyd",
978 443),
979 });
980 ConnectJobParams params = ConstructConnectJobParams(
981 kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
982 /*allowed_bad_certs=*/{}, alpn_mode(),
983 /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
984 kEndpointNak, secure_dns_policy(), disable_cert_network_fetches(),
985 &common_connect_job_params_, kProxyDnsNak);
986
987 auto endpoint_ssl_socket_params = ExpectSSLSocketParams(params);
988 SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
989 VerifySSLSocketParams(endpoint_ssl_socket_params,
990 "endpoint_ssl_socket_params",
991 HostPortPair::FromSchemeHostPort(kEndpoint),
992 endpoint_ssl_config, privacy_mode(), kEndpointNak);
993
994 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_d =
995 endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
996 VerifyHttpProxySocketParams(
997 http_proxy_socket_params_d, "http_proxy_socket_params_d",
998 /*quic_ssl_config=*/std::nullopt,
999 HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
1000 /*proxy_chain_index=*/3,
1001 /*tunnel=*/true, kEndpointNak, secure_dns_policy());
1002
1003 scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_d =
1004 http_proxy_socket_params_d->ssl_params();
1005 ASSERT_TRUE(proxy_ssl_socket_params_d);
1006 SSLConfig proxy_ssl_config = SSLConfigForProxy();
1007 VerifySSLSocketParams(proxy_ssl_socket_params_d, "proxy_ssl_socket_params_d",
1008 HostPortPair::FromString("proxyd:443"),
1009 proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
1010 kEndpointNak);
1011
1012 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_c =
1013 proxy_ssl_socket_params_d->GetHttpProxyConnectionParams();
1014 VerifyHttpProxySocketParams(
1015 http_proxy_socket_params_c, "http_proxy_socket_params_c",
1016 /*quic_ssl_config=*/std::nullopt, HostPortPair("proxyd", 443),
1017 proxy_chain,
1018 /*proxy_chain_index=*/2,
1019 /*tunnel=*/true,
1020 partition_proxy_chains() ? kEndpointNak : NetworkAnonymizationKey(),
1021 secure_dns_policy());
1022
1023 scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_c =
1024 http_proxy_socket_params_c->ssl_params();
1025 ASSERT_TRUE(proxy_ssl_socket_params_c);
1026 VerifySSLSocketParams(
1027 proxy_ssl_socket_params_c, "proxy_ssl_socket_params_c",
1028 HostPortPair::FromString("proxyc:443"), proxy_ssl_config,
1029 PrivacyMode::PRIVACY_MODE_DISABLED,
1030 partition_proxy_chains() ? kEndpointNak : NetworkAnonymizationKey());
1031
1032 auto http_proxy_socket_params_b =
1033 proxy_ssl_socket_params_c->GetHttpProxyConnectionParams();
1034 SSLConfig quic_ssl_config_b = SSLConfigForProxy();
1035 VerifyHttpProxySocketParams(
1036 http_proxy_socket_params_b, "http_proxy_socket_params_b",
1037 quic_ssl_config_b, HostPortPair("proxyc", 443), proxy_chain,
1038 /*proxy_chain_index=*/1,
1039 /*tunnel=*/true,
1040 partition_proxy_chains() ? kEndpointNak : NetworkAnonymizationKey(),
1041 secure_dns_policy());
1042 }
1043
1044 INSTANTIATE_TEST_SUITE_P(
1045 All,
1046 ConnectJobParamsFactoryTest,
1047 testing::ConvertGenerator<TestParams::ParamTuple>(testing::Combine(
1048 testing::Values(false, true),
1049 testing::Values(PrivacyMode::PRIVACY_MODE_ENABLED,
1050 PrivacyMode::PRIVACY_MODE_DISABLED),
1051 testing::Values(SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable),
1052 testing::Values(ConnectJobFactory::AlpnMode::kDisabled,
1053 ConnectJobFactory::AlpnMode::kHttp11Only,
1054 ConnectJobFactory::AlpnMode::kHttpAll),
1055 testing::Values(false, true),
1056 testing::Values(false, true))));
1057
1058 } // namespace
1059
1060 } // namespace net
1061