ssl_connect_job_unittest.cc 73 KB

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