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_client_stream.h"
6 
7 #include <memory>
8 #include <string>
9 #include <utility>
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/quic_decrypter.h"
13 #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
14 #include "net/third_party/quiche/src/quic/core/quic_packets.h"
15 #include "net/third_party/quiche/src/quic/core/quic_server_id.h"
16 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
17 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
18 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
19 #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
20 #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
21 #include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h"
22 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
23 #include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h"
24 #include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h"
25 #include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
26 #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h"
27 
28 using testing::_;
29 
30 namespace quic {
31 namespace test {
32 namespace {
33 
34 const char kServerHostname[] = "test.example.com";
35 const uint16_t kServerPort = 443;
36 
37 class QuicCryptoClientStreamTest : public QuicTest {
38  public:
QuicCryptoClientStreamTest()39   QuicCryptoClientStreamTest()
40       : supported_versions_(AllSupportedVersions()),
41         server_id_(kServerHostname, kServerPort, false),
42         crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
43                        std::make_unique<test::SimpleSessionCache>()),
44         server_crypto_config_(
45             crypto_test_utils::CryptoServerConfigForTesting()) {
46     CreateConnection();
47   }
48 
CreateSession()49   void CreateSession() {
50     session_ = std::make_unique<TestQuicSpdyClientSession>(
51         connection_, DefaultQuicConfig(), supported_versions_, server_id_,
52         &crypto_config_);
53     EXPECT_CALL(*session_, GetAlpnsToOffer())
54         .WillRepeatedly(testing::Return(std::vector<std::string>(
55             {AlpnForVersion(connection_->version())})));
56   }
57 
CreateConnection()58   void CreateConnection() {
59     connection_ =
60         new PacketSavingConnection(&client_helper_, &alarm_factory_,
61                                    Perspective::IS_CLIENT, supported_versions_);
62     // Advance the time, because timers do not like uninitialized times.
63     connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
64     CreateSession();
65   }
66 
UseTlsHandshake()67   void UseTlsHandshake() {
68     supported_versions_.clear();
69     for (ParsedQuicVersion version : AllSupportedVersions()) {
70       if (version.handshake_protocol != PROTOCOL_TLS1_3) {
71         continue;
72       }
73       supported_versions_.push_back(version);
74     }
75   }
76 
UseQuicCryptoHandshake()77   void UseQuicCryptoHandshake() {
78     supported_versions_.clear();
79     for (ParsedQuicVersion version : AllSupportedVersions()) {
80       if (version.handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
81         continue;
82       }
83       supported_versions_.push_back(version);
84     }
85   }
86 
CompleteCryptoHandshake()87   void CompleteCryptoHandshake() {
88     int proof_verify_details_calls = 1;
89     if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) {
90       EXPECT_CALL(*session_, OnProofValid(testing::_));
91       proof_verify_details_calls = 0;
92     }
93     EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
94         .Times(testing::AtLeast(proof_verify_details_calls));
95     stream()->CryptoConnect();
96     QuicConfig config;
97     crypto_test_utils::HandshakeWithFakeServer(
98         &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
99         connection_, stream(), AlpnForVersion(connection_->version()));
100   }
101 
stream()102   QuicCryptoClientStream* stream() {
103     return session_->GetMutableCryptoStream();
104   }
105 
106   MockQuicConnectionHelper server_helper_;
107   MockQuicConnectionHelper client_helper_;
108   MockAlarmFactory alarm_factory_;
109   PacketSavingConnection* connection_;
110   ParsedQuicVersionVector supported_versions_;
111   std::unique_ptr<TestQuicSpdyClientSession> session_;
112   QuicServerId server_id_;
113   CryptoHandshakeMessage message_;
114   QuicCryptoClientConfig crypto_config_;
115   std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
116 };
117 
TEST_F(QuicCryptoClientStreamTest,NotInitiallyConected)118 TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
119   EXPECT_FALSE(stream()->encryption_established());
120   EXPECT_FALSE(stream()->one_rtt_keys_available());
121 }
122 
TEST_F(QuicCryptoClientStreamTest,ConnectedAfterSHLO)123 TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
124   CompleteCryptoHandshake();
125   EXPECT_TRUE(stream()->encryption_established());
126   EXPECT_TRUE(stream()->one_rtt_keys_available());
127   EXPECT_FALSE(stream()->IsResumption());
128 }
129 
TEST_F(QuicCryptoClientStreamTest,ConnectedAfterTlsHandshake)130 TEST_F(QuicCryptoClientStreamTest, ConnectedAfterTlsHandshake) {
131   UseTlsHandshake();
132   CreateConnection();
133   CompleteCryptoHandshake();
134   EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
135   EXPECT_TRUE(stream()->encryption_established());
136   EXPECT_TRUE(stream()->one_rtt_keys_available());
137   EXPECT_FALSE(stream()->IsResumption());
138 }
139 
TEST_F(QuicCryptoClientStreamTest,ProofVerifyDetailsAvailableAfterTlsHandshake)140 TEST_F(QuicCryptoClientStreamTest,
141        ProofVerifyDetailsAvailableAfterTlsHandshake) {
142   UseTlsHandshake();
143   CreateConnection();
144 
145   EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_));
146   stream()->CryptoConnect();
147   QuicConfig config;
148   crypto_test_utils::HandshakeWithFakeServer(
149       &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
150       connection_, stream(), AlpnForVersion(connection_->version()));
151   EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
152   EXPECT_TRUE(stream()->encryption_established());
153   EXPECT_TRUE(stream()->one_rtt_keys_available());
154 }
155 
TEST_F(QuicCryptoClientStreamTest,TlsResumption)156 TEST_F(QuicCryptoClientStreamTest, TlsResumption) {
157   UseTlsHandshake();
158   // Enable resumption on the server:
159   SSL_CTX_clear_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
160   CreateConnection();
161 
162   // Finish establishing the first connection:
163   CompleteCryptoHandshake();
164 
165   EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
166   EXPECT_TRUE(stream()->encryption_established());
167   EXPECT_TRUE(stream()->one_rtt_keys_available());
168   EXPECT_FALSE(stream()->IsResumption());
169 
170   // Create a second connection
171   CreateConnection();
172   CompleteCryptoHandshake();
173 
174   EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
175   EXPECT_TRUE(stream()->encryption_established());
176   EXPECT_TRUE(stream()->one_rtt_keys_available());
177   EXPECT_TRUE(stream()->IsResumption());
178 }
179 
TEST_F(QuicCryptoClientStreamTest,MessageAfterHandshake)180 TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
181   UseQuicCryptoHandshake();
182   CreateConnection();
183   CompleteCryptoHandshake();
184 
185   EXPECT_CALL(
186       *connection_,
187       CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
188   message_.set_tag(kCHLO);
189   crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
190                                                   Perspective::IS_CLIENT);
191 }
192 
TEST_F(QuicCryptoClientStreamTest,BadMessageType)193 TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
194   UseQuicCryptoHandshake();
195   CreateConnection();
196   stream()->CryptoConnect();
197 
198   message_.set_tag(kCHLO);
199 
200   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
201                                             "Expected REJ", _));
202   crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
203                                                   Perspective::IS_CLIENT);
204 }
205 
TEST_F(QuicCryptoClientStreamTest,NegotiatedParameters)206 TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
207   UseQuicCryptoHandshake();
208   CreateConnection();
209   CompleteCryptoHandshake();
210 
211   const QuicConfig* config = session_->config();
212   EXPECT_EQ(kMaximumIdleTimeoutSecs, config->IdleNetworkTimeout().ToSeconds());
213 
214   const QuicCryptoNegotiatedParameters& crypto_params(
215       stream()->crypto_negotiated_params());
216   EXPECT_EQ(crypto_config_.aead[0], crypto_params.aead);
217   EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
218 }
219 
TEST_F(QuicCryptoClientStreamTest,ExpiredServerConfig)220 TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
221   UseQuicCryptoHandshake();
222   CreateConnection();
223   // Seed the config with a cached server config.
224   CompleteCryptoHandshake();
225 
226   // Recreate connection with the new config.
227   CreateConnection();
228 
229   // Advance time 5 years to ensure that we pass the expiry time of the cached
230   // server config.
231   connection_->AdvanceTime(
232       QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
233 
234   EXPECT_CALL(*session_, OnProofValid(testing::_));
235   stream()->CryptoConnect();
236   // Check that a client hello was sent.
237   ASSERT_EQ(1u, connection_->encrypted_packets_.size());
238   EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
239 }
240 
TEST_F(QuicCryptoClientStreamTest,ClockSkew)241 TEST_F(QuicCryptoClientStreamTest, ClockSkew) {
242   // Test that if the client's clock is skewed with respect to the server,
243   // the handshake succeeds. In the past, the client would get the server
244   // config, notice that it had already expired and then close the connection.
245 
246   // Advance time 5 years to ensure that we pass the expiry time in the server
247   // config, but the TTL is used instead.
248   connection_->AdvanceTime(
249       QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
250 
251   // The handshakes completes!
252   CompleteCryptoHandshake();
253 }
254 
TEST_F(QuicCryptoClientStreamTest,InvalidCachedServerConfig)255 TEST_F(QuicCryptoClientStreamTest, InvalidCachedServerConfig) {
256   // Seed the config with a cached server config.
257   CompleteCryptoHandshake();
258 
259   // Recreate connection with the new config.
260   CreateConnection();
261 
262   QuicCryptoClientConfig::CachedState* state =
263       crypto_config_.LookupOrCreate(server_id_);
264 
265   std::vector<std::string> certs = state->certs();
266   std::string cert_sct = state->cert_sct();
267   std::string signature = state->signature();
268   std::string chlo_hash = state->chlo_hash();
269   state->SetProof(certs, cert_sct, chlo_hash, signature + signature);
270 
271   EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
272       .Times(testing::AnyNumber());
273   stream()->CryptoConnect();
274   // Check that a client hello was sent.
275   ASSERT_EQ(1u, connection_->encrypted_packets_.size());
276 }
277 
TEST_F(QuicCryptoClientStreamTest,ServerConfigUpdate)278 TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
279   // Test that the crypto client stream can receive server config updates after
280   // the connection has been established.
281   UseQuicCryptoHandshake();
282   CreateConnection();
283   CompleteCryptoHandshake();
284 
285   QuicCryptoClientConfig::CachedState* state =
286       crypto_config_.LookupOrCreate(server_id_);
287 
288   // Ensure cached STK is different to what we send in the handshake.
289   EXPECT_NE("xstk", state->source_address_token());
290 
291   // Initialize using {...} syntax to avoid trailing \0 if converting from
292   // string.
293   unsigned char stk[] = {'x', 's', 't', 'k'};
294 
295   // Minimum SCFG that passes config validation checks.
296   unsigned char scfg[] = {// SCFG
297                           0x53, 0x43, 0x46, 0x47,
298                           // num entries
299                           0x01, 0x00,
300                           // padding
301                           0x00, 0x00,
302                           // EXPY
303                           0x45, 0x58, 0x50, 0x59,
304                           // EXPY end offset
305                           0x08, 0x00, 0x00, 0x00,
306                           // Value
307                           '1', '2', '3', '4', '5', '6', '7', '8'};
308 
309   CryptoHandshakeMessage server_config_update;
310   server_config_update.set_tag(kSCUP);
311   server_config_update.SetValue(kSourceAddressTokenTag, stk);
312   server_config_update.SetValue(kSCFG, scfg);
313   const uint64_t expiry_seconds = 60 * 60 * 24 * 2;
314   server_config_update.SetValue(kSTTL, expiry_seconds);
315 
316   crypto_test_utils::SendHandshakeMessageToStream(
317       stream(), server_config_update, Perspective::IS_SERVER);
318 
319   // Make sure that the STK and SCFG are cached correctly.
320   EXPECT_EQ("xstk", state->source_address_token());
321 
322   const std::string& cached_scfg = state->server_config();
323   quiche::test::CompareCharArraysWithHexError(
324       "scfg", cached_scfg.data(), cached_scfg.length(),
325       reinterpret_cast<char*>(scfg), QUICHE_ARRAYSIZE(scfg));
326 
327   QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream());
328   EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
329 }
330 
TEST_F(QuicCryptoClientStreamTest,ServerConfigUpdateWithCert)331 TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
332   // Test that the crypto client stream can receive and use server config
333   // updates with certificates after the connection has been established.
334   UseQuicCryptoHandshake();
335   CreateConnection();
336   CompleteCryptoHandshake();
337 
338   // Build a server config update message with certificates
339   QuicCryptoServerConfig crypto_config(
340       QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
341       crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
342   crypto_test_utils::SetupCryptoServerConfigForTest(
343       connection_->clock(), QuicRandom::GetInstance(), &crypto_config);
344   SourceAddressTokens tokens;
345   QuicCompressedCertsCache cache(1);
346   CachedNetworkParameters network_params;
347   CryptoHandshakeMessage server_config_update;
348 
349   class Callback : public BuildServerConfigUpdateMessageResultCallback {
350    public:
351     Callback(bool* ok, CryptoHandshakeMessage* message)
352         : ok_(ok), message_(message) {}
353     void Run(bool ok, const CryptoHandshakeMessage& message) override {
354       *ok_ = ok;
355       *message_ = message;
356     }
357 
358    private:
359     bool* ok_;
360     CryptoHandshakeMessage* message_;
361   };
362 
363   // Note: relies on the callback being invoked synchronously
364   bool ok = false;
365   crypto_config.BuildServerConfigUpdateMessage(
366       session_->transport_version(), stream()->chlo_hash(), tokens,
367       QuicSocketAddress(QuicIpAddress::Loopback6(), 1234),
368       QuicIpAddress::Loopback6(), connection_->clock(),
369       QuicRandom::GetInstance(), &cache, stream()->crypto_negotiated_params(),
370       &network_params,
371       std::unique_ptr<BuildServerConfigUpdateMessageResultCallback>(
372           new Callback(&ok, &server_config_update)));
373   EXPECT_TRUE(ok);
374 
375   EXPECT_CALL(*session_, OnProofValid(testing::_));
376   crypto_test_utils::SendHandshakeMessageToStream(
377       stream(), server_config_update, Perspective::IS_SERVER);
378 
379   // Recreate connection with the new config and verify a 0-RTT attempt.
380   CreateConnection();
381 
382   EXPECT_CALL(*connection_, OnCanWrite());
383   EXPECT_CALL(*session_, OnProofValid(testing::_));
384   EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
385       .Times(testing::AnyNumber());
386   stream()->CryptoConnect();
387   EXPECT_TRUE(session_->IsEncryptionEstablished());
388 }
389 
TEST_F(QuicCryptoClientStreamTest,ServerConfigUpdateBeforeHandshake)390 TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
391   UseQuicCryptoHandshake();
392   CreateConnection();
393   EXPECT_CALL(
394       *connection_,
395       CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, _, _));
396   CryptoHandshakeMessage server_config_update;
397   server_config_update.set_tag(kSCUP);
398   crypto_test_utils::SendHandshakeMessageToStream(
399       stream(), server_config_update, Perspective::IS_SERVER);
400 }
401 
TEST_F(QuicCryptoClientStreamTest,PreferredVersion)402 TEST_F(QuicCryptoClientStreamTest, PreferredVersion) {
403   // This mimics the case where client receives version negotiation packet, such
404   // that, the preferred version is different from the packets' version.
405   UseQuicCryptoHandshake();
406   connection_ = new PacketSavingConnection(
407       &client_helper_, &alarm_factory_, Perspective::IS_CLIENT,
408       ParsedVersionOfIndex(supported_versions_, 1));
409   connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
410 
411   CreateSession();
412   CompleteCryptoHandshake();
413   // 2 CHLOs are sent.
414   ASSERT_EQ(2u, session_->sent_crypto_handshake_messages().size());
415   // Verify preferred version is the highest version that session supports, and
416   // is different from connection's version.
417   QuicVersionLabel client_version_label;
418   EXPECT_THAT(session_->sent_crypto_handshake_messages()[0].GetVersionLabel(
419                   kVER, &client_version_label),
420               IsQuicNoError());
421   EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
422             client_version_label);
423   EXPECT_THAT(session_->sent_crypto_handshake_messages()[1].GetVersionLabel(
424                   kVER, &client_version_label),
425               IsQuicNoError());
426   EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
427             client_version_label);
428   EXPECT_NE(CreateQuicVersionLabel(connection_->version()),
429             client_version_label);
430 }
431 
432 }  // namespace
433 }  // namespace test
434 }  // namespace quic
435