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