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