1 // 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_base.h"
6
7 #include <map>
8 #include <memory>
9 #include <utility>
10 #include <vector>
11
12 #include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h"
13 #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
14 #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
15 #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
16 #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h"
17 #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
18 #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
19 #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
20 #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
21 #include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
22 #include "net/third_party/quiche/src/quic/core/quic_packets.h"
23 #include "net/third_party/quiche/src/quic/core/quic_session.h"
24 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
25 #include "net/third_party/quiche/src/quic/core/quic_versions.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_socket_address.h"
29 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
30 #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
31 #include "net/third_party/quiche/src/quic/test_tools/failing_proof_source.h"
32 #include "net/third_party/quiche/src/quic/test_tools/fake_proof_source.h"
33 #include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h"
34 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
35 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
36
37 namespace quic {
38 class QuicConnection;
39 class QuicStream;
40 } // namespace quic
41
42 using testing::_;
43 using testing::NiceMock;
44
45 namespace quic {
46 namespace test {
47
48 namespace {
49
50 const char kServerHostname[] = "test.example.com";
51 const uint16_t kServerPort = 443;
52
53 class QuicCryptoServerStreamTest : public QuicTestWithParam<bool> {
54 public:
QuicCryptoServerStreamTest()55 QuicCryptoServerStreamTest()
56 : QuicCryptoServerStreamTest(crypto_test_utils::ProofSourceForTesting()) {
57 }
58
QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source)59 explicit QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source)
60 : server_crypto_config_(QuicCryptoServerConfig::TESTING,
61 QuicRandom::GetInstance(),
62 std::move(proof_source),
63 KeyExchangeSource::Default()),
64 server_compressed_certs_cache_(
65 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
66 server_id_(kServerHostname, kServerPort, false),
67 client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
68
Initialize()69 void Initialize() { InitializeServer(); }
70
~QuicCryptoServerStreamTest()71 ~QuicCryptoServerStreamTest() override {
72 // Ensure that anything that might reference |helpers_| is destroyed before
73 // |helpers_| is destroyed.
74 server_session_.reset();
75 client_session_.reset();
76 helpers_.clear();
77 alarm_factories_.clear();
78 }
79
80 // Initializes the crypto server stream state for testing. May be
81 // called multiple times.
InitializeServer()82 void InitializeServer() {
83 TestQuicSpdyServerSession* server_session = nullptr;
84 helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
85 alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
86 CreateServerSessionForTest(
87 server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
88 helpers_.back().get(), alarm_factories_.back().get(),
89 &server_crypto_config_, &server_compressed_certs_cache_,
90 &server_connection_, &server_session);
91 CHECK(server_session);
92 server_session_.reset(server_session);
93 EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
94 .Times(testing::AnyNumber());
95 EXPECT_CALL(*server_session_, SelectAlpn(_))
96 .WillRepeatedly(
97 [this](const std::vector<quiche::QuicheStringPiece>& alpns) {
98 return std::find(
99 alpns.cbegin(), alpns.cend(),
100 AlpnForVersion(server_session_->connection()->version()));
101 });
102 crypto_test_utils::SetupCryptoServerConfigForTest(
103 server_connection_->clock(), server_connection_->random_generator(),
104 &server_crypto_config_);
105 }
106
server_stream()107 QuicCryptoServerStreamBase* server_stream() {
108 return server_session_->GetMutableCryptoStream();
109 }
110
client_stream()111 QuicCryptoClientStream* client_stream() {
112 return client_session_->GetMutableCryptoStream();
113 }
114
115 // Initializes a fake client, and all its associated state, for
116 // testing. May be called multiple times.
InitializeFakeClient()117 void InitializeFakeClient() {
118 TestQuicSpdyClientSession* client_session = nullptr;
119 helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
120 alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
121 CreateClientSessionForTest(
122 server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
123 helpers_.back().get(), alarm_factories_.back().get(),
124 &client_crypto_config_, &client_connection_, &client_session);
125 CHECK(client_session);
126 client_session_.reset(client_session);
127 }
128
CompleteCryptoHandshake()129 int CompleteCryptoHandshake() {
130 CHECK(server_connection_);
131 CHECK(server_session_ != nullptr);
132
133 return crypto_test_utils::HandshakeWithFakeClient(
134 helpers_.back().get(), alarm_factories_.back().get(),
135 server_connection_, server_stream(), server_id_, client_options_,
136 /*alpn=*/"");
137 }
138
139 // Performs a single round of handshake message-exchange between the
140 // client and server.
AdvanceHandshakeWithFakeClient()141 void AdvanceHandshakeWithFakeClient() {
142 CHECK(server_connection_);
143 CHECK(client_session_ != nullptr);
144
145 EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
146 EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
147 .Times(testing::AnyNumber());
148 EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
149 EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
150 client_stream()->CryptoConnect();
151 crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 0,
152 server_connection_, server_stream(), 0);
153 }
154
UseTlsHandshake()155 void UseTlsHandshake() {
156 client_options_.only_tls_versions = true;
157 supported_versions_.clear();
158 for (ParsedQuicVersion version : AllSupportedVersions()) {
159 if (version.handshake_protocol != PROTOCOL_TLS1_3) {
160 continue;
161 }
162 supported_versions_.push_back(version);
163 }
164 }
165
UseQuicCryptoHandshake()166 void UseQuicCryptoHandshake() {
167 client_options_.only_quic_crypto_versions = true;
168 supported_versions_.clear();
169 for (ParsedQuicVersion version : AllSupportedVersions()) {
170 if (version.handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
171 continue;
172 }
173 supported_versions_.push_back(version);
174 }
175 }
176
177 protected:
178 // Every connection gets its own MockQuicConnectionHelper and
179 // MockAlarmFactory, tracked separately from the server and client state so
180 // their lifetimes persist through the whole test.
181 std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
182 std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
183
184 // Server state.
185 PacketSavingConnection* server_connection_;
186 std::unique_ptr<TestQuicSpdyServerSession> server_session_;
187 QuicCryptoServerConfig server_crypto_config_;
188 QuicCompressedCertsCache server_compressed_certs_cache_;
189 QuicServerId server_id_;
190
191 // Client state.
192 PacketSavingConnection* client_connection_;
193 QuicCryptoClientConfig client_crypto_config_;
194 std::unique_ptr<TestQuicSpdyClientSession> client_session_;
195
196 CryptoHandshakeMessage message_;
197 crypto_test_utils::FakeClientOptions client_options_;
198
199 // Which QUIC versions the client and server support.
200 ParsedQuicVersionVector supported_versions_ = AllSupportedVersions();
201 };
202
203 INSTANTIATE_TEST_SUITE_P(Tests,
204 QuicCryptoServerStreamTest,
205 ::testing::Bool(),
206 ::testing::PrintToStringParamName());
207
TEST_P(QuicCryptoServerStreamTest,NotInitiallyConected)208 TEST_P(QuicCryptoServerStreamTest, NotInitiallyConected) {
209 Initialize();
210 EXPECT_FALSE(server_stream()->encryption_established());
211 EXPECT_FALSE(server_stream()->one_rtt_keys_available());
212 }
213
TEST_P(QuicCryptoServerStreamTest,ConnectedAfterCHLO)214 TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
215 // CompleteCryptoHandshake returns the number of client hellos sent. This
216 // test should send:
217 // * One to get a source-address token and certificates.
218 // * One to complete the handshake.
219 UseQuicCryptoHandshake();
220 Initialize();
221 EXPECT_EQ(2, CompleteCryptoHandshake());
222 EXPECT_TRUE(server_stream()->encryption_established());
223 EXPECT_TRUE(server_stream()->one_rtt_keys_available());
224 }
225
TEST_P(QuicCryptoServerStreamTest,ConnectedAfterTlsHandshake)226 TEST_P(QuicCryptoServerStreamTest, ConnectedAfterTlsHandshake) {
227 UseTlsHandshake();
228 Initialize();
229 CompleteCryptoHandshake();
230 EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
231 EXPECT_TRUE(server_stream()->encryption_established());
232 EXPECT_TRUE(server_stream()->one_rtt_keys_available());
233 }
234
TEST_P(QuicCryptoServerStreamTest,ForwardSecureAfterCHLO)235 TEST_P(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
236 UseQuicCryptoHandshake();
237 Initialize();
238 InitializeFakeClient();
239
240 // Do a first handshake in order to prime the client config with the server's
241 // information.
242 AdvanceHandshakeWithFakeClient();
243 EXPECT_FALSE(server_stream()->encryption_established());
244 EXPECT_FALSE(server_stream()->one_rtt_keys_available());
245
246 // Now do another handshake, with the blocking SHLO connection option.
247 InitializeServer();
248 InitializeFakeClient();
249
250 AdvanceHandshakeWithFakeClient();
251 EXPECT_TRUE(server_stream()->encryption_established());
252 EXPECT_TRUE(server_stream()->one_rtt_keys_available());
253 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE,
254 server_session_->connection()->encryption_level());
255 }
256
TEST_P(QuicCryptoServerStreamTest,ZeroRTT)257 TEST_P(QuicCryptoServerStreamTest, ZeroRTT) {
258 UseQuicCryptoHandshake();
259 Initialize();
260 InitializeFakeClient();
261
262 // Do a first handshake in order to prime the client config with the server's
263 // information.
264 AdvanceHandshakeWithFakeClient();
265 EXPECT_FALSE(server_stream()->ZeroRttAttempted());
266
267 // Now do another handshake, hopefully in 0-RTT.
268 QUIC_LOG(INFO) << "Resetting for 0-RTT handshake attempt";
269 InitializeFakeClient();
270 InitializeServer();
271
272 EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
273 EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
274 .Times(testing::AnyNumber());
275 EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
276 client_stream()->CryptoConnect();
277
278 EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
279 EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
280 .Times(testing::AnyNumber());
281 EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
282 crypto_test_utils::CommunicateHandshakeMessages(
283 client_connection_, client_stream(), server_connection_, server_stream());
284
285 EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
286 EXPECT_TRUE(server_stream()->ZeroRttAttempted());
287 }
288
TEST_P(QuicCryptoServerStreamTest,FailByPolicy)289 TEST_P(QuicCryptoServerStreamTest, FailByPolicy) {
290 UseQuicCryptoHandshake();
291 Initialize();
292 InitializeFakeClient();
293
294 EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
295 .WillOnce(testing::Return(false));
296 EXPECT_CALL(*server_connection_,
297 CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
298
299 AdvanceHandshakeWithFakeClient();
300 }
301
TEST_P(QuicCryptoServerStreamTest,MessageAfterHandshake)302 TEST_P(QuicCryptoServerStreamTest, MessageAfterHandshake) {
303 UseQuicCryptoHandshake();
304 Initialize();
305 CompleteCryptoHandshake();
306 EXPECT_CALL(
307 *server_connection_,
308 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
309 message_.set_tag(kCHLO);
310 crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
311 Perspective::IS_CLIENT);
312 }
313
TEST_P(QuicCryptoServerStreamTest,BadMessageType)314 TEST_P(QuicCryptoServerStreamTest, BadMessageType) {
315 UseQuicCryptoHandshake();
316 Initialize();
317
318 message_.set_tag(kSHLO);
319 EXPECT_CALL(*server_connection_,
320 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, _, _));
321 crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
322 Perspective::IS_SERVER);
323 }
324
TEST_P(QuicCryptoServerStreamTest,OnlySendSCUPAfterHandshakeComplete)325 TEST_P(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) {
326 // An attempt to send a SCUP before completing handshake should fail.
327 Initialize();
328
329 server_stream()->SendServerConfigUpdate(nullptr);
330 EXPECT_EQ(0, server_stream()->NumServerConfigUpdateMessagesSent());
331 }
332
TEST_P(QuicCryptoServerStreamTest,SendSCUPAfterHandshakeComplete)333 TEST_P(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) {
334 UseQuicCryptoHandshake();
335 Initialize();
336
337 InitializeFakeClient();
338
339 // Do a first handshake in order to prime the client config with the server's
340 // information.
341 AdvanceHandshakeWithFakeClient();
342
343 // Now do another handshake, with the blocking SHLO connection option.
344 InitializeServer();
345 InitializeFakeClient();
346 AdvanceHandshakeWithFakeClient();
347
348 // Send a SCUP message and ensure that the client was able to verify it.
349 EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
350 server_stream()->SendServerConfigUpdate(nullptr);
351 crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 1,
352 server_connection_, server_stream(), 1);
353
354 EXPECT_EQ(1, server_stream()->NumServerConfigUpdateMessagesSent());
355 EXPECT_EQ(1, client_stream()->num_scup_messages_received());
356 }
357
358 class QuicCryptoServerStreamTestWithFailingProofSource
359 : public QuicCryptoServerStreamTest {
360 public:
QuicCryptoServerStreamTestWithFailingProofSource()361 QuicCryptoServerStreamTestWithFailingProofSource()
362 : QuicCryptoServerStreamTest(
363 std::unique_ptr<FailingProofSource>(new FailingProofSource)) {}
364 };
365
366 INSTANTIATE_TEST_SUITE_P(MoreTests,
367 QuicCryptoServerStreamTestWithFailingProofSource,
368 ::testing::Bool(),
369 ::testing::PrintToStringParamName());
370
TEST_P(QuicCryptoServerStreamTestWithFailingProofSource,Test)371 TEST_P(QuicCryptoServerStreamTestWithFailingProofSource, Test) {
372 UseQuicCryptoHandshake();
373 Initialize();
374 InitializeFakeClient();
375
376 EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
377 .WillOnce(testing::Return(true));
378 EXPECT_CALL(*server_connection_,
379 CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to get proof", _));
380 // Regression test for b/31521252, in which a crash would happen here.
381 AdvanceHandshakeWithFakeClient();
382 EXPECT_FALSE(server_stream()->encryption_established());
383 EXPECT_FALSE(server_stream()->one_rtt_keys_available());
384 }
385
386 class QuicCryptoServerStreamTestWithFakeProofSource
387 : public QuicCryptoServerStreamTest {
388 public:
QuicCryptoServerStreamTestWithFakeProofSource()389 QuicCryptoServerStreamTestWithFakeProofSource()
390 : QuicCryptoServerStreamTest(
391 std::unique_ptr<FakeProofSource>(new FakeProofSource)),
392 crypto_config_peer_(&server_crypto_config_) {}
393
GetFakeProofSource() const394 FakeProofSource* GetFakeProofSource() const {
395 return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
396 }
397
398 protected:
399 QuicCryptoServerConfigPeer crypto_config_peer_;
400 };
401
402 INSTANTIATE_TEST_SUITE_P(YetMoreTests,
403 QuicCryptoServerStreamTestWithFakeProofSource,
404 ::testing::Bool(),
405 ::testing::PrintToStringParamName());
406
407 // Regression test for b/35422225, in which multiple CHLOs arriving on the same
408 // connection in close succession could cause a crash, especially when the use
409 // of Mentat signing meant that it took a while for each CHLO to be processed.
TEST_P(QuicCryptoServerStreamTestWithFakeProofSource,MultipleChlo)410 TEST_P(QuicCryptoServerStreamTestWithFakeProofSource, MultipleChlo) {
411 UseQuicCryptoHandshake();
412 Initialize();
413 GetFakeProofSource()->Activate();
414 EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
415 .WillOnce(testing::Return(true));
416
417 // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
418 // first one from the list of supported versions.
419 QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
420 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
421 if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
422 transport_version = version.transport_version;
423 break;
424 }
425 }
426 ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
427
428 // Create a minimal CHLO
429 MockClock clock;
430 CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
431 &clock, transport_version, &server_crypto_config_);
432
433 // Send in the CHLO, and check that a callback is now pending in the
434 // ProofSource.
435 crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
436 Perspective::IS_CLIENT);
437 EXPECT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
438
439 // Send in a second CHLO while processing of the first is still pending.
440 // Verify that the server closes the connection rather than crashing. Note
441 // that the crash is a use-after-free, so it may only show up consistently in
442 // ASAN tests.
443 EXPECT_CALL(
444 *server_connection_,
445 CloseConnection(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
446 "Unexpected handshake message while processing CHLO", _));
447 crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
448 Perspective::IS_CLIENT);
449 }
450
451 } // namespace
452 } // namespace test
453 } // namespace quic
454