blob: 660c588377b1af4d886078be81ff3a872d84eff3 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
6
7#include <map>
8#include <memory>
9#include <vector>
10
11#include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h"
12#include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
13#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
14#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
15#include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h"
16#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
17#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
18#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
19#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
20#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
21#include "net/third_party/quiche/src/quic/core/quic_packets.h"
22#include "net/third_party/quiche/src/quic/core/quic_session.h"
23#include "net/third_party/quiche/src/quic/core/quic_utils.h"
24#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
25#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
26#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
27#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
28#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
29#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
30#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
31#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
32#include "net/third_party/quiche/src/quic/test_tools/failing_proof_source.h"
33#include "net/third_party/quiche/src/quic/test_tools/fake_proof_source.h"
34#include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h"
35#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
36
37namespace quic {
38class QuicConnection;
39class QuicStream;
40} // namespace quic
41
42using testing::_;
43using testing::NiceMock;
44
45namespace quic {
46namespace test {
47
48class QuicCryptoServerStreamPeer {
49 public:
50 static bool DoesPeerSupportStatelessRejects(
51 const CryptoHandshakeMessage& message) {
52 return QuicCryptoServerStream::DoesPeerSupportStatelessRejects(message);
53 }
54};
55
56namespace {
57
58const char kServerHostname[] = "test.example.com";
59const uint16_t kServerPort = 443;
60
61class QuicCryptoServerStreamTest : public QuicTestWithParam<bool> {
62 public:
63 QuicCryptoServerStreamTest()
64 : QuicCryptoServerStreamTest(crypto_test_utils::ProofSourceForTesting()) {
65 }
66
67 explicit QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source)
68 : server_crypto_config_(QuicCryptoServerConfig::TESTING,
69 QuicRandom::GetInstance(),
70 std::move(proof_source),
71 KeyExchangeSource::Default(),
72 TlsServerHandshaker::CreateSslCtx()),
73 server_compressed_certs_cache_(
74 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
75 server_id_(kServerHostname, kServerPort, false),
76 client_crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
77 TlsClientHandshaker::CreateSslCtx()) {
78 SetQuicReloadableFlag(enable_quic_stateless_reject_support, false);
79 }
80
81 void Initialize() { InitializeServer(); }
82
83 ~QuicCryptoServerStreamTest() override {
84 // Ensure that anything that might reference |helpers_| is destroyed before
85 // |helpers_| is destroyed.
86 server_session_.reset();
87 client_session_.reset();
88 helpers_.clear();
89 alarm_factories_.clear();
90 }
91
92 // Initializes the crypto server stream state for testing. May be
93 // called multiple times.
94 void InitializeServer() {
95 TestQuicSpdyServerSession* server_session = nullptr;
96 helpers_.push_back(QuicMakeUnique<NiceMock<MockQuicConnectionHelper>>());
97 alarm_factories_.push_back(QuicMakeUnique<MockAlarmFactory>());
98 CreateServerSessionForTest(
99 server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
100 helpers_.back().get(), alarm_factories_.back().get(),
101 &server_crypto_config_, &server_compressed_certs_cache_,
102 &server_connection_, &server_session);
103 CHECK(server_session);
104 server_session_.reset(server_session);
105 EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
106 .Times(testing::AnyNumber());
107 EXPECT_CALL(*server_session_->helper(), GenerateConnectionIdForReject(_, _))
108 .Times(testing::AnyNumber());
109 crypto_test_utils::FakeServerOptions options;
110 options.token_binding_params = QuicTagVector{kTB10};
111 crypto_test_utils::SetupCryptoServerConfigForTest(
112 server_connection_->clock(), server_connection_->random_generator(),
113 &server_crypto_config_, options);
114 server_session_->GetMutableCryptoStream()->OnSuccessfulVersionNegotiation(
115 supported_versions_.front());
116 }
117
118 QuicCryptoServerStream* server_stream() {
119 return server_session_->GetMutableCryptoStream();
120 }
121
122 QuicCryptoClientStream* client_stream() {
123 return client_session_->GetMutableCryptoStream();
124 }
125
126 // Initializes a fake client, and all its associated state, for
127 // testing. May be called multiple times.
128 void InitializeFakeClient(bool supports_stateless_rejects) {
129 TestQuicSpdyClientSession* client_session = nullptr;
130 helpers_.push_back(QuicMakeUnique<NiceMock<MockQuicConnectionHelper>>());
131 alarm_factories_.push_back(QuicMakeUnique<MockAlarmFactory>());
132 CreateClientSessionForTest(
133 server_id_, supports_stateless_rejects,
134 QuicTime::Delta::FromSeconds(100000), supported_versions_,
135 helpers_.back().get(), alarm_factories_.back().get(),
136 &client_crypto_config_, &client_connection_, &client_session);
137 CHECK(client_session);
138 client_session_.reset(client_session);
139 }
140
141 int CompleteCryptoHandshake() {
142 CHECK(server_connection_);
143 CHECK(server_session_ != nullptr);
144
145 return crypto_test_utils::HandshakeWithFakeClient(
146 helpers_.back().get(), alarm_factories_.back().get(),
147 server_connection_, server_stream(), server_id_, client_options_);
148 }
149
150 // Performs a single round of handshake message-exchange between the
151 // client and server.
152 void AdvanceHandshakeWithFakeClient() {
153 CHECK(server_connection_);
154 CHECK(client_session_ != nullptr);
155
156 EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
157 EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
158 .Times(testing::AnyNumber());
159 EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
160 EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
161 client_stream()->CryptoConnect();
162 crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 0,
163 server_connection_, server_stream(), 0);
164 }
165
166 protected:
167 // Every connection gets its own MockQuicConnectionHelper and
168 // MockAlarmFactory, tracked separately from the server and client state so
169 // their lifetimes persist through the whole test.
170 std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
171 std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
172
173 // Server state.
174 PacketSavingConnection* server_connection_;
175 std::unique_ptr<TestQuicSpdyServerSession> server_session_;
176 QuicCryptoServerConfig server_crypto_config_;
177 QuicCompressedCertsCache server_compressed_certs_cache_;
178 QuicServerId server_id_;
179
180 // Client state.
181 PacketSavingConnection* client_connection_;
182 QuicCryptoClientConfig client_crypto_config_;
183 std::unique_ptr<TestQuicSpdyClientSession> client_session_;
184
185 CryptoHandshakeMessage message_;
186 crypto_test_utils::FakeClientOptions client_options_;
187
188 // Which QUIC versions the client and server support.
189 ParsedQuicVersionVector supported_versions_ = AllSupportedVersions();
190};
191
192INSTANTIATE_TEST_SUITE_P(Tests, QuicCryptoServerStreamTest, testing::Bool());
193
194TEST_P(QuicCryptoServerStreamTest, NotInitiallyConected) {
195 Initialize();
196 EXPECT_FALSE(server_stream()->encryption_established());
197 EXPECT_FALSE(server_stream()->handshake_confirmed());
198}
199
200TEST_P(QuicCryptoServerStreamTest, NotInitiallySendingStatelessRejects) {
201 Initialize();
202 EXPECT_FALSE(server_stream()->UseStatelessRejectsIfPeerSupported());
203 EXPECT_FALSE(server_stream()->PeerSupportsStatelessRejects());
204}
205
206TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
207 // CompleteCryptoHandshake returns the number of client hellos sent. This
208 // test should send:
209 // * One to get a source-address token and certificates.
210 // * One to complete the handshake.
211 Initialize();
212 EXPECT_EQ(2, CompleteCryptoHandshake());
213 EXPECT_TRUE(server_stream()->encryption_established());
214 EXPECT_TRUE(server_stream()->handshake_confirmed());
215}
216
217TEST_P(QuicCryptoServerStreamTest, ConnectedAfterTlsHandshake) {
218 FLAGS_quic_supports_tls_handshake = true;
219 client_options_.only_tls_versions = true;
220 supported_versions_.clear();
221 for (QuicTransportVersion transport_version :
222 AllSupportedTransportVersions()) {
223 supported_versions_.push_back(
224 ParsedQuicVersion(PROTOCOL_TLS1_3, transport_version));
225 }
226 Initialize();
227 CompleteCryptoHandshake();
228 EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
229 EXPECT_TRUE(server_stream()->encryption_established());
230 EXPECT_TRUE(server_stream()->handshake_confirmed());
231}
232
233TEST_P(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
234 Initialize();
235 InitializeFakeClient(/* supports_stateless_rejects= */ false);
236
237 // Do a first handshake in order to prime the client config with the server's
238 // information.
239 AdvanceHandshakeWithFakeClient();
240 EXPECT_FALSE(server_stream()->encryption_established());
241 EXPECT_FALSE(server_stream()->handshake_confirmed());
242
243 // Now do another handshake, with the blocking SHLO connection option.
244 InitializeServer();
245 InitializeFakeClient(/* supports_stateless_rejects= */ false);
246
247 AdvanceHandshakeWithFakeClient();
248 EXPECT_TRUE(server_stream()->encryption_established());
249 EXPECT_TRUE(server_stream()->handshake_confirmed());
250 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE,
251 server_session_->connection()->encryption_level());
252}
253
254TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) {
255 SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
256 Initialize();
257
258 InitializeFakeClient(/* supports_stateless_rejects= */ true);
259 EXPECT_CALL(*server_connection_,
260 CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
261 EXPECT_CALL(*client_connection_,
262 CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
263 AdvanceHandshakeWithFakeClient();
264
265 // Check the server to make the sure the handshake did not succeed.
266 EXPECT_FALSE(server_stream()->encryption_established());
267 EXPECT_FALSE(server_stream()->handshake_confirmed());
268
269 // Check the client state to make sure that it received a server-designated
270 // connection id.
271 QuicCryptoClientConfig::CachedState* client_state =
272 client_crypto_config_.LookupOrCreate(server_id_);
273
274 ASSERT_TRUE(client_state->has_server_nonce());
275 ASSERT_FALSE(client_state->GetNextServerNonce().empty());
276 ASSERT_FALSE(client_state->has_server_nonce());
277
278 ASSERT_TRUE(client_state->has_server_designated_connection_id());
279 const QuicConnectionId server_designated_connection_id =
280 client_state->GetNextServerDesignatedConnectionId();
281 const QuicConnectionId expected_id = QuicUtils::CreateRandomConnectionId(
282 server_connection_->random_generator());
283 EXPECT_EQ(expected_id, server_designated_connection_id);
284 EXPECT_FALSE(client_state->has_server_designated_connection_id());
285 ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
286}
287
288TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
289 SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
290 Initialize();
291
292 InitializeFakeClient(/* supports_stateless_rejects= */ true);
293 EXPECT_CALL(*server_connection_,
294 CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
295 EXPECT_CALL(*client_connection_,
296 CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
297 AdvanceHandshakeWithFakeClient();
298
299 // On the first round, encryption will not be established.
300 EXPECT_FALSE(server_stream()->encryption_established());
301 EXPECT_FALSE(server_stream()->handshake_confirmed());
302 EXPECT_EQ(1, server_stream()->NumHandshakeMessages());
303 EXPECT_EQ(0, server_stream()->NumHandshakeMessagesWithServerNonces());
304
305 // Now check the client state.
306 QuicCryptoClientConfig::CachedState* client_state =
307 client_crypto_config_.LookupOrCreate(server_id_);
308
309 ASSERT_TRUE(client_state->has_server_designated_connection_id());
310 const QuicConnectionId server_designated_connection_id =
311 client_state->GetNextServerDesignatedConnectionId();
312 const QuicConnectionId expected_id = QuicUtils::CreateRandomConnectionId(
313 server_connection_->random_generator());
314 EXPECT_EQ(expected_id, server_designated_connection_id);
315 EXPECT_FALSE(client_state->has_server_designated_connection_id());
316 ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
317
318 // Now create new client and server streams with the existing config
319 // and try the handshake again (0-RTT handshake).
320 InitializeServer();
321
322 InitializeFakeClient(/* supports_stateless_rejects= */ true);
323 // In the stateless case, the second handshake contains a server-nonce, so the
324 // AsyncStrikeRegisterVerification() case will still succeed (unlike a 0-RTT
325 // handshake).
326 AdvanceHandshakeWithFakeClient();
327
328 // On the second round, encryption will be established.
329 EXPECT_TRUE(server_stream()->encryption_established());
330 EXPECT_TRUE(server_stream()->handshake_confirmed());
331 EXPECT_EQ(1, server_stream()->NumHandshakeMessages());
332 EXPECT_EQ(1, server_stream()->NumHandshakeMessagesWithServerNonces());
333}
334
335TEST_P(QuicCryptoServerStreamTest, NoStatelessRejectIfNoClientSupport) {
336 SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
337 Initialize();
338
339 // The server is configured to use stateless rejects, but the client does not
340 // support it.
341 InitializeFakeClient(/* supports_stateless_rejects= */ false);
342 AdvanceHandshakeWithFakeClient();
343
344 // Check the server to make the sure the handshake did not succeed.
345 EXPECT_FALSE(server_stream()->encryption_established());
346 EXPECT_FALSE(server_stream()->handshake_confirmed());
347
348 // Check the client state to make sure that it did not receive a
349 // server-designated connection id.
350 QuicCryptoClientConfig::CachedState* client_state =
351 client_crypto_config_.LookupOrCreate(server_id_);
352
353 ASSERT_FALSE(client_state->has_server_designated_connection_id());
354 ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
355}
356
357TEST_P(QuicCryptoServerStreamTest, ZeroRTT) {
358 Initialize();
359 InitializeFakeClient(/* supports_stateless_rejects= */ false);
360
361 // Do a first handshake in order to prime the client config with the server's
362 // information.
363 AdvanceHandshakeWithFakeClient();
364 EXPECT_FALSE(server_stream()->ZeroRttAttempted());
365
366 // Now do another handshake, hopefully in 0-RTT.
367 QUIC_LOG(INFO) << "Resetting for 0-RTT handshake attempt";
368 InitializeFakeClient(/* supports_stateless_rejects= */ false);
369 InitializeServer();
370
371 EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
372 EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
373 .Times(testing::AnyNumber());
374 EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
375 client_stream()->CryptoConnect();
376
377 EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
378 EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
379 .Times(testing::AnyNumber());
380 EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
381 crypto_test_utils::CommunicateHandshakeMessages(
382 client_connection_, client_stream(), server_connection_, server_stream());
383
384 EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
385 EXPECT_TRUE(server_stream()->ZeroRttAttempted());
386}
387
388TEST_P(QuicCryptoServerStreamTest, FailByPolicy) {
389 Initialize();
390 InitializeFakeClient(/* supports_stateless_rejects= */ false);
391
392 EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
393 .WillOnce(testing::Return(false));
394 EXPECT_CALL(*server_connection_,
395 CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
396
397 AdvanceHandshakeWithFakeClient();
398}
399
400TEST_P(QuicCryptoServerStreamTest, MessageAfterHandshake) {
401 Initialize();
402 CompleteCryptoHandshake();
403 EXPECT_CALL(
404 *server_connection_,
405 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
406 message_.set_tag(kCHLO);
407 crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
408 Perspective::IS_CLIENT);
409}
410
411TEST_P(QuicCryptoServerStreamTest, BadMessageType) {
412 Initialize();
413
414 message_.set_tag(kSHLO);
415 EXPECT_CALL(*server_connection_,
416 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, _, _));
417 crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
418 Perspective::IS_SERVER);
419}
420
421TEST_P(QuicCryptoServerStreamTest, ChannelID) {
422 Initialize();
423
424 client_options_.channel_id_enabled = true;
425 client_options_.channel_id_source_async = false;
426 // CompleteCryptoHandshake verifies
427 // server_stream()->crypto_negotiated_params().channel_id is correct.
428 EXPECT_EQ(2, CompleteCryptoHandshake());
429 EXPECT_TRUE(server_stream()->encryption_established());
430 EXPECT_TRUE(server_stream()->handshake_confirmed());
431}
432
433TEST_P(QuicCryptoServerStreamTest, ChannelIDAsync) {
434 Initialize();
435
436 client_options_.channel_id_enabled = true;
437 client_options_.channel_id_source_async = true;
438 // CompleteCryptoHandshake verifies
439 // server_stream()->crypto_negotiated_params().channel_id is correct.
440 EXPECT_EQ(2, CompleteCryptoHandshake());
441 EXPECT_TRUE(server_stream()->encryption_established());
442 EXPECT_TRUE(server_stream()->handshake_confirmed());
443}
444
445TEST_P(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) {
446 // An attempt to send a SCUP before completing handshake should fail.
447 Initialize();
448
449 server_stream()->SendServerConfigUpdate(nullptr);
450 EXPECT_EQ(0, server_stream()->NumServerConfigUpdateMessagesSent());
451}
452
453TEST_P(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) {
454 Initialize();
455
456 InitializeFakeClient(/* supports_stateless_rejects= */ false);
457
458 // Do a first handshake in order to prime the client config with the server's
459 // information.
460 AdvanceHandshakeWithFakeClient();
461
462 // Now do another handshake, with the blocking SHLO connection option.
463 InitializeServer();
464 InitializeFakeClient(/* supports_stateless_rejects= */ false);
465 AdvanceHandshakeWithFakeClient();
466
467 // Send a SCUP message and ensure that the client was able to verify it.
468 EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
469 server_stream()->SendServerConfigUpdate(nullptr);
470 crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 1,
471 server_connection_, server_stream(), 1);
472
473 EXPECT_EQ(1, server_stream()->NumServerConfigUpdateMessagesSent());
474 EXPECT_EQ(1, client_stream()->num_scup_messages_received());
475}
476
477TEST_P(QuicCryptoServerStreamTest, DoesPeerSupportStatelessRejects) {
478 Initialize();
479
480 QuicConfig stateless_reject_config = DefaultQuicConfigStatelessRejects();
481 stateless_reject_config.ToHandshakeMessage(&message_);
482 EXPECT_TRUE(
483 QuicCryptoServerStreamPeer::DoesPeerSupportStatelessRejects(message_));
484
485 message_.Clear();
486 QuicConfig stateful_reject_config = DefaultQuicConfig();
487 stateful_reject_config.ToHandshakeMessage(&message_);
488 EXPECT_FALSE(
489 QuicCryptoServerStreamPeer::DoesPeerSupportStatelessRejects(message_));
490}
491
492class QuicCryptoServerStreamTestWithFailingProofSource
493 : public QuicCryptoServerStreamTest {
494 public:
495 QuicCryptoServerStreamTestWithFailingProofSource()
496 : QuicCryptoServerStreamTest(
497 std::unique_ptr<FailingProofSource>(new FailingProofSource)) {}
498};
499
500INSTANTIATE_TEST_SUITE_P(MoreTests,
501 QuicCryptoServerStreamTestWithFailingProofSource,
502 testing::Bool());
503
504TEST_P(QuicCryptoServerStreamTestWithFailingProofSource, Test) {
505 Initialize();
506 InitializeFakeClient(/* supports_stateless_rejects= */ false);
507
508 EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
509 .WillOnce(testing::Return(true));
510 EXPECT_CALL(*server_connection_,
511 CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to get proof", _));
512 // Regression test for b/31521252, in which a crash would happen here.
513 AdvanceHandshakeWithFakeClient();
514 EXPECT_FALSE(server_stream()->encryption_established());
515 EXPECT_FALSE(server_stream()->handshake_confirmed());
516}
517
518class QuicCryptoServerStreamTestWithFakeProofSource
519 : public QuicCryptoServerStreamTest {
520 public:
521 QuicCryptoServerStreamTestWithFakeProofSource()
522 : QuicCryptoServerStreamTest(
523 std::unique_ptr<FakeProofSource>(new FakeProofSource)),
524 crypto_config_peer_(&server_crypto_config_) {}
525
526 FakeProofSource* GetFakeProofSource() const {
527 return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
528 }
529
530 protected:
531 QuicCryptoServerConfigPeer crypto_config_peer_;
532};
533
534INSTANTIATE_TEST_SUITE_P(YetMoreTests,
535 QuicCryptoServerStreamTestWithFakeProofSource,
536 testing::Bool());
537
538// Regression test for b/35422225, in which multiple CHLOs arriving on the same
539// connection in close succession could cause a crash, especially when the use
540// of Mentat signing meant that it took a while for each CHLO to be processed.
541TEST_P(QuicCryptoServerStreamTestWithFakeProofSource, MultipleChlo) {
542 Initialize();
543 GetFakeProofSource()->Activate();
544 EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
545 .WillOnce(testing::Return(true));
546
547 // Create a minimal CHLO
548 MockClock clock;
549 QuicTransportVersion version = AllSupportedTransportVersions().front();
550 CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
551 &clock, version, &server_crypto_config_);
552
553 // Send in the CHLO, and check that a callback is now pending in the
554 // ProofSource.
555 crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
556 Perspective::IS_CLIENT);
557 EXPECT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
558
559 // Send in a second CHLO while processing of the first is still pending.
560 // Verify that the server closes the connection rather than crashing. Note
561 // that the crash is a use-after-free, so it may only show up consistently in
562 // ASAN tests.
563 EXPECT_CALL(
564 *server_connection_,
565 CloseConnection(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
566 "Unexpected handshake message while processing CHLO", _));
567 crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
568 Perspective::IS_CLIENT);
569}
570
571} // namespace
572} // namespace test
573} // namespace quic