• 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/cert/ct_policy_enforcer.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/ssl_legacy_crypto_fallback.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_(std::make_unique<SSLConfigServiceDefaults>()),
114         http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
115         session_(CreateNetworkSession()),
116         common_connect_job_params_(session_->CreateCommonConnectJobParams()) {}
117 
118   ~SSLConnectJobTest() override = default;
119 
CreateDirectTransportSocketParams(SecureDnsPolicy secure_dns_policy) const120   scoped_refptr<TransportSocketParams> CreateDirectTransportSocketParams(
121       SecureDnsPolicy secure_dns_policy) const {
122     return base::MakeRefCounted<TransportSocketParams>(
123         kHostHttps, NetworkAnonymizationKey(), secure_dns_policy,
124         OnHostResolutionCallback(),
125         /*supported_alpns=*/base::flat_set<std::string>({"h2", "http/1.1"}));
126   }
127 
CreateProxyTransportSocketParams(SecureDnsPolicy secure_dns_policy) const128   scoped_refptr<TransportSocketParams> CreateProxyTransportSocketParams(
129       SecureDnsPolicy secure_dns_policy) const {
130     return base::MakeRefCounted<TransportSocketParams>(
131         kHttpProxyServer.host_port_pair(), NetworkAnonymizationKey(),
132         secure_dns_policy, OnHostResolutionCallback(),
133         /*supported_alpns=*/base::flat_set<std::string>({}));
134   }
135 
CreateSOCKSSocketParams(SecureDnsPolicy secure_dns_policy)136   scoped_refptr<SOCKSSocketParams> CreateSOCKSSocketParams(
137       SecureDnsPolicy secure_dns_policy) {
138     return base::MakeRefCounted<SOCKSSocketParams>(
139         CreateProxyTransportSocketParams(secure_dns_policy),
140         kSocksProxyServer.scheme() == ProxyServer::SCHEME_SOCKS5,
141         kSocksProxyServer.host_port_pair(), NetworkAnonymizationKey(),
142         TRAFFIC_ANNOTATION_FOR_TESTS);
143   }
144 
CreateHttpProxySocketParams(SecureDnsPolicy secure_dns_policy)145   scoped_refptr<HttpProxySocketParams> CreateHttpProxySocketParams(
146       SecureDnsPolicy secure_dns_policy) {
147     return base::MakeRefCounted<HttpProxySocketParams>(
148         CreateProxyTransportSocketParams(secure_dns_policy),
149         /*ssl_params=*/nullptr, kHostHttp, kHttpProxyChain,
150         /*proxy_server_index=*/0,
151         /*tunnel=*/true, TRAFFIC_ANNOTATION_FOR_TESTS,
152         NetworkAnonymizationKey(), secure_dns_policy);
153   }
154 
CreateConnectJob(TestConnectJobDelegate * test_delegate,ProxyServer::Scheme proxy_scheme=ProxyServer::SCHEME_DIRECT,RequestPriority priority=DEFAULT_PRIORITY,SecureDnsPolicy secure_dns_policy=SecureDnsPolicy::kAllow)155   std::unique_ptr<ConnectJob> CreateConnectJob(
156       TestConnectJobDelegate* test_delegate,
157       ProxyServer::Scheme proxy_scheme = ProxyServer::SCHEME_DIRECT,
158       RequestPriority priority = DEFAULT_PRIORITY,
159       SecureDnsPolicy secure_dns_policy = SecureDnsPolicy::kAllow) {
160     return std::make_unique<SSLConnectJob>(
161         priority, SocketTag(), &common_connect_job_params_,
162         CreateSSLSocketParams(proxy_scheme, secure_dns_policy), test_delegate,
163         /*net_log=*/nullptr);
164   }
165 
CreateSSLSocketParams(ProxyServer::Scheme proxy_scheme,SecureDnsPolicy secure_dns_policy)166   scoped_refptr<SSLSocketParams> CreateSSLSocketParams(
167       ProxyServer::Scheme proxy_scheme,
168       SecureDnsPolicy secure_dns_policy) {
169     return base::MakeRefCounted<SSLSocketParams>(
170         proxy_scheme == ProxyServer::SCHEME_DIRECT
171             ? CreateDirectTransportSocketParams(secure_dns_policy)
172             : nullptr,
173         proxy_scheme == ProxyServer::SCHEME_SOCKS5
174             ? CreateSOCKSSocketParams(secure_dns_policy)
175             : nullptr,
176         proxy_scheme == ProxyServer::SCHEME_HTTP
177             ? CreateHttpProxySocketParams(secure_dns_policy)
178             : nullptr,
179         HostPortPair::FromSchemeHostPort(kHostHttps), SSLConfig(),
180         PRIVACY_MODE_DISABLED, NetworkAnonymizationKey());
181   }
182 
AddAuthToCache()183   void AddAuthToCache() {
184     const std::u16string kFoo(u"foo");
185     const std::u16string kBar(u"bar");
186     session_->http_auth_cache()->Add(
187         url::SchemeHostPort(GURL("http://proxy:443/")), HttpAuth::AUTH_PROXY,
188         "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
189         "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
190   }
191 
CreateNetworkSession()192   std::unique_ptr<HttpNetworkSession> CreateNetworkSession() {
193     HttpNetworkSessionContext session_context;
194     session_context.host_resolver = &host_resolver_;
195     session_context.cert_verifier = &cert_verifier_;
196     session_context.transport_security_state = &transport_security_state_;
197     session_context.ct_policy_enforcer = &ct_policy_enforcer_;
198     session_context.proxy_resolution_service = proxy_resolution_service_.get();
199     session_context.client_socket_factory = &socket_factory_;
200     session_context.ssl_config_service = ssl_config_service_.get();
201     session_context.http_auth_handler_factory =
202         http_auth_handler_factory_.get();
203     session_context.http_server_properties = &http_server_properties_;
204     session_context.quic_context = &quic_context_;
205     return std::make_unique<HttpNetworkSession>(HttpNetworkSessionParams(),
206                                                 session_context);
207   }
208 
209  protected:
210   MockClientSocketFactory socket_factory_;
211   MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
212                                       RuleResolver::GetLocalhostResult()};
213   MockCertVerifier cert_verifier_;
214   TransportSecurityState transport_security_state_;
215   DefaultCTPolicyEnforcer ct_policy_enforcer_;
216   const std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
217   const std::unique_ptr<SSLConfigService> 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, ProxyServer::SCHEME_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, ProxyServer::SCHEME_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, ProxyServer::SCHEME_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       TestConnectJobDelegate test_delegate;
446       std::unique_ptr<ConnectJob> ssl_connect_job =
447           CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT,
448                            static_cast<RequestPriority>(initial_priority));
449       EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
450       EXPECT_TRUE(host_resolver_.has_pending_requests());
451       int request_id = host_resolver_.num_resolve();
452       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
453 
454       ssl_connect_job->ChangePriority(
455           static_cast<RequestPriority>(new_priority));
456       EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
457 
458       ssl_connect_job->ChangePriority(
459           static_cast<RequestPriority>(initial_priority));
460       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
461     }
462   }
463 }
464 
TEST_F(SSLConnectJobTest,SecureDnsPolicy)465 TEST_F(SSLConnectJobTest, SecureDnsPolicy) {
466   for (auto secure_dns_policy :
467        {SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable}) {
468     TestConnectJobDelegate test_delegate;
469     std::unique_ptr<ConnectJob> ssl_connect_job =
470         CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT,
471                          DEFAULT_PRIORITY, secure_dns_policy);
472 
473     EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
474     EXPECT_EQ(secure_dns_policy, host_resolver_.last_secure_dns_policy());
475   }
476 }
477 
TEST_F(SSLConnectJobTest,DirectHostResolutionFailure)478 TEST_F(SSLConnectJobTest, DirectHostResolutionFailure) {
479   host_resolver_.rules()->AddSimulatedTimeoutFailure("host");
480 
481   TestConnectJobDelegate test_delegate;
482   std::unique_ptr<ConnectJob> ssl_connect_job =
483       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT);
484   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
485                                         ERR_NAME_NOT_RESOLVED,
486                                         false /* expect_sync_result */);
487   EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
488               test::IsError(ERR_DNS_TIMED_OUT));
489 }
490 
TEST_F(SSLConnectJobTest,DirectCertError)491 TEST_F(SSLConnectJobTest, DirectCertError) {
492   StaticSocketDataProvider data;
493   socket_factory_.AddSocketDataProvider(&data);
494   SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
495   socket_factory_.AddSSLSocketDataProvider(&ssl);
496 
497   TestConnectJobDelegate test_delegate(
498       TestConnectJobDelegate::SocketExpected::ALWAYS);
499   std::unique_ptr<ConnectJob> ssl_connect_job =
500       CreateConnectJob(&test_delegate);
501 
502   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
503                                         ERR_CERT_COMMON_NAME_INVALID,
504                                         false /* expect_sync_result */);
505   EXPECT_TRUE(ssl_connect_job->IsSSLError());
506   ConnectionAttempts connection_attempts =
507       ssl_connect_job->GetConnectionAttempts();
508   ASSERT_EQ(1u, connection_attempts.size());
509   EXPECT_THAT(connection_attempts[0].result,
510               test::IsError(ERR_CERT_COMMON_NAME_INVALID));
511   CheckConnectTimesSet(ssl_connect_job->connect_timing());
512 }
513 
TEST_F(SSLConnectJobTest,DirectIgnoreCertErrors)514 TEST_F(SSLConnectJobTest, DirectIgnoreCertErrors) {
515   session_->IgnoreCertificateErrorsForTesting();
516 
517   StaticSocketDataProvider data;
518   socket_factory_.AddSocketDataProvider(&data);
519   SSLSocketDataProvider ssl(ASYNC, OK);
520   ssl.expected_ignore_certificate_errors = true;
521   socket_factory_.AddSSLSocketDataProvider(&ssl);
522 
523   TestConnectJobDelegate test_delegate(
524       TestConnectJobDelegate::SocketExpected::ALWAYS);
525   std::unique_ptr<ConnectJob> ssl_connect_job =
526       CreateConnectJob(&test_delegate);
527 
528   test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
529                                         /*expect_sync_result=*/false);
530 }
531 
TEST_F(SSLConnectJobTest,DirectSSLError)532 TEST_F(SSLConnectJobTest, DirectSSLError) {
533   StaticSocketDataProvider data;
534   socket_factory_.AddSocketDataProvider(&data);
535   SSLSocketDataProvider ssl(ASYNC, ERR_BAD_SSL_CLIENT_AUTH_CERT);
536   socket_factory_.AddSSLSocketDataProvider(&ssl);
537 
538   TestConnectJobDelegate test_delegate;
539   std::unique_ptr<ConnectJob> ssl_connect_job =
540       CreateConnectJob(&test_delegate);
541 
542   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
543                                         ERR_BAD_SSL_CLIENT_AUTH_CERT,
544                                         false /* expect_sync_result */);
545   ConnectionAttempts connection_attempts =
546       ssl_connect_job->GetConnectionAttempts();
547   ASSERT_EQ(1u, connection_attempts.size());
548   EXPECT_THAT(connection_attempts[0].result,
549               test::IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
550 }
551 
552 // Test that the sha1 server handshakes fallback is triggered on applicable
553 // error codes.
TEST_F(SSLConnectJobTest,SHA1ServerHandshakeFallback)554 TEST_F(SSLConnectJobTest, SHA1ServerHandshakeFallback) {
555   for (bool feature_enabled : {true, false}) {
556     SCOPED_TRACE(feature_enabled);
557     base::test::ScopedFeatureList feature_list;
558     if (feature_enabled) {
559       feature_list.InitAndEnableFeature(features::kSHA1ServerSignature);
560     } else {
561       feature_list.InitAndDisableFeature(features::kSHA1ServerSignature);
562     }
563     for (Error error :
564          {ERR_CONNECTION_CLOSED, ERR_CONNECTION_RESET, ERR_SSL_PROTOCOL_ERROR,
565           ERR_SSL_VERSION_OR_CIPHER_MISMATCH}) {
566       SCOPED_TRACE(error);
567 
568       for (bool second_attempt_ok : {true, false}) {
569         SCOPED_TRACE(second_attempt_ok);
570 
571         StaticSocketDataProvider data;
572         socket_factory_.AddSocketDataProvider(&data);
573         SSLSocketDataProvider ssl(ASYNC, error);
574         socket_factory_.AddSSLSocketDataProvider(&ssl);
575         ssl.expected_disable_sha1_server_signatures = true;
576 
577         Error error2 = second_attempt_ok ? OK : error;
578         StaticSocketDataProvider data2;
579         socket_factory_.AddSocketDataProvider(&data2);
580         SSLSocketDataProvider ssl2(ASYNC, error2);
581         socket_factory_.AddSSLSocketDataProvider(&ssl2);
582         if (feature_enabled) {
583           ssl2.expected_disable_sha1_server_signatures = false;
584         } else {
585           ssl2.expected_disable_sha1_server_signatures = true;
586         }
587 
588         TestConnectJobDelegate test_delegate;
589         std::unique_ptr<ConnectJob> ssl_connect_job =
590             CreateConnectJob(&test_delegate);
591 
592         test_delegate.StartJobExpectingResult(ssl_connect_job.get(), error2,
593                                               /*expect_sync_result=*/false);
594         ConnectionAttempts connection_attempts =
595             ssl_connect_job->GetConnectionAttempts();
596         if (second_attempt_ok) {
597           ASSERT_EQ(1u, connection_attempts.size());
598           EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
599         } else {
600           ASSERT_EQ(2u, connection_attempts.size());
601           EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
602           EXPECT_THAT(connection_attempts[1].result, test::IsError(error));
603         }
604       }
605     }
606   }
607 }
608 
TEST_F(SSLConnectJobTest,LegacyCryptoFallbackHistograms)609 TEST_F(SSLConnectJobTest, LegacyCryptoFallbackHistograms) {
610   base::FilePath certs_dir = GetTestCertsDirectory();
611 
612   scoped_refptr<X509Certificate> sha1_leaf =
613       ImportCertFromFile(certs_dir, "sha1_leaf.pem");
614   ASSERT_TRUE(sha1_leaf);
615 
616   scoped_refptr<X509Certificate> ok_cert =
617       ImportCertFromFile(certs_dir, "ok_cert.pem");
618   ASSERT_TRUE(ok_cert);
619 
620   // Make a copy of |ok_cert| with an unused |sha1_leaf| in the intermediate
621   // list.
622   std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
623   for (const auto& cert : ok_cert->intermediate_buffers()) {
624     intermediates.push_back(bssl::UpRef(cert));
625   }
626   intermediates.push_back(bssl::UpRef(sha1_leaf->cert_buffer()));
627   scoped_refptr<X509Certificate> ok_with_unused_sha1 =
628       X509Certificate::CreateFromBuffer(bssl::UpRef(ok_cert->cert_buffer()),
629                                         std::move(intermediates));
630   ASSERT_TRUE(ok_with_unused_sha1);
631 
632   // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
633   const uint16_t kModernCipher = 0xc02f;
634 
635   struct HistogramTest {
636     SSLLegacyCryptoFallback expected;
637     Error first_attempt;
638     uint16_t cipher_suite;
639     uint16_t peer_signature_algorithm;
640     scoped_refptr<X509Certificate> unverified_cert;
641   };
642 
643   const HistogramTest kHistogramTests[] = {
644       // Connections not using the fallback map to kNoFallback.
645       {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
646        SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
647       {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
648        SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
649       {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
650        SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
651 
652       // Connections using SHA-1 map to kUsedSHA1 or kSentSHA1CertAndUsedSHA1.
653       {SSLLegacyCryptoFallback::kUsedSHA1, ERR_SSL_PROTOCOL_ERROR,
654        kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1, ok_cert},
655       {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
656        ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
657        sha1_leaf},
658       {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
659        ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
660        ok_with_unused_sha1},
661 
662       // Connections using neither map to kUnknownReason or kSentSHA1Cert.
663       {SSLLegacyCryptoFallback::kUnknownReason, ERR_SSL_PROTOCOL_ERROR,
664        kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
665       {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
666        kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
667       {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
668        kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
669   };
670   for (size_t i = 0; i < std::size(kHistogramTests); i++) {
671     SCOPED_TRACE(i);
672     const auto& test = kHistogramTests[i];
673 
674     base::HistogramTester tester;
675 
676     SSLInfo ssl_info;
677     SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
678                                   &ssl_info.connection_status);
679     SSLConnectionStatusSetCipherSuite(test.cipher_suite,
680                                       &ssl_info.connection_status);
681     ssl_info.peer_signature_algorithm = test.peer_signature_algorithm;
682     ssl_info.unverified_cert = test.unverified_cert;
683 
684     StaticSocketDataProvider data;
685     socket_factory_.AddSocketDataProvider(&data);
686     SSLSocketDataProvider ssl(ASYNC, test.first_attempt);
687     socket_factory_.AddSSLSocketDataProvider(&ssl);
688     ssl.expected_disable_sha1_server_signatures = true;
689 
690     StaticSocketDataProvider data2;
691     SSLSocketDataProvider ssl2(ASYNC, OK);
692     if (test.first_attempt != OK) {
693       socket_factory_.AddSocketDataProvider(&data2);
694       socket_factory_.AddSSLSocketDataProvider(&ssl2);
695       ssl2.ssl_info = ssl_info;
696       ssl2.expected_disable_sha1_server_signatures = true;
697     } else {
698       ssl.ssl_info = ssl_info;
699     }
700 
701     TestConnectJobDelegate test_delegate;
702     std::unique_ptr<ConnectJob> ssl_connect_job =
703         CreateConnectJob(&test_delegate);
704 
705     test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
706                                           /*expect_sync_result=*/false);
707 
708     tester.ExpectUniqueSample("Net.SSLLegacyCryptoFallback2", test.expected, 1);
709   }
710 }
711 
TEST_F(SSLConnectJobTest,DirectWithNPN)712 TEST_F(SSLConnectJobTest, DirectWithNPN) {
713   StaticSocketDataProvider data;
714   socket_factory_.AddSocketDataProvider(&data);
715   SSLSocketDataProvider ssl(ASYNC, OK);
716   ssl.next_proto = kProtoHTTP11;
717   socket_factory_.AddSSLSocketDataProvider(&ssl);
718 
719   TestConnectJobDelegate test_delegate;
720   std::unique_ptr<ConnectJob> ssl_connect_job =
721       CreateConnectJob(&test_delegate);
722 
723   test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
724                                         false /* expect_sync_result */);
725   CheckConnectTimesSet(ssl_connect_job->connect_timing());
726 }
727 
TEST_F(SSLConnectJobTest,DirectGotHTTP2)728 TEST_F(SSLConnectJobTest, DirectGotHTTP2) {
729   StaticSocketDataProvider data;
730   socket_factory_.AddSocketDataProvider(&data);
731   SSLSocketDataProvider ssl(ASYNC, OK);
732   ssl.next_proto = kProtoHTTP2;
733   socket_factory_.AddSSLSocketDataProvider(&ssl);
734 
735   TestConnectJobDelegate test_delegate;
736   std::unique_ptr<ConnectJob> ssl_connect_job =
737       CreateConnectJob(&test_delegate);
738 
739   test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
740                                         false /* expect_sync_result */);
741   EXPECT_EQ(kProtoHTTP2, test_delegate.socket()->GetNegotiatedProtocol());
742   CheckConnectTimesSet(ssl_connect_job->connect_timing());
743 }
744 
TEST_F(SSLConnectJobTest,SOCKSFail)745 TEST_F(SSLConnectJobTest, SOCKSFail) {
746   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
747     SCOPED_TRACE(io_mode);
748     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
749     StaticSocketDataProvider data;
750     data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
751     socket_factory_.AddSocketDataProvider(&data);
752 
753     TestConnectJobDelegate test_delegate;
754     std::unique_ptr<ConnectJob> ssl_connect_job =
755         CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
756     test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
757                                           ERR_PROXY_CONNECTION_FAILED,
758                                           io_mode == SYNCHRONOUS);
759     EXPECT_FALSE(ssl_connect_job->IsSSLError());
760 
761     ConnectionAttempts connection_attempts =
762         ssl_connect_job->GetConnectionAttempts();
763     EXPECT_EQ(0u, connection_attempts.size());
764   }
765 }
766 
TEST_F(SSLConnectJobTest,SOCKSHostResolutionFailure)767 TEST_F(SSLConnectJobTest, SOCKSHostResolutionFailure) {
768   host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
769 
770   TestConnectJobDelegate test_delegate;
771   std::unique_ptr<ConnectJob> ssl_connect_job =
772       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
773   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
774                                         ERR_PROXY_CONNECTION_FAILED,
775                                         false /* expect_sync_result */);
776   EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
777               test::IsError(ERR_DNS_TIMED_OUT));
778 }
779 
TEST_F(SSLConnectJobTest,SOCKSBasic)780 TEST_F(SSLConnectJobTest, SOCKSBasic) {
781   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
782     SCOPED_TRACE(io_mode);
783     const uint8_t kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
784                                       'o',  'c',  'k',  's',  'h',  'o',
785                                       's',  't',  0x01, 0xBB};
786 
787     MockWrite writes[] = {
788         MockWrite(io_mode, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
789         MockWrite(io_mode, reinterpret_cast<const char*>(kSOCKS5Request),
790                   std::size(kSOCKS5Request)),
791     };
792 
793     MockRead reads[] = {
794         MockRead(io_mode, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
795         MockRead(io_mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
796     };
797 
798     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
799     StaticSocketDataProvider data(reads, writes);
800     data.set_connect_data(MockConnect(io_mode, OK));
801     socket_factory_.AddSocketDataProvider(&data);
802     SSLSocketDataProvider ssl(io_mode, OK);
803     socket_factory_.AddSSLSocketDataProvider(&ssl);
804 
805     TestConnectJobDelegate test_delegate;
806     std::unique_ptr<ConnectJob> ssl_connect_job =
807         CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
808     test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
809                                           io_mode == SYNCHRONOUS);
810     CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
811 
812     // Proxies should not set any DNS aliases.
813     EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
814   }
815 }
816 
TEST_F(SSLConnectJobTest,SOCKSHasEstablishedConnection)817 TEST_F(SSLConnectJobTest, SOCKSHasEstablishedConnection) {
818   const uint8_t kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
819                                     'o',  'c',  'k',  's',  'h',  'o',
820                                     's',  't',  0x01, 0xBB};
821 
822   MockWrite writes[] = {
823       MockWrite(SYNCHRONOUS, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength, 0),
824       MockWrite(SYNCHRONOUS, reinterpret_cast<const char*>(kSOCKS5Request),
825                 std::size(kSOCKS5Request), 3),
826   };
827 
828   MockRead reads[] = {
829       // Pause so can probe current state.
830       MockRead(ASYNC, ERR_IO_PENDING, 1),
831       MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength, 2),
832       MockRead(SYNCHRONOUS, kSOCKS5OkResponse, kSOCKS5OkResponseLength, 4),
833   };
834 
835   host_resolver_.set_ondemand_mode(true);
836   SequencedSocketData data(reads, writes);
837   data.set_connect_data(MockConnect(ASYNC, OK));
838   socket_factory_.AddSocketDataProvider(&data);
839 
840   // SSL negotiation hangs. Value returned after SSL negotiation is complete
841   // doesn't matter, as HasEstablishedConnection() may only be used between job
842   // start and job complete.
843   SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
844   socket_factory_.AddSSLSocketDataProvider(&ssl);
845 
846   TestConnectJobDelegate test_delegate;
847   std::unique_ptr<ConnectJob> ssl_connect_job =
848       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
849   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
850   EXPECT_TRUE(host_resolver_.has_pending_requests());
851   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
852   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
853 
854   // DNS resolution completes, and then the ConnectJob tries to connect the
855   // socket, which should succeed asynchronously.
856   host_resolver_.ResolveNow(1);
857   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
858   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
859 
860   // Spin the message loop until the first read of the handshake.
861   // HasEstablishedConnection() should return true, as a TCP connection has been
862   // successfully established by this point.
863   data.RunUntilPaused();
864   EXPECT_FALSE(test_delegate.has_result());
865   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
866   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
867 
868   // Finish up the handshake, and spin the message loop until the SSL handshake
869   // starts and hang.
870   data.Resume();
871   base::RunLoop().RunUntilIdle();
872   EXPECT_FALSE(test_delegate.has_result());
873   EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
874   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
875 }
876 
TEST_F(SSLConnectJobTest,SOCKSRequestPriority)877 TEST_F(SSLConnectJobTest, SOCKSRequestPriority) {
878   host_resolver_.set_ondemand_mode(true);
879   for (int initial_priority = MINIMUM_PRIORITY;
880        initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
881     SCOPED_TRACE(initial_priority);
882     for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
883          ++new_priority) {
884       SCOPED_TRACE(new_priority);
885       if (initial_priority == new_priority)
886         continue;
887       TestConnectJobDelegate test_delegate;
888       std::unique_ptr<ConnectJob> ssl_connect_job =
889           CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5,
890                            static_cast<RequestPriority>(initial_priority));
891       EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
892       EXPECT_TRUE(host_resolver_.has_pending_requests());
893       int request_id = host_resolver_.num_resolve();
894       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
895 
896       ssl_connect_job->ChangePriority(
897           static_cast<RequestPriority>(new_priority));
898       EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
899 
900       ssl_connect_job->ChangePriority(
901           static_cast<RequestPriority>(initial_priority));
902       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
903     }
904   }
905 }
906 
TEST_F(SSLConnectJobTest,HttpProxyFail)907 TEST_F(SSLConnectJobTest, HttpProxyFail) {
908   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
909     SCOPED_TRACE(io_mode);
910     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
911     StaticSocketDataProvider data;
912     data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
913     socket_factory_.AddSocketDataProvider(&data);
914 
915     TestConnectJobDelegate test_delegate;
916     std::unique_ptr<ConnectJob> ssl_connect_job =
917         CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
918     test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
919                                           ERR_PROXY_CONNECTION_FAILED,
920                                           io_mode == SYNCHRONOUS);
921 
922     EXPECT_FALSE(ssl_connect_job->IsSSLError());
923     ConnectionAttempts connection_attempts =
924         ssl_connect_job->GetConnectionAttempts();
925     EXPECT_EQ(0u, connection_attempts.size());
926   }
927 }
928 
TEST_F(SSLConnectJobTest,HttpProxyHostResolutionFailure)929 TEST_F(SSLConnectJobTest, HttpProxyHostResolutionFailure) {
930   host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
931 
932   TestConnectJobDelegate test_delegate;
933   std::unique_ptr<ConnectJob> ssl_connect_job =
934       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
935   test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
936                                         ERR_PROXY_CONNECTION_FAILED,
937                                         false /* expect_sync_result */);
938   EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
939               test::IsError(ERR_DNS_TIMED_OUT));
940 }
941 
TEST_F(SSLConnectJobTest,HttpProxyAuthChallenge)942 TEST_F(SSLConnectJobTest, HttpProxyAuthChallenge) {
943   MockWrite writes[] = {
944       MockWrite(ASYNC, 0,
945                 "CONNECT host:80 HTTP/1.1\r\n"
946                 "Host: host:80\r\n"
947                 "Proxy-Connection: keep-alive\r\n\r\n"),
948       MockWrite(ASYNC, 5,
949                 "CONNECT host:80 HTTP/1.1\r\n"
950                 "Host: host:80\r\n"
951                 "Proxy-Connection: keep-alive\r\n"
952                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
953   };
954   MockRead reads[] = {
955       MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
956       MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
957       MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
958       MockRead(ASYNC, 4, "0123456789"),
959       MockRead(ASYNC, 6, "HTTP/1.1 200 Connection Established\r\n\r\n"),
960   };
961   StaticSocketDataProvider data(reads, writes);
962   socket_factory_.AddSocketDataProvider(&data);
963   SSLSocketDataProvider ssl(ASYNC, OK);
964   socket_factory_.AddSSLSocketDataProvider(&ssl);
965 
966   TestConnectJobDelegate test_delegate;
967   std::unique_ptr<ConnectJob> ssl_connect_job =
968       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
969   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
970   test_delegate.WaitForAuthChallenge(1);
971 
972   EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code());
973   std::string proxy_authenticate;
974   ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader(
975       nullptr, "Proxy-Authenticate", &proxy_authenticate));
976   EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\"");
977 
978   // While waiting for auth credentials to be provided, the Job should not time
979   // out.
980   FastForwardBy(base::Days(1));
981   test_delegate.WaitForAuthChallenge(1);
982   EXPECT_FALSE(test_delegate.has_result());
983 
984   // Respond to challenge.
985   test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
986   test_delegate.RunAuthCallback();
987 
988   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
989 
990   // Proxies should not set any DNS aliases.
991   EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
992 }
993 
TEST_F(SSLConnectJobTest,HttpProxyAuthWithCachedCredentials)994 TEST_F(SSLConnectJobTest, HttpProxyAuthWithCachedCredentials) {
995   for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
996     SCOPED_TRACE(io_mode);
997     host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
998     MockWrite writes[] = {
999         MockWrite(io_mode,
1000                   "CONNECT host:80 HTTP/1.1\r\n"
1001                   "Host: host:80\r\n"
1002                   "Proxy-Connection: keep-alive\r\n"
1003                   "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1004     };
1005     MockRead reads[] = {
1006         MockRead(io_mode, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1007     };
1008     StaticSocketDataProvider data(reads, writes);
1009     data.set_connect_data(MockConnect(io_mode, OK));
1010     socket_factory_.AddSocketDataProvider(&data);
1011     AddAuthToCache();
1012     SSLSocketDataProvider ssl(io_mode, OK);
1013     socket_factory_.AddSSLSocketDataProvider(&ssl);
1014 
1015     TestConnectJobDelegate test_delegate;
1016     std::unique_ptr<ConnectJob> ssl_connect_job =
1017         CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1018     test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
1019                                           io_mode == SYNCHRONOUS);
1020     CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
1021     EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
1022   }
1023 }
1024 
TEST_F(SSLConnectJobTest,HttpProxyRequestPriority)1025 TEST_F(SSLConnectJobTest, HttpProxyRequestPriority) {
1026   host_resolver_.set_ondemand_mode(true);
1027   for (int initial_priority = MINIMUM_PRIORITY;
1028        initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
1029     SCOPED_TRACE(initial_priority);
1030     for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
1031          ++new_priority) {
1032       SCOPED_TRACE(new_priority);
1033       if (initial_priority == new_priority)
1034         continue;
1035       TestConnectJobDelegate test_delegate;
1036       std::unique_ptr<ConnectJob> ssl_connect_job =
1037           CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP,
1038                            static_cast<RequestPriority>(initial_priority));
1039       EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1040       EXPECT_TRUE(host_resolver_.has_pending_requests());
1041       int request_id = host_resolver_.num_resolve();
1042       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
1043 
1044       ssl_connect_job->ChangePriority(
1045           static_cast<RequestPriority>(new_priority));
1046       EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
1047 
1048       ssl_connect_job->ChangePriority(
1049           static_cast<RequestPriority>(initial_priority));
1050       EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
1051     }
1052   }
1053 }
1054 
TEST_F(SSLConnectJobTest,HttpProxyAuthHasEstablishedConnection)1055 TEST_F(SSLConnectJobTest, HttpProxyAuthHasEstablishedConnection) {
1056   host_resolver_.set_ondemand_mode(true);
1057   MockWrite writes[] = {
1058       MockWrite(ASYNC, 0,
1059                 "CONNECT host:80 HTTP/1.1\r\n"
1060                 "Host: host:80\r\n"
1061                 "Proxy-Connection: keep-alive\r\n\r\n"),
1062       MockWrite(ASYNC, 3,
1063                 "CONNECT host:80 HTTP/1.1\r\n"
1064                 "Host: host:80\r\n"
1065                 "Proxy-Connection: keep-alive\r\n"
1066                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1067   };
1068   MockRead reads[] = {
1069       // Pause reading.
1070       MockRead(ASYNC, ERR_IO_PENDING, 1),
1071       MockRead(ASYNC, 2,
1072                "HTTP/1.1 407 Proxy Authentication Required\r\n"
1073                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1074                "Content-Length: 0\r\n\r\n"),
1075       // Pause reading.
1076       MockRead(ASYNC, ERR_IO_PENDING, 4),
1077       MockRead(ASYNC, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1078   };
1079   SequencedSocketData data(reads, writes);
1080   socket_factory_.AddSocketDataProvider(&data);
1081   SSLSocketDataProvider ssl(ASYNC, OK);
1082   socket_factory_.AddSSLSocketDataProvider(&ssl);
1083 
1084   TestConnectJobDelegate test_delegate;
1085   std::unique_ptr<ConnectJob> ssl_connect_job =
1086       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1087   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1088   EXPECT_TRUE(host_resolver_.has_pending_requests());
1089   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1090   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1091 
1092   // DNS resolution completes, and then the ConnectJob tries to connect the
1093   // socket, which should succeed asynchronously.
1094   host_resolver_.ResolveOnlyRequestNow();
1095   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1096   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1097 
1098   // Spinning the message loop causes the connection to be established and the
1099   // nested HttpProxyConnectJob to start establishing a tunnel.
1100   base::RunLoop().RunUntilIdle();
1101   EXPECT_FALSE(test_delegate.has_result());
1102   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1103             ssl_connect_job->GetLoadState());
1104   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1105 
1106   // Receive the auth challenge.
1107   data.Resume();
1108   test_delegate.WaitForAuthChallenge(1);
1109   EXPECT_FALSE(test_delegate.has_result());
1110   EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1111   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1112 
1113   // Respond to challenge.
1114   test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
1115   test_delegate.RunAuthCallback();
1116   EXPECT_FALSE(test_delegate.has_result());
1117   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1118             ssl_connect_job->GetLoadState());
1119   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1120 
1121   // Run until the next read pauses.
1122   base::RunLoop().RunUntilIdle();
1123   EXPECT_FALSE(test_delegate.has_result());
1124   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1125             ssl_connect_job->GetLoadState());
1126   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1127 
1128   // Receive the connection established response, at which point SSL negotiation
1129   // finally starts.
1130   data.Resume();
1131   EXPECT_FALSE(test_delegate.has_result());
1132   EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1133   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1134 
1135   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1136 }
1137 
TEST_F(SSLConnectJobTest,HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose)1138 TEST_F(SSLConnectJobTest,
1139        HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose) {
1140   host_resolver_.set_ondemand_mode(true);
1141   MockWrite writes1[] = {
1142       MockWrite(ASYNC, 0,
1143                 "CONNECT host:80 HTTP/1.1\r\n"
1144                 "Host: host:80\r\n"
1145                 "Proxy-Connection: keep-alive\r\n\r\n"),
1146   };
1147   MockRead reads1[] = {
1148       // Pause reading.
1149       MockRead(ASYNC, ERR_IO_PENDING, 1),
1150       MockRead(ASYNC, 2,
1151                "HTTP/1.1 407 Proxy Authentication Required\r\n"
1152                "Proxy-Connection: Close\r\n"
1153                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1154                "Content-Length: 0\r\n\r\n"),
1155   };
1156   SequencedSocketData data1(reads1, writes1);
1157   socket_factory_.AddSocketDataProvider(&data1);
1158 
1159   MockWrite writes2[] = {
1160       MockWrite(ASYNC, 0,
1161                 "CONNECT host:80 HTTP/1.1\r\n"
1162                 "Host: host:80\r\n"
1163                 "Proxy-Connection: keep-alive\r\n"
1164                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1165   };
1166   MockRead reads2[] = {
1167       // Pause reading.
1168       MockRead(ASYNC, ERR_IO_PENDING, 1),
1169       MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1170   };
1171   SequencedSocketData data2(reads2, writes2);
1172   socket_factory_.AddSocketDataProvider(&data2);
1173   SSLSocketDataProvider ssl(ASYNC, OK);
1174   socket_factory_.AddSSLSocketDataProvider(&ssl);
1175 
1176   TestConnectJobDelegate test_delegate;
1177   std::unique_ptr<ConnectJob> ssl_connect_job =
1178       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1179   ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1180   EXPECT_TRUE(host_resolver_.has_pending_requests());
1181   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1182   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1183 
1184   // DNS resolution completes, and then the ConnectJob tries to connect the
1185   // socket, which should succeed asynchronously.
1186   host_resolver_.ResolveOnlyRequestNow();
1187   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1188   EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1189 
1190   // Spinning the message loop causes the connection to be established and the
1191   // nested HttpProxyConnectJob to start establishing a tunnel.
1192   base::RunLoop().RunUntilIdle();
1193   EXPECT_FALSE(test_delegate.has_result());
1194   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1195             ssl_connect_job->GetLoadState());
1196   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1197 
1198   // Receive the auth challenge.
1199   data1.Resume();
1200   test_delegate.WaitForAuthChallenge(1);
1201   EXPECT_FALSE(test_delegate.has_result());
1202   EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1203   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1204 
1205   // Respond to challenge.
1206   test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
1207   test_delegate.RunAuthCallback();
1208   EXPECT_FALSE(test_delegate.has_result());
1209   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1210             ssl_connect_job->GetLoadState());
1211   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1212 
1213   // Run until the next DNS lookup.
1214   base::RunLoop().RunUntilIdle();
1215   EXPECT_TRUE(host_resolver_.has_pending_requests());
1216   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1217   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1218 
1219   // DNS resolution completes, and then the ConnectJob tries to connect the
1220   // socket, which should succeed asynchronously.
1221   host_resolver_.ResolveOnlyRequestNow();
1222   EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1223   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1224 
1225   // Spinning the message loop causes the connection to be established and the
1226   // nested HttpProxyConnectJob to start establishing a tunnel.
1227   base::RunLoop().RunUntilIdle();
1228   EXPECT_FALSE(test_delegate.has_result());
1229   EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1230             ssl_connect_job->GetLoadState());
1231   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1232 
1233   // Receive the connection established response, at which point SSL negotiation
1234   // finally starts.
1235   data2.Resume();
1236   EXPECT_FALSE(test_delegate.has_result());
1237   EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1238   EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1239 
1240   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1241 }
1242 
TEST_F(SSLConnectJobTest,DnsAliases)1243 TEST_F(SSLConnectJobTest, DnsAliases) {
1244   host_resolver_.set_synchronous_mode(true);
1245 
1246   // Resolve an AddressList with DNS aliases.
1247   std::vector<std::string> aliases({"alias1", "alias2", "host"});
1248   host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1249                                                          std::move(aliases));
1250   StaticSocketDataProvider data;
1251   data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1252   socket_factory_.AddSocketDataProvider(&data);
1253   SSLSocketDataProvider ssl(ASYNC, OK);
1254   socket_factory_.AddSSLSocketDataProvider(&ssl);
1255   TestConnectJobDelegate test_delegate;
1256 
1257   std::unique_ptr<ConnectJob> ssl_connect_job =
1258       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1259 
1260   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1261 
1262   base::RunLoop().RunUntilIdle();
1263 
1264   // Verify that the elements of the alias list are those from the
1265   // parameter vector.
1266   EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1267               testing::ElementsAre("alias1", "alias2", "host"));
1268 }
1269 
TEST_F(SSLConnectJobTest,NoAdditionalDnsAliases)1270 TEST_F(SSLConnectJobTest, NoAdditionalDnsAliases) {
1271   host_resolver_.set_synchronous_mode(true);
1272 
1273   // Resolve an AddressList without additional DNS aliases. (The parameter
1274   // is an empty vector.)
1275   std::vector<std::string> aliases;
1276   host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1277                                                          std::move(aliases));
1278   StaticSocketDataProvider data;
1279   data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1280   socket_factory_.AddSocketDataProvider(&data);
1281   SSLSocketDataProvider ssl(ASYNC, OK);
1282   socket_factory_.AddSSLSocketDataProvider(&ssl);
1283   TestConnectJobDelegate test_delegate;
1284 
1285   std::unique_ptr<ConnectJob> ssl_connect_job =
1286       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1287 
1288   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1289 
1290   base::RunLoop().RunUntilIdle();
1291 
1292   // Verify that the alias list only contains "host".
1293   EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1294               testing::ElementsAre("host"));
1295 }
1296 
1297 // Test that `SSLConnectJob` passes the ECHConfigList from DNS to
1298 // `SSLClientSocket`.
TEST_F(SSLConnectJobTest,EncryptedClientHello)1299 TEST_F(SSLConnectJobTest, EncryptedClientHello) {
1300   std::vector<uint8_t> ech_config_list1, ech_config_list2;
1301   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1302                               &ech_config_list1));
1303   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1304                               &ech_config_list2));
1305 
1306   // Configure two HTTPS RR routes, to test we pass the correct one.
1307   HostResolverEndpointResult endpoint1, endpoint2;
1308   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1309   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1310   endpoint1.metadata.ech_config_list = ech_config_list1;
1311   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1312   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1313   endpoint2.metadata.ech_config_list = ech_config_list2;
1314   host_resolver_.rules()->AddRule(
1315       "host", MockHostResolverBase::RuleResolver::RuleResult(
1316                   std::vector{endpoint1, endpoint2}));
1317 
1318   for (bool feature_enabled : {true, false}) {
1319     SCOPED_TRACE(feature_enabled);
1320     base::test::ScopedFeatureList feature_list;
1321     if (feature_enabled) {
1322       feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
1323     } else {
1324       feature_list.InitAndDisableFeature(features::kEncryptedClientHello);
1325     }
1326 
1327     // The first connection attempt will be to `endpoint1`, which will fail.
1328     StaticSocketDataProvider data1;
1329     data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1330     data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1331     socket_factory_.AddSocketDataProvider(&data1);
1332     // The second connection attempt will be to `endpoint2`, which will succeed.
1333     StaticSocketDataProvider data2;
1334     data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1335     data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1336     socket_factory_.AddSocketDataProvider(&data2);
1337     // The handshake then succeeds.
1338     SSLSocketDataProvider ssl2(ASYNC, OK);
1339     // The ECH configuration should be passed if and only if the feature is
1340     // enabled.
1341     ssl2.expected_ech_config_list =
1342         feature_enabled ? ech_config_list2 : std::vector<uint8_t>{};
1343     socket_factory_.AddSSLSocketDataProvider(&ssl2);
1344 
1345     // The connection should ultimately succeed.
1346     base::HistogramTester histogram_tester;
1347     TestConnectJobDelegate test_delegate;
1348     std::unique_ptr<ConnectJob> ssl_connect_job =
1349         CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1350     EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1351     EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1352 
1353     // Whether or not the feature is enabled, we should record data for the
1354     // ECH-capable server.
1355     histogram_tester.ExpectUniqueSample("Net.SSL_Connection_Error_ECH", OK, 1);
1356     histogram_tester.ExpectTotalCount("Net.SSL_Connection_Latency_ECH", 1);
1357     // The ECH result should only be recorded if ECH was actually enabled.
1358     if (feature_enabled) {
1359       histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1360                                           0 /* kSuccessInitial */, 1);
1361     } else {
1362       histogram_tester.ExpectTotalCount("Net.SSL.ECHResult", 0);
1363     }
1364   }
1365 }
1366 
1367 // Test that `SSLConnectJob` retries the connection if there was a stale ECH
1368 // configuration.
TEST_F(SSLConnectJobTest,ECHStaleConfig)1369 TEST_F(SSLConnectJobTest, ECHStaleConfig) {
1370   base::test::ScopedFeatureList feature_list;
1371   feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
1372 
1373   std::vector<uint8_t> ech_config_list1, ech_config_list2, ech_config_list3;
1374   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1375                               &ech_config_list1));
1376   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1377                               &ech_config_list2));
1378   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1379                               &ech_config_list3));
1380 
1381   // Configure two HTTPS RR routes, to test the retry uses the correct one.
1382   HostResolverEndpointResult endpoint1, endpoint2;
1383   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1384   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1385   endpoint1.metadata.ech_config_list = ech_config_list1;
1386   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1387   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1388   endpoint2.metadata.ech_config_list = ech_config_list2;
1389   host_resolver_.rules()->AddRule(
1390       "host", MockHostResolverBase::RuleResolver::RuleResult(
1391                   std::vector{endpoint1, endpoint2}));
1392 
1393   // The first connection attempt will be to `endpoint1`, which will fail.
1394   StaticSocketDataProvider data1;
1395   data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1396   data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1397   socket_factory_.AddSocketDataProvider(&data1);
1398   // The second connection attempt will be to `endpoint2`, which will succeed.
1399   StaticSocketDataProvider data2;
1400   data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1401   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1402   socket_factory_.AddSocketDataProvider(&data2);
1403   // The handshake will then fail, but then provide retry configs.
1404   SSLSocketDataProvider ssl2(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1405   ssl2.expected_ech_config_list = ech_config_list2;
1406   ssl2.ech_retry_configs = ech_config_list3;
1407   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1408   // The third connection attempt should skip `endpoint1` and retry with only
1409   // `endpoint2`.
1410   StaticSocketDataProvider data3;
1411   data3.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1412   data3.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1413   socket_factory_.AddSocketDataProvider(&data3);
1414   // The handshake should be passed the retry configs.
1415   SSLSocketDataProvider ssl3(ASYNC, OK);
1416   ssl3.expected_ech_config_list = ech_config_list3;
1417   socket_factory_.AddSSLSocketDataProvider(&ssl3);
1418 
1419   // The connection should ultimately succeed.
1420   base::HistogramTester histogram_tester;
1421   TestConnectJobDelegate test_delegate;
1422   std::unique_ptr<ConnectJob> ssl_connect_job =
1423       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1424   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1425   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1426 
1427   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1428                                       2 /* kSuccessRetry */, 1);
1429 }
1430 
1431 // Test that `SSLConnectJob` retries the connection given a secure rollback
1432 // signal.
TEST_F(SSLConnectJobTest,ECHRollback)1433 TEST_F(SSLConnectJobTest, ECHRollback) {
1434   base::test::ScopedFeatureList feature_list;
1435   feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
1436 
1437   std::vector<uint8_t> ech_config_list1, ech_config_list2;
1438   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1439                               &ech_config_list1));
1440   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1441                               &ech_config_list2));
1442 
1443   // Configure two HTTPS RR routes, to test the retry uses the correct one.
1444   HostResolverEndpointResult endpoint1, endpoint2;
1445   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1446   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1447   endpoint1.metadata.ech_config_list = ech_config_list1;
1448   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1449   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1450   endpoint2.metadata.ech_config_list = ech_config_list2;
1451   host_resolver_.rules()->AddRule(
1452       "host", MockHostResolverBase::RuleResolver::RuleResult(
1453                   std::vector{endpoint1, endpoint2}));
1454 
1455   // The first connection attempt will be to `endpoint1`, which will fail.
1456   StaticSocketDataProvider data1;
1457   data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1458   data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1459   socket_factory_.AddSocketDataProvider(&data1);
1460   // The second connection attempt will be to `endpoint2`, which will succeed.
1461   StaticSocketDataProvider data2;
1462   data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1463   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1464   socket_factory_.AddSocketDataProvider(&data2);
1465   // The handshake will then fail, and provide no retry configs.
1466   SSLSocketDataProvider ssl2(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1467   ssl2.expected_ech_config_list = ech_config_list2;
1468   ssl2.ech_retry_configs = std::vector<uint8_t>();
1469   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1470   // The third connection attempt should skip `endpoint1` and retry with only
1471   // `endpoint2`.
1472   StaticSocketDataProvider data3;
1473   data3.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1474   data3.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1475   socket_factory_.AddSocketDataProvider(&data3);
1476   // The handshake should not be passed ECH configs.
1477   SSLSocketDataProvider ssl3(ASYNC, OK);
1478   ssl3.expected_ech_config_list = std::vector<uint8_t>();
1479   socket_factory_.AddSSLSocketDataProvider(&ssl3);
1480 
1481   // The connection should ultimately succeed.
1482   base::HistogramTester histogram_tester;
1483   TestConnectJobDelegate test_delegate;
1484   std::unique_ptr<ConnectJob> ssl_connect_job =
1485       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1486   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1487   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1488 
1489   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1490                                       4 /* kSuccessRollback */, 1);
1491 }
1492 
1493 // Test that `SSLConnectJob` will not retry more than once.
TEST_F(SSLConnectJobTest,ECHTooManyRetries)1494 TEST_F(SSLConnectJobTest, ECHTooManyRetries) {
1495   base::test::ScopedFeatureList feature_list;
1496   feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
1497 
1498   std::vector<uint8_t> ech_config_list1, ech_config_list2, ech_config_list3;
1499   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1500                               &ech_config_list1));
1501   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1502                               &ech_config_list2));
1503   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1504                               &ech_config_list3));
1505 
1506   HostResolverEndpointResult endpoint;
1507   endpoint.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1508   endpoint.metadata.supported_protocol_alpns = {"http/1.1"};
1509   endpoint.metadata.ech_config_list = ech_config_list1;
1510   host_resolver_.rules()->AddRule(
1511       "host",
1512       MockHostResolverBase::RuleResolver::RuleResult(std::vector{endpoint}));
1513 
1514   // The first connection attempt will succeed.
1515   StaticSocketDataProvider data1;
1516   data1.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1517   socket_factory_.AddSocketDataProvider(&data1);
1518   // The handshake will then fail, but provide retry configs.
1519   SSLSocketDataProvider ssl1(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1520   ssl1.expected_ech_config_list = ech_config_list1;
1521   ssl1.ech_retry_configs = ech_config_list2;
1522   socket_factory_.AddSSLSocketDataProvider(&ssl1);
1523   // The second connection attempt will succeed.
1524   StaticSocketDataProvider data2;
1525   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1526   socket_factory_.AddSocketDataProvider(&data2);
1527   // The handshake will then fail, but provide new retry configs.
1528   SSLSocketDataProvider ssl2(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1529   ssl2.expected_ech_config_list = ech_config_list2;
1530   ssl2.ech_retry_configs = ech_config_list3;
1531   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1532   // There will be no third connection attempt.
1533 
1534   base::HistogramTester histogram_tester;
1535   TestConnectJobDelegate test_delegate;
1536   std::unique_ptr<ConnectJob> ssl_connect_job =
1537       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1538   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1539   EXPECT_THAT(test_delegate.WaitForResult(),
1540               test::IsError(ERR_ECH_NOT_NEGOTIATED));
1541 
1542   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult", 3 /* kErrorRetry */,
1543                                       1);
1544 }
1545 
1546 // Test that `SSLConnectJob` will not retry for ECH given the wrong error.
TEST_F(SSLConnectJobTest,ECHWrongRetryError)1547 TEST_F(SSLConnectJobTest, ECHWrongRetryError) {
1548   base::test::ScopedFeatureList feature_list;
1549   feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
1550 
1551   std::vector<uint8_t> ech_config_list1, ech_config_list2;
1552   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1553                               &ech_config_list1));
1554   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1555                               &ech_config_list2));
1556 
1557   HostResolverEndpointResult endpoint;
1558   endpoint.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1559   endpoint.metadata.supported_protocol_alpns = {"http/1.1"};
1560   endpoint.metadata.ech_config_list = ech_config_list1;
1561   host_resolver_.rules()->AddRule(
1562       "host",
1563       MockHostResolverBase::RuleResolver::RuleResult(std::vector{endpoint}));
1564 
1565   // The first connection attempt will succeed.
1566   StaticSocketDataProvider data1;
1567   data1.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1568   socket_factory_.AddSocketDataProvider(&data1);
1569   // The handshake will then fail, but provide retry configs.
1570   SSLSocketDataProvider ssl1(ASYNC, ERR_FAILED);
1571   ssl1.expected_ech_config_list = ech_config_list1;
1572   ssl1.ech_retry_configs = ech_config_list2;
1573   socket_factory_.AddSSLSocketDataProvider(&ssl1);
1574   // There will be no second connection attempt.
1575 
1576   base::HistogramTester histogram_tester;
1577   TestConnectJobDelegate test_delegate;
1578   std::unique_ptr<ConnectJob> ssl_connect_job =
1579       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1580   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1581   EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_FAILED));
1582 
1583   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1584                                       1 /* kErrorInitial */, 1);
1585 }
1586 
1587 // Test the legacy crypto callback can trigger after the ECH recovery flow.
TEST_F(SSLConnectJobTest,ECHRecoveryThenLegacyCrypto)1588 TEST_F(SSLConnectJobTest, ECHRecoveryThenLegacyCrypto) {
1589   base::test::ScopedFeatureList feature_list;
1590   feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
1591 
1592   std::vector<uint8_t> ech_config_list1, ech_config_list2, ech_config_list3;
1593   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1594                               &ech_config_list1));
1595   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1596                               &ech_config_list2));
1597   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1598                               &ech_config_list3));
1599 
1600   // Configure two HTTPS RR routes, to test the retry uses the correct one.
1601   HostResolverEndpointResult endpoint1, endpoint2;
1602   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1603   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1604   endpoint1.metadata.ech_config_list = ech_config_list1;
1605   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1606   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1607   endpoint2.metadata.ech_config_list = ech_config_list2;
1608   host_resolver_.rules()->AddRule(
1609       "host", MockHostResolverBase::RuleResolver::RuleResult(
1610                   std::vector{endpoint1, endpoint2}));
1611 
1612   // The first connection attempt will be to `endpoint1`, which will fail.
1613   StaticSocketDataProvider data1;
1614   data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1615   data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1616   socket_factory_.AddSocketDataProvider(&data1);
1617   // The second connection attempt will be to `endpoint2`, which will succeed.
1618   StaticSocketDataProvider data2;
1619   data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1620   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1621   socket_factory_.AddSocketDataProvider(&data2);
1622   // The handshake will then fail, and provide retry configs.
1623   SSLSocketDataProvider ssl2(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1624   ssl2.expected_ech_config_list = ech_config_list2;
1625   ssl2.expected_disable_sha1_server_signatures = true;
1626   ssl2.ech_retry_configs = ech_config_list3;
1627   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1628   // The third connection attempt should skip `endpoint1` and retry with only
1629   // `endpoint2`.
1630   StaticSocketDataProvider data3;
1631   data3.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1632   data3.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1633   socket_factory_.AddSocketDataProvider(&data3);
1634   // The handshake should be passed the retry configs. This will progress
1635   // further but trigger the legacy crypto fallback.
1636   SSLSocketDataProvider ssl3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
1637   ssl3.expected_ech_config_list = ech_config_list3;
1638   ssl3.expected_disable_sha1_server_signatures = true;
1639   socket_factory_.AddSSLSocketDataProvider(&ssl3);
1640   // The third connection attempt should still skip `endpoint1` and retry with
1641   // only `endpoint2`.
1642   StaticSocketDataProvider data4;
1643   data4.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1644   data4.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1645   socket_factory_.AddSocketDataProvider(&data4);
1646   // The handshake should still be passed ECH retry configs. This time, the
1647   // connection enables legacy crypto and succeeds.
1648   SSLSocketDataProvider ssl4(ASYNC, OK);
1649   ssl4.expected_ech_config_list = ech_config_list3;
1650   ssl4.expected_disable_sha1_server_signatures = true;
1651   socket_factory_.AddSSLSocketDataProvider(&ssl4);
1652 
1653   // The connection should ultimately succeed.
1654   base::HistogramTester histogram_tester;
1655   TestConnectJobDelegate test_delegate;
1656   std::unique_ptr<ConnectJob> ssl_connect_job =
1657       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1658   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1659   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1660 
1661   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1662                                       2 /* kSuccessRetry */, 1);
1663 }
1664 
1665 // Test the ECH recovery flow can trigger after the legacy crypto fallback.
TEST_F(SSLConnectJobTest,LegacyCryptoThenECHRecovery)1666 TEST_F(SSLConnectJobTest, LegacyCryptoThenECHRecovery) {
1667   base::test::ScopedFeatureList feature_list;
1668   feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
1669 
1670   std::vector<uint8_t> ech_config_list1, ech_config_list2, ech_config_list3;
1671   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1672                               &ech_config_list1));
1673   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1674                               &ech_config_list2));
1675   ASSERT_TRUE(MakeTestEchKeys("public.example", /*max_name_len=*/128,
1676                               &ech_config_list3));
1677 
1678   // Configure two HTTPS RR routes, to test the retry uses the correct one.
1679   HostResolverEndpointResult endpoint1, endpoint2;
1680   endpoint1.ip_endpoints = {IPEndPoint(ParseIP("1::"), 8441)};
1681   endpoint1.metadata.supported_protocol_alpns = {"http/1.1"};
1682   endpoint1.metadata.ech_config_list = ech_config_list1;
1683   endpoint2.ip_endpoints = {IPEndPoint(ParseIP("2::"), 8442)};
1684   endpoint2.metadata.supported_protocol_alpns = {"http/1.1"};
1685   endpoint2.metadata.ech_config_list = ech_config_list2;
1686   host_resolver_.rules()->AddRule(
1687       "host", MockHostResolverBase::RuleResolver::RuleResult(
1688                   std::vector{endpoint1, endpoint2}));
1689 
1690   // The first connection attempt will be to `endpoint1`, which will fail.
1691   StaticSocketDataProvider data1;
1692   data1.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1693   data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1694   socket_factory_.AddSocketDataProvider(&data1);
1695   // The second connection attempt will be to `endpoint2`, which will succeed.
1696   StaticSocketDataProvider data2;
1697   data2.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1698   data2.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1699   socket_factory_.AddSocketDataProvider(&data2);
1700   // The handshake will then fail, and trigger the legacy cryptography fallback.
1701   SSLSocketDataProvider ssl2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
1702   ssl2.expected_ech_config_list = ech_config_list2;
1703   ssl2.expected_disable_sha1_server_signatures = true;
1704   socket_factory_.AddSSLSocketDataProvider(&ssl2);
1705   // The third and fourth connection attempts proceed as before, but with legacy
1706   // cryptography enabled.
1707   StaticSocketDataProvider data3;
1708   data3.set_expected_addresses(AddressList(endpoint1.ip_endpoints));
1709   data3.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1710   socket_factory_.AddSocketDataProvider(&data3);
1711   StaticSocketDataProvider data4;
1712   data4.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1713   data4.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1714   socket_factory_.AddSocketDataProvider(&data4);
1715   // The handshake enables legacy crypto. Now ECH fails with retry configs.
1716   SSLSocketDataProvider ssl4(ASYNC, ERR_ECH_NOT_NEGOTIATED);
1717   ssl4.expected_ech_config_list = ech_config_list2;
1718   ssl4.expected_disable_sha1_server_signatures = true;
1719   ssl4.ech_retry_configs = ech_config_list3;
1720   socket_factory_.AddSSLSocketDataProvider(&ssl4);
1721   // The fourth connection attempt should still skip `endpoint1` and retry with
1722   // only `endpoint2`.
1723   StaticSocketDataProvider data5;
1724   data5.set_expected_addresses(AddressList(endpoint2.ip_endpoints));
1725   data5.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1726   socket_factory_.AddSocketDataProvider(&data5);
1727   // The handshake will now succeed with ECH retry configs and legacy
1728   // cryptography.
1729   SSLSocketDataProvider ssl5(ASYNC, OK);
1730   ssl5.expected_ech_config_list = ech_config_list3;
1731   ssl5.expected_disable_sha1_server_signatures = true;
1732   socket_factory_.AddSSLSocketDataProvider(&ssl5);
1733 
1734   // The connection should ultimately succeed.
1735   base::HistogramTester histogram_tester;
1736   TestConnectJobDelegate test_delegate;
1737   std::unique_ptr<ConnectJob> ssl_connect_job =
1738       CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1739   EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1740   EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1741 
1742   histogram_tester.ExpectUniqueSample("Net.SSL.ECHResult",
1743                                       2 /* kSuccessRetry */, 1);
1744 }
1745 
1746 }  // namespace
1747 }  // namespace net
1748