blob: 9504949257292502ecc752720ee3b7c9a8eeb359 [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]d069c11a2013-04-13 00:01:557#include "base/strings/string_piece.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"
17#include "net/quic/test_tools/quic_test_utils.h"
18#include "net/quic/test_tools/simple_quic_framer.h"
[email protected]ed3fc15d2013-03-08 18:37:4419
[email protected]14e8106c2013-03-14 16:25:3320using base::StringPiece;
[email protected]ccc66e8a2013-03-26 08:26:1421using std::string;
[email protected]fe053f92013-04-23 20:18:5522using std::vector;
[email protected]14e8106c2013-03-14 16:25:3323
[email protected]ed3fc15d2013-03-08 18:37:4424namespace net {
25namespace test {
26
27namespace {
28
29class TestSession : public QuicSession {
30 public:
31 TestSession(QuicConnection* connection, bool is_server)
32 : QuicSession(connection, is_server) {
33 }
34
35 MOCK_METHOD1(CreateIncomingReliableStream,
36 ReliableQuicStream*(QuicStreamId id));
37 MOCK_METHOD0(GetCryptoStream, QuicCryptoStream*());
38 MOCK_METHOD0(CreateOutgoingReliableStream, ReliableQuicStream*());
39};
40
[email protected]fe053f92013-04-23 20:18:5541// CryptoFramerVisitor is a framer visitor that records handshake messages.
42class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
43 public:
44 CryptoFramerVisitor()
45 : error_(false) {
46 }
[email protected]ed3fc15d2013-03-08 18:37:4447
[email protected]42091902013-05-02 02:24:1248 virtual void OnError(CryptoFramer* framer) OVERRIDE {
[email protected]fe053f92013-04-23 20:18:5549 error_ = true;
50 }
[email protected]ed3fc15d2013-03-08 18:37:4451
[email protected]42091902013-05-02 02:24:1252 virtual void OnHandshakeMessage(
53 const CryptoHandshakeMessage& message) OVERRIDE {
[email protected]fe053f92013-04-23 20:18:5554 messages_.push_back(message);
55 }
[email protected]ed3fc15d2013-03-08 18:37:4456
[email protected]fe053f92013-04-23 20:18:5557 bool error() const {
58 return error_;
59 }
[email protected]ed3fc15d2013-03-08 18:37:4460
[email protected]fe053f92013-04-23 20:18:5561 const vector<CryptoHandshakeMessage>& messages() const {
62 return messages_;
63 }
[email protected]ed3fc15d2013-03-08 18:37:4464
[email protected]fe053f92013-04-23 20:18:5565 private:
66 bool error_;
67 vector<CryptoHandshakeMessage> messages_;
68};
69
70// MovePackets parses crypto handshake messages from packet number
71// |*inout_packet_index| through to the last packet and has |dest_stream|
72// process them. |*inout_packet_index| is updated with an index one greater
73// than the last packet processed.
74void MovePackets(PacketSavingConnection* source_conn,
75 size_t *inout_packet_index,
76 QuicCryptoStream* dest_stream) {
77 SimpleQuicFramer framer;
78 CryptoFramer crypto_framer;
79 CryptoFramerVisitor crypto_visitor;
80
81 crypto_framer.set_visitor(&crypto_visitor);
82
83 size_t index = *inout_packet_index;
84 for (; index < source_conn->packets_.size(); index++) {
85 ASSERT_TRUE(framer.ProcessPacket(*source_conn->packets_[index]));
86 for (vector<QuicStreamFrame>::const_iterator
87 i = framer.stream_frames().begin();
88 i != framer.stream_frames().end(); ++i) {
89 ASSERT_TRUE(crypto_framer.ProcessInput(i->data));
90 ASSERT_FALSE(crypto_visitor.error());
91 }
92 }
93 *inout_packet_index = index;
94
95 ASSERT_EQ(0u, crypto_framer.InputBytesRemaining());
96
97 for (vector<CryptoHandshakeMessage>::const_iterator
98 i = crypto_visitor.messages().begin();
99 i != crypto_visitor.messages().end(); ++i) {
100 dest_stream->OnHandshakeMessage(*i);
[email protected]ed3fc15d2013-03-08 18:37:44101 }
102}
103
104} // anonymous namespace
105
106// static
[email protected]fe053f92013-04-23 20:18:55107void CryptoTestUtils::CommunicateHandshakeMessages(
108 PacketSavingConnection* a_conn,
109 QuicCryptoStream* a,
110 PacketSavingConnection* b_conn,
111 QuicCryptoStream* b) {
112 size_t a_i = 0, b_i = 0;
113 while (!a->handshake_complete()) {
114 ASSERT_GT(a_conn->packets_.size(), a_i);
115 LOG(INFO) << "Processing " << a_conn->packets_.size() - a_i
116 << " packets a->b";
117 MovePackets(a_conn, &a_i, b);
118
119 ASSERT_GT(b_conn->packets_.size(), b_i);
120 LOG(INFO) << "Processing " << b_conn->packets_.size() - b_i
121 << " packets b->a";
122 if (b_conn->packets_.size() - b_i == 2) {
123 LOG(INFO) << "here";
124 }
125 MovePackets(b_conn, &b_i, a);
126 }
127}
128
129// static
130int CryptoTestUtils::HandshakeWithFakeServer(
[email protected]ed3fc15d2013-03-08 18:37:44131 PacketSavingConnection* client_conn,
[email protected]14e8106c2013-03-14 16:25:33132 QuicCryptoClientStream* client) {
[email protected]ed3fc15d2013-03-08 18:37:44133 QuicGuid guid(1);
[email protected]72818ea2013-03-13 03:23:57134 IPAddressNumber ip;
135 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
136 IPEndPoint addr = IPEndPoint(ip, 1);
[email protected]ed3fc15d2013-03-08 18:37:44137 PacketSavingConnection* server_conn =
[email protected]14e8106c2013-03-14 16:25:33138 new PacketSavingConnection(guid, addr, true);
[email protected]ed3fc15d2013-03-08 18:37:44139 TestSession server_session(server_conn, true);
[email protected]ef95114d2013-04-17 17:57:01140
141 QuicConfig config;
142 QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING);
143 SetupCryptoServerConfigForTest(
144 server_session.connection()->clock(),
145 server_session.connection()->random_generator(),
146 &config, &crypto_config);
147
148 QuicCryptoServerStream server(config, crypto_config, &server_session);
[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]ed3fc15d2013-03-08 18:37:44180
181 CHECK(client.CryptoConnect());
182 CHECK_EQ(1u, client_conn->packets_.size());
183
184 CommunicateHandshakeMessages(client_conn, &client, server_conn, server);
[email protected]14e8106c2013-03-14 16:25:33185
186 CompareClientAndServerKeys(&client, server);
[email protected]fe053f92013-04-23 20:18:55187
188 return client.num_sent_client_hellos();
[email protected]14e8106c2013-03-14 16:25:33189}
190
191// static
[email protected]ef95114d2013-04-17 17:57:01192void CryptoTestUtils::SetupCryptoServerConfigForTest(
193 const QuicClock* clock,
194 QuicRandom* rand,
195 QuicConfig* config,
196 QuicCryptoServerConfig* crypto_config) {
197 config->SetDefaults();
198 CryptoHandshakeMessage extra_tags;
199 config->ToHandshakeMessage(&extra_tags);
200
201 scoped_ptr<CryptoHandshakeMessage> scfg(
202 crypto_config->AddDefaultConfig(rand, clock, extra_tags));
203 if (!config->SetFromHandshakeMessage(*scfg)) {
204 CHECK(false) << "Crypto config could not be parsed by QuicConfig.";
205 }
206}
207
208// static
[email protected]ccc66e8a2013-03-26 08:26:14209string CryptoTestUtils::GetValueForTag(const CryptoHandshakeMessage& message,
210 CryptoTag tag) {
211 CryptoTagValueMap::const_iterator it = message.tag_value_map().find(tag);
212 if (it == message.tag_value_map().end()) {
213 return string();
214 }
215 return it->second;
216}
217
[email protected]14e8106c2013-03-14 16:25:33218void CryptoTestUtils::CompareClientAndServerKeys(
219 QuicCryptoClientStream* client,
220 QuicCryptoServerStream* server) {
221 StringPiece client_encrypter_key =
[email protected]74bda142013-03-31 02:49:11222 client->session()->connection()->encrypter()->GetKey();
[email protected]14e8106c2013-03-14 16:25:33223 StringPiece client_encrypter_iv =
[email protected]74bda142013-03-31 02:49:11224 client->session()->connection()->encrypter()->GetNoncePrefix();
[email protected]14e8106c2013-03-14 16:25:33225 StringPiece client_decrypter_key =
[email protected]74bda142013-03-31 02:49:11226 client->session()->connection()->decrypter()->GetKey();
[email protected]14e8106c2013-03-14 16:25:33227 StringPiece client_decrypter_iv =
[email protected]74bda142013-03-31 02:49:11228 client->session()->connection()->decrypter()->GetNoncePrefix();
[email protected]14e8106c2013-03-14 16:25:33229 StringPiece server_encrypter_key =
[email protected]74bda142013-03-31 02:49:11230 server->session()->connection()->encrypter()->GetKey();
[email protected]14e8106c2013-03-14 16:25:33231 StringPiece server_encrypter_iv =
[email protected]74bda142013-03-31 02:49:11232 server->session()->connection()->encrypter()->GetNoncePrefix();
[email protected]14e8106c2013-03-14 16:25:33233 StringPiece server_decrypter_key =
[email protected]74bda142013-03-31 02:49:11234 server->session()->connection()->decrypter()->GetKey();
[email protected]14e8106c2013-03-14 16:25:33235 StringPiece server_decrypter_iv =
[email protected]74bda142013-03-31 02:49:11236 server->session()->connection()->decrypter()->GetNoncePrefix();
[email protected]14e8106c2013-03-14 16:25:33237 CompareCharArraysWithHexError("client write key",
238 client_encrypter_key.data(),
239 client_encrypter_key.length(),
240 server_decrypter_key.data(),
241 server_decrypter_key.length());
242 CompareCharArraysWithHexError("client write IV",
243 client_encrypter_iv.data(),
244 client_encrypter_iv.length(),
245 server_decrypter_iv.data(),
246 server_decrypter_iv.length());
247 CompareCharArraysWithHexError("server write key",
248 server_encrypter_key.data(),
249 server_encrypter_key.length(),
250 client_decrypter_key.data(),
251 client_decrypter_key.length());
252 CompareCharArraysWithHexError("server write IV",
253 server_encrypter_iv.data(),
254 server_encrypter_iv.length(),
255 client_decrypter_iv.data(),
256 client_decrypter_iv.length());
[email protected]ed3fc15d2013-03-08 18:37:44257}
258} // namespace test
259} // namespace net