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