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