Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / net / quic / quic_crypto_server_stream_test.cc
bloba60fcaae5a29e3d8a2302b053366e3e17122cdf7
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.
5 #include "net/quic/quic_crypto_server_stream.h"
7 #include <map>
8 #include <vector>
10 #include "base/memory/scoped_ptr.h"
11 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
12 #include "net/quic/crypto/crypto_framer.h"
13 #include "net/quic/crypto/crypto_handshake.h"
14 #include "net/quic/crypto/crypto_protocol.h"
15 #include "net/quic/crypto/crypto_utils.h"
16 #include "net/quic/crypto/quic_crypto_server_config.h"
17 #include "net/quic/crypto/quic_decrypter.h"
18 #include "net/quic/crypto/quic_encrypter.h"
19 #include "net/quic/crypto/quic_random.h"
20 #include "net/quic/quic_crypto_client_stream.h"
21 #include "net/quic/quic_flags.h"
22 #include "net/quic/quic_protocol.h"
23 #include "net/quic/quic_session.h"
24 #include "net/quic/test_tools/crypto_test_utils.h"
25 #include "net/quic/test_tools/delayed_verify_strike_register_client.h"
26 #include "net/quic/test_tools/quic_test_utils.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 namespace net {
31 class QuicConnection;
32 class ReliableQuicStream;
33 } // namespace net
35 using std::pair;
36 using std::string;
37 using testing::_;
39 namespace net {
40 namespace test {
42 class QuicCryptoServerConfigPeer {
43 public:
44 static string GetPrimaryOrbit(const QuicCryptoServerConfig& config) {
45 base::AutoLock lock(config.configs_lock_);
46 CHECK(config.primary_config_.get() != nullptr);
47 return string(reinterpret_cast<const char*>(config.primary_config_->orbit),
48 kOrbitSize);
52 class QuicCryptoServerStreamPeer {
53 public:
54 static bool DoesPeerSupportStatelessRejects(
55 const CryptoHandshakeMessage& message) {
56 return net::QuicCryptoServerStream::DoesPeerSupportStatelessRejects(
57 message);
61 namespace {
63 const char kServerHostname[] = "test.example.com";
64 const uint16 kServerPort = 80;
66 class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
67 public:
68 QuicCryptoServerStreamTest()
69 : server_crypto_config_(QuicCryptoServerConfig::TESTING,
70 QuicRandom::GetInstance()),
71 server_id_(kServerHostname, kServerPort, false, PRIVACY_MODE_DISABLED) {
72 // TODO(wtc): replace this with ProofSourceForTesting() when Chromium has
73 // a working ProofSourceForTesting().
74 server_crypto_config_.SetProofSource(
75 CryptoTestUtils::FakeProofSourceForTesting());
76 server_crypto_config_.set_strike_register_no_startup_period();
78 InitializeServer();
80 if (AsyncStrikeRegisterVerification()) {
81 string orbit =
82 QuicCryptoServerConfigPeer::GetPrimaryOrbit(server_crypto_config_);
83 strike_register_client_ = new DelayedVerifyStrikeRegisterClient(
84 10000, // strike_register_max_entries
85 static_cast<uint32>(
86 server_connection_->clock()->WallNow().ToUNIXSeconds()),
87 60, // strike_register_window_secs
88 reinterpret_cast<const uint8*>(orbit.data()),
89 StrikeRegister::NO_STARTUP_PERIOD_NEEDED);
90 strike_register_client_->StartDelayingVerification();
91 server_crypto_config_.SetStrikeRegisterClient(strike_register_client_);
95 // Initializes the crypto server stream state for testing. May be
96 // called multiple times.
97 void InitializeServer() {
98 TestQuicSpdyServerSession* server_session = nullptr;
99 CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000),
100 &server_crypto_config_, &server_connection_,
101 &server_session);
102 CHECK(server_session);
103 server_session_.reset(server_session);
104 CryptoTestUtils::SetupCryptoServerConfigForTest(
105 server_connection_->clock(), server_connection_->random_generator(),
106 server_session_->config(), &server_crypto_config_);
109 QuicCryptoServerStream* server_stream() {
110 return server_session_->GetCryptoStream();
113 QuicCryptoClientStream* client_stream() {
114 return client_session_->GetCryptoStream();
117 // Initializes a fake client, and all its associated state, for
118 // testing. May be called multiple times.
119 void InitializeFakeClient(bool supports_stateless_rejects) {
120 TestQuicSpdyClientSession* client_session = nullptr;
121 CreateClientSessionForTest(server_id_, supports_stateless_rejects,
122 QuicTime::Delta::FromSeconds(100000),
123 &client_crypto_config_, &client_connection_,
124 &client_session);
125 CHECK(client_session);
126 client_session_.reset(client_session);
129 bool AsyncStrikeRegisterVerification() {
130 return GetParam();
133 void ConstructHandshakeMessage() {
134 CryptoFramer framer;
135 message_data_.reset(framer.ConstructHandshakeMessage(message_));
138 int CompleteCryptoHandshake() {
139 CHECK(server_connection_);
140 CHECK(server_session_ != nullptr);
141 return CryptoTestUtils::HandshakeWithFakeClient(
142 server_connection_, server_stream(), client_options_);
145 // Performs a single round of handshake message-exchange between the
146 // client and server.
147 void AdvanceHandshakeWithFakeClient() {
148 CHECK(server_connection_);
149 CHECK(client_session_ != nullptr);
151 EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
152 client_stream()->CryptoConnect();
153 CryptoTestUtils::AdvanceHandshake(client_connection_, client_stream(), 0,
154 server_connection_, server_stream(), 0);
157 protected:
158 // Server state
159 PacketSavingConnection* server_connection_;
160 scoped_ptr<TestQuicSpdyServerSession> server_session_;
161 QuicCryptoServerConfig server_crypto_config_;
162 QuicServerId server_id_;
164 // Client state
165 PacketSavingConnection* client_connection_;
166 QuicCryptoClientConfig client_crypto_config_;
167 scoped_ptr<TestQuicSpdyClientSession> client_session_;
169 CryptoHandshakeMessage message_;
170 scoped_ptr<QuicData> message_data_;
171 CryptoTestUtils::FakeClientOptions client_options_;
172 DelayedVerifyStrikeRegisterClient* strike_register_client_;
175 INSTANTIATE_TEST_CASE_P(Tests, QuicCryptoServerStreamTest, testing::Bool());
177 TEST_P(QuicCryptoServerStreamTest, NotInitiallyConected) {
178 EXPECT_FALSE(server_stream()->encryption_established());
179 EXPECT_FALSE(server_stream()->handshake_confirmed());
182 TEST_P(QuicCryptoServerStreamTest, NotInitiallySendingStatelessRejects) {
183 EXPECT_FALSE(server_stream()->use_stateless_rejects_if_peer_supported());
184 EXPECT_FALSE(server_stream()->peer_supports_stateless_rejects());
187 TEST_P(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 EXPECT_EQ(2, CompleteCryptoHandshake());
193 EXPECT_TRUE(server_stream()->encryption_established());
194 EXPECT_TRUE(server_stream()->handshake_confirmed());
197 TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) {
198 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stateless_reject_support,
199 true);
200 server_stream()->set_use_stateless_rejects_if_peer_supported(true);
202 InitializeFakeClient(/* supports_stateless_rejects= */ true);
203 AdvanceHandshakeWithFakeClient();
205 // Check the server to make the sure the handshake did not succeed.
206 EXPECT_FALSE(server_stream()->encryption_established());
207 EXPECT_FALSE(server_stream()->handshake_confirmed());
209 // Check the client state to make sure that it received a server-designated
210 // connection id.
211 QuicCryptoClientConfig::CachedState* client_state =
212 client_crypto_config_.LookupOrCreate(server_id_);
214 ASSERT_TRUE(client_state->has_server_nonce());
215 ASSERT_FALSE(client_state->GetNextServerNonce().empty());
216 ASSERT_FALSE(client_state->has_server_nonce());
218 ASSERT_TRUE(client_state->has_server_designated_connection_id());
219 const QuicConnectionId server_designated_connection_id =
220 client_state->GetNextServerDesignatedConnectionId();
221 const QuicConnectionId expected_id =
222 reinterpret_cast<MockRandom*>(server_connection_->random_generator())
223 ->RandUint64();
224 EXPECT_EQ(expected_id, server_designated_connection_id);
225 EXPECT_FALSE(client_state->has_server_designated_connection_id());
226 ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
229 TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
230 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stateless_reject_support,
231 true);
232 server_stream()->set_use_stateless_rejects_if_peer_supported(true);
234 InitializeFakeClient(/* supports_stateless_rejects= */ true);
235 AdvanceHandshakeWithFakeClient();
237 // On the first round, encryption will not be established.
238 EXPECT_FALSE(server_stream()->encryption_established());
239 EXPECT_FALSE(server_stream()->handshake_confirmed());
240 EXPECT_EQ(1, server_stream()->num_handshake_messages());
241 EXPECT_EQ(0, server_stream()->num_handshake_messages_with_server_nonces());
243 // Now check the client state.
244 QuicCryptoClientConfig::CachedState* client_state =
245 client_crypto_config_.LookupOrCreate(server_id_);
247 ASSERT_TRUE(client_state->has_server_designated_connection_id());
248 const QuicConnectionId server_designated_connection_id =
249 client_state->GetNextServerDesignatedConnectionId();
250 const QuicConnectionId expected_id =
251 reinterpret_cast<MockRandom*>(server_connection_->random_generator())
252 ->RandUint64();
253 EXPECT_EQ(expected_id, server_designated_connection_id);
254 EXPECT_FALSE(client_state->has_server_designated_connection_id());
255 ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
257 // Now create new client and server streams with the existing config
258 // and try the handshake again (0-RTT handshake).
259 InitializeServer();
260 server_stream()->set_use_stateless_rejects_if_peer_supported(true);
262 InitializeFakeClient(/* supports_stateless_rejects= */ true);
264 client_stream()->CryptoConnect();
266 // In the stateless case, the second handshake contains a server-nonce, so the
267 // AsyncStrikeRegisterVerification() case will still succeed (unlike a 0-RTT
268 // handshake).
269 AdvanceHandshakeWithFakeClient();
271 // On the second round, encryption will be established.
272 EXPECT_TRUE(server_stream()->encryption_established());
273 EXPECT_TRUE(server_stream()->handshake_confirmed());
274 EXPECT_EQ(2, server_stream()->num_handshake_messages());
275 EXPECT_EQ(1, server_stream()->num_handshake_messages_with_server_nonces());
278 TEST_P(QuicCryptoServerStreamTest, NoStatelessRejectIfNoClientSupport) {
279 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stateless_reject_support,
280 true);
281 server_stream()->set_use_stateless_rejects_if_peer_supported(true);
283 // The server is configured to use stateless rejects, but the client does not
284 // support it.
285 InitializeFakeClient(/* supports_stateless_rejects= */ false);
286 AdvanceHandshakeWithFakeClient();
288 // Check the server to make the sure the handshake did not succeed.
289 EXPECT_FALSE(server_stream()->encryption_established());
290 EXPECT_FALSE(server_stream()->handshake_confirmed());
292 // Check the client state to make sure that it did not receive a
293 // server-designated connection id.
294 QuicCryptoClientConfig::CachedState* client_state =
295 client_crypto_config_.LookupOrCreate(server_id_);
297 ASSERT_FALSE(client_state->has_server_designated_connection_id());
298 ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
301 TEST_P(QuicCryptoServerStreamTest, ZeroRTT) {
302 InitializeFakeClient(/* supports_stateless_rejects= */ false);
304 // Do a first handshake in order to prime the client config with the server's
305 // information.
306 AdvanceHandshakeWithFakeClient();
308 // Now do another handshake, hopefully in 0-RTT.
309 DVLOG(1) << "Resetting for 0-RTT handshake attempt";
310 InitializeFakeClient(/* supports_stateless_rejects= */ false);
311 InitializeServer();
313 client_stream()->CryptoConnect();
315 if (AsyncStrikeRegisterVerification()) {
316 EXPECT_FALSE(client_stream()->handshake_confirmed());
317 EXPECT_FALSE(server_stream()->handshake_confirmed());
319 // Advance the handshake. Expect that the server will be stuck waiting for
320 // client nonce verification to complete.
321 pair<size_t, size_t> messages_moved = CryptoTestUtils::AdvanceHandshake(
322 client_connection_, client_stream(), 0, server_connection_,
323 server_stream(), 0);
324 EXPECT_EQ(1u, messages_moved.first);
325 EXPECT_EQ(0u, messages_moved.second);
326 EXPECT_EQ(1, strike_register_client_->PendingVerifications());
327 EXPECT_FALSE(client_stream()->handshake_confirmed());
328 EXPECT_FALSE(server_stream()->handshake_confirmed());
330 // The server handshake completes once the nonce verification completes.
331 strike_register_client_->RunPendingVerifications();
332 EXPECT_FALSE(client_stream()->handshake_confirmed());
333 EXPECT_TRUE(server_stream()->handshake_confirmed());
335 messages_moved = CryptoTestUtils::AdvanceHandshake(
336 client_connection_, client_stream(), messages_moved.first,
337 server_connection_, server_stream(), messages_moved.second);
338 EXPECT_EQ(1u, messages_moved.first);
339 EXPECT_EQ(1u, messages_moved.second);
340 EXPECT_TRUE(client_stream()->handshake_confirmed());
341 EXPECT_TRUE(server_stream()->handshake_confirmed());
342 } else {
343 CryptoTestUtils::CommunicateHandshakeMessages(
344 client_connection_, client_stream(), server_connection_,
345 server_stream());
348 EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
351 TEST_P(QuicCryptoServerStreamTest, MessageAfterHandshake) {
352 CompleteCryptoHandshake();
353 EXPECT_CALL(
354 *server_connection_,
355 SendConnectionClose(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE));
356 message_.set_tag(kCHLO);
357 ConstructHandshakeMessage();
358 server_stream()->OnStreamFrame(
359 QuicStreamFrame(kCryptoStreamId, /*fin=*/false, /*offset=*/0,
360 message_data_->AsStringPiece()));
363 TEST_P(QuicCryptoServerStreamTest, BadMessageType) {
364 message_.set_tag(kSHLO);
365 ConstructHandshakeMessage();
366 EXPECT_CALL(*server_connection_,
367 SendConnectionClose(QUIC_INVALID_CRYPTO_MESSAGE_TYPE));
368 server_stream()->OnStreamFrame(
369 QuicStreamFrame(kCryptoStreamId, /*fin=*/false, /*offset=*/0,
370 message_data_->AsStringPiece()));
373 TEST_P(QuicCryptoServerStreamTest, WithoutCertificates) {
374 server_crypto_config_.SetProofSource(nullptr);
375 client_options_.dont_verify_certs = true;
377 // Only 2 client hellos need to be sent in the no-certs case: one to get the
378 // source-address token and the second to finish.
379 EXPECT_EQ(2, CompleteCryptoHandshake());
380 EXPECT_TRUE(server_stream()->encryption_established());
381 EXPECT_TRUE(server_stream()->handshake_confirmed());
384 TEST_P(QuicCryptoServerStreamTest, ChannelID) {
385 client_options_.channel_id_enabled = true;
386 client_options_.channel_id_source_async = false;
387 // CompleteCryptoHandshake verifies
388 // server_stream()->crypto_negotiated_params().channel_id is correct.
389 EXPECT_EQ(2, CompleteCryptoHandshake());
390 EXPECT_TRUE(server_stream()->encryption_established());
391 EXPECT_TRUE(server_stream()->handshake_confirmed());
394 TEST_P(QuicCryptoServerStreamTest, ChannelIDAsync) {
395 client_options_.channel_id_enabled = true;
396 client_options_.channel_id_source_async = true;
397 // CompleteCryptoHandshake verifies
398 // server_stream()->crypto_negotiated_params().channel_id is correct.
399 EXPECT_EQ(2, CompleteCryptoHandshake());
400 EXPECT_TRUE(server_stream()->encryption_established());
401 EXPECT_TRUE(server_stream()->handshake_confirmed());
404 TEST_P(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) {
405 // An attempt to send a SCUP before completing handshake should fail.
406 server_stream()->SendServerConfigUpdate(nullptr);
407 EXPECT_EQ(0, server_stream()->num_server_config_update_messages_sent());
410 TEST_P(QuicCryptoServerStreamTest, DoesPeerSupportStatelessRejects) {
411 ConstructHandshakeMessage();
412 QuicConfig stateless_reject_config = DefaultQuicConfigStatelessRejects();
413 stateless_reject_config.ToHandshakeMessage(&message_);
414 EXPECT_TRUE(
415 QuicCryptoServerStreamPeer::DoesPeerSupportStatelessRejects(message_));
417 message_.Clear();
418 QuicConfig stateful_reject_config = DefaultQuicConfig();
419 stateful_reject_config.ToHandshakeMessage(&message_);
420 EXPECT_FALSE(
421 QuicCryptoServerStreamPeer::DoesPeerSupportStatelessRejects(message_));
424 } // namespace
425 } // namespace test
426 } // namespace net