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