blob: 118df885dd79d031a9981359b35b0336c35311ac [file] [log] [blame]
Matt Menke7b5051072019-01-27 21:22:491// Copyright 2019 The Chromium Authors. All rights reserved.
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/callback.h"
11#include "base/compiler_specific.h"
Lei Zhang305c015e12021-06-04 21:07:0212#include "base/cxx17_backports.h"
Matt Menke7b5051072019-01-27 21:22:4913#include "base/strings/string_util.h"
14#include "base/strings/utf_string_conversions.h"
David Benjamin07a07d652020-02-26 22:26:5915#include "base/test/metrics/histogram_tester.h"
16#include "base/test/scoped_feature_list.h"
Gabriel Charettec7108742019-08-23 03:31:4017#include "base/test/task_environment.h"
Matt Menke7b5051072019-01-27 21:22:4918#include "base/time/time.h"
19#include "net/base/auth.h"
David Benjamin07a07d652020-02-26 22:26:5920#include "net/base/features.h"
Matt Menke7b5051072019-01-27 21:22:4921#include "net/base/load_timing_info.h"
22#include "net/base/net_errors.h"
Matt Menkeae58eeb2019-05-24 21:09:5023#include "net/base/network_isolation_key.h"
Matt Menke7b5051072019-01-27 21:22:4924#include "net/cert/ct_policy_enforcer.h"
25#include "net/cert/mock_cert_verifier.h"
Matt Menke7b5051072019-01-27 21:22:4926#include "net/dns/mock_host_resolver.h"
Ben Schwartz3ff4dc1e62021-04-27 21:15:2327#include "net/dns/public/secure_dns_policy.h"
Matt Menke7b5051072019-01-27 21:22:4928#include "net/http/http_auth_handler_factory.h"
29#include "net/http/http_network_session.h"
Matt Menke0754b5d02019-02-10 21:46:4330#include "net/http/http_proxy_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4931#include "net/http/http_request_headers.h"
32#include "net/http/http_response_headers.h"
Matt Menke609160742019-08-02 18:47:2633#include "net/http/http_server_properties.h"
Matt Menke7b5051072019-01-27 21:22:4934#include "net/http/transport_security_state.h"
35#include "net/log/net_log_source.h"
36#include "net/log/net_log_with_source.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5637#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Victor Vasiliev7752898d2019-11-14 21:30:2238#include "net/quic/quic_context.h"
Matt Menke7b5051072019-01-27 21:22:4939#include "net/socket/connect_job_test_util.h"
Matt Menke6030ed9f2019-04-11 20:25:5540#include "net/socket/connection_attempts.h"
Matt Menke7b5051072019-01-27 21:22:4941#include "net/socket/next_proto.h"
42#include "net/socket/socket_tag.h"
43#include "net/socket/socket_test_util.h"
44#include "net/socket/socks_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4945#include "net/socket/transport_connect_job.h"
46#include "net/ssl/ssl_config_service_defaults.h"
David Benjamin07a07d652020-02-26 22:26:5947#include "net/ssl/ssl_connection_status_flags.h"
48#include "net/ssl/ssl_legacy_crypto_fallback.h"
49#include "net/test/cert_test_util.h"
Matt Menke7b5051072019-01-27 21:22:4950#include "net/test/gtest_util.h"
51#include "net/test/test_certificate_data.h"
David Benjamin07a07d652020-02-26 22:26:5952#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4053#include "net/test/test_with_task_environment.h"
Matt Menke7b5051072019-01-27 21:22:4954#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
55#include "testing/gtest/include/gtest/gtest.h"
David Benjamin07a07d652020-02-26 22:26:5956#include "third_party/boringssl/src/include/openssl/ssl.h"
Eric Orthc98a3e62021-07-02 17:46:3757#include "url/scheme_host_port.h"
58#include "url/url_constants.h"
Matt Menke7b5051072019-01-27 21:22:4959
60namespace net {
61namespace {
62
Matt Menke7b5051072019-01-27 21:22:4963// Just check that all connect times are set to base::TimeTicks::Now(), for
64// tests that don't update the mocked out time.
65void CheckConnectTimesSet(const LoadTimingInfo::ConnectTiming& connect_timing) {
66 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_start);
67 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_end);
68 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
69 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
70 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
71 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
72}
73
74// Just check that all connect times are set to base::TimeTicks::Now(), except
75// for DNS times, for tests that don't update the mocked out time and use a
76// proxy.
77void CheckConnectTimesExceptDnsSet(
78 const LoadTimingInfo::ConnectTiming& connect_timing) {
79 EXPECT_TRUE(connect_timing.dns_start.is_null());
80 EXPECT_TRUE(connect_timing.dns_end.is_null());
81 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
82 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
83 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
84 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
85}
86
Gabriel Charette694c3c332019-08-19 14:53:0587class SSLConnectJobTest : public WithTaskEnvironment, public testing::Test {
Matt Menke7b5051072019-01-27 21:22:4988 public:
89 SSLConnectJobTest()
Gabriel Charette694c3c332019-08-19 14:53:0590 : WithTaskEnvironment(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Nicolas Arciniegad2013f92020-02-07 23:00:5691 proxy_resolution_service_(
92 ConfiguredProxyResolutionService::CreateDirect()),
Matt Menke7b5051072019-01-27 21:22:4993 ssl_config_service_(new SSLConfigServiceDefaults),
Eric Orthbe2efac2019-03-06 01:11:1194 http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke7b5051072019-01-27 21:22:4995 session_(CreateNetworkSession()),
Eric Orthc98a3e62021-07-02 17:46:3796 direct_transport_socket_params_(new TransportSocketParams(
97 url::SchemeHostPort(url::kHttpsScheme, "host", 443),
98 NetworkIsolationKey(),
99 SecureDnsPolicy::kAllow,
100 OnHostResolutionCallback())),
Matt Menke7b5051072019-01-27 21:22:49101 proxy_transport_socket_params_(
102 new TransportSocketParams(HostPortPair("proxy", 443),
Matt Menkecd439232019-11-05 15:15:33103 NetworkIsolationKey(),
Ben Schwartz3ff4dc1e62021-04-27 21:15:23104 SecureDnsPolicy::kAllow,
Matt Menke7b5051072019-01-27 21:22:49105 OnHostResolutionCallback())),
106 socks_socket_params_(
107 new SOCKSSocketParams(proxy_transport_socket_params_,
108 true,
109 HostPortPair("sockshost", 443),
Matt Menke166710e2019-11-06 03:35:51110 NetworkIsolationKey(),
Matt Menke7b5051072019-01-27 21:22:49111 TRAFFIC_ANNOTATION_FOR_TESTS)),
112 http_proxy_socket_params_(
113 new HttpProxySocketParams(proxy_transport_socket_params_,
114 nullptr /* ssl_params */,
Matt Menkeb5fb42b2019-03-22 17:26:13115 false /* is_quic */,
Matt Menke7b5051072019-01-27 21:22:49116 HostPortPair("host", 80),
Matt Menke7b5051072019-01-27 21:22:49117 /*tunnel=*/true,
Matt Menkeae58eeb2019-05-24 21:09:50118 TRAFFIC_ANNOTATION_FOR_TESTS,
119 NetworkIsolationKey())),
Gabriel Charette694c3c332019-08-19 14:53:05120 common_connect_job_params_(session_->CreateCommonConnectJobParams()) {}
Matt Menke7b5051072019-01-27 21:22:49121
122 ~SSLConnectJobTest() override = default;
123
124 std::unique_ptr<ConnectJob> CreateConnectJob(
125 TestConnectJobDelegate* test_delegate,
126 ProxyServer::Scheme proxy_scheme = ProxyServer::SCHEME_DIRECT,
127 RequestPriority priority = DEFAULT_PRIORITY) {
128 return std::make_unique<SSLConnectJob>(
Matt Menkea6f99ad2019-03-08 02:26:43129 priority, SocketTag(), &common_connect_job_params_,
Matt Menke14819512019-03-02 16:59:58130 SSLParams(proxy_scheme), test_delegate, nullptr /* net_log */);
Matt Menke7b5051072019-01-27 21:22:49131 }
132
133 scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy) {
134 return base::MakeRefCounted<SSLSocketParams>(
135 proxy == ProxyServer::SCHEME_DIRECT ? direct_transport_socket_params_
136 : nullptr,
137 proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : nullptr,
138 proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : nullptr,
David Benjamin151ec6b2019-08-02 19:38:52139 HostPortPair("host", 443), SSLConfig(), PRIVACY_MODE_DISABLED,
David Benjamin6f2da652019-06-26 23:36:35140 NetworkIsolationKey());
Matt Menke7b5051072019-01-27 21:22:49141 }
142
143 void AddAuthToCache() {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:48144 const std::u16string kFoo(u"foo");
145 const std::u16string kBar(u"bar");
Matt Menke7b5051072019-01-27 21:22:49146 session_->http_auth_cache()->Add(
Matt Menke96092e62019-10-18 04:09:33147 GURL("http://proxy:443/"), HttpAuth::AUTH_PROXY, "MyRealm1",
Matt Menkebe090422019-10-18 20:25:26148 HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
149 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
Matt Menke7b5051072019-01-27 21:22:49150 }
151
152 HttpNetworkSession* CreateNetworkSession() {
Matt Menke30a878c2021-07-20 22:25:09153 HttpNetworkSessionContext session_context;
Matt Menke7b5051072019-01-27 21:22:49154 session_context.host_resolver = &host_resolver_;
155 session_context.cert_verifier = &cert_verifier_;
156 session_context.transport_security_state = &transport_security_state_;
Matt Menke7b5051072019-01-27 21:22:49157 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
158 session_context.proxy_resolution_service = proxy_resolution_service_.get();
159 session_context.client_socket_factory = &socket_factory_;
160 session_context.ssl_config_service = ssl_config_service_.get();
161 session_context.http_auth_handler_factory =
162 http_auth_handler_factory_.get();
163 session_context.http_server_properties = &http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:22164 session_context.quic_context = &quic_context_;
Matt Menke30a878c2021-07-20 22:25:09165 return new HttpNetworkSession(HttpNetworkSessionParams(), session_context);
Matt Menke7b5051072019-01-27 21:22:49166 }
167
168 protected:
169 MockClientSocketFactory socket_factory_;
Matt Menkeaade5812019-03-02 13:38:00170 MockHostResolver host_resolver_;
Matt Menke7b5051072019-01-27 21:22:49171 MockCertVerifier cert_verifier_;
172 TransportSecurityState transport_security_state_;
Matt Menke7b5051072019-01-27 21:22:49173 DefaultCTPolicyEnforcer ct_policy_enforcer_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:26174 const std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
Matt Menke7b5051072019-01-27 21:22:49175 const std::unique_ptr<SSLConfigService> ssl_config_service_;
176 const std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:26177 HttpServerProperties http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:22178 QuicContext quic_context_;
Matt Menke7b5051072019-01-27 21:22:49179 const std::unique_ptr<HttpNetworkSession> session_;
Matt Menke7b5051072019-01-27 21:22:49180
181 scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
Matt Menke7b5051072019-01-27 21:22:49182
183 scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
184 scoped_refptr<SOCKSSocketParams> socks_socket_params_;
185 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
186
Matt Menkea6f99ad2019-03-08 02:26:43187 const CommonConnectJobParams common_connect_job_params_;
Matt Menke7b5051072019-01-27 21:22:49188};
189
190TEST_F(SSLConnectJobTest, TCPFail) {
191 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
192 SCOPED_TRACE(io_mode);
193 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
194 StaticSocketDataProvider data;
195 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
196 socket_factory_.AddSocketDataProvider(&data);
197
198 TestConnectJobDelegate test_delegate;
199 std::unique_ptr<ConnectJob> ssl_connect_job =
200 CreateConnectJob(&test_delegate);
201 test_delegate.StartJobExpectingResult(
202 ssl_connect_job.get(), ERR_CONNECTION_FAILED, io_mode == SYNCHRONOUS);
203 EXPECT_FALSE(test_delegate.socket());
Matt Menke6f84d1f12019-04-11 19:26:47204 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55205 ConnectionAttempts connection_attempts =
206 ssl_connect_job->GetConnectionAttempts();
207 ASSERT_EQ(1u, connection_attempts.size());
208 EXPECT_THAT(connection_attempts[0].result,
Matt Menke7b5051072019-01-27 21:22:49209 test::IsError(ERR_CONNECTION_FAILED));
210 }
211}
212
Matt Menke36eaf5c2019-04-02 16:15:52213TEST_F(SSLConnectJobTest, TCPTimeout) {
214 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
215
216 // Make request hang.
217 host_resolver_.set_ondemand_mode(true);
218
219 TestConnectJobDelegate test_delegate;
220 std::unique_ptr<ConnectJob> ssl_connect_job =
221 CreateConnectJob(&test_delegate);
222 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
223
224 // Right up until just before the TCP connection timeout, the job does not
225 // time out.
226 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
227 EXPECT_FALSE(test_delegate.has_result());
228
229 // But at the exact time of TCP connection timeout, the job fails.
230 FastForwardBy(kTinyTime);
231 EXPECT_TRUE(test_delegate.has_result());
232 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
233}
234
235TEST_F(SSLConnectJobTest, SSLTimeoutSyncConnect) {
236 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
237
238 // DNS lookup and transport connect complete synchronously, but SSL
239 // negotiation hangs.
240 host_resolver_.set_synchronous_mode(true);
241 StaticSocketDataProvider data;
242 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
243 socket_factory_.AddSocketDataProvider(&data);
244 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
245 socket_factory_.AddSSLSocketDataProvider(&ssl);
246
247 // Make request hang.
248 TestConnectJobDelegate test_delegate;
249 std::unique_ptr<ConnectJob> ssl_connect_job =
250 CreateConnectJob(&test_delegate);
251 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
252
253 // Right up until just before the SSL handshake timeout, the job does not time
254 // out.
255 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
256 EXPECT_FALSE(test_delegate.has_result());
257
258 // But at the exact SSL handshake timeout time, the job fails.
259 FastForwardBy(kTinyTime);
260 EXPECT_TRUE(test_delegate.has_result());
261 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
262}
263
264TEST_F(SSLConnectJobTest, SSLTimeoutAsyncTcpConnect) {
265 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
266
267 // DNS lookup is asynchronous, and later SSL negotiation hangs.
268 host_resolver_.set_ondemand_mode(true);
269 StaticSocketDataProvider data;
270 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
271 socket_factory_.AddSocketDataProvider(&data);
272 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
273 socket_factory_.AddSSLSocketDataProvider(&ssl);
274
275 TestConnectJobDelegate test_delegate;
276 std::unique_ptr<ConnectJob> ssl_connect_job =
277 CreateConnectJob(&test_delegate);
278 // Connecting should hand on the TransportConnectJob connect.
279 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
280
281 // Right up until just before the TCP connection timeout, the job does not
282 // time out.
283 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
284 EXPECT_FALSE(test_delegate.has_result());
285
286 // The DNS lookup completes, and a TCP connection is immediately establshed,
287 // which cancels the TCP connection timer. The SSL handshake timer is started,
288 // and the SSL handshake hangs.
289 host_resolver_.ResolveOnlyRequestNow();
290 EXPECT_FALSE(test_delegate.has_result());
291
292 // Right up until just before the SSL handshake timeout, the job does not time
293 // out.
294 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
295 EXPECT_FALSE(test_delegate.has_result());
296
297 // But at the exact SSL handshake timeout time, the job fails.
298 FastForwardBy(kTinyTime);
299 EXPECT_TRUE(test_delegate.has_result());
300 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
301}
302
Matt Menke7b5051072019-01-27 21:22:49303TEST_F(SSLConnectJobTest, BasicDirectSync) {
304 host_resolver_.set_synchronous_mode(true);
305 StaticSocketDataProvider data;
306 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
307 socket_factory_.AddSocketDataProvider(&data);
308 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
309 socket_factory_.AddSSLSocketDataProvider(&ssl);
310
311 TestConnectJobDelegate test_delegate;
312 std::unique_ptr<ConnectJob> ssl_connect_job =
313 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
314
315 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
316 true /* expect_sync_result */);
317 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
318
Matt Menke6030ed9f2019-04-11 20:25:55319 ConnectionAttempts connection_attempts =
320 ssl_connect_job->GetConnectionAttempts();
321 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49322 CheckConnectTimesSet(ssl_connect_job->connect_timing());
323}
324
325TEST_F(SSLConnectJobTest, BasicDirectAsync) {
326 host_resolver_.set_ondemand_mode(true);
327 base::TimeTicks start_time = base::TimeTicks::Now();
328 StaticSocketDataProvider data;
329 data.set_connect_data(MockConnect(ASYNC, OK));
330 socket_factory_.AddSocketDataProvider(&data);
331 SSLSocketDataProvider ssl(ASYNC, OK);
332 socket_factory_.AddSSLSocketDataProvider(&ssl);
333
334 TestConnectJobDelegate test_delegate;
335 std::unique_ptr<ConnectJob> ssl_connect_job =
336 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
337 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
338 EXPECT_TRUE(host_resolver_.has_pending_requests());
339 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
340 FastForwardBy(base::TimeDelta::FromSeconds(5));
341
342 base::TimeTicks resolve_complete_time = base::TimeTicks::Now();
343 host_resolver_.ResolveAllPending();
344 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
345
Matt Menke6030ed9f2019-04-11 20:25:55346 ConnectionAttempts connection_attempts =
347 ssl_connect_job->GetConnectionAttempts();
348 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49349
350 // Check times. Since time is mocked out, all times will be the same, except
351 // |dns_start|, which is the only one recorded before the FastForwardBy()
352 // call. The test classes don't allow any other phases to be triggered on
353 // demand, or delayed by a set interval.
354 EXPECT_EQ(start_time, ssl_connect_job->connect_timing().dns_start);
355 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().dns_end);
356 EXPECT_EQ(resolve_complete_time,
357 ssl_connect_job->connect_timing().connect_start);
358 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_start);
359 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_end);
360 EXPECT_EQ(resolve_complete_time,
361 ssl_connect_job->connect_timing().connect_end);
362}
363
Matt Menke9d5e2c92019-02-05 01:42:23364TEST_F(SSLConnectJobTest, DirectHasEstablishedConnection) {
365 host_resolver_.set_ondemand_mode(true);
366 StaticSocketDataProvider data;
367 data.set_connect_data(MockConnect(ASYNC, OK));
368 socket_factory_.AddSocketDataProvider(&data);
369
370 // SSL negotiation hangs. Value returned after SSL negotiation is complete
371 // doesn't matter, as HasEstablishedConnection() may only be used between job
372 // start and job complete.
373 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
374 socket_factory_.AddSSLSocketDataProvider(&ssl);
375
376 TestConnectJobDelegate test_delegate;
377 std::unique_ptr<ConnectJob> ssl_connect_job =
378 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
379 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
380 EXPECT_TRUE(host_resolver_.has_pending_requests());
381 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
382 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
383
384 // DNS resolution completes, and then the ConnectJob tries to connect the
385 // socket, which should succeed asynchronously.
386 host_resolver_.ResolveNow(1);
387 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
388 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
389
390 // Spinning the message loop causes the socket to finish connecting. The SSL
391 // handshake should start and hang.
392 base::RunLoop().RunUntilIdle();
393 EXPECT_FALSE(test_delegate.has_result());
394 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
395 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
396}
397
Matt Menke7b5051072019-01-27 21:22:49398TEST_F(SSLConnectJobTest, RequestPriority) {
399 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49400 for (int initial_priority = MINIMUM_PRIORITY;
401 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
402 SCOPED_TRACE(initial_priority);
403 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
404 ++new_priority) {
405 SCOPED_TRACE(new_priority);
406 if (initial_priority == new_priority)
407 continue;
408 TestConnectJobDelegate test_delegate;
409 std::unique_ptr<ConnectJob> ssl_connect_job =
410 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT,
411 static_cast<RequestPriority>(initial_priority));
412 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
413 EXPECT_TRUE(host_resolver_.has_pending_requests());
414 int request_id = host_resolver_.num_resolve();
415 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
416
417 ssl_connect_job->ChangePriority(
418 static_cast<RequestPriority>(new_priority));
419 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
420
421 ssl_connect_job->ChangePriority(
422 static_cast<RequestPriority>(initial_priority));
423 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49424 }
425 }
426}
427
Ben Schwartz3ff4dc1e62021-04-27 21:15:23428TEST_F(SSLConnectJobTest, SecureDnsPolicy) {
429 for (auto secure_dns_policy :
430 {SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable}) {
dalyk5f48a132019-10-14 15:20:19431 TestConnectJobDelegate test_delegate;
432 direct_transport_socket_params_ =
Matt Menkecd439232019-11-05 15:15:33433 base::MakeRefCounted<TransportSocketParams>(
Eric Orthc98a3e62021-07-02 17:46:37434 url::SchemeHostPort(url::kHttpsScheme, "host", 443),
435 NetworkIsolationKey(), secure_dns_policy,
Ben Schwartz3ff4dc1e62021-04-27 21:15:23436 OnHostResolutionCallback());
dalyk5f48a132019-10-14 15:20:19437 auto common_connect_job_params = session_->CreateCommonConnectJobParams();
438 std::unique_ptr<ConnectJob> ssl_connect_job =
439 std::make_unique<SSLConnectJob>(DEFAULT_PRIORITY, SocketTag(),
440 &common_connect_job_params,
441 SSLParams(ProxyServer::SCHEME_DIRECT),
442 &test_delegate, nullptr /* net_log */);
443
444 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
Ben Schwartz432ce032021-05-05 21:49:24445 EXPECT_EQ(secure_dns_policy, host_resolver_.last_secure_dns_policy());
dalyk5f48a132019-10-14 15:20:19446 }
447}
448
dalykedd30d982019-12-16 15:31:10449TEST_F(SSLConnectJobTest, DirectHostResolutionFailure) {
450 host_resolver_.rules()->AddSimulatedTimeoutFailure("host");
451
452 TestConnectJobDelegate test_delegate;
453 std::unique_ptr<ConnectJob> ssl_connect_job =
454 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT);
455 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
456 ERR_NAME_NOT_RESOLVED,
457 false /* expect_sync_result */);
458 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
459 test::IsError(ERR_DNS_TIMED_OUT));
460}
461
Matt Menke7b5051072019-01-27 21:22:49462TEST_F(SSLConnectJobTest, DirectCertError) {
463 StaticSocketDataProvider data;
464 socket_factory_.AddSocketDataProvider(&data);
465 SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
466 socket_factory_.AddSSLSocketDataProvider(&ssl);
467
468 TestConnectJobDelegate test_delegate(
469 TestConnectJobDelegate::SocketExpected::ALWAYS);
470 std::unique_ptr<ConnectJob> ssl_connect_job =
471 CreateConnectJob(&test_delegate);
472
473 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
474 ERR_CERT_COMMON_NAME_INVALID,
475 false /* expect_sync_result */);
Matt Menke6f84d1f12019-04-11 19:26:47476 EXPECT_TRUE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55477 ConnectionAttempts connection_attempts =
478 ssl_connect_job->GetConnectionAttempts();
479 ASSERT_EQ(1u, connection_attempts.size());
480 EXPECT_THAT(connection_attempts[0].result,
Matt Menke7b5051072019-01-27 21:22:49481 test::IsError(ERR_CERT_COMMON_NAME_INVALID));
482 CheckConnectTimesSet(ssl_connect_job->connect_timing());
483}
484
485TEST_F(SSLConnectJobTest, DirectSSLError) {
486 StaticSocketDataProvider data;
487 socket_factory_.AddSocketDataProvider(&data);
David Benjamin07a07d652020-02-26 22:26:59488 SSLSocketDataProvider ssl(ASYNC, ERR_BAD_SSL_CLIENT_AUTH_CERT);
Matt Menke7b5051072019-01-27 21:22:49489 socket_factory_.AddSSLSocketDataProvider(&ssl);
490
491 TestConnectJobDelegate test_delegate;
492 std::unique_ptr<ConnectJob> ssl_connect_job =
493 CreateConnectJob(&test_delegate);
494
495 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
David Benjamin07a07d652020-02-26 22:26:59496 ERR_BAD_SSL_CLIENT_AUTH_CERT,
Matt Menke7b5051072019-01-27 21:22:49497 false /* expect_sync_result */);
Matt Menke6030ed9f2019-04-11 20:25:55498 ConnectionAttempts connection_attempts =
499 ssl_connect_job->GetConnectionAttempts();
500 ASSERT_EQ(1u, connection_attempts.size());
501 EXPECT_THAT(connection_attempts[0].result,
David Benjamin07a07d652020-02-26 22:26:59502 test::IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
503}
504
505// Test that the legacy crypto fallback is triggered on applicable error codes.
506TEST_F(SSLConnectJobTest, DirectLegacyCryptoFallback) {
507 for (Error error :
508 {ERR_CONNECTION_CLOSED, ERR_CONNECTION_RESET, ERR_SSL_PROTOCOL_ERROR,
509 ERR_SSL_VERSION_OR_CIPHER_MISMATCH}) {
510 SCOPED_TRACE(error);
511
512 for (bool second_attempt_ok : {true, false}) {
513 SCOPED_TRACE(second_attempt_ok);
514
515 StaticSocketDataProvider data;
516 socket_factory_.AddSocketDataProvider(&data);
517 SSLSocketDataProvider ssl(ASYNC, error);
518 socket_factory_.AddSSLSocketDataProvider(&ssl);
519 ssl.expected_disable_legacy_crypto = true;
520
521 Error error2 = second_attempt_ok ? OK : error;
522 StaticSocketDataProvider data2;
523 socket_factory_.AddSocketDataProvider(&data2);
524 SSLSocketDataProvider ssl2(ASYNC, error2);
525 socket_factory_.AddSSLSocketDataProvider(&ssl2);
526 ssl2.expected_disable_legacy_crypto = false;
527
528 TestConnectJobDelegate test_delegate;
529 std::unique_ptr<ConnectJob> ssl_connect_job =
530 CreateConnectJob(&test_delegate);
531
532 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), error2,
533 /*expect_sync_result=*/false);
534 ConnectionAttempts connection_attempts =
535 ssl_connect_job->GetConnectionAttempts();
536 if (second_attempt_ok) {
537 ASSERT_EQ(1u, connection_attempts.size());
538 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
539 } else {
540 ASSERT_EQ(2u, connection_attempts.size());
541 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
542 EXPECT_THAT(connection_attempts[1].result, test::IsError(error));
543 }
544 }
545 }
546}
547
548// Test that the feature flag disables the legacy crypto fallback.
549TEST_F(SSLConnectJobTest, LegacyCryptoFallbackDisabled) {
550 base::test::ScopedFeatureList feature_list;
551 feature_list.InitAndDisableFeature(
552 features::kTLSLegacyCryptoFallbackForMetrics);
553 for (Error error :
554 {ERR_CONNECTION_CLOSED, ERR_CONNECTION_RESET, ERR_SSL_PROTOCOL_ERROR,
555 ERR_SSL_VERSION_OR_CIPHER_MISMATCH}) {
556 SCOPED_TRACE(error);
557
558 StaticSocketDataProvider data;
559 socket_factory_.AddSocketDataProvider(&data);
560 SSLSocketDataProvider ssl(ASYNC, error);
561 socket_factory_.AddSSLSocketDataProvider(&ssl);
562 ssl.expected_disable_legacy_crypto = false;
563
564 TestConnectJobDelegate test_delegate;
565 std::unique_ptr<ConnectJob> ssl_connect_job =
566 CreateConnectJob(&test_delegate);
567
568 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), error,
569 /*expect_sync_result=*/false);
570 ConnectionAttempts connection_attempts =
571 ssl_connect_job->GetConnectionAttempts();
572 ASSERT_EQ(1u, connection_attempts.size());
573 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
574 }
575}
576
577TEST_F(SSLConnectJobTest, LegacyCryptoFallbackHistograms) {
578 base::FilePath certs_dir = GetTestCertsDirectory();
579
580 scoped_refptr<X509Certificate> sha1_leaf =
581 ImportCertFromFile(certs_dir, "sha1_leaf.pem");
582 ASSERT_TRUE(sha1_leaf);
583
584 scoped_refptr<X509Certificate> ok_cert =
585 ImportCertFromFile(certs_dir, "ok_cert.pem");
586 ASSERT_TRUE(ok_cert);
587
588 // Make a copy of |ok_cert| with an unused |sha1_leaf| in the intermediate
589 // list.
590 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
591 for (const auto& cert : ok_cert->intermediate_buffers()) {
592 intermediates.push_back(bssl::UpRef(cert));
593 }
594 intermediates.push_back(bssl::UpRef(sha1_leaf->cert_buffer()));
595 scoped_refptr<X509Certificate> ok_with_unused_sha1 =
596 X509Certificate::CreateFromBuffer(bssl::UpRef(ok_cert->cert_buffer()),
597 std::move(intermediates));
598 ASSERT_TRUE(ok_with_unused_sha1);
599
600 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
601 const uint16_t kModernCipher = 0xc02f;
602 // TLS_RSA_WITH_3DES_EDE_CBC_SHA
603 const uint16_t k3DESCipher = 0x000a;
604
605 struct HistogramTest {
606 SSLLegacyCryptoFallback expected;
607 Error first_attempt;
608 uint16_t cipher_suite;
609 uint16_t peer_signature_algorithm;
610 scoped_refptr<X509Certificate> unverified_cert;
611 };
612
613 const HistogramTest kHistogramTests[] = {
614 // Connections not using the fallback map to kNoFallback.
615 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
616 SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
617 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
618 SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
619 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
620 SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
621
622 // Connections using 3DES map to kUsed3DES or kSentSHA1CertAndUsed3DES.
623 // Note our only supported 3DES cipher suite does not include a server
624 // signature, so |peer_signature_algorithm| would always be zero.
625 {SSLLegacyCryptoFallback::kUsed3DES, ERR_SSL_PROTOCOL_ERROR, k3DESCipher,
626 0, ok_cert},
627 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsed3DES,
628 ERR_SSL_PROTOCOL_ERROR, k3DESCipher, 0, sha1_leaf},
629 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsed3DES,
630 ERR_SSL_PROTOCOL_ERROR, k3DESCipher, 0, ok_with_unused_sha1},
631
632 // Connections using SHA-1 map to kUsedSHA1 or kSentSHA1CertAndUsedSHA1.
633 {SSLLegacyCryptoFallback::kUsedSHA1, ERR_SSL_PROTOCOL_ERROR,
634 kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1, ok_cert},
635 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
636 ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
637 sha1_leaf},
638 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
639 ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
640 ok_with_unused_sha1},
641
642 // Connections using neither map to kUnknownReason or kSentSHA1Cert.
643 {SSLLegacyCryptoFallback::kUnknownReason, ERR_SSL_PROTOCOL_ERROR,
644 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
645 {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
646 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
647 {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
648 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
649 };
650 for (size_t i = 0; i < base::size(kHistogramTests); i++) {
651 SCOPED_TRACE(i);
652 const auto& test = kHistogramTests[i];
653
654 base::HistogramTester tester;
655
656 SSLInfo ssl_info;
657 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
658 &ssl_info.connection_status);
659 SSLConnectionStatusSetCipherSuite(test.cipher_suite,
660 &ssl_info.connection_status);
661 ssl_info.peer_signature_algorithm = test.peer_signature_algorithm;
662 ssl_info.unverified_cert = test.unverified_cert;
663
664 StaticSocketDataProvider data;
665 socket_factory_.AddSocketDataProvider(&data);
666 SSLSocketDataProvider ssl(ASYNC, test.first_attempt);
667 socket_factory_.AddSSLSocketDataProvider(&ssl);
668 ssl.expected_disable_legacy_crypto = true;
669
670 StaticSocketDataProvider data2;
671 SSLSocketDataProvider ssl2(ASYNC, OK);
672 if (test.first_attempt != OK) {
673 socket_factory_.AddSocketDataProvider(&data2);
674 socket_factory_.AddSSLSocketDataProvider(&ssl2);
675 ssl2.ssl_info = ssl_info;
676 ssl2.expected_disable_legacy_crypto = false;
677 } else {
678 ssl.ssl_info = ssl_info;
679 }
680
681 TestConnectJobDelegate test_delegate;
682 std::unique_ptr<ConnectJob> ssl_connect_job =
683 CreateConnectJob(&test_delegate);
684
685 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
686 /*expect_sync_result=*/false);
687
688 tester.ExpectUniqueSample("Net.SSLLegacyCryptoFallback", test.expected, 1);
689 }
Matt Menke7b5051072019-01-27 21:22:49690}
691
692TEST_F(SSLConnectJobTest, DirectWithNPN) {
693 StaticSocketDataProvider data;
694 socket_factory_.AddSocketDataProvider(&data);
695 SSLSocketDataProvider ssl(ASYNC, OK);
696 ssl.next_proto = kProtoHTTP11;
697 socket_factory_.AddSSLSocketDataProvider(&ssl);
698
699 TestConnectJobDelegate test_delegate;
700 std::unique_ptr<ConnectJob> ssl_connect_job =
701 CreateConnectJob(&test_delegate);
702
703 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
704 false /* expect_sync_result */);
705 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
706 CheckConnectTimesSet(ssl_connect_job->connect_timing());
707}
708
709TEST_F(SSLConnectJobTest, DirectGotHTTP2) {
710 StaticSocketDataProvider data;
711 socket_factory_.AddSocketDataProvider(&data);
712 SSLSocketDataProvider ssl(ASYNC, OK);
713 ssl.next_proto = kProtoHTTP2;
714 socket_factory_.AddSSLSocketDataProvider(&ssl);
715
716 TestConnectJobDelegate test_delegate;
717 std::unique_ptr<ConnectJob> ssl_connect_job =
718 CreateConnectJob(&test_delegate);
719
720 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
721 false /* expect_sync_result */);
722 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
723 EXPECT_EQ(kProtoHTTP2, test_delegate.socket()->GetNegotiatedProtocol());
724 CheckConnectTimesSet(ssl_connect_job->connect_timing());
725}
726
727TEST_F(SSLConnectJobTest, SOCKSFail) {
728 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
729 SCOPED_TRACE(io_mode);
730 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
731 StaticSocketDataProvider data;
732 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
733 socket_factory_.AddSocketDataProvider(&data);
734
735 TestConnectJobDelegate test_delegate;
736 std::unique_ptr<ConnectJob> ssl_connect_job =
737 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
738 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
739 ERR_PROXY_CONNECTION_FAILED,
740 io_mode == SYNCHRONOUS);
Matt Menke6f84d1f12019-04-11 19:26:47741 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke7b5051072019-01-27 21:22:49742
Matt Menke6030ed9f2019-04-11 20:25:55743 ConnectionAttempts connection_attempts =
744 ssl_connect_job->GetConnectionAttempts();
745 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49746 }
747}
748
dalykedd30d982019-12-16 15:31:10749TEST_F(SSLConnectJobTest, SOCKSHostResolutionFailure) {
750 host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
751
752 TestConnectJobDelegate test_delegate;
753 std::unique_ptr<ConnectJob> ssl_connect_job =
754 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
755 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
756 ERR_PROXY_CONNECTION_FAILED,
757 false /* expect_sync_result */);
758 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
759 test::IsError(ERR_DNS_TIMED_OUT));
760}
761
Matt Menke7b5051072019-01-27 21:22:49762TEST_F(SSLConnectJobTest, SOCKSBasic) {
763 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
764 SCOPED_TRACE(io_mode);
Peter Kasting0ff39d42021-06-14 13:26:06765 const uint8_t kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
766 'o', 'c', 'k', 's', 'h', 'o',
767 's', 't', 0x01, 0xBB};
Matt Menke7b5051072019-01-27 21:22:49768
769 MockWrite writes[] = {
770 MockWrite(io_mode, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Peter Kasting0ff39d42021-06-14 13:26:06771 MockWrite(io_mode, reinterpret_cast<const char*>(kSOCKS5Request),
772 base::size(kSOCKS5Request)),
Matt Menke628d624f2019-02-09 00:40:24773 };
Matt Menke7b5051072019-01-27 21:22:49774
775 MockRead reads[] = {
776 MockRead(io_mode, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
Matt Menke628d624f2019-02-09 00:40:24777 MockRead(io_mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
778 };
Matt Menke7b5051072019-01-27 21:22:49779
780 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
781 StaticSocketDataProvider data(reads, writes);
782 data.set_connect_data(MockConnect(io_mode, OK));
783 socket_factory_.AddSocketDataProvider(&data);
784 SSLSocketDataProvider ssl(io_mode, OK);
785 socket_factory_.AddSSLSocketDataProvider(&ssl);
786
787 TestConnectJobDelegate test_delegate;
788 std::unique_ptr<ConnectJob> ssl_connect_job =
789 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
790 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
791 io_mode == SYNCHRONOUS);
792 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19793
794 // Proxies should not set any DNS aliases.
795 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menke7b5051072019-01-27 21:22:49796 }
797}
798
Matt Menke628d624f2019-02-09 00:40:24799TEST_F(SSLConnectJobTest, SOCKSHasEstablishedConnection) {
Peter Kasting0ff39d42021-06-14 13:26:06800 const uint8_t kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
801 'o', 'c', 'k', 's', 'h', 'o',
802 's', 't', 0x01, 0xBB};
Matt Menke628d624f2019-02-09 00:40:24803
804 MockWrite writes[] = {
805 MockWrite(SYNCHRONOUS, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength, 0),
Peter Kasting0ff39d42021-06-14 13:26:06806 MockWrite(SYNCHRONOUS, reinterpret_cast<const char*>(kSOCKS5Request),
807 base::size(kSOCKS5Request), 3),
Matt Menke628d624f2019-02-09 00:40:24808 };
809
810 MockRead reads[] = {
811 // Pause so can probe current state.
812 MockRead(ASYNC, ERR_IO_PENDING, 1),
813 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength, 2),
814 MockRead(SYNCHRONOUS, kSOCKS5OkResponse, kSOCKS5OkResponseLength, 4),
815 };
816
817 host_resolver_.set_ondemand_mode(true);
818 SequencedSocketData data(reads, writes);
819 data.set_connect_data(MockConnect(ASYNC, OK));
820 socket_factory_.AddSocketDataProvider(&data);
821
822 // SSL negotiation hangs. Value returned after SSL negotiation is complete
823 // doesn't matter, as HasEstablishedConnection() may only be used between job
824 // start and job complete.
825 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
826 socket_factory_.AddSSLSocketDataProvider(&ssl);
827
828 TestConnectJobDelegate test_delegate;
829 std::unique_ptr<ConnectJob> ssl_connect_job =
830 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
831 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
832 EXPECT_TRUE(host_resolver_.has_pending_requests());
833 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
834 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
835
836 // DNS resolution completes, and then the ConnectJob tries to connect the
837 // socket, which should succeed asynchronously.
838 host_resolver_.ResolveNow(1);
839 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
840 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
841
842 // Spin the message loop until the first read of the handshake.
843 // HasEstablishedConnection() should return true, as a TCP connection has been
844 // successfully established by this point.
845 data.RunUntilPaused();
846 EXPECT_FALSE(test_delegate.has_result());
847 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
848 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
849
850 // Finish up the handshake, and spin the message loop until the SSL handshake
851 // starts and hang.
852 data.Resume();
853 base::RunLoop().RunUntilIdle();
854 EXPECT_FALSE(test_delegate.has_result());
855 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
856 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
857}
858
Matt Menke7b5051072019-01-27 21:22:49859TEST_F(SSLConnectJobTest, SOCKSRequestPriority) {
860 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49861 for (int initial_priority = MINIMUM_PRIORITY;
862 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
863 SCOPED_TRACE(initial_priority);
864 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
865 ++new_priority) {
866 SCOPED_TRACE(new_priority);
867 if (initial_priority == new_priority)
868 continue;
869 TestConnectJobDelegate test_delegate;
870 std::unique_ptr<ConnectJob> ssl_connect_job =
871 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5,
872 static_cast<RequestPriority>(initial_priority));
873 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
874 EXPECT_TRUE(host_resolver_.has_pending_requests());
875 int request_id = host_resolver_.num_resolve();
876 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
877
878 ssl_connect_job->ChangePriority(
879 static_cast<RequestPriority>(new_priority));
880 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
881
882 ssl_connect_job->ChangePriority(
883 static_cast<RequestPriority>(initial_priority));
884 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49885 }
886 }
887}
888
889TEST_F(SSLConnectJobTest, HttpProxyFail) {
890 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
891 SCOPED_TRACE(io_mode);
892 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
893 StaticSocketDataProvider data;
894 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
895 socket_factory_.AddSocketDataProvider(&data);
896
897 TestConnectJobDelegate test_delegate;
898 std::unique_ptr<ConnectJob> ssl_connect_job =
899 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
900 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
901 ERR_PROXY_CONNECTION_FAILED,
902 io_mode == SYNCHRONOUS);
903
Matt Menke6f84d1f12019-04-11 19:26:47904 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55905 ConnectionAttempts connection_attempts =
906 ssl_connect_job->GetConnectionAttempts();
907 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49908 }
909}
910
dalykedd30d982019-12-16 15:31:10911TEST_F(SSLConnectJobTest, HttpProxyHostResolutionFailure) {
912 host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
913
914 TestConnectJobDelegate test_delegate;
915 std::unique_ptr<ConnectJob> ssl_connect_job =
916 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
917 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
918 ERR_PROXY_CONNECTION_FAILED,
919 false /* expect_sync_result */);
920 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
921 test::IsError(ERR_DNS_TIMED_OUT));
922}
923
Matt Menkeb57663b32019-03-01 17:17:10924TEST_F(SSLConnectJobTest, HttpProxyAuthChallenge) {
925 MockWrite writes[] = {
926 MockWrite(ASYNC, 0,
927 "CONNECT host:80 HTTP/1.1\r\n"
928 "Host: host:80\r\n"
929 "Proxy-Connection: keep-alive\r\n\r\n"),
930 MockWrite(ASYNC, 5,
931 "CONNECT host:80 HTTP/1.1\r\n"
932 "Host: host:80\r\n"
933 "Proxy-Connection: keep-alive\r\n"
934 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
935 };
936 MockRead reads[] = {
937 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
938 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
939 MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
940 MockRead(ASYNC, 4, "0123456789"),
941 MockRead(ASYNC, 6, "HTTP/1.1 200 Connection Established\r\n\r\n"),
942 };
943 StaticSocketDataProvider data(reads, writes);
944 socket_factory_.AddSocketDataProvider(&data);
945 SSLSocketDataProvider ssl(ASYNC, OK);
946 socket_factory_.AddSSLSocketDataProvider(&ssl);
947
Matt Menkeb57663b32019-03-01 17:17:10948 TestConnectJobDelegate test_delegate;
949 std::unique_ptr<ConnectJob> ssl_connect_job =
950 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
951 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
952 test_delegate.WaitForAuthChallenge(1);
953
954 EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code());
955 std::string proxy_authenticate;
956 ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader(
957 nullptr, "Proxy-Authenticate", &proxy_authenticate));
958 EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\"");
959
960 // While waiting for auth credentials to be provided, the Job should not time
961 // out.
962 FastForwardBy(base::TimeDelta::FromDays(1));
963 test_delegate.WaitForAuthChallenge(1);
964 EXPECT_FALSE(test_delegate.has_result());
965
966 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:48967 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeb57663b32019-03-01 17:17:10968 test_delegate.RunAuthCallback();
969
970 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19971
972 // Proxies should not set any DNS aliases.
973 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menkeb57663b32019-03-01 17:17:10974}
975
976TEST_F(SSLConnectJobTest, HttpProxyAuthWithCachedCredentials) {
Matt Menke7b5051072019-01-27 21:22:49977 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
978 SCOPED_TRACE(io_mode);
979 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
980 MockWrite writes[] = {
981 MockWrite(io_mode,
982 "CONNECT host:80 HTTP/1.1\r\n"
983 "Host: host:80\r\n"
984 "Proxy-Connection: keep-alive\r\n"
985 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
986 };
987 MockRead reads[] = {
988 MockRead(io_mode, "HTTP/1.1 200 Connection Established\r\n\r\n"),
989 };
990 StaticSocketDataProvider data(reads, writes);
991 data.set_connect_data(MockConnect(io_mode, OK));
992 socket_factory_.AddSocketDataProvider(&data);
993 AddAuthToCache();
994 SSLSocketDataProvider ssl(io_mode, OK);
995 socket_factory_.AddSSLSocketDataProvider(&ssl);
996
997 TestConnectJobDelegate test_delegate;
998 std::unique_ptr<ConnectJob> ssl_connect_job =
999 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1000 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
1001 io_mode == SYNCHRONOUS);
1002 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:191003 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menke7b5051072019-01-27 21:22:491004 }
1005}
1006
1007TEST_F(SSLConnectJobTest, HttpProxyRequestPriority) {
1008 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:491009 for (int initial_priority = MINIMUM_PRIORITY;
1010 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
1011 SCOPED_TRACE(initial_priority);
1012 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
1013 ++new_priority) {
1014 SCOPED_TRACE(new_priority);
1015 if (initial_priority == new_priority)
1016 continue;
1017 TestConnectJobDelegate test_delegate;
1018 std::unique_ptr<ConnectJob> ssl_connect_job =
1019 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP,
1020 static_cast<RequestPriority>(initial_priority));
1021 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1022 EXPECT_TRUE(host_resolver_.has_pending_requests());
1023 int request_id = host_resolver_.num_resolve();
1024 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
1025
1026 ssl_connect_job->ChangePriority(
1027 static_cast<RequestPriority>(new_priority));
1028 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
1029
1030 ssl_connect_job->ChangePriority(
1031 static_cast<RequestPriority>(initial_priority));
1032 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:491033 }
1034 }
1035}
1036
Matt Menkeaade5812019-03-02 13:38:001037TEST_F(SSLConnectJobTest, HttpProxyAuthHasEstablishedConnection) {
1038 host_resolver_.set_ondemand_mode(true);
1039 MockWrite writes[] = {
1040 MockWrite(ASYNC, 0,
1041 "CONNECT host:80 HTTP/1.1\r\n"
1042 "Host: host:80\r\n"
1043 "Proxy-Connection: keep-alive\r\n\r\n"),
1044 MockWrite(ASYNC, 3,
1045 "CONNECT host:80 HTTP/1.1\r\n"
1046 "Host: host:80\r\n"
1047 "Proxy-Connection: keep-alive\r\n"
1048 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1049 };
1050 MockRead reads[] = {
1051 // Pause reading.
1052 MockRead(ASYNC, ERR_IO_PENDING, 1),
1053 MockRead(ASYNC, 2,
1054 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1055 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1056 "Content-Length: 0\r\n\r\n"),
1057 // Pause reading.
1058 MockRead(ASYNC, ERR_IO_PENDING, 4),
1059 MockRead(ASYNC, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1060 };
1061 SequencedSocketData data(reads, writes);
1062 socket_factory_.AddSocketDataProvider(&data);
1063 SSLSocketDataProvider ssl(ASYNC, OK);
1064 socket_factory_.AddSSLSocketDataProvider(&ssl);
1065
Matt Menkeaade5812019-03-02 13:38:001066 TestConnectJobDelegate test_delegate;
1067 std::unique_ptr<ConnectJob> ssl_connect_job =
1068 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1069 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1070 EXPECT_TRUE(host_resolver_.has_pending_requests());
1071 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1072 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1073
1074 // DNS resolution completes, and then the ConnectJob tries to connect the
1075 // socket, which should succeed asynchronously.
1076 host_resolver_.ResolveOnlyRequestNow();
1077 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1078 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1079
1080 // Spinning the message loop causes the connection to be established and the
1081 // nested HttpProxyConnectJob to start establishing a tunnel.
1082 base::RunLoop().RunUntilIdle();
1083 EXPECT_FALSE(test_delegate.has_result());
1084 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1085 ssl_connect_job->GetLoadState());
1086 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1087
1088 // Receive the auth challenge.
1089 data.Resume();
1090 test_delegate.WaitForAuthChallenge(1);
1091 EXPECT_FALSE(test_delegate.has_result());
1092 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1093 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1094
1095 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:481096 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeaade5812019-03-02 13:38:001097 test_delegate.RunAuthCallback();
1098 EXPECT_FALSE(test_delegate.has_result());
1099 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1100 ssl_connect_job->GetLoadState());
1101 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1102
1103 // Run until the next read pauses.
1104 base::RunLoop().RunUntilIdle();
1105 EXPECT_FALSE(test_delegate.has_result());
1106 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1107 ssl_connect_job->GetLoadState());
1108 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1109
1110 // Receive the connection established response, at which point SSL negotiation
1111 // finally starts.
1112 data.Resume();
1113 EXPECT_FALSE(test_delegate.has_result());
1114 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1115 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1116
1117 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1118}
1119
1120TEST_F(SSLConnectJobTest,
1121 HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose) {
1122 host_resolver_.set_ondemand_mode(true);
1123 MockWrite writes1[] = {
1124 MockWrite(ASYNC, 0,
1125 "CONNECT host:80 HTTP/1.1\r\n"
1126 "Host: host:80\r\n"
1127 "Proxy-Connection: keep-alive\r\n\r\n"),
1128 };
1129 MockRead reads1[] = {
1130 // Pause reading.
1131 MockRead(ASYNC, ERR_IO_PENDING, 1),
1132 MockRead(ASYNC, 2,
1133 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1134 "Proxy-Connection: Close\r\n"
1135 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1136 "Content-Length: 0\r\n\r\n"),
1137 };
1138 SequencedSocketData data1(reads1, writes1);
1139 socket_factory_.AddSocketDataProvider(&data1);
1140
1141 MockWrite writes2[] = {
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"
1146 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1147 };
1148 MockRead reads2[] = {
1149 // Pause reading.
1150 MockRead(ASYNC, ERR_IO_PENDING, 1),
1151 MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1152 };
1153 SequencedSocketData data2(reads2, writes2);
1154 socket_factory_.AddSocketDataProvider(&data2);
1155 SSLSocketDataProvider ssl(ASYNC, OK);
1156 socket_factory_.AddSSLSocketDataProvider(&ssl);
1157
Matt Menkeaade5812019-03-02 13:38:001158 TestConnectJobDelegate test_delegate;
1159 std::unique_ptr<ConnectJob> ssl_connect_job =
1160 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1161 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1162 EXPECT_TRUE(host_resolver_.has_pending_requests());
1163 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1164 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1165
1166 // DNS resolution completes, and then the ConnectJob tries to connect the
1167 // socket, which should succeed asynchronously.
1168 host_resolver_.ResolveOnlyRequestNow();
1169 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1170 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1171
1172 // Spinning the message loop causes the connection to be established and the
1173 // nested HttpProxyConnectJob to start establishing a tunnel.
1174 base::RunLoop().RunUntilIdle();
1175 EXPECT_FALSE(test_delegate.has_result());
1176 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1177 ssl_connect_job->GetLoadState());
1178 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1179
1180 // Receive the auth challenge.
1181 data1.Resume();
1182 test_delegate.WaitForAuthChallenge(1);
1183 EXPECT_FALSE(test_delegate.has_result());
1184 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1185 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1186
1187 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:481188 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeaade5812019-03-02 13:38:001189 test_delegate.RunAuthCallback();
1190 EXPECT_FALSE(test_delegate.has_result());
1191 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1192 ssl_connect_job->GetLoadState());
1193 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1194
1195 // Run until the next DNS lookup.
1196 base::RunLoop().RunUntilIdle();
1197 EXPECT_TRUE(host_resolver_.has_pending_requests());
1198 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1199 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1200
1201 // DNS resolution completes, and then the ConnectJob tries to connect the
1202 // socket, which should succeed asynchronously.
1203 host_resolver_.ResolveOnlyRequestNow();
1204 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1205 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1206
1207 // Spinning the message loop causes the connection to be established and the
1208 // nested HttpProxyConnectJob to start establishing a tunnel.
1209 base::RunLoop().RunUntilIdle();
1210 EXPECT_FALSE(test_delegate.has_result());
1211 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1212 ssl_connect_job->GetLoadState());
1213 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1214
1215 // Receive the connection established response, at which point SSL negotiation
1216 // finally starts.
1217 data2.Resume();
1218 EXPECT_FALSE(test_delegate.has_result());
1219 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1220 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1221
1222 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1223}
1224
Cammie Smith Barnesaa2a8b52020-12-17 19:33:191225TEST_F(SSLConnectJobTest, DnsAliases) {
1226 host_resolver_.set_synchronous_mode(true);
1227
1228 // Resolve an AddressList with DNS aliases.
1229 std::vector<std::string> aliases({"alias1", "alias2", "host"});
1230 host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1231 std::move(aliases));
1232 StaticSocketDataProvider data;
1233 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1234 socket_factory_.AddSocketDataProvider(&data);
1235 SSLSocketDataProvider ssl(ASYNC, OK);
1236 socket_factory_.AddSSLSocketDataProvider(&ssl);
1237 TestConnectJobDelegate test_delegate;
1238
1239 std::unique_ptr<ConnectJob> ssl_connect_job =
1240 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1241
1242 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1243
1244 base::RunLoop().RunUntilIdle();
1245
1246 // Verify that the elements of the alias list are those from the
1247 // parameter vector.
1248 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1249 testing::ElementsAre("alias1", "alias2", "host"));
1250}
1251
1252TEST_F(SSLConnectJobTest, NoAdditionalDnsAliases) {
1253 host_resolver_.set_synchronous_mode(true);
1254
1255 // Resolve an AddressList without additional DNS aliases. (The parameter
1256 // is an empty vector.)
1257 std::vector<std::string> aliases;
1258 host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1259 std::move(aliases));
1260 StaticSocketDataProvider data;
1261 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1262 socket_factory_.AddSocketDataProvider(&data);
1263 SSLSocketDataProvider ssl(ASYNC, OK);
1264 socket_factory_.AddSSLSocketDataProvider(&ssl);
1265 TestConnectJobDelegate test_delegate;
1266
1267 std::unique_ptr<ConnectJob> ssl_connect_job =
1268 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1269
1270 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1271
1272 base::RunLoop().RunUntilIdle();
1273
1274 // Verify that the alias list only contains "host".
1275 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1276 testing::ElementsAre("host"));
1277}
1278
Matt Menke7b5051072019-01-27 21:22:491279} // namespace
1280} // namespace net