Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: net/quic/quic_crypto_client_stream_test.cc

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/quic/quic_crypto_client_stream.h"
6
7 #include <memory>
8
9 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
10 #include "net/quic/crypto/quic_decrypter.h"
11 #include "net/quic/crypto/quic_encrypter.h"
12 #include "net/quic/quic_flags.h"
13 #include "net/quic/quic_protocol.h"
14 #include "net/quic/quic_server_id.h"
15 #include "net/quic/quic_utils.h"
16 #include "net/quic/test_tools/crypto_test_utils.h"
17 #include "net/quic/test_tools/quic_test_utils.h"
18 #include "net/quic/test_tools/simple_quic_framer.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using std::string;
23 using std::vector;
24
25 using testing::_;
26
27 namespace net {
28 namespace test {
29 namespace {
30
31 const char kServerHostname[] = "test.example.com";
32 const uint16_t kServerPort = 443;
33
34 class QuicCryptoClientStreamTest : public ::testing::Test {
35 public:
36 QuicCryptoClientStreamTest()
37 : server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
38 crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) {
39 CreateConnection();
40 }
41
42 void CreateConnection() {
43 connection_ = new PacketSavingConnection(&helper_, &alarm_factory_,
44 Perspective::IS_CLIENT);
45 // Advance the time, because timers do not like uninitialized times.
46 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
47
48 session_.reset(new TestQuicSpdyClientSession(
49 connection_, DefaultQuicConfig(), server_id_, &crypto_config_));
50 }
51
52 void CompleteCryptoHandshake() {
53 stream()->CryptoConnect();
54 QuicConfig config;
55 CryptoTestUtils::HandshakeWithFakeServer(&config, &helper_, &alarm_factory_,
56 connection_, stream(),
57 server_options_);
58 }
59
60 void ConstructHandshakeMessage() {
61 CryptoFramer framer;
62 message_data_.reset(framer.ConstructHandshakeMessage(message_));
63 }
64
65 QuicCryptoClientStream* stream() { return session_->GetCryptoStream(); }
66
67 MockQuicConnectionHelper helper_;
68 MockAlarmFactory alarm_factory_;
69 PacketSavingConnection* connection_;
70 std::unique_ptr<TestQuicSpdyClientSession> session_;
71 QuicServerId server_id_;
72 CryptoHandshakeMessage message_;
73 std::unique_ptr<QuicData> message_data_;
74 QuicCryptoClientConfig crypto_config_;
75 CryptoTestUtils::FakeServerOptions server_options_;
76 };
77
78 TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
79 EXPECT_FALSE(stream()->encryption_established());
80 EXPECT_FALSE(stream()->handshake_confirmed());
81 }
82
83 TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
84 CompleteCryptoHandshake();
85 EXPECT_TRUE(stream()->encryption_established());
86 EXPECT_TRUE(stream()->handshake_confirmed());
87 }
88
89 TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
90 CompleteCryptoHandshake();
91
92 EXPECT_CALL(
93 *connection_,
94 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
95 message_.set_tag(kCHLO);
96 ConstructHandshakeMessage();
97 stream()->OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false,
98 /*offset=*/0,
99 message_data_->AsStringPiece()));
100 }
101
102 TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
103 stream()->CryptoConnect();
104
105 message_.set_tag(kCHLO);
106 ConstructHandshakeMessage();
107
108 EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
109 "Expected REJ", _));
110 stream()->OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false,
111 /*offset=*/0,
112 message_data_->AsStringPiece()));
113 }
114
115 TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
116 CompleteCryptoHandshake();
117
118 const QuicConfig* config = session_->config();
119 EXPECT_EQ(kMaximumIdleTimeoutSecs,
120 config->IdleConnectionStateLifetime().ToSeconds());
121 EXPECT_EQ(kDefaultMaxStreamsPerConnection, config->MaxStreamsPerConnection());
122
123 const QuicCryptoNegotiatedParameters& crypto_params(
124 stream()->crypto_negotiated_params());
125 EXPECT_EQ(crypto_config_.aead[0], crypto_params.aead);
126 EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
127 }
128
129 TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
130 // Seed the config with a cached server config.
131 CompleteCryptoHandshake();
132
133 // Recreate connection with the new config.
134 CreateConnection();
135
136 // Advance time 5 years to ensure that we pass the expiry time of the cached
137 // server config.
138 connection_->AdvanceTime(
139 QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
140
141 stream()->CryptoConnect();
142 // Check that a client hello was sent.
143 ASSERT_EQ(1u, connection_->encrypted_packets_.size());
144 }
145
146 TEST_F(QuicCryptoClientStreamTest, InvalidCachedServerConfig) {
147 // Seed the config with a cached server config.
148 CompleteCryptoHandshake();
149
150 // Recreate connection with the new config.
151 CreateConnection();
152
153 QuicCryptoClientConfig::CachedState* state =
154 crypto_config_.LookupOrCreate(server_id_);
155
156 vector<string> certs = state->certs();
157 string cert_sct = state->cert_sct();
158 string signature = state->signature();
159 string chlo_hash = state->chlo_hash();
160 state->SetProof(certs, cert_sct, chlo_hash, signature + signature);
161
162 stream()->CryptoConnect();
163 // Check that a client hello was sent.
164 ASSERT_EQ(1u, connection_->encrypted_packets_.size());
165 }
166
167 TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
168 // Test that the crypto client stream can receive server config updates after
169 // the connection has been established.
170 CompleteCryptoHandshake();
171
172 QuicCryptoClientConfig::CachedState* state =
173 crypto_config_.LookupOrCreate(server_id_);
174
175 // Ensure cached STK is different to what we send in the handshake.
176 EXPECT_NE("xstk", state->source_address_token());
177
178 // Initialize using {...} syntax to avoid trailing \0 if converting from
179 // string.
180 unsigned char stk[] = {'x', 's', 't', 'k'};
181
182 // Minimum SCFG that passes config validation checks.
183 unsigned char scfg[] = {// SCFG
184 0x53, 0x43, 0x46, 0x47,
185 // num entries
186 0x01, 0x00,
187 // padding
188 0x00, 0x00,
189 // EXPY
190 0x45, 0x58, 0x50, 0x59,
191 // EXPY end offset
192 0x08, 0x00, 0x00, 0x00,
193 // Value
194 '1', '2', '3', '4', '5', '6', '7', '8'};
195
196 CryptoHandshakeMessage server_config_update;
197 server_config_update.set_tag(kSCUP);
198 server_config_update.SetValue(kSourceAddressTokenTag, stk);
199 server_config_update.SetValue(kSCFG, scfg);
200
201 std::unique_ptr<QuicData> data(
202 CryptoFramer::ConstructHandshakeMessage(server_config_update));
203 stream()->OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false,
204 /*offset=*/0, data->AsStringPiece()));
205
206 // Make sure that the STK and SCFG are cached correctly.
207 EXPECT_EQ("xstk", state->source_address_token());
208
209 string cached_scfg = state->server_config();
210 test::CompareCharArraysWithHexError(
211 "scfg", cached_scfg.data(), cached_scfg.length(),
212 QuicUtils::AsChars(scfg), arraysize(scfg));
213 }
214
215 TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
216 EXPECT_CALL(
217 *connection_,
218 CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, _, _));
219 CryptoHandshakeMessage server_config_update;
220 server_config_update.set_tag(kSCUP);
221 std::unique_ptr<QuicData> data(
222 CryptoFramer::ConstructHandshakeMessage(server_config_update));
223 stream()->OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false,
224 /*offset=*/0, data->AsStringPiece()));
225 }
226
227 TEST_F(QuicCryptoClientStreamTest, TokenBindingNegotiation) {
228 server_options_.token_binding_enabled = true;
229 crypto_config_.tb_key_params.push_back(kP256);
230
231 CompleteCryptoHandshake();
232 EXPECT_TRUE(stream()->encryption_established());
233 EXPECT_TRUE(stream()->handshake_confirmed());
234 EXPECT_EQ(kP256,
235 stream()->crypto_negotiated_params().token_binding_key_param);
236 }
237
238 TEST_F(QuicCryptoClientStreamTest, NoTokenBindingWithoutServerSupport) {
239 crypto_config_.tb_key_params.push_back(kP256);
240
241 CompleteCryptoHandshake();
242 EXPECT_TRUE(stream()->encryption_established());
243 EXPECT_TRUE(stream()->handshake_confirmed());
244 EXPECT_EQ(0u, stream()->crypto_negotiated_params().token_binding_key_param);
245 }
246
247 TEST_F(QuicCryptoClientStreamTest, NoTokenBindingWithoutClientSupport) {
248 server_options_.token_binding_enabled = true;
249
250 CompleteCryptoHandshake();
251 EXPECT_TRUE(stream()->encryption_established());
252 EXPECT_TRUE(stream()->handshake_confirmed());
253 EXPECT_EQ(0u, stream()->crypto_negotiated_params().token_binding_key_param);
254 }
255
256 TEST_F(QuicCryptoClientStreamTest, TokenBindingNotNegotiated) {
257 CompleteCryptoHandshake();
258 EXPECT_TRUE(stream()->encryption_established());
259 EXPECT_TRUE(stream()->handshake_confirmed());
260 EXPECT_EQ(0u, stream()->crypto_negotiated_params().token_binding_key_param);
261 }
262
263 class QuicCryptoClientStreamStatelessTest : public ::testing::Test {
264 public:
265 QuicCryptoClientStreamStatelessTest()
266 : client_crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
267 server_crypto_config_(QuicCryptoServerConfig::TESTING,
268 QuicRandom::GetInstance(),
269 CryptoTestUtils::ProofSourceForTesting()),
270 server_compressed_certs_cache_(
271 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
272 server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED) {
273 TestQuicSpdyClientSession* client_session = nullptr;
274 CreateClientSessionForTest(server_id_,
275 /* supports_stateless_rejects= */ true,
276 QuicTime::Delta::FromSeconds(100000),
277 QuicSupportedVersions(), &helper_,
278 &alarm_factory_, &client_crypto_config_,
279 &client_connection_, &client_session);
280 CHECK(client_session);
281 client_session_.reset(client_session);
282 }
283
284 QuicCryptoServerStream* server_stream() {
285 return server_session_->GetCryptoStream();
286 }
287
288 void AdvanceHandshakeWithFakeServer() {
289 client_session_->GetCryptoStream()->CryptoConnect();
290 CryptoTestUtils::AdvanceHandshake(client_connection_,
291 client_session_->GetCryptoStream(), 0,
292 server_connection_, server_stream(), 0);
293 }
294
295 // Initializes the server_stream_ for stateless rejects.
296 void InitializeFakeStatelessRejectServer() {
297 TestQuicSpdyServerSession* server_session = nullptr;
298 CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000),
299 QuicSupportedVersions(), &helper_,
300 &alarm_factory_, &server_crypto_config_,
301 &server_compressed_certs_cache_,
302 &server_connection_, &server_session);
303 CHECK(server_session);
304 server_session_.reset(server_session);
305 CryptoTestUtils::FakeServerOptions options;
306 CryptoTestUtils::SetupCryptoServerConfigForTest(
307 server_connection_->clock(), server_connection_->random_generator(),
308 server_session_->config(), &server_crypto_config_, options);
309 FLAGS_enable_quic_stateless_reject_support = true;
310 }
311
312 MockQuicConnectionHelper helper_;
313 MockAlarmFactory alarm_factory_;
314
315 // Client crypto stream state
316 PacketSavingConnection* client_connection_;
317 std::unique_ptr<TestQuicSpdyClientSession> client_session_;
318 QuicCryptoClientConfig client_crypto_config_;
319
320 // Server crypto stream state
321 PacketSavingConnection* server_connection_;
322 std::unique_ptr<TestQuicSpdyServerSession> server_session_;
323 QuicCryptoServerConfig server_crypto_config_;
324 QuicCompressedCertsCache server_compressed_certs_cache_;
325 QuicServerId server_id_;
326 };
327
328 TEST_F(QuicCryptoClientStreamStatelessTest, StatelessReject) {
329 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stateless_reject_support,
330 true);
331
332 QuicCryptoClientConfig::CachedState* client_state =
333 client_crypto_config_.LookupOrCreate(server_id_);
334
335 EXPECT_FALSE(client_state->has_server_designated_connection_id());
336 EXPECT_CALL(*client_session_, OnProofValid(testing::_));
337
338 InitializeFakeStatelessRejectServer();
339 AdvanceHandshakeWithFakeServer();
340
341 EXPECT_EQ(1, server_stream()->NumHandshakeMessages());
342 EXPECT_EQ(0, server_stream()->NumHandshakeMessagesWithServerNonces());
343
344 EXPECT_FALSE(client_session_->GetCryptoStream()->encryption_established());
345 EXPECT_FALSE(client_session_->GetCryptoStream()->handshake_confirmed());
346 // Even though the handshake was not complete, the cached client_state is
347 // complete, and can be used for a subsequent successful handshake.
348 EXPECT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
349
350 ASSERT_TRUE(client_state->has_server_nonce());
351 ASSERT_FALSE(client_state->GetNextServerNonce().empty());
352 ASSERT_TRUE(client_state->has_server_designated_connection_id());
353 QuicConnectionId server_designated_id =
354 client_state->GetNextServerDesignatedConnectionId();
355 QuicConnectionId expected_id =
356 server_session_->connection()->random_generator()->RandUint64();
357 EXPECT_EQ(expected_id, server_designated_id);
358 EXPECT_FALSE(client_state->has_server_designated_connection_id());
359 }
360
361 } // namespace
362 } // namespace test
363 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_crypto_client_stream_factory.cc ('k') | net/quic/quic_crypto_framer_parse_message_fuzzer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698