blob: 3d7cd05dee717129e253b37a21dc6e86943667aa [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"
12#include "base/stl_util.h"
13#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"
Eric Ortha093b092020-09-24 23:13:0227#include "net/dns/public/secure_dns_mode.h"
Ben Schwartz3ff4dc1e62021-04-27 21:15:2328#include "net/dns/public/secure_dns_policy.h"
Matt Menke7b5051072019-01-27 21:22:4929#include "net/http/http_auth_handler_factory.h"
30#include "net/http/http_network_session.h"
Matt Menke0754b5d02019-02-10 21:46:4331#include "net/http/http_proxy_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4932#include "net/http/http_request_headers.h"
33#include "net/http/http_response_headers.h"
Matt Menke609160742019-08-02 18:47:2634#include "net/http/http_server_properties.h"
Matt Menke7b5051072019-01-27 21:22:4935#include "net/http/transport_security_state.h"
36#include "net/log/net_log_source.h"
37#include "net/log/net_log_with_source.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5638#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Victor Vasiliev7752898d2019-11-14 21:30:2239#include "net/quic/quic_context.h"
Matt Menke7b5051072019-01-27 21:22:4940#include "net/socket/connect_job_test_util.h"
Matt Menke6030ed9f2019-04-11 20:25:5541#include "net/socket/connection_attempts.h"
Matt Menke7b5051072019-01-27 21:22:4942#include "net/socket/next_proto.h"
43#include "net/socket/socket_tag.h"
44#include "net/socket/socket_test_util.h"
45#include "net/socket/socks_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4946#include "net/socket/transport_connect_job.h"
47#include "net/ssl/ssl_config_service_defaults.h"
David Benjamin07a07d652020-02-26 22:26:5948#include "net/ssl/ssl_connection_status_flags.h"
49#include "net/ssl/ssl_legacy_crypto_fallback.h"
50#include "net/test/cert_test_util.h"
Matt Menke7b5051072019-01-27 21:22:4951#include "net/test/gtest_util.h"
52#include "net/test/test_certificate_data.h"
David Benjamin07a07d652020-02-26 22:26:5953#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4054#include "net/test/test_with_task_environment.h"
Matt Menke7b5051072019-01-27 21:22:4955#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
56#include "testing/gtest/include/gtest/gtest.h"
David Benjamin07a07d652020-02-26 22:26:5957#include "third_party/boringssl/src/include/openssl/ssl.h"
Matt Menke7b5051072019-01-27 21:22:4958
59namespace net {
60namespace {
61
Matt Menke7b5051072019-01-27 21:22:4962// Just check that all connect times are set to base::TimeTicks::Now(), for
63// tests that don't update the mocked out time.
64void CheckConnectTimesSet(const LoadTimingInfo::ConnectTiming& connect_timing) {
65 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_start);
66 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_end);
67 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
68 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
69 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
70 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
71}
72
73// Just check that all connect times are set to base::TimeTicks::Now(), except
74// for DNS times, for tests that don't update the mocked out time and use a
75// proxy.
76void CheckConnectTimesExceptDnsSet(
77 const LoadTimingInfo::ConnectTiming& connect_timing) {
78 EXPECT_TRUE(connect_timing.dns_start.is_null());
79 EXPECT_TRUE(connect_timing.dns_end.is_null());
80 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
81 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
82 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
83 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
84}
85
Gabriel Charette694c3c332019-08-19 14:53:0586class SSLConnectJobTest : public WithTaskEnvironment, public testing::Test {
Matt Menke7b5051072019-01-27 21:22:4987 public:
88 SSLConnectJobTest()
Gabriel Charette694c3c332019-08-19 14:53:0589 : WithTaskEnvironment(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Nicolas Arciniegad2013f92020-02-07 23:00:5690 proxy_resolution_service_(
91 ConfiguredProxyResolutionService::CreateDirect()),
Matt Menke7b5051072019-01-27 21:22:4992 ssl_config_service_(new SSLConfigServiceDefaults),
Eric Orthbe2efac2019-03-06 01:11:1193 http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke7b5051072019-01-27 21:22:4994 session_(CreateNetworkSession()),
Matt Menke7b5051072019-01-27 21:22:4995 direct_transport_socket_params_(
96 new TransportSocketParams(HostPortPair("host", 443),
Matt Menkecd439232019-11-05 15:15:3397 NetworkIsolationKey(),
Ben Schwartz3ff4dc1e62021-04-27 21:15:2398 SecureDnsPolicy::kAllow,
Matt Menke7b5051072019-01-27 21:22:4999 OnHostResolutionCallback())),
Matt Menke7b5051072019-01-27 21:22:49100 proxy_transport_socket_params_(
101 new TransportSocketParams(HostPortPair("proxy", 443),
Matt Menkecd439232019-11-05 15:15:33102 NetworkIsolationKey(),
Ben Schwartz3ff4dc1e62021-04-27 21:15:23103 SecureDnsPolicy::kAllow,
Matt Menke7b5051072019-01-27 21:22:49104 OnHostResolutionCallback())),
105 socks_socket_params_(
106 new SOCKSSocketParams(proxy_transport_socket_params_,
107 true,
108 HostPortPair("sockshost", 443),
Matt Menke166710e2019-11-06 03:35:51109 NetworkIsolationKey(),
Matt Menke7b5051072019-01-27 21:22:49110 TRAFFIC_ANNOTATION_FOR_TESTS)),
111 http_proxy_socket_params_(
112 new HttpProxySocketParams(proxy_transport_socket_params_,
113 nullptr /* ssl_params */,
Matt Menkeb5fb42b2019-03-22 17:26:13114 false /* is_quic */,
Matt Menke7b5051072019-01-27 21:22:49115 HostPortPair("host", 80),
Matt Menke7b5051072019-01-27 21:22:49116 /*is_trusted_proxy=*/false,
117 /*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() {
153 HttpNetworkSession::Context session_context;
154 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 Menke7b5051072019-01-27 21:22:49165 return new HttpNetworkSession(HttpNetworkSession::Params(),
166 session_context);
167 }
168
169 protected:
170 MockClientSocketFactory socket_factory_;
Matt Menkeaade5812019-03-02 13:38:00171 MockHostResolver host_resolver_;
Matt Menke7b5051072019-01-27 21:22:49172 MockCertVerifier cert_verifier_;
173 TransportSecurityState transport_security_state_;
Matt Menke7b5051072019-01-27 21:22:49174 DefaultCTPolicyEnforcer ct_policy_enforcer_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:26175 const std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
Matt Menke7b5051072019-01-27 21:22:49176 const std::unique_ptr<SSLConfigService> ssl_config_service_;
177 const std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:26178 HttpServerProperties http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:22179 QuicContext quic_context_;
Matt Menke7b5051072019-01-27 21:22:49180 const std::unique_ptr<HttpNetworkSession> session_;
Matt Menke7b5051072019-01-27 21:22:49181
182 scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
Matt Menke7b5051072019-01-27 21:22:49183
184 scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
185 scoped_refptr<SOCKSSocketParams> socks_socket_params_;
186 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
187
Matt Menkea6f99ad2019-03-08 02:26:43188 const CommonConnectJobParams common_connect_job_params_;
Matt Menke7b5051072019-01-27 21:22:49189};
190
191TEST_F(SSLConnectJobTest, TCPFail) {
192 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
193 SCOPED_TRACE(io_mode);
194 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
195 StaticSocketDataProvider data;
196 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
197 socket_factory_.AddSocketDataProvider(&data);
198
199 TestConnectJobDelegate test_delegate;
200 std::unique_ptr<ConnectJob> ssl_connect_job =
201 CreateConnectJob(&test_delegate);
202 test_delegate.StartJobExpectingResult(
203 ssl_connect_job.get(), ERR_CONNECTION_FAILED, io_mode == SYNCHRONOUS);
204 EXPECT_FALSE(test_delegate.socket());
Matt Menke6f84d1f12019-04-11 19:26:47205 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55206 ConnectionAttempts connection_attempts =
207 ssl_connect_job->GetConnectionAttempts();
208 ASSERT_EQ(1u, connection_attempts.size());
209 EXPECT_THAT(connection_attempts[0].result,
Matt Menke7b5051072019-01-27 21:22:49210 test::IsError(ERR_CONNECTION_FAILED));
211 }
212}
213
Matt Menke36eaf5c2019-04-02 16:15:52214TEST_F(SSLConnectJobTest, TCPTimeout) {
215 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
216
217 // Make request hang.
218 host_resolver_.set_ondemand_mode(true);
219
220 TestConnectJobDelegate test_delegate;
221 std::unique_ptr<ConnectJob> ssl_connect_job =
222 CreateConnectJob(&test_delegate);
223 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
224
225 // Right up until just before the TCP connection timeout, the job does not
226 // time out.
227 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
228 EXPECT_FALSE(test_delegate.has_result());
229
230 // But at the exact time of TCP connection timeout, the job fails.
231 FastForwardBy(kTinyTime);
232 EXPECT_TRUE(test_delegate.has_result());
233 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
234}
235
236TEST_F(SSLConnectJobTest, SSLTimeoutSyncConnect) {
237 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
238
239 // DNS lookup and transport connect complete synchronously, but SSL
240 // negotiation hangs.
241 host_resolver_.set_synchronous_mode(true);
242 StaticSocketDataProvider data;
243 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
244 socket_factory_.AddSocketDataProvider(&data);
245 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
246 socket_factory_.AddSSLSocketDataProvider(&ssl);
247
248 // Make request hang.
249 TestConnectJobDelegate test_delegate;
250 std::unique_ptr<ConnectJob> ssl_connect_job =
251 CreateConnectJob(&test_delegate);
252 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
253
254 // Right up until just before the SSL handshake timeout, the job does not time
255 // out.
256 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
257 EXPECT_FALSE(test_delegate.has_result());
258
259 // But at the exact SSL handshake timeout time, the job fails.
260 FastForwardBy(kTinyTime);
261 EXPECT_TRUE(test_delegate.has_result());
262 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
263}
264
265TEST_F(SSLConnectJobTest, SSLTimeoutAsyncTcpConnect) {
266 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
267
268 // DNS lookup is asynchronous, and later SSL negotiation hangs.
269 host_resolver_.set_ondemand_mode(true);
270 StaticSocketDataProvider data;
271 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
272 socket_factory_.AddSocketDataProvider(&data);
273 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
274 socket_factory_.AddSSLSocketDataProvider(&ssl);
275
276 TestConnectJobDelegate test_delegate;
277 std::unique_ptr<ConnectJob> ssl_connect_job =
278 CreateConnectJob(&test_delegate);
279 // Connecting should hand on the TransportConnectJob connect.
280 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
281
282 // Right up until just before the TCP connection timeout, the job does not
283 // time out.
284 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
285 EXPECT_FALSE(test_delegate.has_result());
286
287 // The DNS lookup completes, and a TCP connection is immediately establshed,
288 // which cancels the TCP connection timer. The SSL handshake timer is started,
289 // and the SSL handshake hangs.
290 host_resolver_.ResolveOnlyRequestNow();
291 EXPECT_FALSE(test_delegate.has_result());
292
293 // Right up until just before the SSL handshake timeout, the job does not time
294 // out.
295 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
296 EXPECT_FALSE(test_delegate.has_result());
297
298 // But at the exact SSL handshake timeout time, the job fails.
299 FastForwardBy(kTinyTime);
300 EXPECT_TRUE(test_delegate.has_result());
301 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
302}
303
Matt Menke7b5051072019-01-27 21:22:49304TEST_F(SSLConnectJobTest, BasicDirectSync) {
305 host_resolver_.set_synchronous_mode(true);
306 StaticSocketDataProvider data;
307 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
308 socket_factory_.AddSocketDataProvider(&data);
309 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
310 socket_factory_.AddSSLSocketDataProvider(&ssl);
311
312 TestConnectJobDelegate test_delegate;
313 std::unique_ptr<ConnectJob> ssl_connect_job =
314 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
315
316 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
317 true /* expect_sync_result */);
318 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
319
Matt Menke6030ed9f2019-04-11 20:25:55320 ConnectionAttempts connection_attempts =
321 ssl_connect_job->GetConnectionAttempts();
322 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49323 CheckConnectTimesSet(ssl_connect_job->connect_timing());
324}
325
326TEST_F(SSLConnectJobTest, BasicDirectAsync) {
327 host_resolver_.set_ondemand_mode(true);
328 base::TimeTicks start_time = base::TimeTicks::Now();
329 StaticSocketDataProvider data;
330 data.set_connect_data(MockConnect(ASYNC, OK));
331 socket_factory_.AddSocketDataProvider(&data);
332 SSLSocketDataProvider ssl(ASYNC, OK);
333 socket_factory_.AddSSLSocketDataProvider(&ssl);
334
335 TestConnectJobDelegate test_delegate;
336 std::unique_ptr<ConnectJob> ssl_connect_job =
337 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
338 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
339 EXPECT_TRUE(host_resolver_.has_pending_requests());
340 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
341 FastForwardBy(base::TimeDelta::FromSeconds(5));
342
343 base::TimeTicks resolve_complete_time = base::TimeTicks::Now();
344 host_resolver_.ResolveAllPending();
345 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
346
Matt Menke6030ed9f2019-04-11 20:25:55347 ConnectionAttempts connection_attempts =
348 ssl_connect_job->GetConnectionAttempts();
349 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49350
351 // Check times. Since time is mocked out, all times will be the same, except
352 // |dns_start|, which is the only one recorded before the FastForwardBy()
353 // call. The test classes don't allow any other phases to be triggered on
354 // demand, or delayed by a set interval.
355 EXPECT_EQ(start_time, ssl_connect_job->connect_timing().dns_start);
356 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().dns_end);
357 EXPECT_EQ(resolve_complete_time,
358 ssl_connect_job->connect_timing().connect_start);
359 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_start);
360 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_end);
361 EXPECT_EQ(resolve_complete_time,
362 ssl_connect_job->connect_timing().connect_end);
363}
364
Matt Menke9d5e2c92019-02-05 01:42:23365TEST_F(SSLConnectJobTest, DirectHasEstablishedConnection) {
366 host_resolver_.set_ondemand_mode(true);
367 StaticSocketDataProvider data;
368 data.set_connect_data(MockConnect(ASYNC, OK));
369 socket_factory_.AddSocketDataProvider(&data);
370
371 // SSL negotiation hangs. Value returned after SSL negotiation is complete
372 // doesn't matter, as HasEstablishedConnection() may only be used between job
373 // start and job complete.
374 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
375 socket_factory_.AddSSLSocketDataProvider(&ssl);
376
377 TestConnectJobDelegate test_delegate;
378 std::unique_ptr<ConnectJob> ssl_connect_job =
379 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
380 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
381 EXPECT_TRUE(host_resolver_.has_pending_requests());
382 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
383 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
384
385 // DNS resolution completes, and then the ConnectJob tries to connect the
386 // socket, which should succeed asynchronously.
387 host_resolver_.ResolveNow(1);
388 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
389 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
390
391 // Spinning the message loop causes the socket to finish connecting. The SSL
392 // handshake should start and hang.
393 base::RunLoop().RunUntilIdle();
394 EXPECT_FALSE(test_delegate.has_result());
395 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
396 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
397}
398
Matt Menke7b5051072019-01-27 21:22:49399TEST_F(SSLConnectJobTest, RequestPriority) {
400 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49401 for (int initial_priority = MINIMUM_PRIORITY;
402 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
403 SCOPED_TRACE(initial_priority);
404 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
405 ++new_priority) {
406 SCOPED_TRACE(new_priority);
407 if (initial_priority == new_priority)
408 continue;
409 TestConnectJobDelegate test_delegate;
410 std::unique_ptr<ConnectJob> ssl_connect_job =
411 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT,
412 static_cast<RequestPriority>(initial_priority));
413 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
414 EXPECT_TRUE(host_resolver_.has_pending_requests());
415 int request_id = host_resolver_.num_resolve();
416 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
417
418 ssl_connect_job->ChangePriority(
419 static_cast<RequestPriority>(new_priority));
420 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
421
422 ssl_connect_job->ChangePriority(
423 static_cast<RequestPriority>(initial_priority));
424 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49425 }
426 }
427}
428
Ben Schwartz3ff4dc1e62021-04-27 21:15:23429TEST_F(SSLConnectJobTest, SecureDnsPolicy) {
430 for (auto secure_dns_policy :
431 {SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable}) {
dalyk5f48a132019-10-14 15:20:19432 TestConnectJobDelegate test_delegate;
433 direct_transport_socket_params_ =
Matt Menkecd439232019-11-05 15:15:33434 base::MakeRefCounted<TransportSocketParams>(
Ben Schwartz3ff4dc1e62021-04-27 21:15:23435 HostPortPair("host", 443), NetworkIsolationKey(), secure_dns_policy,
436 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 Schwartz3ff4dc1e62021-04-27 21:15:23445 EXPECT_EQ(secure_dns_policy == SecureDnsPolicy::kDisable,
dalyk5f48a132019-10-14 15:20:19446 host_resolver_.last_secure_dns_mode_override().has_value());
Ben Schwartz3ff4dc1e62021-04-27 21:15:23447 if (secure_dns_policy == SecureDnsPolicy::kDisable) {
Eric Ortha093b092020-09-24 23:13:02448 EXPECT_EQ(net::SecureDnsMode::kOff,
dalyk5f48a132019-10-14 15:20:19449 host_resolver_.last_secure_dns_mode_override().value());
450 }
451 }
452}
453
dalykedd30d982019-12-16 15:31:10454TEST_F(SSLConnectJobTest, DirectHostResolutionFailure) {
455 host_resolver_.rules()->AddSimulatedTimeoutFailure("host");
456
457 TestConnectJobDelegate test_delegate;
458 std::unique_ptr<ConnectJob> ssl_connect_job =
459 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT);
460 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
461 ERR_NAME_NOT_RESOLVED,
462 false /* expect_sync_result */);
463 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
464 test::IsError(ERR_DNS_TIMED_OUT));
465}
466
Matt Menke7b5051072019-01-27 21:22:49467TEST_F(SSLConnectJobTest, DirectCertError) {
468 StaticSocketDataProvider data;
469 socket_factory_.AddSocketDataProvider(&data);
470 SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
471 socket_factory_.AddSSLSocketDataProvider(&ssl);
472
473 TestConnectJobDelegate test_delegate(
474 TestConnectJobDelegate::SocketExpected::ALWAYS);
475 std::unique_ptr<ConnectJob> ssl_connect_job =
476 CreateConnectJob(&test_delegate);
477
478 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
479 ERR_CERT_COMMON_NAME_INVALID,
480 false /* expect_sync_result */);
Matt Menke6f84d1f12019-04-11 19:26:47481 EXPECT_TRUE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55482 ConnectionAttempts connection_attempts =
483 ssl_connect_job->GetConnectionAttempts();
484 ASSERT_EQ(1u, connection_attempts.size());
485 EXPECT_THAT(connection_attempts[0].result,
Matt Menke7b5051072019-01-27 21:22:49486 test::IsError(ERR_CERT_COMMON_NAME_INVALID));
487 CheckConnectTimesSet(ssl_connect_job->connect_timing());
488}
489
490TEST_F(SSLConnectJobTest, DirectSSLError) {
491 StaticSocketDataProvider data;
492 socket_factory_.AddSocketDataProvider(&data);
David Benjamin07a07d652020-02-26 22:26:59493 SSLSocketDataProvider ssl(ASYNC, ERR_BAD_SSL_CLIENT_AUTH_CERT);
Matt Menke7b5051072019-01-27 21:22:49494 socket_factory_.AddSSLSocketDataProvider(&ssl);
495
496 TestConnectJobDelegate test_delegate;
497 std::unique_ptr<ConnectJob> ssl_connect_job =
498 CreateConnectJob(&test_delegate);
499
500 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
David Benjamin07a07d652020-02-26 22:26:59501 ERR_BAD_SSL_CLIENT_AUTH_CERT,
Matt Menke7b5051072019-01-27 21:22:49502 false /* expect_sync_result */);
Matt Menke6030ed9f2019-04-11 20:25:55503 ConnectionAttempts connection_attempts =
504 ssl_connect_job->GetConnectionAttempts();
505 ASSERT_EQ(1u, connection_attempts.size());
506 EXPECT_THAT(connection_attempts[0].result,
David Benjamin07a07d652020-02-26 22:26:59507 test::IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
508}
509
510// Test that the legacy crypto fallback is triggered on applicable error codes.
511TEST_F(SSLConnectJobTest, DirectLegacyCryptoFallback) {
512 for (Error error :
513 {ERR_CONNECTION_CLOSED, ERR_CONNECTION_RESET, ERR_SSL_PROTOCOL_ERROR,
514 ERR_SSL_VERSION_OR_CIPHER_MISMATCH}) {
515 SCOPED_TRACE(error);
516
517 for (bool second_attempt_ok : {true, false}) {
518 SCOPED_TRACE(second_attempt_ok);
519
520 StaticSocketDataProvider data;
521 socket_factory_.AddSocketDataProvider(&data);
522 SSLSocketDataProvider ssl(ASYNC, error);
523 socket_factory_.AddSSLSocketDataProvider(&ssl);
524 ssl.expected_disable_legacy_crypto = true;
525
526 Error error2 = second_attempt_ok ? OK : error;
527 StaticSocketDataProvider data2;
528 socket_factory_.AddSocketDataProvider(&data2);
529 SSLSocketDataProvider ssl2(ASYNC, error2);
530 socket_factory_.AddSSLSocketDataProvider(&ssl2);
531 ssl2.expected_disable_legacy_crypto = false;
532
533 TestConnectJobDelegate test_delegate;
534 std::unique_ptr<ConnectJob> ssl_connect_job =
535 CreateConnectJob(&test_delegate);
536
537 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), error2,
538 /*expect_sync_result=*/false);
539 ConnectionAttempts connection_attempts =
540 ssl_connect_job->GetConnectionAttempts();
541 if (second_attempt_ok) {
542 ASSERT_EQ(1u, connection_attempts.size());
543 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
544 } else {
545 ASSERT_EQ(2u, connection_attempts.size());
546 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
547 EXPECT_THAT(connection_attempts[1].result, test::IsError(error));
548 }
549 }
550 }
551}
552
553// Test that the feature flag disables the legacy crypto fallback.
554TEST_F(SSLConnectJobTest, LegacyCryptoFallbackDisabled) {
555 base::test::ScopedFeatureList feature_list;
556 feature_list.InitAndDisableFeature(
557 features::kTLSLegacyCryptoFallbackForMetrics);
558 for (Error error :
559 {ERR_CONNECTION_CLOSED, ERR_CONNECTION_RESET, ERR_SSL_PROTOCOL_ERROR,
560 ERR_SSL_VERSION_OR_CIPHER_MISMATCH}) {
561 SCOPED_TRACE(error);
562
563 StaticSocketDataProvider data;
564 socket_factory_.AddSocketDataProvider(&data);
565 SSLSocketDataProvider ssl(ASYNC, error);
566 socket_factory_.AddSSLSocketDataProvider(&ssl);
567 ssl.expected_disable_legacy_crypto = false;
568
569 TestConnectJobDelegate test_delegate;
570 std::unique_ptr<ConnectJob> ssl_connect_job =
571 CreateConnectJob(&test_delegate);
572
573 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), error,
574 /*expect_sync_result=*/false);
575 ConnectionAttempts connection_attempts =
576 ssl_connect_job->GetConnectionAttempts();
577 ASSERT_EQ(1u, connection_attempts.size());
578 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
579 }
580}
581
582TEST_F(SSLConnectJobTest, LegacyCryptoFallbackHistograms) {
583 base::FilePath certs_dir = GetTestCertsDirectory();
584
585 scoped_refptr<X509Certificate> sha1_leaf =
586 ImportCertFromFile(certs_dir, "sha1_leaf.pem");
587 ASSERT_TRUE(sha1_leaf);
588
589 scoped_refptr<X509Certificate> ok_cert =
590 ImportCertFromFile(certs_dir, "ok_cert.pem");
591 ASSERT_TRUE(ok_cert);
592
593 // Make a copy of |ok_cert| with an unused |sha1_leaf| in the intermediate
594 // list.
595 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
596 for (const auto& cert : ok_cert->intermediate_buffers()) {
597 intermediates.push_back(bssl::UpRef(cert));
598 }
599 intermediates.push_back(bssl::UpRef(sha1_leaf->cert_buffer()));
600 scoped_refptr<X509Certificate> ok_with_unused_sha1 =
601 X509Certificate::CreateFromBuffer(bssl::UpRef(ok_cert->cert_buffer()),
602 std::move(intermediates));
603 ASSERT_TRUE(ok_with_unused_sha1);
604
605 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
606 const uint16_t kModernCipher = 0xc02f;
607 // TLS_RSA_WITH_3DES_EDE_CBC_SHA
608 const uint16_t k3DESCipher = 0x000a;
609
610 struct HistogramTest {
611 SSLLegacyCryptoFallback expected;
612 Error first_attempt;
613 uint16_t cipher_suite;
614 uint16_t peer_signature_algorithm;
615 scoped_refptr<X509Certificate> unverified_cert;
616 };
617
618 const HistogramTest kHistogramTests[] = {
619 // Connections not using the fallback map to kNoFallback.
620 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
621 SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
622 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
623 SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
624 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
625 SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
626
627 // Connections using 3DES map to kUsed3DES or kSentSHA1CertAndUsed3DES.
628 // Note our only supported 3DES cipher suite does not include a server
629 // signature, so |peer_signature_algorithm| would always be zero.
630 {SSLLegacyCryptoFallback::kUsed3DES, ERR_SSL_PROTOCOL_ERROR, k3DESCipher,
631 0, ok_cert},
632 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsed3DES,
633 ERR_SSL_PROTOCOL_ERROR, k3DESCipher, 0, sha1_leaf},
634 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsed3DES,
635 ERR_SSL_PROTOCOL_ERROR, k3DESCipher, 0, ok_with_unused_sha1},
636
637 // Connections using SHA-1 map to kUsedSHA1 or kSentSHA1CertAndUsedSHA1.
638 {SSLLegacyCryptoFallback::kUsedSHA1, ERR_SSL_PROTOCOL_ERROR,
639 kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1, ok_cert},
640 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
641 ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
642 sha1_leaf},
643 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
644 ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
645 ok_with_unused_sha1},
646
647 // Connections using neither map to kUnknownReason or kSentSHA1Cert.
648 {SSLLegacyCryptoFallback::kUnknownReason, ERR_SSL_PROTOCOL_ERROR,
649 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
650 {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
651 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
652 {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
653 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
654 };
655 for (size_t i = 0; i < base::size(kHistogramTests); i++) {
656 SCOPED_TRACE(i);
657 const auto& test = kHistogramTests[i];
658
659 base::HistogramTester tester;
660
661 SSLInfo ssl_info;
662 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
663 &ssl_info.connection_status);
664 SSLConnectionStatusSetCipherSuite(test.cipher_suite,
665 &ssl_info.connection_status);
666 ssl_info.peer_signature_algorithm = test.peer_signature_algorithm;
667 ssl_info.unverified_cert = test.unverified_cert;
668
669 StaticSocketDataProvider data;
670 socket_factory_.AddSocketDataProvider(&data);
671 SSLSocketDataProvider ssl(ASYNC, test.first_attempt);
672 socket_factory_.AddSSLSocketDataProvider(&ssl);
673 ssl.expected_disable_legacy_crypto = true;
674
675 StaticSocketDataProvider data2;
676 SSLSocketDataProvider ssl2(ASYNC, OK);
677 if (test.first_attempt != OK) {
678 socket_factory_.AddSocketDataProvider(&data2);
679 socket_factory_.AddSSLSocketDataProvider(&ssl2);
680 ssl2.ssl_info = ssl_info;
681 ssl2.expected_disable_legacy_crypto = false;
682 } else {
683 ssl.ssl_info = ssl_info;
684 }
685
686 TestConnectJobDelegate test_delegate;
687 std::unique_ptr<ConnectJob> ssl_connect_job =
688 CreateConnectJob(&test_delegate);
689
690 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
691 /*expect_sync_result=*/false);
692
693 tester.ExpectUniqueSample("Net.SSLLegacyCryptoFallback", test.expected, 1);
694 }
Matt Menke7b5051072019-01-27 21:22:49695}
696
697TEST_F(SSLConnectJobTest, DirectWithNPN) {
698 StaticSocketDataProvider data;
699 socket_factory_.AddSocketDataProvider(&data);
700 SSLSocketDataProvider ssl(ASYNC, OK);
701 ssl.next_proto = kProtoHTTP11;
702 socket_factory_.AddSSLSocketDataProvider(&ssl);
703
704 TestConnectJobDelegate test_delegate;
705 std::unique_ptr<ConnectJob> ssl_connect_job =
706 CreateConnectJob(&test_delegate);
707
708 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
709 false /* expect_sync_result */);
710 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
711 CheckConnectTimesSet(ssl_connect_job->connect_timing());
712}
713
714TEST_F(SSLConnectJobTest, DirectGotHTTP2) {
715 StaticSocketDataProvider data;
716 socket_factory_.AddSocketDataProvider(&data);
717 SSLSocketDataProvider ssl(ASYNC, OK);
718 ssl.next_proto = kProtoHTTP2;
719 socket_factory_.AddSSLSocketDataProvider(&ssl);
720
721 TestConnectJobDelegate test_delegate;
722 std::unique_ptr<ConnectJob> ssl_connect_job =
723 CreateConnectJob(&test_delegate);
724
725 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
726 false /* expect_sync_result */);
727 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
728 EXPECT_EQ(kProtoHTTP2, test_delegate.socket()->GetNegotiatedProtocol());
729 CheckConnectTimesSet(ssl_connect_job->connect_timing());
730}
731
732TEST_F(SSLConnectJobTest, SOCKSFail) {
733 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
734 SCOPED_TRACE(io_mode);
735 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
736 StaticSocketDataProvider data;
737 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
738 socket_factory_.AddSocketDataProvider(&data);
739
740 TestConnectJobDelegate test_delegate;
741 std::unique_ptr<ConnectJob> ssl_connect_job =
742 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
743 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
744 ERR_PROXY_CONNECTION_FAILED,
745 io_mode == SYNCHRONOUS);
Matt Menke6f84d1f12019-04-11 19:26:47746 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke7b5051072019-01-27 21:22:49747
Matt Menke6030ed9f2019-04-11 20:25:55748 ConnectionAttempts connection_attempts =
749 ssl_connect_job->GetConnectionAttempts();
750 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49751 }
752}
753
dalykedd30d982019-12-16 15:31:10754TEST_F(SSLConnectJobTest, SOCKSHostResolutionFailure) {
755 host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
756
757 TestConnectJobDelegate test_delegate;
758 std::unique_ptr<ConnectJob> ssl_connect_job =
759 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
760 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
761 ERR_PROXY_CONNECTION_FAILED,
762 false /* expect_sync_result */);
763 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
764 test::IsError(ERR_DNS_TIMED_OUT));
765}
766
Matt Menke7b5051072019-01-27 21:22:49767TEST_F(SSLConnectJobTest, SOCKSBasic) {
768 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
769 SCOPED_TRACE(io_mode);
770 const char kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
771 'o', 'c', 'k', 's', 'h', 'o',
772 's', 't', 0x01, 0xBB};
773
774 MockWrite writes[] = {
775 MockWrite(io_mode, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Matt Menke628d624f2019-02-09 00:40:24776 MockWrite(io_mode, kSOCKS5Request, base::size(kSOCKS5Request)),
777 };
Matt Menke7b5051072019-01-27 21:22:49778
779 MockRead reads[] = {
780 MockRead(io_mode, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
Matt Menke628d624f2019-02-09 00:40:24781 MockRead(io_mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
782 };
Matt Menke7b5051072019-01-27 21:22:49783
784 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
785 StaticSocketDataProvider data(reads, writes);
786 data.set_connect_data(MockConnect(io_mode, OK));
787 socket_factory_.AddSocketDataProvider(&data);
788 SSLSocketDataProvider ssl(io_mode, OK);
789 socket_factory_.AddSSLSocketDataProvider(&ssl);
790
791 TestConnectJobDelegate test_delegate;
792 std::unique_ptr<ConnectJob> ssl_connect_job =
793 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
794 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
795 io_mode == SYNCHRONOUS);
796 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19797
798 // Proxies should not set any DNS aliases.
799 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menke7b5051072019-01-27 21:22:49800 }
801}
802
Matt Menke628d624f2019-02-09 00:40:24803TEST_F(SSLConnectJobTest, SOCKSHasEstablishedConnection) {
804 const char kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's', 'o', 'c',
805 'k', 's', 'h', 'o', 's', 't', 0x01, 0xBB};
806
807 MockWrite writes[] = {
808 MockWrite(SYNCHRONOUS, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength, 0),
809 MockWrite(SYNCHRONOUS, kSOCKS5Request, base::size(kSOCKS5Request), 3),
810 };
811
812 MockRead reads[] = {
813 // Pause so can probe current state.
814 MockRead(ASYNC, ERR_IO_PENDING, 1),
815 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength, 2),
816 MockRead(SYNCHRONOUS, kSOCKS5OkResponse, kSOCKS5OkResponseLength, 4),
817 };
818
819 host_resolver_.set_ondemand_mode(true);
820 SequencedSocketData data(reads, writes);
821 data.set_connect_data(MockConnect(ASYNC, OK));
822 socket_factory_.AddSocketDataProvider(&data);
823
824 // SSL negotiation hangs. Value returned after SSL negotiation is complete
825 // doesn't matter, as HasEstablishedConnection() may only be used between job
826 // start and job complete.
827 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
828 socket_factory_.AddSSLSocketDataProvider(&ssl);
829
830 TestConnectJobDelegate test_delegate;
831 std::unique_ptr<ConnectJob> ssl_connect_job =
832 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
833 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
834 EXPECT_TRUE(host_resolver_.has_pending_requests());
835 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
836 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
837
838 // DNS resolution completes, and then the ConnectJob tries to connect the
839 // socket, which should succeed asynchronously.
840 host_resolver_.ResolveNow(1);
841 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
842 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
843
844 // Spin the message loop until the first read of the handshake.
845 // HasEstablishedConnection() should return true, as a TCP connection has been
846 // successfully established by this point.
847 data.RunUntilPaused();
848 EXPECT_FALSE(test_delegate.has_result());
849 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
850 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
851
852 // Finish up the handshake, and spin the message loop until the SSL handshake
853 // starts and hang.
854 data.Resume();
855 base::RunLoop().RunUntilIdle();
856 EXPECT_FALSE(test_delegate.has_result());
857 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
858 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
859}
860
Matt Menke7b5051072019-01-27 21:22:49861TEST_F(SSLConnectJobTest, SOCKSRequestPriority) {
862 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49863 for (int initial_priority = MINIMUM_PRIORITY;
864 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
865 SCOPED_TRACE(initial_priority);
866 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
867 ++new_priority) {
868 SCOPED_TRACE(new_priority);
869 if (initial_priority == new_priority)
870 continue;
871 TestConnectJobDelegate test_delegate;
872 std::unique_ptr<ConnectJob> ssl_connect_job =
873 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5,
874 static_cast<RequestPriority>(initial_priority));
875 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
876 EXPECT_TRUE(host_resolver_.has_pending_requests());
877 int request_id = host_resolver_.num_resolve();
878 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
879
880 ssl_connect_job->ChangePriority(
881 static_cast<RequestPriority>(new_priority));
882 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
883
884 ssl_connect_job->ChangePriority(
885 static_cast<RequestPriority>(initial_priority));
886 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49887 }
888 }
889}
890
891TEST_F(SSLConnectJobTest, HttpProxyFail) {
892 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
893 SCOPED_TRACE(io_mode);
894 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
895 StaticSocketDataProvider data;
896 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
897 socket_factory_.AddSocketDataProvider(&data);
898
899 TestConnectJobDelegate test_delegate;
900 std::unique_ptr<ConnectJob> ssl_connect_job =
901 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
902 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
903 ERR_PROXY_CONNECTION_FAILED,
904 io_mode == SYNCHRONOUS);
905
Matt Menke6f84d1f12019-04-11 19:26:47906 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55907 ConnectionAttempts connection_attempts =
908 ssl_connect_job->GetConnectionAttempts();
909 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49910 }
911}
912
dalykedd30d982019-12-16 15:31:10913TEST_F(SSLConnectJobTest, HttpProxyHostResolutionFailure) {
914 host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
915
916 TestConnectJobDelegate test_delegate;
917 std::unique_ptr<ConnectJob> ssl_connect_job =
918 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
919 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
920 ERR_PROXY_CONNECTION_FAILED,
921 false /* expect_sync_result */);
922 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
923 test::IsError(ERR_DNS_TIMED_OUT));
924}
925
Matt Menkeb57663b32019-03-01 17:17:10926TEST_F(SSLConnectJobTest, HttpProxyAuthChallenge) {
927 MockWrite writes[] = {
928 MockWrite(ASYNC, 0,
929 "CONNECT host:80 HTTP/1.1\r\n"
930 "Host: host:80\r\n"
931 "Proxy-Connection: keep-alive\r\n\r\n"),
932 MockWrite(ASYNC, 5,
933 "CONNECT host:80 HTTP/1.1\r\n"
934 "Host: host:80\r\n"
935 "Proxy-Connection: keep-alive\r\n"
936 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
937 };
938 MockRead reads[] = {
939 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
940 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
941 MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
942 MockRead(ASYNC, 4, "0123456789"),
943 MockRead(ASYNC, 6, "HTTP/1.1 200 Connection Established\r\n\r\n"),
944 };
945 StaticSocketDataProvider data(reads, writes);
946 socket_factory_.AddSocketDataProvider(&data);
947 SSLSocketDataProvider ssl(ASYNC, OK);
948 socket_factory_.AddSSLSocketDataProvider(&ssl);
949
Matt Menkeb57663b32019-03-01 17:17:10950 TestConnectJobDelegate test_delegate;
951 std::unique_ptr<ConnectJob> ssl_connect_job =
952 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
953 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
954 test_delegate.WaitForAuthChallenge(1);
955
956 EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code());
957 std::string proxy_authenticate;
958 ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader(
959 nullptr, "Proxy-Authenticate", &proxy_authenticate));
960 EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\"");
961
962 // While waiting for auth credentials to be provided, the Job should not time
963 // out.
964 FastForwardBy(base::TimeDelta::FromDays(1));
965 test_delegate.WaitForAuthChallenge(1);
966 EXPECT_FALSE(test_delegate.has_result());
967
968 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:48969 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeb57663b32019-03-01 17:17:10970 test_delegate.RunAuthCallback();
971
972 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19973
974 // Proxies should not set any DNS aliases.
975 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menkeb57663b32019-03-01 17:17:10976}
977
978TEST_F(SSLConnectJobTest, HttpProxyAuthWithCachedCredentials) {
Matt Menke7b5051072019-01-27 21:22:49979 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
980 SCOPED_TRACE(io_mode);
981 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
982 MockWrite writes[] = {
983 MockWrite(io_mode,
984 "CONNECT host:80 HTTP/1.1\r\n"
985 "Host: host:80\r\n"
986 "Proxy-Connection: keep-alive\r\n"
987 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
988 };
989 MockRead reads[] = {
990 MockRead(io_mode, "HTTP/1.1 200 Connection Established\r\n\r\n"),
991 };
992 StaticSocketDataProvider data(reads, writes);
993 data.set_connect_data(MockConnect(io_mode, OK));
994 socket_factory_.AddSocketDataProvider(&data);
995 AddAuthToCache();
996 SSLSocketDataProvider ssl(io_mode, OK);
997 socket_factory_.AddSSLSocketDataProvider(&ssl);
998
999 TestConnectJobDelegate test_delegate;
1000 std::unique_ptr<ConnectJob> ssl_connect_job =
1001 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1002 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
1003 io_mode == SYNCHRONOUS);
1004 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:191005 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menke7b5051072019-01-27 21:22:491006 }
1007}
1008
1009TEST_F(SSLConnectJobTest, HttpProxyRequestPriority) {
1010 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:491011 for (int initial_priority = MINIMUM_PRIORITY;
1012 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
1013 SCOPED_TRACE(initial_priority);
1014 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
1015 ++new_priority) {
1016 SCOPED_TRACE(new_priority);
1017 if (initial_priority == new_priority)
1018 continue;
1019 TestConnectJobDelegate test_delegate;
1020 std::unique_ptr<ConnectJob> ssl_connect_job =
1021 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP,
1022 static_cast<RequestPriority>(initial_priority));
1023 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1024 EXPECT_TRUE(host_resolver_.has_pending_requests());
1025 int request_id = host_resolver_.num_resolve();
1026 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
1027
1028 ssl_connect_job->ChangePriority(
1029 static_cast<RequestPriority>(new_priority));
1030 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
1031
1032 ssl_connect_job->ChangePriority(
1033 static_cast<RequestPriority>(initial_priority));
1034 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:491035 }
1036 }
1037}
1038
Matt Menkeaade5812019-03-02 13:38:001039TEST_F(SSLConnectJobTest, HttpProxyAuthHasEstablishedConnection) {
1040 host_resolver_.set_ondemand_mode(true);
1041 MockWrite writes[] = {
1042 MockWrite(ASYNC, 0,
1043 "CONNECT host:80 HTTP/1.1\r\n"
1044 "Host: host:80\r\n"
1045 "Proxy-Connection: keep-alive\r\n\r\n"),
1046 MockWrite(ASYNC, 3,
1047 "CONNECT host:80 HTTP/1.1\r\n"
1048 "Host: host:80\r\n"
1049 "Proxy-Connection: keep-alive\r\n"
1050 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1051 };
1052 MockRead reads[] = {
1053 // Pause reading.
1054 MockRead(ASYNC, ERR_IO_PENDING, 1),
1055 MockRead(ASYNC, 2,
1056 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1057 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1058 "Content-Length: 0\r\n\r\n"),
1059 // Pause reading.
1060 MockRead(ASYNC, ERR_IO_PENDING, 4),
1061 MockRead(ASYNC, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1062 };
1063 SequencedSocketData data(reads, writes);
1064 socket_factory_.AddSocketDataProvider(&data);
1065 SSLSocketDataProvider ssl(ASYNC, OK);
1066 socket_factory_.AddSSLSocketDataProvider(&ssl);
1067
Matt Menkeaade5812019-03-02 13:38:001068 TestConnectJobDelegate test_delegate;
1069 std::unique_ptr<ConnectJob> ssl_connect_job =
1070 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1071 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1072 EXPECT_TRUE(host_resolver_.has_pending_requests());
1073 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1074 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1075
1076 // DNS resolution completes, and then the ConnectJob tries to connect the
1077 // socket, which should succeed asynchronously.
1078 host_resolver_.ResolveOnlyRequestNow();
1079 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1080 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1081
1082 // Spinning the message loop causes the connection to be established and the
1083 // nested HttpProxyConnectJob to start establishing a tunnel.
1084 base::RunLoop().RunUntilIdle();
1085 EXPECT_FALSE(test_delegate.has_result());
1086 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1087 ssl_connect_job->GetLoadState());
1088 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1089
1090 // Receive the auth challenge.
1091 data.Resume();
1092 test_delegate.WaitForAuthChallenge(1);
1093 EXPECT_FALSE(test_delegate.has_result());
1094 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1095 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1096
1097 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:481098 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeaade5812019-03-02 13:38:001099 test_delegate.RunAuthCallback();
1100 EXPECT_FALSE(test_delegate.has_result());
1101 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1102 ssl_connect_job->GetLoadState());
1103 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1104
1105 // Run until the next read pauses.
1106 base::RunLoop().RunUntilIdle();
1107 EXPECT_FALSE(test_delegate.has_result());
1108 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1109 ssl_connect_job->GetLoadState());
1110 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1111
1112 // Receive the connection established response, at which point SSL negotiation
1113 // finally starts.
1114 data.Resume();
1115 EXPECT_FALSE(test_delegate.has_result());
1116 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1117 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1118
1119 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1120}
1121
1122TEST_F(SSLConnectJobTest,
1123 HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose) {
1124 host_resolver_.set_ondemand_mode(true);
1125 MockWrite writes1[] = {
1126 MockWrite(ASYNC, 0,
1127 "CONNECT host:80 HTTP/1.1\r\n"
1128 "Host: host:80\r\n"
1129 "Proxy-Connection: keep-alive\r\n\r\n"),
1130 };
1131 MockRead reads1[] = {
1132 // Pause reading.
1133 MockRead(ASYNC, ERR_IO_PENDING, 1),
1134 MockRead(ASYNC, 2,
1135 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1136 "Proxy-Connection: Close\r\n"
1137 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1138 "Content-Length: 0\r\n\r\n"),
1139 };
1140 SequencedSocketData data1(reads1, writes1);
1141 socket_factory_.AddSocketDataProvider(&data1);
1142
1143 MockWrite writes2[] = {
1144 MockWrite(ASYNC, 0,
1145 "CONNECT host:80 HTTP/1.1\r\n"
1146 "Host: host:80\r\n"
1147 "Proxy-Connection: keep-alive\r\n"
1148 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1149 };
1150 MockRead reads2[] = {
1151 // Pause reading.
1152 MockRead(ASYNC, ERR_IO_PENDING, 1),
1153 MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1154 };
1155 SequencedSocketData data2(reads2, writes2);
1156 socket_factory_.AddSocketDataProvider(&data2);
1157 SSLSocketDataProvider ssl(ASYNC, OK);
1158 socket_factory_.AddSSLSocketDataProvider(&ssl);
1159
Matt Menkeaade5812019-03-02 13:38:001160 TestConnectJobDelegate test_delegate;
1161 std::unique_ptr<ConnectJob> ssl_connect_job =
1162 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1163 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1164 EXPECT_TRUE(host_resolver_.has_pending_requests());
1165 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1166 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1167
1168 // DNS resolution completes, and then the ConnectJob tries to connect the
1169 // socket, which should succeed asynchronously.
1170 host_resolver_.ResolveOnlyRequestNow();
1171 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1172 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1173
1174 // Spinning the message loop causes the connection to be established and the
1175 // nested HttpProxyConnectJob to start establishing a tunnel.
1176 base::RunLoop().RunUntilIdle();
1177 EXPECT_FALSE(test_delegate.has_result());
1178 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1179 ssl_connect_job->GetLoadState());
1180 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1181
1182 // Receive the auth challenge.
1183 data1.Resume();
1184 test_delegate.WaitForAuthChallenge(1);
1185 EXPECT_FALSE(test_delegate.has_result());
1186 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1187 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1188
1189 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:481190 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeaade5812019-03-02 13:38:001191 test_delegate.RunAuthCallback();
1192 EXPECT_FALSE(test_delegate.has_result());
1193 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1194 ssl_connect_job->GetLoadState());
1195 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1196
1197 // Run until the next DNS lookup.
1198 base::RunLoop().RunUntilIdle();
1199 EXPECT_TRUE(host_resolver_.has_pending_requests());
1200 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1201 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1202
1203 // DNS resolution completes, and then the ConnectJob tries to connect the
1204 // socket, which should succeed asynchronously.
1205 host_resolver_.ResolveOnlyRequestNow();
1206 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1207 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1208
1209 // Spinning the message loop causes the connection to be established and the
1210 // nested HttpProxyConnectJob to start establishing a tunnel.
1211 base::RunLoop().RunUntilIdle();
1212 EXPECT_FALSE(test_delegate.has_result());
1213 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1214 ssl_connect_job->GetLoadState());
1215 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1216
1217 // Receive the connection established response, at which point SSL negotiation
1218 // finally starts.
1219 data2.Resume();
1220 EXPECT_FALSE(test_delegate.has_result());
1221 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1222 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1223
1224 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1225}
1226
Cammie Smith Barnesaa2a8b52020-12-17 19:33:191227TEST_F(SSLConnectJobTest, DnsAliases) {
1228 host_resolver_.set_synchronous_mode(true);
1229
1230 // Resolve an AddressList with DNS aliases.
1231 std::vector<std::string> aliases({"alias1", "alias2", "host"});
1232 host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1233 std::move(aliases));
1234 StaticSocketDataProvider data;
1235 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1236 socket_factory_.AddSocketDataProvider(&data);
1237 SSLSocketDataProvider ssl(ASYNC, OK);
1238 socket_factory_.AddSSLSocketDataProvider(&ssl);
1239 TestConnectJobDelegate test_delegate;
1240
1241 std::unique_ptr<ConnectJob> ssl_connect_job =
1242 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1243
1244 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1245
1246 base::RunLoop().RunUntilIdle();
1247
1248 // Verify that the elements of the alias list are those from the
1249 // parameter vector.
1250 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1251 testing::ElementsAre("alias1", "alias2", "host"));
1252}
1253
1254TEST_F(SSLConnectJobTest, NoAdditionalDnsAliases) {
1255 host_resolver_.set_synchronous_mode(true);
1256
1257 // Resolve an AddressList without additional DNS aliases. (The parameter
1258 // is an empty vector.)
1259 std::vector<std::string> aliases;
1260 host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1261 std::move(aliases));
1262 StaticSocketDataProvider data;
1263 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1264 socket_factory_.AddSocketDataProvider(&data);
1265 SSLSocketDataProvider ssl(ASYNC, OK);
1266 socket_factory_.AddSSLSocketDataProvider(&ssl);
1267 TestConnectJobDelegate test_delegate;
1268
1269 std::unique_ptr<ConnectJob> ssl_connect_job =
1270 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1271
1272 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1273
1274 base::RunLoop().RunUntilIdle();
1275
1276 // Verify that the alias list only contains "host".
1277 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1278 testing::ElementsAre("host"));
1279}
1280
Matt Menke7b5051072019-01-27 21:22:491281} // namespace
1282} // namespace net