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"
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_protocol.h"
22 #include "net/quic/quic_session.h"
23 #include "net/quic/test_tools/crypto_test_utils.h"
24 #include "net/quic/test_tools/delayed_verify_strike_register_client.h"
25 #include "net/quic/test_tools/quic_test_utils.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
31 class ReliableQuicStream
;
40 class QuicCryptoServerConfigPeer
{
42 static string
GetPrimaryOrbit(const QuicCryptoServerConfig
& config
) {
43 base::AutoLock
lock(config
.configs_lock_
);
44 CHECK(config
.primary_config_
!= NULL
);
45 return string(reinterpret_cast<const char*>(config
.primary_config_
->orbit
),
52 class QuicCryptoServerStreamTest
: public testing::TestWithParam
<bool> {
54 QuicCryptoServerStreamTest()
55 : connection_(new PacketSavingConnection(true)),
56 session_(connection_
, DefaultQuicConfig()),
57 crypto_config_(QuicCryptoServerConfig::TESTING
,
58 QuicRandom::GetInstance()),
59 stream_(crypto_config_
, &session_
),
60 strike_register_client_(NULL
) {
61 config_
.SetDefaults();
62 session_
.config()->SetDefaults();
63 session_
.SetCryptoStream(&stream_
);
64 // We advance the clock initially because the default time is zero and the
65 // strike register worries that we've just overflowed a uint32 time.
66 connection_
->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
67 // TODO(rtenneti): Enable testing of ProofSource.
68 // crypto_config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting());
69 crypto_config_
.set_strike_register_no_startup_period();
71 CryptoTestUtils::SetupCryptoServerConfigForTest(
72 connection_
->clock(), connection_
->random_generator(),
73 session_
.config(), &crypto_config_
);
75 if (AsyncStrikeRegisterVerification()) {
77 QuicCryptoServerConfigPeer::GetPrimaryOrbit(crypto_config_
);
78 strike_register_client_
= new DelayedVerifyStrikeRegisterClient(
79 10000, // strike_register_max_entries
80 static_cast<uint32
>(connection_
->clock()->WallNow().ToUNIXSeconds()),
81 60, // strike_register_window_secs
82 reinterpret_cast<const uint8
*>(orbit
.data()),
83 StrikeRegister::NO_STARTUP_PERIOD_NEEDED
);
84 strike_register_client_
->StartDelayingVerification();
85 crypto_config_
.SetStrikeRegisterClient(strike_register_client_
);
89 bool AsyncStrikeRegisterVerification() {
93 void ConstructHandshakeMessage() {
95 message_data_
.reset(framer
.ConstructHandshakeMessage(message_
));
98 int CompleteCryptoHandshake() {
99 return CryptoTestUtils::HandshakeWithFakeClient(connection_
, &stream_
,
104 PacketSavingConnection
* connection_
;
105 TestSession session_
;
107 QuicCryptoServerConfig crypto_config_
;
108 QuicCryptoServerStream stream_
;
109 CryptoHandshakeMessage message_
;
110 scoped_ptr
<QuicData
> message_data_
;
111 CryptoTestUtils::FakeClientOptions client_options_
;
112 DelayedVerifyStrikeRegisterClient
* strike_register_client_
;
115 INSTANTIATE_TEST_CASE_P(Tests
, QuicCryptoServerStreamTest
, testing::Bool());
117 TEST_P(QuicCryptoServerStreamTest
, NotInitiallyConected
) {
118 EXPECT_FALSE(stream_
.encryption_established());
119 EXPECT_FALSE(stream_
.handshake_confirmed());
122 TEST_P(QuicCryptoServerStreamTest
, ConnectedAfterCHLO
) {
123 // CompleteCryptoHandshake returns the number of client hellos sent. This
125 // * One to get a source-address token and certificates.
126 // * One to complete the handshake.
127 EXPECT_EQ(2, CompleteCryptoHandshake());
128 EXPECT_TRUE(stream_
.encryption_established());
129 EXPECT_TRUE(stream_
.handshake_confirmed());
132 TEST_P(QuicCryptoServerStreamTest
, ZeroRTT
) {
133 PacketSavingConnection
* client_conn
= new PacketSavingConnection(false);
134 PacketSavingConnection
* server_conn
= new PacketSavingConnection(false);
135 client_conn
->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
136 server_conn
->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
138 QuicConfig client_config
;
139 client_config
.SetDefaults();
140 scoped_ptr
<TestSession
> client_session(
141 new TestSession(client_conn
, client_config
));
142 QuicCryptoClientConfig client_crypto_config
;
143 client_crypto_config
.SetDefaults();
145 scoped_ptr
<QuicCryptoClientStream
> client(new QuicCryptoClientStream(
146 "test.example.com", client_session
.get(), &client_crypto_config
));
147 client_session
->SetCryptoStream(client
.get());
149 // Do a first handshake in order to prime the client config with the server's
151 CHECK(client
->CryptoConnect());
152 CHECK_EQ(1u, client_conn
->packets_
.size());
154 scoped_ptr
<TestSession
> server_session(new TestSession(server_conn
, config_
));
155 scoped_ptr
<QuicCryptoServerStream
> server(
156 new QuicCryptoServerStream(crypto_config_
, server_session
.get()));
157 server_session
->SetCryptoStream(server
.get());
159 CryptoTestUtils::CommunicateHandshakeMessages(
160 client_conn
, client
.get(), server_conn
, server
.get());
161 EXPECT_EQ(2, client
->num_sent_client_hellos());
163 // Now do another handshake, hopefully in 0-RTT.
164 LOG(INFO
) << "Resetting for 0-RTT handshake attempt";
166 client_conn
= new PacketSavingConnection(false);
167 server_conn
= new PacketSavingConnection(false);
168 // We need to advance time past the strike-server window so that it's
169 // authoritative in this time span.
170 client_conn
->AdvanceTime(QuicTime::Delta::FromSeconds(102000));
171 server_conn
->AdvanceTime(QuicTime::Delta::FromSeconds(102000));
173 // This causes the client's nonce to be different and thus stops the
174 // strike-register from rejecting the repeated nonce.
175 reinterpret_cast<MockRandom
*>(client_conn
->random_generator())->ChangeValue();
176 client_session
.reset(new TestSession(client_conn
, client_config
));
177 server_session
.reset(new TestSession(server_conn
, config_
));
178 client
.reset(new QuicCryptoClientStream(
179 "test.example.com", client_session
.get(), &client_crypto_config
));
180 client_session
->SetCryptoStream(client
.get());
182 server
.reset(new QuicCryptoServerStream(crypto_config_
,
183 server_session
.get()));
184 server_session
->SetCryptoStream(server
.get());
186 CHECK(client
->CryptoConnect());
188 if (AsyncStrikeRegisterVerification()) {
189 EXPECT_FALSE(client
->handshake_confirmed());
190 EXPECT_FALSE(server
->handshake_confirmed());
192 // Advance the handshake. Expect that the server will be stuck
193 // waiting for client nonce verification to complete.
194 pair
<size_t, size_t> messages_moved
= CryptoTestUtils::AdvanceHandshake(
195 client_conn
, client
.get(), 0, server_conn
, server
.get(), 0);
196 EXPECT_EQ(1u, messages_moved
.first
);
197 EXPECT_EQ(0u, messages_moved
.second
);
198 EXPECT_EQ(1, strike_register_client_
->PendingVerifications());
199 EXPECT_FALSE(client
->handshake_confirmed());
200 EXPECT_FALSE(server
->handshake_confirmed());
202 // The server handshake completes once the nonce verification completes.
203 strike_register_client_
->RunPendingVerifications();
204 EXPECT_FALSE(client
->handshake_confirmed());
205 EXPECT_TRUE(server
->handshake_confirmed());
207 messages_moved
= CryptoTestUtils::AdvanceHandshake(
208 client_conn
, client
.get(), messages_moved
.first
,
209 server_conn
, server
.get(), messages_moved
.second
);
210 EXPECT_EQ(1u, messages_moved
.first
);
211 EXPECT_EQ(1u, messages_moved
.second
);
212 EXPECT_TRUE(client
->handshake_confirmed());
213 EXPECT_TRUE(server
->handshake_confirmed());
215 CryptoTestUtils::CommunicateHandshakeMessages(
216 client_conn
, client
.get(), server_conn
, server
.get());
219 EXPECT_EQ(1, client
->num_sent_client_hellos());
222 TEST_P(QuicCryptoServerStreamTest
, MessageAfterHandshake
) {
223 CompleteCryptoHandshake();
224 EXPECT_CALL(*connection_
, SendConnectionClose(
225 QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE
));
226 message_
.set_tag(kCHLO
);
227 ConstructHandshakeMessage();
228 stream_
.ProcessRawData(message_data_
->data(), message_data_
->length());
231 TEST_P(QuicCryptoServerStreamTest
, BadMessageType
) {
232 message_
.set_tag(kSHLO
);
233 ConstructHandshakeMessage();
234 EXPECT_CALL(*connection_
, SendConnectionClose(
235 QUIC_INVALID_CRYPTO_MESSAGE_TYPE
));
236 stream_
.ProcessRawData(message_data_
->data(), message_data_
->length());
239 TEST_P(QuicCryptoServerStreamTest
, WithoutCertificates
) {
240 crypto_config_
.SetProofSource(NULL
);
241 client_options_
.dont_verify_certs
= true;
243 // Only 2 client hellos need to be sent in the no-certs case: one to get the
244 // source-address token and the second to finish.
245 EXPECT_EQ(2, CompleteCryptoHandshake());
246 EXPECT_TRUE(stream_
.encryption_established());
247 EXPECT_TRUE(stream_
.handshake_confirmed());
250 TEST_P(QuicCryptoServerStreamTest
, ChannelID
) {
251 client_options_
.channel_id_enabled
= true;
252 // TODO(rtenneti): Enable testing of ProofVerifier.
253 // CompleteCryptoHandshake verifies
254 // stream_.crypto_negotiated_params().channel_id is correct.
255 EXPECT_EQ(2, CompleteCryptoHandshake());
256 EXPECT_TRUE(stream_
.encryption_established());
257 EXPECT_TRUE(stream_
.handshake_confirmed());