• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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