blob: 058157ebc957c6afb644a8cfb8fb9ae20526b351 [file] [log] [blame]
[email protected]ed3fc15d2013-03-08 18:37:441// 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/test_tools/crypto_test_utils.h"
[email protected]72818ea2013-03-13 03:23:576
[email protected]c244c5a12013-05-07 20:55:047#include "net/quic/crypto/common_cert_set.h"
[email protected]ef95114d2013-04-17 17:57:018#include "net/quic/crypto/crypto_handshake.h"
[email protected]fe053f92013-04-23 20:18:559#include "net/quic/crypto/crypto_server_config.h"
[email protected]14e8106c2013-03-14 16:25:3310#include "net/quic/crypto/quic_decrypter.h"
11#include "net/quic/crypto/quic_encrypter.h"
[email protected]ef95114d2013-04-17 17:57:0112#include "net/quic/crypto/quic_random.h"
13#include "net/quic/quic_clock.h"
[email protected]ed3fc15d2013-03-08 18:37:4414#include "net/quic/quic_crypto_client_stream.h"
15#include "net/quic/quic_crypto_server_stream.h"
16#include "net/quic/quic_crypto_stream.h"
[email protected]2532de12013-05-09 12:29:3317#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]ed3fc15d2013-03-08 18:37:4418#include "net/quic/test_tools/quic_test_utils.h"
19#include "net/quic/test_tools/simple_quic_framer.h"
[email protected]ed3fc15d2013-03-08 18:37:4420
[email protected]14e8106c2013-03-14 16:25:3321using base::StringPiece;
[email protected]ccc66e8a2013-03-26 08:26:1422using std::string;
[email protected]fe053f92013-04-23 20:18:5523using std::vector;
[email protected]14e8106c2013-03-14 16:25:3324
[email protected]ed3fc15d2013-03-08 18:37:4425namespace net {
26namespace test {
27
28namespace {
29
[email protected]fe053f92013-04-23 20:18:5530// CryptoFramerVisitor is a framer visitor that records handshake messages.
31class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
32 public:
33 CryptoFramerVisitor()
34 : error_(false) {
35 }
[email protected]ed3fc15d2013-03-08 18:37:4436
[email protected]42091902013-05-02 02:24:1237 virtual void OnError(CryptoFramer* framer) OVERRIDE {
[email protected]fe053f92013-04-23 20:18:5538 error_ = true;
39 }
[email protected]ed3fc15d2013-03-08 18:37:4440
[email protected]42091902013-05-02 02:24:1241 virtual void OnHandshakeMessage(
42 const CryptoHandshakeMessage& message) OVERRIDE {
[email protected]fe053f92013-04-23 20:18:5543 messages_.push_back(message);
44 }
[email protected]ed3fc15d2013-03-08 18:37:4445
[email protected]fe053f92013-04-23 20:18:5546 bool error() const {
47 return error_;
48 }
[email protected]ed3fc15d2013-03-08 18:37:4449
[email protected]fe053f92013-04-23 20:18:5550 const vector<CryptoHandshakeMessage>& messages() const {
51 return messages_;
52 }
[email protected]ed3fc15d2013-03-08 18:37:4453
[email protected]fe053f92013-04-23 20:18:5554 private:
55 bool error_;
56 vector<CryptoHandshakeMessage> messages_;
57};
58
59// MovePackets parses crypto handshake messages from packet number
60// |*inout_packet_index| through to the last packet and has |dest_stream|
61// process them. |*inout_packet_index| is updated with an index one greater
62// than the last packet processed.
63void MovePackets(PacketSavingConnection* source_conn,
64 size_t *inout_packet_index,
[email protected]2532de12013-05-09 12:29:3365 QuicCryptoStream* dest_stream,
66 PacketSavingConnection* dest_conn) {
[email protected]fe053f92013-04-23 20:18:5567 SimpleQuicFramer framer;
68 CryptoFramer crypto_framer;
69 CryptoFramerVisitor crypto_visitor;
70
[email protected]2532de12013-05-09 12:29:3371 // In order to properly test the code we need to perform encryption and
72 // decryption so that the crypters latch when expected. The crypters are in
73 // |dest_conn|, but we don't want to try and use them there. Instead we swap
74 // them into |framer|, perform the decryption with them, and then swap them
75 // back.
76 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
77
[email protected]fe053f92013-04-23 20:18:5578 crypto_framer.set_visitor(&crypto_visitor);
79
80 size_t index = *inout_packet_index;
[email protected]2532de12013-05-09 12:29:3381 for (; index < source_conn->encrypted_packets_.size(); index++) {
82 ASSERT_TRUE(framer.ProcessPacket(*source_conn->encrypted_packets_[index]));
[email protected]fe053f92013-04-23 20:18:5583 for (vector<QuicStreamFrame>::const_iterator
84 i = framer.stream_frames().begin();
85 i != framer.stream_frames().end(); ++i) {
86 ASSERT_TRUE(crypto_framer.ProcessInput(i->data));
87 ASSERT_FALSE(crypto_visitor.error());
88 }
89 }
90 *inout_packet_index = index;
91
[email protected]2532de12013-05-09 12:29:3392 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
93
[email protected]fe053f92013-04-23 20:18:5594 ASSERT_EQ(0u, crypto_framer.InputBytesRemaining());
95
96 for (vector<CryptoHandshakeMessage>::const_iterator
97 i = crypto_visitor.messages().begin();
98 i != crypto_visitor.messages().end(); ++i) {
99 dest_stream->OnHandshakeMessage(*i);
[email protected]ed3fc15d2013-03-08 18:37:44100 }
101}
102
103} // anonymous namespace
104
105// static
[email protected]fe053f92013-04-23 20:18:55106void CryptoTestUtils::CommunicateHandshakeMessages(
107 PacketSavingConnection* a_conn,
108 QuicCryptoStream* a,
109 PacketSavingConnection* b_conn,
110 QuicCryptoStream* b) {
111 size_t a_i = 0, b_i = 0;
[email protected]8ba81212013-05-03 13:11:48112 while (!a->handshake_confirmed()) {
[email protected]fe053f92013-04-23 20:18:55113 ASSERT_GT(a_conn->packets_.size(), a_i);
114 LOG(INFO) << "Processing " << a_conn->packets_.size() - a_i
115 << " packets a->b";
[email protected]2532de12013-05-09 12:29:33116 MovePackets(a_conn, &a_i, b, b_conn);
[email protected]fe053f92013-04-23 20:18:55117
118 ASSERT_GT(b_conn->packets_.size(), b_i);
119 LOG(INFO) << "Processing " << b_conn->packets_.size() - b_i
120 << " packets b->a";
121 if (b_conn->packets_.size() - b_i == 2) {
122 LOG(INFO) << "here";
123 }
[email protected]2532de12013-05-09 12:29:33124 MovePackets(b_conn, &b_i, a, a_conn);
[email protected]fe053f92013-04-23 20:18:55125 }
126}
127
128// static
129int CryptoTestUtils::HandshakeWithFakeServer(
[email protected]ed3fc15d2013-03-08 18:37:44130 PacketSavingConnection* client_conn,
[email protected]14e8106c2013-03-14 16:25:33131 QuicCryptoClientStream* client) {
[email protected]ed3fc15d2013-03-08 18:37:44132 QuicGuid guid(1);
[email protected]72818ea2013-03-13 03:23:57133 IPAddressNumber ip;
134 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
135 IPEndPoint addr = IPEndPoint(ip, 1);
[email protected]ed3fc15d2013-03-08 18:37:44136 PacketSavingConnection* server_conn =
[email protected]14e8106c2013-03-14 16:25:33137 new PacketSavingConnection(guid, addr, true);
[email protected]ed3fc15d2013-03-08 18:37:44138 TestSession server_session(server_conn, true);
[email protected]ef95114d2013-04-17 17:57:01139
140 QuicConfig config;
141 QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING);
142 SetupCryptoServerConfigForTest(
143 server_session.connection()->clock(),
144 server_session.connection()->random_generator(),
145 &config, &crypto_config);
146
147 QuicCryptoServerStream server(config, crypto_config, &server_session);
[email protected]2532de12013-05-09 12:29:33148 server_session.SetCryptoStream(&server);
[email protected]ed3fc15d2013-03-08 18:37:44149
150 // The client's handshake must have been started already.
151 CHECK_NE(0u, client_conn->packets_.size());
152
153 CommunicateHandshakeMessages(client_conn, client, server_conn, &server);
[email protected]14e8106c2013-03-14 16:25:33154
155 CompareClientAndServerKeys(client, &server);
[email protected]fe053f92013-04-23 20:18:55156
157 return client->num_sent_client_hellos();
[email protected]ed3fc15d2013-03-08 18:37:44158}
159
160// static
[email protected]fe053f92013-04-23 20:18:55161int CryptoTestUtils::HandshakeWithFakeClient(
[email protected]ed3fc15d2013-03-08 18:37:44162 PacketSavingConnection* server_conn,
[email protected]14e8106c2013-03-14 16:25:33163 QuicCryptoServerStream* server) {
[email protected]ed3fc15d2013-03-08 18:37:44164 QuicGuid guid(1);
[email protected]72818ea2013-03-13 03:23:57165 IPAddressNumber ip;
166 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
167 IPEndPoint addr = IPEndPoint(ip, 1);
[email protected]ed3fc15d2013-03-08 18:37:44168 PacketSavingConnection* client_conn =
[email protected]14e8106c2013-03-14 16:25:33169 new PacketSavingConnection(guid, addr, false);
[email protected]ed3fc15d2013-03-08 18:37:44170 TestSession client_session(client_conn, true);
[email protected]ef95114d2013-04-17 17:57:01171 QuicConfig config;
172 QuicCryptoClientConfig crypto_config;
173
174 config.SetDefaults();
175 crypto_config.SetDefaults();
[email protected]a57e0272013-04-26 07:31:47176 // TODO(rtenneti): Enable testing of ProofVerifier.
177 // crypto_config.SetProofVerifier(ProofVerifierForTesting());
[email protected]ef95114d2013-04-17 17:57:01178 QuicCryptoClientStream client("test.example.com", config, &client_session,
179 &crypto_config);
[email protected]2532de12013-05-09 12:29:33180 client_session.SetCryptoStream(&client);
[email protected]ed3fc15d2013-03-08 18:37:44181
182 CHECK(client.CryptoConnect());
183 CHECK_EQ(1u, client_conn->packets_.size());
184
185 CommunicateHandshakeMessages(client_conn, &client, server_conn, server);
[email protected]14e8106c2013-03-14 16:25:33186
187 CompareClientAndServerKeys(&client, server);
[email protected]fe053f92013-04-23 20:18:55188
189 return client.num_sent_client_hellos();
[email protected]14e8106c2013-03-14 16:25:33190}
191
192// static
[email protected]ef95114d2013-04-17 17:57:01193void CryptoTestUtils::SetupCryptoServerConfigForTest(
194 const QuicClock* clock,
195 QuicRandom* rand,
196 QuicConfig* config,
197 QuicCryptoServerConfig* crypto_config) {
198 config->SetDefaults();
199 CryptoHandshakeMessage extra_tags;
200 config->ToHandshakeMessage(&extra_tags);
201
202 scoped_ptr<CryptoHandshakeMessage> scfg(
[email protected]2532de12013-05-09 12:29:33203 crypto_config->AddDefaultConfig(
204 rand, clock, extra_tags, QuicCryptoServerConfig::kDefaultExpiry));
[email protected]ef95114d2013-04-17 17:57:01205 if (!config->SetFromHandshakeMessage(*scfg)) {
206 CHECK(false) << "Crypto config could not be parsed by QuicConfig.";
207 }
208}
209
210// static
[email protected]ccc66e8a2013-03-26 08:26:14211string CryptoTestUtils::GetValueForTag(const CryptoHandshakeMessage& message,
[email protected]2532de12013-05-09 12:29:33212 QuicTag tag) {
213 QuicTagValueMap::const_iterator it = message.tag_value_map().find(tag);
[email protected]ccc66e8a2013-03-26 08:26:14214 if (it == message.tag_value_map().end()) {
215 return string();
216 }
217 return it->second;
218}
219
[email protected]2532de12013-05-09 12:29:33220class MockCommonCertSets : public CommonCertSets {
[email protected]c244c5a12013-05-07 20:55:04221 public:
[email protected]2532de12013-05-09 12:29:33222 MockCommonCertSets(StringPiece cert, uint64 hash, uint32 index)
[email protected]c244c5a12013-05-07 20:55:04223 : cert_(cert.as_string()),
224 hash_(hash),
225 index_(index) {
226 }
227
[email protected]2532de12013-05-09 12:29:33228 virtual StringPiece GetCommonHashes() const OVERRIDE {
[email protected]c244c5a12013-05-07 20:55:04229 CHECK(false) << "not implemented";
230 return StringPiece();
231 }
232
[email protected]2532de12013-05-09 12:29:33233 virtual StringPiece GetCert(uint64 hash, uint32 index) const OVERRIDE {
[email protected]c244c5a12013-05-07 20:55:04234 if (hash == hash_ && index == index_) {
235 return cert_;
236 }
237 return StringPiece();
238 }
239
240 virtual bool MatchCert(StringPiece cert,
241 StringPiece common_set_hashes,
242 uint64* out_hash,
[email protected]2532de12013-05-09 12:29:33243 uint32* out_index) const OVERRIDE {
[email protected]c244c5a12013-05-07 20:55:04244 if (cert != cert_) {
245 return false;
246 }
247
248 if (common_set_hashes.size() % sizeof(uint64) != 0) {
249 return false;
250 }
251 bool client_has_set = false;
252 for (size_t i = 0; i < common_set_hashes.size(); i += sizeof(uint64)) {
253 uint64 hash;
254 memcpy(&hash, common_set_hashes.data() + i, sizeof(hash));
255 if (hash == hash_) {
256 client_has_set = true;
257 break;
258 }
259 }
260
261 if (!client_has_set) {
262 return false;
263 }
264
265 *out_hash = hash_;
266 *out_index = index_;
267 return true;
268 }
269
270 private:
271 const string cert_;
272 const uint64 hash_;
273 const uint32 index_;
274};
275
[email protected]2532de12013-05-09 12:29:33276CommonCertSets* CryptoTestUtils::MockCommonCertSets(StringPiece cert,
277 uint64 hash,
278 uint32 index) {
279 return new class MockCommonCertSets(cert, hash, index);
[email protected]c244c5a12013-05-07 20:55:04280}
281
[email protected]14e8106c2013-03-14 16:25:33282void CryptoTestUtils::CompareClientAndServerKeys(
283 QuicCryptoClientStream* client,
284 QuicCryptoServerStream* server) {
[email protected]8ba81212013-05-03 13:11:48285 const QuicEncrypter* client_encrypter(
286 client->session()->connection()->encrypter(ENCRYPTION_INITIAL));
[email protected]8ba81212013-05-03 13:11:48287 const QuicDecrypter* client_decrypter(
[email protected]2532de12013-05-09 12:29:33288 client->session()->connection()->decrypter());
289 const QuicEncrypter* client_forward_secure_encrypter(
290 client->session()->connection()->encrypter(ENCRYPTION_FORWARD_SECURE));
291 const QuicDecrypter* client_forward_secure_decrypter(
[email protected]8ba81212013-05-03 13:11:48292 client->session()->connection()->alternative_decrypter());
293 const QuicEncrypter* server_encrypter(
294 server->session()->connection()->encrypter(ENCRYPTION_INITIAL));
295 const QuicDecrypter* server_decrypter(
296 server->session()->connection()->decrypter());
[email protected]2532de12013-05-09 12:29:33297 const QuicEncrypter* server_forward_secure_encrypter(
298 server->session()->connection()->encrypter(ENCRYPTION_FORWARD_SECURE));
299 const QuicDecrypter* server_forward_secure_decrypter(
300 server->session()->connection()->alternative_decrypter());
[email protected]8ba81212013-05-03 13:11:48301
302 StringPiece client_encrypter_key = client_encrypter->GetKey();
303 StringPiece client_encrypter_iv = client_encrypter->GetNoncePrefix();
304 StringPiece client_decrypter_key = client_decrypter->GetKey();
305 StringPiece client_decrypter_iv = client_decrypter->GetNoncePrefix();
[email protected]2532de12013-05-09 12:29:33306 StringPiece client_forward_secure_encrypter_key =
307 client_forward_secure_encrypter->GetKey();
308 StringPiece client_forward_secure_encrypter_iv =
309 client_forward_secure_encrypter->GetNoncePrefix();
310 StringPiece client_forward_secure_decrypter_key =
311 client_forward_secure_decrypter->GetKey();
312 StringPiece client_forward_secure_decrypter_iv =
313 client_forward_secure_decrypter->GetNoncePrefix();
[email protected]8ba81212013-05-03 13:11:48314 StringPiece server_encrypter_key = server_encrypter->GetKey();
315 StringPiece server_encrypter_iv = server_encrypter->GetNoncePrefix();
316 StringPiece server_decrypter_key = server_decrypter->GetKey();
317 StringPiece server_decrypter_iv = server_decrypter->GetNoncePrefix();
[email protected]2532de12013-05-09 12:29:33318 StringPiece server_forward_secure_encrypter_key =
319 server_forward_secure_encrypter->GetKey();
320 StringPiece server_forward_secure_encrypter_iv =
321 server_forward_secure_encrypter->GetNoncePrefix();
322 StringPiece server_forward_secure_decrypter_key =
323 server_forward_secure_decrypter->GetKey();
324 StringPiece server_forward_secure_decrypter_iv =
325 server_forward_secure_decrypter->GetNoncePrefix();
[email protected]8ba81212013-05-03 13:11:48326
[email protected]14e8106c2013-03-14 16:25:33327 CompareCharArraysWithHexError("client write key",
328 client_encrypter_key.data(),
329 client_encrypter_key.length(),
330 server_decrypter_key.data(),
331 server_decrypter_key.length());
332 CompareCharArraysWithHexError("client write IV",
333 client_encrypter_iv.data(),
334 client_encrypter_iv.length(),
335 server_decrypter_iv.data(),
336 server_decrypter_iv.length());
337 CompareCharArraysWithHexError("server write key",
338 server_encrypter_key.data(),
339 server_encrypter_key.length(),
340 client_decrypter_key.data(),
341 client_decrypter_key.length());
342 CompareCharArraysWithHexError("server write IV",
343 server_encrypter_iv.data(),
344 server_encrypter_iv.length(),
345 client_decrypter_iv.data(),
346 client_decrypter_iv.length());
[email protected]2532de12013-05-09 12:29:33347 CompareCharArraysWithHexError("client forward secure write key",
348 client_forward_secure_encrypter_key.data(),
349 client_forward_secure_encrypter_key.length(),
350 server_forward_secure_decrypter_key.data(),
351 server_forward_secure_decrypter_key.length());
352 CompareCharArraysWithHexError("client forward secure write IV",
353 client_forward_secure_encrypter_iv.data(),
354 client_forward_secure_encrypter_iv.length(),
355 server_forward_secure_decrypter_iv.data(),
356 server_forward_secure_decrypter_iv.length());
357 CompareCharArraysWithHexError("server forward secure write key",
358 server_forward_secure_encrypter_key.data(),
359 server_forward_secure_encrypter_key.length(),
360 client_forward_secure_decrypter_key.data(),
361 client_forward_secure_decrypter_key.length());
362 CompareCharArraysWithHexError("server forward secure write IV",
363 server_forward_secure_encrypter_iv.data(),
364 server_forward_secure_encrypter_iv.length(),
365 client_forward_secure_decrypter_iv.data(),
366 client_forward_secure_decrypter_iv.length());
[email protected]ed3fc15d2013-03-08 18:37:44367}
368} // namespace test
369} // namespace net