• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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/ssl_connect_job.h"
6 
7 #include <memory>
8 #include <string>
9 
10 #include "base/compiler_specific.h"
11 #include "base/functional/callback.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/test/metrics/histogram_tester.h"
15 #include "base/test/scoped_feature_list.h"
16 #include "base/test/task_environment.h"
17 #include "base/time/time.h"
18 #include "net/base/auth.h"
19 #include "net/base/features.h"
20 #include "net/base/host_port_pair.h"
21 #include "net/base/load_timing_info.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/network_anonymization_key.h"
24 #include "net/base/network_isolation_key.h"
25 #include "net/base/proxy_chain.h"
26 #include "net/base/proxy_server.h"
27 #include "net/base/proxy_string_util.h"
28 #include "net/cert/mock_cert_verifier.h"
29 #include "net/dns/mock_host_resolver.h"
30 #include "net/dns/public/secure_dns_policy.h"
31 #include "net/http/http_auth_handler_factory.h"
32 #include "net/http/http_network_session.h"
33 #include "net/http/http_proxy_connect_job.h"
34 #include "net/http/http_request_headers.h"
35 #include "net/http/http_response_headers.h"
36 #include "net/http/http_server_properties.h"
37 #include "net/http/transport_security_state.h"
38 #include "net/log/net_log_source.h"
39 #include "net/log/net_log_with_source.h"
40 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
41 #include "net/quic/quic_context.h"
42 #include "net/socket/connect_job_test_util.h"
43 #include "net/socket/connection_attempts.h"
44 #include "net/socket/next_proto.h"
45 #include "net/socket/socket_tag.h"
46 #include "net/socket/socket_test_util.h"
47 #include "net/socket/socks_connect_job.h"
48 #include "net/socket/transport_connect_job.h"
49 #include "net/ssl/ssl_config_service_defaults.h"
50 #include "net/ssl/ssl_connection_status_flags.h"
51 #include "net/ssl/test_ssl_config_service.h"
52 #include "net/test/cert_test_util.h"
53 #include "net/test/gtest_util.h"
54 #include "net/test/ssl_test_util.h"
55 #include "net/test/test_certificate_data.h"
56 #include "net/test/test_data_directory.h"
57 #include "net/test/test_with_task_environment.h"
58 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
59 #include "net/url_request/static_http_user_agent_settings.h"
60 #include "testing/gtest/include/gtest/gtest.h"
61 #include "third_party/boringssl/src/include/openssl/ssl.h"
62 #include "url/gurl.h"
63 #include "url/scheme_host_port.h"
64 #include "url/url_constants.h"
65 
66 namespace net {
67 namespace {
68 
ParseIP(const std::string & ip)69 IPAddress ParseIP(const std::string& ip) {
70   IPAddress address;
71   CHECK(address.AssignFromIPLiteral(ip));
72   return address;
73 }
74 
75 // Just check that all connect times are set to base::TimeTicks::Now(), for
76 // tests that don't update the mocked out time.
CheckConnectTimesSet(const LoadTimingInfo::ConnectTiming & connect_timing)77 void CheckConnectTimesSet(const LoadTimingInfo::ConnectTiming& connect_timing) {
78   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.domain_lookup_start);
79   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.domain_lookup_end);
80   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
81   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
82   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
83   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
84 }
85 
86 // Just check that all connect times are set to base::TimeTicks::Now(), except
87 // for DNS times, for tests that don't update the mocked out time and use a
88 // proxy.
CheckConnectTimesExceptDnsSet(const LoadTimingInfo::ConnectTiming & connect_timing)89 void CheckConnectTimesExceptDnsSet(
90     const LoadTimingInfo::ConnectTiming& connect_timing) {
91   EXPECT_TRUE(connect_timing.domain_lookup_start.is_null());
92   EXPECT_TRUE(connect_timing.domain_lookup_end.is_null());
93   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
94   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
95   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
96   EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
97 }
98 
99 const url::SchemeHostPort kHostHttps{url::kHttpsScheme, "host", 443};
100 const HostPortPair kHostHttp{"host", 80};
101 const ProxyServer kSocksProxyServer{ProxyServer::SCHEME_SOCKS5,
102                                     HostPortPair("sockshost", 443)};
103 const ProxyServer kHttpProxyServer{ProxyServer::SCHEME_HTTP,
104                                    HostPortPair("proxy", 443)};
105 
106 const ProxyChain kHttpProxyChain{kHttpProxyServer};
107 
108 class SSLConnectJobTest : public WithTaskEnvironment, public testing::Test {
109  public:
SSLConnectJobTest()110   SSLConnectJobTest()
111       : WithTaskEnvironment(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
112         proxy_resolution_service_(
113             ConfiguredProxyResolutionService::CreateDirect()),
114         ssl_config_service_(
115             std::make_unique<TestSSLConfigService>(SSLContextConfig())),
116         http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
117         session_(CreateNetworkSession()),
118         common_connect_job_params_(session_->CreateCommonConnectJobParams()) {}
119 
120   ~SSLConnectJobTest() override = default;
121 
CreateDirectTransportSocketParams(SecureDnsPolicy secure_dns_policy) const122   scoped_refptr<TransportSocketParams> CreateDirectTransportSocketParams(
123       SecureDnsPolicy secure_dns_policy) const {
124     return base::MakeRefCounted<TransportSocketParams>(
125         kHostHttps, NetworkAnonymizationKey(), secure_dns_policy,
126         OnHostResolutionCallback(),
127         /*supported_alpns=*/base::flat_set<std::string>({"h2", "http/1.1"}));
128   }
129 
CreateProxyTransportSocketParams(SecureDnsPolicy secure_dns_policy) const130   scoped_refptr<TransportSocketParams> CreateProxyTransportSocketParams(
131       SecureDnsPolicy secure_dns_policy) const {
132     return base::MakeRefCounted<TransportSocketParams>(
133         kHttpProxyServer.host_port_pair(), NetworkAnonymizationKey(),
134         secure_dns_policy, OnHostResolutionCallback(),
135         /*supported_alpns=*/base::flat_set<std::string>({}));
136   }
137 
CreateSOCKSSocketParams(SecureDnsPolicy secure_dns_policy)138   scoped_refptr<SOCKSSocketParams> CreateSOCKSSocketParams(
139       SecureDnsPolicy secure_dns_policy) {
140     return base::MakeRefCounted<SOCKSSocketParams>(
141         ConnectJobParams(CreateProxyTransportSocketParams(secure_dns_policy)),
142         kSocksProxyServer.scheme() == ProxyServer::SCHEME_SOCKS5,
143         kSocksProxyServer.host_port_pair(), NetworkAnonymizationKey(),
144         TRAFFIC_ANNOTATION_FOR_TESTS);
145   }
146 
CreateHttpProxySocketParams(SecureDnsPolicy secure_dns_policy)147   scoped_refptr<HttpProxySocketParams> CreateHttpProxySocketParams(
148       SecureDnsPolicy secure_dns_policy) {
149     return base::MakeRefCounted<HttpProxySocketParams>(
150         ConnectJobParams(CreateProxyTransportSocketParams(secure_dns_policy)),
151         kHostHttp, kHttpProxyChain,
152         /*proxy_server_index=*/0,
153         /*tunnel=*/true, TRAFFIC_ANNOTATION_FOR_TESTS,
154         NetworkAnonymizationKey(), secure_dns_policy);
155   }
156 
CreateConnectJob(TestConnectJobDelegate * test_delegate,ProxyChain proxy_chain=ProxyChain::Direct (),RequestPriority priority=DEFAULT_PRIORITY,SecureDnsPolicy secure_dns_policy=SecureDnsPolicy::kAllow)157   std::unique_ptr<ConnectJob> CreateConnectJob(
158       TestConnectJobDelegate* test_delegate,
159       ProxyChain proxy_chain = ProxyChain::Direct(),
160       RequestPriority priority = DEFAULT_PRIORITY,
161       SecureDnsPolicy secure_dns_policy = SecureDnsPolicy::kAllow) {
162     return std::make_unique<SSLConnectJob>(
163         priority, SocketTag(), &common_connect_job_params_,
164         CreateSSLSocketParams(proxy_chain, secure_dns_policy), test_delegate,
165         /*net_log=*/nullptr);
166   }
167 
CreateSSLSocketParams(ProxyChain proxy_chain,SecureDnsPolicy secure_dns_policy)168   scoped_refptr<SSLSocketParams> CreateSSLSocketParams(
169       ProxyChain proxy_chain,
170       SecureDnsPolicy secure_dns_policy) {
171     return base::MakeRefCounted<SSLSocketParams>(
172         proxy_chain == ProxyChain::Direct()
173             ? ConnectJobParams(
174                   CreateDirectTransportSocketParams(secure_dns_policy))
175         : proxy_chain.is_single_proxy() &&
176                 proxy_chain.First().scheme() == ProxyServer::SCHEME_SOCKS5
177             ? ConnectJobParams(CreateSOCKSSocketParams(secure_dns_policy))
178         : proxy_chain.is_single_proxy() &&
179                 proxy_chain.First().scheme() == ProxyServer::SCHEME_HTTP
180             ? ConnectJobParams(CreateHttpProxySocketParams(secure_dns_policy))
181             : ConnectJobParams(),
182         HostPortPair::FromSchemeHostPort(kHostHttps), SSLConfig(),
183         NetworkAnonymizationKey());
184   }
185 
AddAuthToCache()186   void AddAuthToCache() {
187     const std::u16string kFoo(u"foo");
188     const std::u16string kBar(u"bar");
189     session_->http_auth_cache()->Add(
190         url::SchemeHostPort(GURL("http://proxy:443/")), HttpAuth::AUTH_PROXY,
191         "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
192         "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
193   }
194 
CreateNetworkSession()195   std::unique_ptr<HttpNetworkSession> CreateNetworkSession() {
196     HttpNetworkSessionContext session_context;
197     session_context.host_resolver = &host_resolver_;
198     session_context.cert_verifier = &cert_verifier_;
199     session_context.transport_security_state = &transport_security_state_;
200     session_context.proxy_resolution_service = proxy_resolution_service_.get();
201     session_context.client_socket_factory = &socket_factory_;
202     session_context.ssl_config_service = ssl_config_service_.get();
203     session_context.http_auth_handler_factory =
204         http_auth_handler_factory_.get();
205     session_context.http_server_properties = &http_server_properties_;
206     session_context.http_user_agent_settings = &http_user_agent_settings_;
207     session_context.quic_context = &quic_context_;
208     return std::make_unique<HttpNetworkSession>(HttpNetworkSessionParams(),
209                                                 session_context);
210   }
211 
212  protected:
213   MockClientSocketFactory socket_factory_;
214   MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
215                                       RuleResolver::GetLocalhostResult()};
216   MockCertVerifier cert_verifier_;
217   TransportSecurityState transport_security_state_;
218   const std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
219   const std::unique_ptr<TestSSLConfigService> ssl_config_service_;
220   const std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
221   const StaticHttpUserAgentSettings http_user_agent_settings_ = {"*",
222                                                                  "test-ua"};
223   HttpServerProperties http_server_properties_;
224   QuicContext quic_context_;
225   const std::unique_ptr<HttpNetworkSession> session_;
226 
227   const CommonConnectJobParams common_connect_job_params_;
228 };
229 
TEST_F(SSLConnectJobTest,TCPFail)230 TEST_F(SSLConnectJobTest, TCPFail) {
231   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
232     SCOPED_TRACE(io_mode);
233     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
234     StaticSocketDataProvider data;
235     data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
236     socket_factory_.AddSocketDataProvider(&data);
237 
238     TestConnectJobDelegate test_delegate;
239     std::unique_ptr<ConnectJob> ssl_connect_job =
240         CreateConnectJob(&test_delegate);
241     test_delegate.StartJobExpectingResult(
242         ssl_connect_job.get(), ERR_CONNECTION_FAILED, io_mode == SYNCHRONOUS);
243     EXPECT_FALSE(test_delegate.socket());
244     EXPECT_FALSE(ssl_connect_job->IsSSLError());
245     ConnectionAttempts connection_attempts =
246         ssl_connect_job->GetConnectionAttempts();
247     ASSERT_EQ(1u, connection_attempts.size());
248     EXPECT_THAT(connection_attempts[0].result,
249                 test::IsError(ERR_CONNECTION_FAILED));
250   }
251 }
252 
TEST_F(SSLConnectJobTest,TCPTimeout)253 TEST_F(SSLConnectJobTest, TCPTimeout) {
254   const base::TimeDelta kTinyTime = base::Microseconds(1);
255 
256   // Make request hang.
257   host_resolver_.set_ondemand_mode(true);
258 
259   TestConnectJobDelegate test_delegate;
260   std::unique_ptr<ConnectJob> ssl_connect_job =
261       CreateConnectJob(&test_delegate);
262   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
263 
264   // Right up until just before the TCP connection timeout, the job does not
265   // time out.
266   FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
267   EXPECT_FALSE(test_delegate.has_result());
268 
269   // But at the exact time of TCP connection timeout, the job fails.
270   FastForwardBy(kTinyTime);
271   EXPECT_TRUE(test_delegate.has_result());
272   EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
273 }
274 
TEST_F(SSLConnectJobTest,SSLTimeoutSyncConnect)275 TEST_F(SSLConnectJobTest, SSLTimeoutSyncConnect) {
276   const base::TimeDelta kTinyTime = base::Microseconds(1);
277 
278   // DNS lookup and transport connect complete synchronously, but SSL
279   // negotiation hangs.
280   host_resolver_.set_synchronous_mode(true);
281   StaticSocketDataProvider data;
282   data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
283   socket_factory_.AddSocketDataProvider(&data);
284   SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
285   socket_factory_.AddSSLSocketDataProvider(&ssl);
286 
287   // Make request hang.
288   TestConnectJobDelegate test_delegate;
289   std::unique_ptr<ConnectJob> ssl_connect_job =
290       CreateConnectJob(&test_delegate);
291   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
292 
293   // Right up until just before the SSL handshake timeout, the job does not time
294   // out.
295   FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
296   EXPECT_FALSE(test_delegate.has_result());
297 
298   // But at the exact SSL handshake timeout time, the job fails.
299   FastForwardBy(kTinyTime);
300   EXPECT_TRUE(test_delegate.has_result());
301   EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
302 }
303 
TEST_F(SSLConnectJobTest,SSLTimeoutAsyncTcpConnect)304 TEST_F(SSLConnectJobTest, SSLTimeoutAsyncTcpConnect) {
305   const base::TimeDelta kTinyTime = base::Microseconds(1);
306 
307   // DNS lookup is asynchronous, and later SSL negotiation hangs.
308   host_resolver_.set_ondemand_mode(true);
309   StaticSocketDataProvider data;
310   data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
311   socket_factory_.AddSocketDataProvider(&data);
312   SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
313   socket_factory_.AddSSLSocketDataProvider(&ssl);
314 
315   TestConnectJobDelegate test_delegate;
316   std::unique_ptr<ConnectJob> ssl_connect_job =
317       CreateConnectJob(&test_delegate);
318   // Connecting should hand on the TransportConnectJob connect.
319   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
320 
321   // Right up until just before the TCP connection timeout, the job does not
322   // time out.
323   FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
324   EXPECT_FALSE(test_delegate.has_result());
325 
326   // The DNS lookup completes, and a TCP connection is immediately establshed,
327   // which cancels the TCP connection timer. The SSL handshake timer is started,
328   // and the SSL handshake hangs.
329   host_resolver_.ResolveOnlyRequestNow();
330   EXPECT_FALSE(test_delegate.has_result());
331 
332   // Right up until just before the SSL handshake timeout, the job does not time
333   // out.
334   FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
335   EXPECT_FALSE(test_delegate.has_result());
336 
337   // But at the exact SSL handshake timeout time, the job fails.
338   FastForwardBy(kTinyTime);
339   EXPECT_TRUE(test_delegate.has_result());
340   EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
341 }
342 
TEST_F(SSLConnectJobTest,BasicDirectSync)343 TEST_F(SSLConnectJobTest, BasicDirectSync) {
344   host_resolver_.set_synchronous_mode(true);
345   StaticSocketDataProvider data;
346   data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
347   socket_factory_.AddSocketDataProvider(&data);
348   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
349   socket_factory_.AddSSLSocketDataProvider(&ssl);
350 
351   TestConnectJobDelegate test_delegate;
352   std::unique_ptr<ConnectJob> ssl_connect_job =
353       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
354 
355   test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
356                                         true /* expect_sync_result */);
357   EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
358 
359   ConnectionAttempts connection_attempts =
360       ssl_connect_job->GetConnectionAttempts();
361   EXPECT_EQ(0u, connection_attempts.size());
362   CheckConnectTimesSet(ssl_connect_job->connect_timing());
363 }
364 
TEST_F(SSLConnectJobTest,BasicDirectAsync)365 TEST_F(SSLConnectJobTest, BasicDirectAsync) {
366   host_resolver_.set_ondemand_mode(true);
367   base::TimeTicks start_time = base::TimeTicks::Now();
368   StaticSocketDataProvider data;
369   data.set_connect_data(MockConnect(ASYNC, OK));
370   socket_factory_.AddSocketDataProvider(&data);
371   SSLSocketDataProvider ssl(ASYNC, OK);
372   socket_factory_.AddSSLSocketDataProvider(&ssl);
373 
374   TestConnectJobDelegate test_delegate;
375   std::unique_ptr<ConnectJob> ssl_connect_job =
376       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
377   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
378   EXPECT_TRUE(host_resolver_.has_pending_requests());
379   EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
380   FastForwardBy(base::Seconds(5));
381 
382   base::TimeTicks resolve_complete_time = base::TimeTicks::Now();
383   host_resolver_.ResolveAllPending();
384   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
385 
386   ConnectionAttempts connection_attempts =
387       ssl_connect_job->GetConnectionAttempts();
388   EXPECT_EQ(0u, connection_attempts.size());
389 
390   // Check times. Since time is mocked out, all times will be the same, except
391   // |dns_start|, which is the only one recorded before the FastForwardBy()
392   // call. The test classes don't allow any other phases to be triggered on
393   // demand, or delayed by a set interval.
394   EXPECT_EQ(start_time, ssl_connect_job->connect_timing().domain_lookup_start);
395   EXPECT_EQ(resolve_complete_time,
396             ssl_connect_job->connect_timing().domain_lookup_end);
397   EXPECT_EQ(resolve_complete_time,
398             ssl_connect_job->connect_timing().connect_start);
399   EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_start);
400   EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_end);
401   EXPECT_EQ(resolve_complete_time,
402             ssl_connect_job->connect_timing().connect_end);
403 }
404 
TEST_F(SSLConnectJobTest,DirectHasEstablishedConnection)405 TEST_F(SSLConnectJobTest, DirectHasEstablishedConnection) {
406   host_resolver_.set_ondemand_mode(true);
407   StaticSocketDataProvider data;
408   data.set_connect_data(MockConnect(ASYNC, OK));
409   socket_factory_.AddSocketDataProvider(&data);
410 
411   // SSL negotiation hangs. Value returned after SSL negotiation is complete
412   // doesn't matter, as HasEstablishedConnection() may only be used between job
413   // start and job complete.
414   SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
415   socket_factory_.AddSSLSocketDataProvider(&ssl);
416 
417   TestConnectJobDelegate test_delegate;
418   std::unique_ptr<ConnectJob> ssl_connect_job =
419       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
420   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
421   EXPECT_TRUE(host_resolver_.has_pending_requests());
422   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
423   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
424 
425   // DNS resolution completes, and then the ConnectJob tries to connect the
426   // socket, which should succeed asynchronously.
427   host_resolver_.ResolveNow(1);
428   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
429   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
430 
431   // Spinning the message loop causes the socket to finish connecting. The SSL
432   // handshake should start and hang.
433   base::RunLoop().RunUntilIdle();
434   EXPECT_FALSE(test_delegate.has_result());
435   EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
436   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
437 }
438 
TEST_F(SSLConnectJobTest,RequestPriority)439 TEST_F(SSLConnectJobTest, RequestPriority) {
440   host_resolver_.set_ondemand_mode(true);
441   for (int initial_priority = MINIMUM_PRIORITY;
442        initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
443     SCOPED_TRACE(initial_priority);
444     for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
445          ++new_priority) {
446       SCOPED_TRACE(new_priority);
447       if (initial_priority == new_priority) {
448         continue;
449       }
450       TestConnectJobDelegate test_delegate;
451       std::unique_ptr<ConnectJob> ssl_connect_job =
452           CreateConnectJob(&test_delegate, ProxyChain::Direct(),
453                            static_cast<RequestPriority>(initial_priority));
454       EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
455       EXPECT_TRUE(host_resolver_.has_pending_requests());
456       int request_id = host_resolver_.num_resolve();
457       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
458 
459       ssl_connect_job->ChangePriority(
460           static_cast<RequestPriority>(new_priority));
461       EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
462 
463       ssl_connect_job->ChangePriority(
464           static_cast<RequestPriority>(initial_priority));
465       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
466     }
467   }
468 }
469 
TEST_F(SSLConnectJobTest,SecureDnsPolicy)470 TEST_F(SSLConnectJobTest, SecureDnsPolicy) {
471   for (auto secure_dns_policy :
472        {SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable}) {
473     TestConnectJobDelegate test_delegate;
474     std::unique_ptr<ConnectJob> ssl_connect_job =
475         CreateConnectJob(&test_delegate, ProxyChain::Direct(), DEFAULT_PRIORITY,
476                          secure_dns_policy);
477 
478     EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
479     EXPECT_EQ(secure_dns_policy, host_resolver_.last_secure_dns_policy());
480   }
481 }
482 
TEST_F(SSLConnectJobTest,DirectHostResolutionFailure)483 TEST_F(SSLConnectJobTest, DirectHostResolutionFailure) {
484   host_resolver_.rules()->AddSimulatedTimeoutFailure("host");
485 
486   TestConnectJobDelegate test_delegate;
487   std::unique_ptr<ConnectJob> ssl_connect_job =
488       CreateConnectJob(&test_delegate, ProxyChain::Direct());
489   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
490                                         ERR_NAME_NOT_RESOLVED,
491                                         false /* expect_sync_result */);
492   EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
493               test::IsError(ERR_DNS_TIMED_OUT));
494 }
495 
TEST_F(SSLConnectJobTest,DirectCertError)496 TEST_F(SSLConnectJobTest, DirectCertError) {
497   StaticSocketDataProvider data;
498   socket_factory_.AddSocketDataProvider(&data);
499   SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
500   socket_factory_.AddSSLSocketDataProvider(&ssl);
501 
502   TestConnectJobDelegate test_delegate(
503       TestConnectJobDelegate::SocketExpected::ALWAYS);
504   std::unique_ptr<ConnectJob> ssl_connect_job =
505       CreateConnectJob(&test_delegate);
506 
507   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
508                                         ERR_CERT_COMMON_NAME_INVALID,
509                                         false /* expect_sync_result */);
510   EXPECT_TRUE(ssl_connect_job->IsSSLError());
511   ConnectionAttempts connection_attempts =
512       ssl_connect_job->GetConnectionAttempts();
513   ASSERT_EQ(1u, connection_attempts.size());
514   EXPECT_THAT(connection_attempts[0].result,
515               test::IsError(ERR_CERT_COMMON_NAME_INVALID));
516   CheckConnectTimesSet(ssl_connect_job->connect_timing());
517 }
518 
TEST_F(SSLConnectJobTest,DirectIgnoreCertErrors)519 TEST_F(SSLConnectJobTest, DirectIgnoreCertErrors) {
520   session_->IgnoreCertificateErrorsForTesting();
521 
522   StaticSocketDataProvider data;
523   socket_factory_.AddSocketDataProvider(&data);
524   SSLSocketDataProvider ssl(ASYNC, OK);
525   ssl.expected_ignore_certificate_errors = true;
526   socket_factory_.AddSSLSocketDataProvider(&ssl);
527 
528   TestConnectJobDelegate test_delegate(
529       TestConnectJobDelegate::SocketExpected::ALWAYS);
530   std::unique_ptr<ConnectJob> ssl_connect_job =
531       CreateConnectJob(&test_delegate);
532 
533   test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
534                                         /*expect_sync_result=*/false);
535 }
536 
TEST_F(SSLConnectJobTest,DirectSSLError)537 TEST_F(SSLConnectJobTest, DirectSSLError) {
538   StaticSocketDataProvider data;
539   socket_factory_.AddSocketDataProvider(&data);
540   SSLSocketDataProvider ssl(ASYNC, ERR_BAD_SSL_CLIENT_AUTH_CERT);
541   socket_factory_.AddSSLSocketDataProvider(&ssl);
542 
543   TestConnectJobDelegate test_delegate;
544   std::unique_ptr<ConnectJob> ssl_connect_job =
545       CreateConnectJob(&test_delegate);
546 
547   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
548                                         ERR_BAD_SSL_CLIENT_AUTH_CERT,
549                                         false /* expect_sync_result */);
550   ConnectionAttempts connection_attempts =
551       ssl_connect_job->GetConnectionAttempts();
552   ASSERT_EQ(1u, connection_attempts.size());
553   EXPECT_THAT(connection_attempts[0].result,
554               test::IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
555 }
556 
TEST_F(SSLConnectJobTest,DirectWithNPN)557 TEST_F(SSLConnectJobTest, DirectWithNPN) {
558   StaticSocketDataProvider data;
559   socket_factory_.AddSocketDataProvider(&data);
560   SSLSocketDataProvider ssl(ASYNC, OK);
561   ssl.next_proto = kProtoHTTP11;
562   socket_factory_.AddSSLSocketDataProvider(&ssl);
563 
564   TestConnectJobDelegate test_delegate;
565   std::unique_ptr<ConnectJob> ssl_connect_job =
566       CreateConnectJob(&test_delegate);
567 
568   test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
569                                         false /* expect_sync_result */);
570   CheckConnectTimesSet(ssl_connect_job->connect_timing());
571 }
572 
TEST_F(SSLConnectJobTest,DirectGotHTTP2)573 TEST_F(SSLConnectJobTest, DirectGotHTTP2) {
574   StaticSocketDataProvider data;
575   socket_factory_.AddSocketDataProvider(&data);
576   SSLSocketDataProvider ssl(ASYNC, OK);
577   ssl.next_proto = kProtoHTTP2;
578   socket_factory_.AddSSLSocketDataProvider(&ssl);
579 
580   TestConnectJobDelegate test_delegate;
581   std::unique_ptr<ConnectJob> ssl_connect_job =
582       CreateConnectJob(&test_delegate);
583 
584   test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
585                                         false /* expect_sync_result */);
586   EXPECT_EQ(kProtoHTTP2, test_delegate.socket()->GetNegotiatedProtocol());
587   CheckConnectTimesSet(ssl_connect_job->connect_timing());
588 }
589 
TEST_F(SSLConnectJobTest,SOCKSFail)590 TEST_F(SSLConnectJobTest, SOCKSFail) {
591   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
592     SCOPED_TRACE(io_mode);
593     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
594     StaticSocketDataProvider data;
595     data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
596     socket_factory_.AddSocketDataProvider(&data);
597 
598     TestConnectJobDelegate test_delegate;
599     std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
600         &test_delegate, PacResultElementToProxyChain("SOCKS5 foo:333"));
601     test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
602                                           ERR_PROXY_CONNECTION_FAILED,
603                                           io_mode == SYNCHRONOUS);
604     EXPECT_FALSE(ssl_connect_job->IsSSLError());
605 
606     ConnectionAttempts connection_attempts =
607         ssl_connect_job->GetConnectionAttempts();
608     EXPECT_EQ(0u, connection_attempts.size());
609   }
610 }
611 
TEST_F(SSLConnectJobTest,SOCKSHostResolutionFailure)612 TEST_F(SSLConnectJobTest, SOCKSHostResolutionFailure) {
613   host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
614 
615   TestConnectJobDelegate test_delegate;
616   std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
617       &test_delegate, PacResultElementToProxyChain("SOCKS5 foo:333"));
618   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
619                                         ERR_PROXY_CONNECTION_FAILED,
620                                         false /* expect_sync_result */);
621   EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
622               test::IsError(ERR_DNS_TIMED_OUT));
623 }
624 
TEST_F(SSLConnectJobTest,SOCKSBasic)625 TEST_F(SSLConnectJobTest, SOCKSBasic) {
626   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
627     SCOPED_TRACE(io_mode);
628     const uint8_t kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
629                                       'o',  'c',  'k',  's',  'h',  'o',
630                                       's',  't',  0x01, 0xBB};
631 
632     MockWrite writes[] = {
633         MockWrite(io_mode, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
634         MockWrite(io_mode, reinterpret_cast<const char*>(kSOCKS5Request),
635                   std::size(kSOCKS5Request)),
636     };
637 
638     MockRead reads[] = {
639         MockRead(io_mode, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
640         MockRead(io_mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
641     };
642 
643     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
644     StaticSocketDataProvider data(reads, writes);
645     data.set_connect_data(MockConnect(io_mode, OK));
646     socket_factory_.AddSocketDataProvider(&data);
647     SSLSocketDataProvider ssl(io_mode, OK);
648     socket_factory_.AddSSLSocketDataProvider(&ssl);
649 
650     TestConnectJobDelegate test_delegate;
651     std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
652         &test_delegate, PacResultElementToProxyChain("SOCKS5 foo:333"));
653     test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
654                                           io_mode == SYNCHRONOUS);
655     CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
656 
657     // Proxies should not set any DNS aliases.
658     EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
659   }
660 }
661 
TEST_F(SSLConnectJobTest,SOCKSHasEstablishedConnection)662 TEST_F(SSLConnectJobTest, SOCKSHasEstablishedConnection) {
663   const uint8_t kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
664                                     'o',  'c',  'k',  's',  'h',  'o',
665                                     's',  't',  0x01, 0xBB};
666 
667   MockWrite writes[] = {
668       MockWrite(SYNCHRONOUS, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength, 0),
669       MockWrite(SYNCHRONOUS, reinterpret_cast<const char*>(kSOCKS5Request),
670                 std::size(kSOCKS5Request), 3),
671   };
672 
673   MockRead reads[] = {
674       // Pause so can probe current state.
675       MockRead(ASYNC, ERR_IO_PENDING, 1),
676       MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength, 2),
677       MockRead(SYNCHRONOUS, kSOCKS5OkResponse, kSOCKS5OkResponseLength, 4),
678   };
679 
680   host_resolver_.set_ondemand_mode(true);
681   SequencedSocketData data(reads, writes);
682   data.set_connect_data(MockConnect(ASYNC, OK));
683   socket_factory_.AddSocketDataProvider(&data);
684 
685   // SSL negotiation hangs. Value returned after SSL negotiation is complete
686   // doesn't matter, as HasEstablishedConnection() may only be used between job
687   // start and job complete.
688   SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
689   socket_factory_.AddSSLSocketDataProvider(&ssl);
690 
691   TestConnectJobDelegate test_delegate;
692   std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
693       &test_delegate, PacResultElementToProxyChain("SOCKS5 foo:333"));
694   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
695   EXPECT_TRUE(host_resolver_.has_pending_requests());
696   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
697   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
698 
699   // DNS resolution completes, and then the ConnectJob tries to connect the
700   // socket, which should succeed asynchronously.
701   host_resolver_.ResolveNow(1);
702   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
703   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
704 
705   // Spin the message loop until the first read of the handshake.
706   // HasEstablishedConnection() should return true, as a TCP connection has been
707   // successfully established by this point.
708   data.RunUntilPaused();
709   EXPECT_FALSE(test_delegate.has_result());
710   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
711   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
712 
713   // Finish up the handshake, and spin the message loop until the SSL handshake
714   // starts and hang.
715   data.Resume();
716   base::RunLoop().RunUntilIdle();
717   EXPECT_FALSE(test_delegate.has_result());
718   EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
719   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
720 }
721 
TEST_F(SSLConnectJobTest,SOCKSRequestPriority)722 TEST_F(SSLConnectJobTest, SOCKSRequestPriority) {
723   host_resolver_.set_ondemand_mode(true);
724   for (int initial_priority = MINIMUM_PRIORITY;
725        initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
726     SCOPED_TRACE(initial_priority);
727     for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
728          ++new_priority) {
729       SCOPED_TRACE(new_priority);
730       if (initial_priority == new_priority) {
731         continue;
732       }
733       TestConnectJobDelegate test_delegate;
734       std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
735           &test_delegate, PacResultElementToProxyChain("SOCKS5 foo:333"),
736           static_cast<RequestPriority>(initial_priority));
737       EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
738       EXPECT_TRUE(host_resolver_.has_pending_requests());
739       int request_id = host_resolver_.num_resolve();
740       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
741 
742       ssl_connect_job->ChangePriority(
743           static_cast<RequestPriority>(new_priority));
744       EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
745 
746       ssl_connect_job->ChangePriority(
747           static_cast<RequestPriority>(initial_priority));
748       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
749     }
750   }
751 }
752 
TEST_F(SSLConnectJobTest,HttpProxyFail)753 TEST_F(SSLConnectJobTest, HttpProxyFail) {
754   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
755     SCOPED_TRACE(io_mode);
756     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
757     StaticSocketDataProvider data;
758     data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
759     socket_factory_.AddSocketDataProvider(&data);
760 
761     TestConnectJobDelegate test_delegate;
762     std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
763         &test_delegate, PacResultElementToProxyChain("PROXY foo:444"));
764     test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
765                                           ERR_PROXY_CONNECTION_FAILED,
766                                           io_mode == SYNCHRONOUS);
767 
768     EXPECT_FALSE(ssl_connect_job->IsSSLError());
769     ConnectionAttempts connection_attempts =
770         ssl_connect_job->GetConnectionAttempts();
771     EXPECT_EQ(0u, connection_attempts.size());
772   }
773 }
774 
TEST_F(SSLConnectJobTest,HttpProxyHostResolutionFailure)775 TEST_F(SSLConnectJobTest, HttpProxyHostResolutionFailure) {
776   host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
777 
778   TestConnectJobDelegate test_delegate;
779   std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
780       &test_delegate, PacResultElementToProxyChain("PROXY foo:444"));
781   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
782                                         ERR_PROXY_CONNECTION_FAILED,
783                                         false /* expect_sync_result */);
784   EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
785               test::IsError(ERR_DNS_TIMED_OUT));
786 }
787 
TEST_F(SSLConnectJobTest,HttpProxyAuthChallenge)788 TEST_F(SSLConnectJobTest, HttpProxyAuthChallenge) {
789   MockWrite writes[] = {
790       MockWrite(ASYNC, 0,
791                 "CONNECT host:80 HTTP/1.1\r\n"
792                 "Host: host:80\r\n"
793                 "Proxy-Connection: keep-alive\r\n"
794                 "User-Agent: test-ua\r\n\r\n"),
795       MockWrite(ASYNC, 5,
796                 "CONNECT host:80 HTTP/1.1\r\n"
797                 "Host: host:80\r\n"
798                 "Proxy-Connection: keep-alive\r\n"
799                 "User-Agent: test-ua\r\n"
800                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
801   };
802   MockRead reads[] = {
803       MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
804       MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
805       MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
806       MockRead(ASYNC, 4, "0123456789"),
807       MockRead(ASYNC, 6, "HTTP/1.1 200 Connection Established\r\n\r\n"),
808   };
809   StaticSocketDataProvider data(reads, writes);
810   socket_factory_.AddSocketDataProvider(&data);
811   SSLSocketDataProvider ssl(ASYNC, OK);
812   socket_factory_.AddSSLSocketDataProvider(&ssl);
813 
814   TestConnectJobDelegate test_delegate;
815   std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
816       &test_delegate, PacResultElementToProxyChain("PROXY foo:444"));
817   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
818   test_delegate.WaitForAuthChallenge(1);
819 
820   EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code());
821   std::string proxy_authenticate;
822   ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader(
823       nullptr, "Proxy-Authenticate", &proxy_authenticate));
824   EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\"");
825 
826   // While waiting for auth credentials to be provided, the Job should not time
827   // out.
828   FastForwardBy(base::Days(1));
829   test_delegate.WaitForAuthChallenge(1);
830   EXPECT_FALSE(test_delegate.has_result());
831 
832   // Respond to challenge.
833   test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
834   test_delegate.RunAuthCallback();
835 
836   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
837 
838   // Proxies should not set any DNS aliases.
839   EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
840 }
841 
TEST_F(SSLConnectJobTest,HttpProxyAuthWithCachedCredentials)842 TEST_F(SSLConnectJobTest, HttpProxyAuthWithCachedCredentials) {
843   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
844     SCOPED_TRACE(io_mode);
845     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
846     MockWrite writes[] = {
847         MockWrite(io_mode,
848                   "CONNECT host:80 HTTP/1.1\r\n"
849                   "Host: host:80\r\n"
850                   "Proxy-Connection: keep-alive\r\n"
851                   "User-Agent: test-ua\r\n"
852                   "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
853     };
854     MockRead reads[] = {
855         MockRead(io_mode, "HTTP/1.1 200 Connection Established\r\n\r\n"),
856     };
857     StaticSocketDataProvider data(reads, writes);
858     data.set_connect_data(MockConnect(io_mode, OK));
859     socket_factory_.AddSocketDataProvider(&data);
860     AddAuthToCache();
861     SSLSocketDataProvider ssl(io_mode, OK);
862     socket_factory_.AddSSLSocketDataProvider(&ssl);
863 
864     TestConnectJobDelegate test_delegate;
865     std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
866         &test_delegate, PacResultElementToProxyChain("PROXY foo:444"));
867     test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
868                                           io_mode == SYNCHRONOUS);
869     CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
870     EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
871   }
872 }
873 
TEST_F(SSLConnectJobTest,HttpProxyRequestPriority)874 TEST_F(SSLConnectJobTest, HttpProxyRequestPriority) {
875   host_resolver_.set_ondemand_mode(true);
876   for (int initial_priority = MINIMUM_PRIORITY;
877        initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
878     SCOPED_TRACE(initial_priority);
879     for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
880          ++new_priority) {
881       SCOPED_TRACE(new_priority);
882       if (initial_priority == new_priority) {
883         continue;
884       }
885       TestConnectJobDelegate test_delegate;
886       std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
887           &test_delegate, PacResultElementToProxyChain("PROXY foo:444"),
888           static_cast<RequestPriority>(initial_priority));
889       EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
890       EXPECT_TRUE(host_resolver_.has_pending_requests());
891       int request_id = host_resolver_.num_resolve();
892       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
893 
894       ssl_connect_job->ChangePriority(
895           static_cast<RequestPriority>(new_priority));
896       EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
897 
898       ssl_connect_job->ChangePriority(
899           static_cast<RequestPriority>(initial_priority));
900       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
901     }
902   }
903 }
904 
TEST_F(SSLConnectJobTest,HttpProxyAuthHasEstablishedConnection)905 TEST_F(SSLConnectJobTest, HttpProxyAuthHasEstablishedConnection) {
906   host_resolver_.set_ondemand_mode(true);
907   MockWrite writes[] = {
908       MockWrite(ASYNC, 0,
909                 "CONNECT host:80 HTTP/1.1\r\n"
910                 "Host: host:80\r\n"
911                 "Proxy-Connection: keep-alive\r\n"
912                 "User-Agent: test-ua\r\n\r\n"),
913       MockWrite(ASYNC, 3,
914                 "CONNECT host:80 HTTP/1.1\r\n"
915                 "Host: host:80\r\n"
916                 "Proxy-Connection: keep-alive\r\n"
917                 "User-Agent: test-ua\r\n"
918                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
919   };
920   MockRead reads[] = {
921       // Pause reading.
922       MockRead(ASYNC, ERR_IO_PENDING, 1),
923       MockRead(ASYNC, 2,
924                "HTTP/1.1 407 Proxy Authentication Required\r\n"
925                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
926                "Content-Length: 0\r\n\r\n"),
927       // Pause reading.
928       MockRead(ASYNC, ERR_IO_PENDING, 4),
929       MockRead(ASYNC, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"),
930   };
931   SequencedSocketData data(reads, writes);
932   socket_factory_.AddSocketDataProvider(&data);
933   SSLSocketDataProvider ssl(ASYNC, OK);
934   socket_factory_.AddSSLSocketDataProvider(&ssl);
935 
936   TestConnectJobDelegate test_delegate;
937   std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
938       &test_delegate, PacResultElementToProxyChain("PROXY foo:444"));
939   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
940   EXPECT_TRUE(host_resolver_.has_pending_requests());
941   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
942   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
943 
944   // DNS resolution completes, and then the ConnectJob tries to connect the
945   // socket, which should succeed asynchronously.
946   host_resolver_.ResolveOnlyRequestNow();
947   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
948   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
949 
950   // Spinning the message loop causes the connection to be established and the
951   // nested HttpProxyConnectJob to start establishing a tunnel.
952   base::RunLoop().RunUntilIdle();
953   EXPECT_FALSE(test_delegate.has_result());
954   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
955             ssl_connect_job->GetLoadState());
956   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
957 
958   // Receive the auth challenge.
959   data.Resume();
960   test_delegate.WaitForAuthChallenge(1);
961   EXPECT_FALSE(test_delegate.has_result());
962   EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
963   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
964 
965   // Respond to challenge.
966   test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
967   test_delegate.RunAuthCallback();
968   EXPECT_FALSE(test_delegate.has_result());
969   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
970             ssl_connect_job->GetLoadState());
971   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
972 
973   // Run until the next read pauses.
974   base::RunLoop().RunUntilIdle();
975   EXPECT_FALSE(test_delegate.has_result());
976   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
977             ssl_connect_job->GetLoadState());
978   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
979 
980   // Receive the connection established response, at which point SSL negotiation
981   // finally starts.
982   data.Resume();
983   EXPECT_FALSE(test_delegate.has_result());
984   EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
985   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
986 
987   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
988 }
989 
TEST_F(SSLConnectJobTest,HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose)990 TEST_F(SSLConnectJobTest,
991        HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose) {
992   host_resolver_.set_ondemand_mode(true);
993   MockWrite writes1[] = {
994       MockWrite(ASYNC, 0,
995                 "CONNECT host:80 HTTP/1.1\r\n"
996                 "Host: host:80\r\n"
997                 "Proxy-Connection: keep-alive\r\n"
998                 "User-Agent: test-ua\r\n\r\n"),
999   };
1000   MockRead reads1[] = {
1001       // Pause reading.
1002       MockRead(ASYNC, ERR_IO_PENDING, 1),
1003       MockRead(ASYNC, 2,
1004                "HTTP/1.1 407 Proxy Authentication Required\r\n"
1005                "Proxy-Connection: Close\r\n"
1006                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1007                "Content-Length: 0\r\n\r\n"),
1008   };
1009   SequencedSocketData data1(reads1, writes1);
1010   socket_factory_.AddSocketDataProvider(&data1);
1011 
1012   MockWrite writes2[] = {
1013       MockWrite(ASYNC, 0,
1014                 "CONNECT host:80 HTTP/1.1\r\n"
1015                 "Host: host:80\r\n"
1016                 "Proxy-Connection: keep-alive\r\n"
1017                 "User-Agent: test-ua\r\n"
1018                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1019   };
1020   MockRead reads2[] = {
1021       // Pause reading.
1022       MockRead(ASYNC, ERR_IO_PENDING, 1),
1023       MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1024   };
1025   SequencedSocketData data2(reads2, writes2);
1026   socket_factory_.AddSocketDataProvider(&data2);
1027   SSLSocketDataProvider ssl(ASYNC, OK);
1028   socket_factory_.AddSSLSocketDataProvider(&ssl);
1029 
1030   TestConnectJobDelegate test_delegate;
1031   std::unique_ptr<ConnectJob> ssl_connect_job = CreateConnectJob(
1032       &test_delegate, PacResultElementToProxyChain("PROXY foo:444"));
1033   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1034   EXPECT_TRUE(host_resolver_.has_pending_requests());
1035   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1036   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1037 
1038   // DNS resolution completes, and then the ConnectJob tries to connect the
1039   // socket, which should succeed asynchronously.
1040   host_resolver_.ResolveOnlyRequestNow();
1041   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1042   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1043 
1044   // Spinning the message loop causes the connection to be established and the
1045   // nested HttpProxyConnectJob to start establishing a tunnel.
1046   base::RunLoop().RunUntilIdle();
1047   EXPECT_FALSE(test_delegate.has_result());
1048   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1049             ssl_connect_job->GetLoadState());
1050   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1051 
1052   // Receive the auth challenge.
1053   data1.Resume();
1054   test_delegate.WaitForAuthChallenge(1);
1055   EXPECT_FALSE(test_delegate.has_result());
1056   EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1057   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1058 
1059   // Respond to challenge.
1060   test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
1061   test_delegate.RunAuthCallback();
1062   EXPECT_FALSE(test_delegate.has_result());
1063   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1064             ssl_connect_job->GetLoadState());
1065   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1066 
1067   // Run until the next DNS lookup.
1068   base::RunLoop().RunUntilIdle();
1069   EXPECT_TRUE(host_resolver_.has_pending_requests());
1070   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1071   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1072 
1073   // DNS resolution completes, and then the ConnectJob tries to connect the
1074   // socket, which should succeed asynchronously.
1075   host_resolver_.ResolveOnlyRequestNow();
1076   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1077   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1078 
1079   // Spinning the message loop causes the connection to be established and the
1080   // nested HttpProxyConnectJob to start establishing a tunnel.
1081   base::RunLoop().RunUntilIdle();
1082   EXPECT_FALSE(test_delegate.has_result());
1083   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1084             ssl_connect_job->GetLoadState());
1085   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1086 
1087   // Receive the connection established response, at which point SSL negotiation
1088   // finally starts.
1089   data2.Resume();
1090   EXPECT_FALSE(test_delegate.has_result());
1091   EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1092   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1093 
1094   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1095 }
1096 
TEST_F(SSLConnectJobTest,DnsAliases)1097 TEST_F(SSLConnectJobTest, DnsAliases) {
1098   host_resolver_.set_synchronous_mode(true);
1099 
1100   // Resolve an AddressList with DNS aliases.
1101   std::vector<std::string> aliases({"alias1", "alias2", "host"});
1102   host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1103                                                          std::move(aliases));
1104   StaticSocketDataProvider data;
1105   data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1106   socket_factory_.AddSocketDataProvider(&data);
1107   SSLSocketDataProvider ssl(ASYNC, OK);
1108   socket_factory_.AddSSLSocketDataProvider(&ssl);
1109   TestConnectJobDelegate test_delegate;
1110 
1111   std::unique_ptr<ConnectJob> ssl_connect_job =
1112       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1113 
1114   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1115 
1116   base::RunLoop().RunUntilIdle();
1117 
1118   // Verify that the elements of the alias list are those from the
1119   // parameter vector.
1120   EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1121               testing::ElementsAre("alias1", "alias2", "host"));
1122 }
1123 
TEST_F(SSLConnectJobTest,NoAdditionalDnsAliases)1124 TEST_F(SSLConnectJobTest, NoAdditionalDnsAliases) {
1125   host_resolver_.set_synchronous_mode(true);
1126 
1127   // Resolve an AddressList without additional DNS aliases. (The parameter
1128   // is an empty vector.)
1129   std::vector<std::string> aliases;
1130   host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1131                                                          std::move(aliases));
1132   StaticSocketDataProvider data;
1133   data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1134   socket_factory_.AddSocketDataProvider(&data);
1135   SSLSocketDataProvider ssl(ASYNC, OK);
1136   socket_factory_.AddSSLSocketDataProvider(&ssl);
1137   TestConnectJobDelegate test_delegate;
1138 
1139   std::unique_ptr<ConnectJob> ssl_connect_job =
1140       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1141 
1142   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1143 
1144   base::RunLoop().RunUntilIdle();
1145 
1146   // Verify that the alias list only contains "host".
1147   EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1148               testing::ElementsAre("host"));
1149 }
1150 
1151 // Test that `SSLConnectJob` passes the ECHConfigList from DNS to
1152 // `SSLClientSocket`.
TEST_F(SSLConnectJobTest,EncryptedClientHello)1153 TEST_F(SSLConnectJobTest, EncryptedClientHello) {
1154   std::vector<uint8_t> ech_config_list1, ech_config_list2;
1155   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1156                               &ech_config_list1));
1157   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1158                               &ech_config_list2));
1159 
1160   // Configure two HTTPS RR routes, to test we pass the correct one.
1161   HostResolverEndpointResult endpoint1, endpoint2;
1162   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1163   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1164   endpoint1.metadata.ech_config_list = ech_config_list1;
1165   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1166   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1167   endpoint2.metadata.ech_config_list = ech_config_list2;
1168   host_resolver_.rules()->AddRule(
1169       "host", MockHostResolverBase::RuleResolver::RuleResult(
1170                   std::vector{endpoint1, endpoint2}));
1171 
1172   for (bool ech_enabled : {true, false}) {
1173     SCOPED_TRACE(ech_enabled);
1174     SSLContextConfig config;
1175     config.ech_enabled = ech_enabled;
1176     ssl_config_service_->UpdateSSLConfigAndNotify(config);
1177 
1178     // The first connection attempt will be to `endpoint1`, which will fail.
1179     StaticSocketDataProvider data1;
1180     data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1181     data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1182     socket_factory_.AddSocketDataProvider(&data1);
1183     // The second connection attempt will be to `endpoint2`, which will succeed.
1184     StaticSocketDataProvider data2;
1185     data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1186     data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1187     socket_factory_.AddSocketDataProvider(&data2);
1188     // The handshake then succeeds.
1189     SSLSocketDataProvider ssl2(ASYNC, OK);
1190     // The ECH configuration should be passed if and only if the feature is
1191     // enabled.
1192     ssl2.expected_ech_config_list =
1193         ech_enabled ? ech_config_list2 : std::vector<uint8_t>{};
1194     socket_factory_.AddSSLSocketDataProvider(&ssl2);
1195 
1196     // The connection should ultimately succeed.
1197     base::HistogramTester histogram_tester;
1198     TestConnectJobDelegate test_delegate;
1199     std::unique_ptr<ConnectJob> ssl_connect_job =
1200         CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1201     EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1202     EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1203 
1204     // Whether or not the feature is enabled, we should record data for the
1205     // ECH-capable server.
1206     histogram_tester.ExpectUniqueSample("Net.SSL_Connection_Error_ECH", OK, 1);
1207     histogram_tester.ExpectTotalCount("Net.SSL_Connection_Latency_ECH", 1);
1208     // The ECH result should only be recorded if ECH was actually enabled.
1209     if (ech_enabled) {
1210       histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1211                                           0 /* kSuccessInitial */, 1);
1212     } else {
1213       histogram_tester.ExpectTotalCount("Net.SSL.ECHResult", 0);
1214     }
1215   }
1216 }
1217 
1218 // Test that `SSLConnectJob` retries the connection if there was a stale ECH
1219 // configuration.
TEST_F(SSLConnectJobTest,ECHStaleConfig)1220 TEST_F(SSLConnectJobTest, ECHStaleConfig) {
1221   std::vector<uint8_t> ech_config_list1, ech_config_list2, ech_config_list3;
1222   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1223                               &ech_config_list1));
1224   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1225                               &ech_config_list2));
1226   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1227                               &ech_config_list3));
1228 
1229   // Configure two HTTPS RR routes, to test the retry uses the correct one.
1230   HostResolverEndpointResult endpoint1, endpoint2;
1231   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1232   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1233   endpoint1.metadata.ech_config_list = ech_config_list1;
1234   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1235   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1236   endpoint2.metadata.ech_config_list = ech_config_list2;
1237   host_resolver_.rules()->AddRule(
1238       "host", MockHostResolverBase::RuleResolver::RuleResult(
1239                   std::vector{endpoint1, endpoint2}));
1240 
1241   // The first connection attempt will be to `endpoint1`, which will fail.
1242   StaticSocketDataProvider data1;
1243   data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1244   data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1245   socket_factory_.AddSocketDataProvider(&data1);
1246   // The second connection attempt will be to `endpoint2`, which will succeed.
1247   StaticSocketDataProvider data2;
1248   data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1249   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1250   socket_factory_.AddSocketDataProvider(&data2);
1251   // The handshake will then fail, but then provide retry configs.
1252   SSLSocketDataProvider ssl2(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1253   ssl2.expected_ech_config_list = ech_config_list2;
1254   ssl2.ech_retry_configs = ech_config_list3;
1255   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1256   // The third connection attempt should skip `endpoint1` and retry with only
1257   // `endpoint2`.
1258   StaticSocketDataProvider data3;
1259   data3.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1260   data3.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1261   socket_factory_.AddSocketDataProvider(&data3);
1262   // The handshake should be passed the retry configs.
1263   SSLSocketDataProvider ssl3(ASYNC, OK);
1264   ssl3.expected_ech_config_list = ech_config_list3;
1265   socket_factory_.AddSSLSocketDataProvider(&ssl3);
1266 
1267   // The connection should ultimately succeed.
1268   base::HistogramTester histogram_tester;
1269   TestConnectJobDelegate test_delegate;
1270   std::unique_ptr<ConnectJob> ssl_connect_job =
1271       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1272   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1273   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1274 
1275   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1276                                       2 /* kSuccessRetry */, 1);
1277 }
1278 
1279 // Test that `SSLConnectJob` retries the connection given a secure rollback
1280 // signal.
TEST_F(SSLConnectJobTest,ECHRollback)1281 TEST_F(SSLConnectJobTest, ECHRollback) {
1282   std::vector<uint8_t> ech_config_list1, ech_config_list2;
1283   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1284                               &ech_config_list1));
1285   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1286                               &ech_config_list2));
1287 
1288   // Configure two HTTPS RR routes, to test the retry uses the correct one.
1289   HostResolverEndpointResult endpoint1, endpoint2;
1290   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1291   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1292   endpoint1.metadata.ech_config_list = ech_config_list1;
1293   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1294   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1295   endpoint2.metadata.ech_config_list = ech_config_list2;
1296   host_resolver_.rules()->AddRule(
1297       "host", MockHostResolverBase::RuleResolver::RuleResult(
1298                   std::vector{endpoint1, endpoint2}));
1299 
1300   // The first connection attempt will be to `endpoint1`, which will fail.
1301   StaticSocketDataProvider data1;
1302   data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1303   data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1304   socket_factory_.AddSocketDataProvider(&data1);
1305   // The second connection attempt will be to `endpoint2`, which will succeed.
1306   StaticSocketDataProvider data2;
1307   data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1308   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1309   socket_factory_.AddSocketDataProvider(&data2);
1310   // The handshake will then fail, and provide no retry configs.
1311   SSLSocketDataProvider ssl2(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1312   ssl2.expected_ech_config_list = ech_config_list2;
1313   ssl2.ech_retry_configs = std::vector<uint8_t>();
1314   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1315   // The third connection attempt should skip `endpoint1` and retry with only
1316   // `endpoint2`.
1317   StaticSocketDataProvider data3;
1318   data3.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1319   data3.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1320   socket_factory_.AddSocketDataProvider(&data3);
1321   // The handshake should not be passed ECH configs.
1322   SSLSocketDataProvider ssl3(ASYNC, OK);
1323   ssl3.expected_ech_config_list = std::vector<uint8_t>();
1324   socket_factory_.AddSSLSocketDataProvider(&ssl3);
1325 
1326   // The connection should ultimately succeed.
1327   base::HistogramTester histogram_tester;
1328   TestConnectJobDelegate test_delegate;
1329   std::unique_ptr<ConnectJob> ssl_connect_job =
1330       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1331   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1332   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1333 
1334   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1335                                       4 /* kSuccessRollback */, 1);
1336 }
1337 
1338 // Test that `SSLConnectJob` will not retry more than once.
TEST_F(SSLConnectJobTest,ECHTooManyRetries)1339 TEST_F(SSLConnectJobTest, ECHTooManyRetries) {
1340   std::vector<uint8_t> ech_config_list1, ech_config_list2, ech_config_list3;
1341   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1342                               &ech_config_list1));
1343   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1344                               &ech_config_list2));
1345   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1346                               &ech_config_list3));
1347 
1348   HostResolverEndpointResult endpoint;
1349   endpoint.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1350   endpoint.metadata.supported_protocol_alpns = {"http/1.1"};
1351   endpoint.metadata.ech_config_list = ech_config_list1;
1352   host_resolver_.rules()->AddRule(
1353       "host",
1354       MockHostResolverBase::RuleResolver::RuleResult(std::vector{endpoint}));
1355 
1356   // The first connection attempt will succeed.
1357   StaticSocketDataProvider data1;
1358   data1.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1359   socket_factory_.AddSocketDataProvider(&data1);
1360   // The handshake will then fail, but provide retry configs.
1361   SSLSocketDataProvider ssl1(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1362   ssl1.expected_ech_config_list = ech_config_list1;
1363   ssl1.ech_retry_configs = ech_config_list2;
1364   socket_factory_.AddSSLSocketDataProvider(&ssl1);
1365   // The second connection attempt will succeed.
1366   StaticSocketDataProvider data2;
1367   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1368   socket_factory_.AddSocketDataProvider(&data2);
1369   // The handshake will then fail, but provide new retry configs.
1370   SSLSocketDataProvider ssl2(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1371   ssl2.expected_ech_config_list = ech_config_list2;
1372   ssl2.ech_retry_configs = ech_config_list3;
1373   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1374   // There will be no third connection attempt.
1375 
1376   base::HistogramTester histogram_tester;
1377   TestConnectJobDelegate test_delegate;
1378   std::unique_ptr<ConnectJob> ssl_connect_job =
1379       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1380   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1381   EXPECT_THAT(test_delegate.WaitForResult(),
1382               test::IsError(ERR_ECH_NOT_NEGOTIATED));
1383 
1384   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult", 3 /* kErrorRetry */,
1385                                       1);
1386 }
1387 
1388 // Test that `SSLConnectJob` will not retry for ECH given the wrong error.
TEST_F(SSLConnectJobTest,ECHWrongRetryError)1389 TEST_F(SSLConnectJobTest, ECHWrongRetryError) {
1390   std::vector<uint8_t> ech_config_list1, ech_config_list2;
1391   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1392                               &ech_config_list1));
1393   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1394                               &ech_config_list2));
1395 
1396   HostResolverEndpointResult endpoint;
1397   endpoint.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1398   endpoint.metadata.supported_protocol_alpns = {"http/1.1"};
1399   endpoint.metadata.ech_config_list = ech_config_list1;
1400   host_resolver_.rules()->AddRule(
1401       "host",
1402       MockHostResolverBase::RuleResolver::RuleResult(std::vector{endpoint}));
1403 
1404   // The first connection attempt will succeed.
1405   StaticSocketDataProvider data1;
1406   data1.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1407   socket_factory_.AddSocketDataProvider(&data1);
1408   // The handshake will then fail, but provide retry configs.
1409   SSLSocketDataProvider ssl1(ASYNC, ERR_FAILED);
1410   ssl1.expected_ech_config_list = ech_config_list1;
1411   ssl1.ech_retry_configs = ech_config_list2;
1412   socket_factory_.AddSSLSocketDataProvider(&ssl1);
1413   // There will be no second connection attempt.
1414 
1415   base::HistogramTester histogram_tester;
1416   TestConnectJobDelegate test_delegate;
1417   std::unique_ptr<ConnectJob> ssl_connect_job =
1418       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1419   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1420   EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_FAILED));
1421 
1422   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1423                                       1 /* kErrorInitial */, 1);
1424 }
1425 
1426 // Test the legacy crypto callback can trigger after the ECH recovery flow.
TEST_F(SSLConnectJobTest,ECHRecoveryThenLegacyCrypto)1427 TEST_F(SSLConnectJobTest, ECHRecoveryThenLegacyCrypto) {
1428   std::vector<uint8_t> ech_config_list1, ech_config_list2, ech_config_list3;
1429   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1430                               &ech_config_list1));
1431   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1432                               &ech_config_list2));
1433   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1434                               &ech_config_list3));
1435 
1436   // Configure two HTTPS RR routes, to test the retry uses the correct one.
1437   HostResolverEndpointResult endpoint1, endpoint2;
1438   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1439   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1440   endpoint1.metadata.ech_config_list = ech_config_list1;
1441   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1442   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1443   endpoint2.metadata.ech_config_list = ech_config_list2;
1444   host_resolver_.rules()->AddRule(
1445       "host", MockHostResolverBase::RuleResolver::RuleResult(
1446                   std::vector{endpoint1, endpoint2}));
1447 
1448   // The first connection attempt will be to `endpoint1`, which will fail.
1449   StaticSocketDataProvider data1;
1450   data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1451   data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1452   socket_factory_.AddSocketDataProvider(&data1);
1453   // The second connection attempt will be to `endpoint2`, which will succeed.
1454   StaticSocketDataProvider data2;
1455   data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1456   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1457   socket_factory_.AddSocketDataProvider(&data2);
1458   // The handshake will then fail, and provide retry configs.
1459   SSLSocketDataProvider ssl2(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1460   ssl2.expected_ech_config_list = ech_config_list2;
1461   ssl2.ech_retry_configs = ech_config_list3;
1462   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1463   // The third connection attempt should skip `endpoint1` and retry with only
1464   // `endpoint2`.
1465   StaticSocketDataProvider data3;
1466   data3.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1467   data3.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1468   socket_factory_.AddSocketDataProvider(&data3);
1469   // The handshake should be passed the retry configs. This will progress
1470   // further but trigger the legacy crypto fallback.
1471   SSLSocketDataProvider ssl3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
1472   ssl3.expected_ech_config_list = ech_config_list3;
1473   socket_factory_.AddSSLSocketDataProvider(&ssl3);
1474   // The third connection attempt should still skip `endpoint1` and retry with
1475   // only `endpoint2`.
1476   StaticSocketDataProvider data4;
1477   data4.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1478   data4.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1479   socket_factory_.AddSocketDataProvider(&data4);
1480   // The handshake should still be passed ECH retry configs. This time, the
1481   // connection enables legacy crypto and succeeds.
1482   SSLSocketDataProvider ssl4(ASYNC, OK);
1483   ssl4.expected_ech_config_list = ech_config_list3;
1484   socket_factory_.AddSSLSocketDataProvider(&ssl4);
1485 
1486   // The connection should ultimately succeed.
1487   base::HistogramTester histogram_tester;
1488   TestConnectJobDelegate test_delegate;
1489   std::unique_ptr<ConnectJob> ssl_connect_job =
1490       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1491   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1492   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1493 
1494   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1495                                       2 /* kSuccessRetry */, 1);
1496 }
1497 
1498 // Test the ECH recovery flow can trigger after the legacy crypto fallback.
TEST_F(SSLConnectJobTest,LegacyCryptoThenECHRecovery)1499 TEST_F(SSLConnectJobTest, LegacyCryptoThenECHRecovery) {
1500   std::vector<uint8_t> ech_config_list1, ech_config_list2, ech_config_list3;
1501   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1502                               &ech_config_list1));
1503   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1504                               &ech_config_list2));
1505   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1506                               &ech_config_list3));
1507 
1508   // Configure two HTTPS RR routes, to test the retry uses the correct one.
1509   HostResolverEndpointResult endpoint1, endpoint2;
1510   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1511   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1512   endpoint1.metadata.ech_config_list = ech_config_list1;
1513   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1514   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1515   endpoint2.metadata.ech_config_list = ech_config_list2;
1516   host_resolver_.rules()->AddRule(
1517       "host", MockHostResolverBase::RuleResolver::RuleResult(
1518                   std::vector{endpoint1, endpoint2}));
1519 
1520   // The first connection attempt will be to `endpoint1`, which will fail.
1521   StaticSocketDataProvider data1;
1522   data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1523   data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1524   socket_factory_.AddSocketDataProvider(&data1);
1525   // The second connection attempt will be to `endpoint2`, which will succeed.
1526   StaticSocketDataProvider data2;
1527   data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1528   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1529   socket_factory_.AddSocketDataProvider(&data2);
1530   // The handshake will then fail, and trigger the legacy cryptography fallback.
1531   SSLSocketDataProvider ssl2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
1532   ssl2.expected_ech_config_list = ech_config_list2;
1533   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1534   // The third and fourth connection attempts proceed as before, but with legacy
1535   // cryptography enabled.
1536   StaticSocketDataProvider data3;
1537   data3.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1538   data3.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1539   socket_factory_.AddSocketDataProvider(&data3);
1540   StaticSocketDataProvider data4;
1541   data4.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1542   data4.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1543   socket_factory_.AddSocketDataProvider(&data4);
1544   // The handshake enables legacy crypto. Now ECH fails with retry configs.
1545   SSLSocketDataProvider ssl4(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1546   ssl4.expected_ech_config_list = ech_config_list2;
1547   ssl4.ech_retry_configs = ech_config_list3;
1548   socket_factory_.AddSSLSocketDataProvider(&ssl4);
1549   // The fourth connection attempt should still skip `endpoint1` and retry with
1550   // only `endpoint2`.
1551   StaticSocketDataProvider data5;
1552   data5.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1553   data5.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1554   socket_factory_.AddSocketDataProvider(&data5);
1555   // The handshake will now succeed with ECH retry configs and legacy
1556   // cryptography.
1557   SSLSocketDataProvider ssl5(ASYNC, OK);
1558   ssl5.expected_ech_config_list = ech_config_list3;
1559   socket_factory_.AddSSLSocketDataProvider(&ssl5);
1560 
1561   // The connection should ultimately succeed.
1562   base::HistogramTester histogram_tester;
1563   TestConnectJobDelegate test_delegate;
1564   std::unique_ptr<ConnectJob> ssl_connect_job =
1565       CreateConnectJob(&test_delegate, ProxyChain::Direct(), MEDIUM);
1566   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1567   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1568 
1569   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1570                                       2 /* kSuccessRetry */, 1);
1571 }
1572 
1573 }  // namespace
1574 }  // namespace net
1575