OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/test_tools/crypto_test_utils.h" | 5 #include "net/quic/test_tools/crypto_test_utils.h" |
6 | 6 |
7 #include "net/quic/crypto/channel_id.h" | 7 #include "net/quic/crypto/channel_id.h" |
8 #include "net/quic/crypto/common_cert_set.h" | 8 #include "net/quic/crypto/common_cert_set.h" |
9 #include "net/quic/crypto/crypto_handshake.h" | 9 #include "net/quic/crypto/crypto_handshake.h" |
10 #include "net/quic/crypto/quic_crypto_server_config.h" | 10 #include "net/quic/crypto/quic_crypto_server_config.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 namespace test { | 30 namespace test { |
31 | 31 |
32 namespace { | 32 namespace { |
33 | 33 |
34 const char kServerHostname[] = "test.example.com"; | 34 const char kServerHostname[] = "test.example.com"; |
35 const uint16 kServerPort = 80; | 35 const uint16 kServerPort = 80; |
36 | 36 |
37 // CryptoFramerVisitor is a framer visitor that records handshake messages. | 37 // CryptoFramerVisitor is a framer visitor that records handshake messages. |
38 class CryptoFramerVisitor : public CryptoFramerVisitorInterface { | 38 class CryptoFramerVisitor : public CryptoFramerVisitorInterface { |
39 public: | 39 public: |
40 CryptoFramerVisitor() | 40 CryptoFramerVisitor() : error_(false) {} |
41 : error_(false) { | |
42 } | |
43 | 41 |
44 virtual void OnError(CryptoFramer* framer) OVERRIDE { error_ = true; } | 42 virtual void OnError(CryptoFramer* framer) OVERRIDE { error_ = true; } |
45 | 43 |
46 virtual void OnHandshakeMessage( | 44 virtual void OnHandshakeMessage( |
47 const CryptoHandshakeMessage& message) OVERRIDE { | 45 const CryptoHandshakeMessage& message) OVERRIDE { |
48 messages_.push_back(message); | 46 messages_.push_back(message); |
49 } | 47 } |
50 | 48 |
51 bool error() const { | 49 bool error() const { return error_; } |
52 return error_; | |
53 } | |
54 | 50 |
55 const vector<CryptoHandshakeMessage>& messages() const { | 51 const vector<CryptoHandshakeMessage>& messages() const { return messages_; } |
56 return messages_; | |
57 } | |
58 | 52 |
59 private: | 53 private: |
60 bool error_; | 54 bool error_; |
61 vector<CryptoHandshakeMessage> messages_; | 55 vector<CryptoHandshakeMessage> messages_; |
62 }; | 56 }; |
63 | 57 |
64 // MovePackets parses crypto handshake messages from packet number | 58 // MovePackets parses crypto handshake messages from packet number |
65 // |*inout_packet_index| through to the last packet and has |dest_stream| | 59 // |*inout_packet_index| through to the last packet and has |dest_stream| |
66 // process them. |*inout_packet_index| is updated with an index one greater | 60 // process them. |*inout_packet_index| is updated with an index one greater |
67 // than the last packet processed. | 61 // than the last packet processed. |
68 void MovePackets(PacketSavingConnection* source_conn, | 62 void MovePackets(PacketSavingConnection* source_conn, |
69 size_t *inout_packet_index, | 63 size_t* inout_packet_index, |
70 QuicCryptoStream* dest_stream, | 64 QuicCryptoStream* dest_stream, |
71 PacketSavingConnection* dest_conn) { | 65 PacketSavingConnection* dest_conn) { |
72 SimpleQuicFramer framer(source_conn->supported_versions()); | 66 SimpleQuicFramer framer(source_conn->supported_versions()); |
73 CryptoFramer crypto_framer; | 67 CryptoFramer crypto_framer; |
74 CryptoFramerVisitor crypto_visitor; | 68 CryptoFramerVisitor crypto_visitor; |
75 | 69 |
76 // In order to properly test the code we need to perform encryption and | 70 // In order to properly test the code we need to perform encryption and |
77 // decryption so that the crypters latch when expected. The crypters are in | 71 // decryption so that the crypters latch when expected. The crypters are in |
78 // |dest_conn|, but we don't want to try and use them there. Instead we swap | 72 // |dest_conn|, but we don't want to try and use them there. Instead we swap |
79 // them into |framer|, perform the decryption with them, and then swap them | 73 // them into |framer|, perform the decryption with them, and then swap them |
80 // back. | 74 // back. |
81 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer()); | 75 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer()); |
82 | 76 |
83 crypto_framer.set_visitor(&crypto_visitor); | 77 crypto_framer.set_visitor(&crypto_visitor); |
84 | 78 |
85 size_t index = *inout_packet_index; | 79 size_t index = *inout_packet_index; |
86 for (; index < source_conn->encrypted_packets_.size(); index++) { | 80 for (; index < source_conn->encrypted_packets_.size(); index++) { |
87 ASSERT_TRUE(framer.ProcessPacket(*source_conn->encrypted_packets_[index])); | 81 ASSERT_TRUE(framer.ProcessPacket(*source_conn->encrypted_packets_[index])); |
88 for (vector<QuicStreamFrame>::const_iterator | 82 for (vector<QuicStreamFrame>::const_iterator i = |
89 i = framer.stream_frames().begin(); | 83 framer.stream_frames().begin(); |
90 i != framer.stream_frames().end(); ++i) { | 84 i != framer.stream_frames().end(); |
| 85 ++i) { |
91 scoped_ptr<string> frame_data(i->GetDataAsString()); | 86 scoped_ptr<string> frame_data(i->GetDataAsString()); |
92 ASSERT_TRUE(crypto_framer.ProcessInput(*frame_data)); | 87 ASSERT_TRUE(crypto_framer.ProcessInput(*frame_data)); |
93 ASSERT_FALSE(crypto_visitor.error()); | 88 ASSERT_FALSE(crypto_visitor.error()); |
94 } | 89 } |
95 } | 90 } |
96 *inout_packet_index = index; | 91 *inout_packet_index = index; |
97 | 92 |
98 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer()); | 93 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer()); |
99 | 94 |
100 ASSERT_EQ(0u, crypto_framer.InputBytesRemaining()); | 95 ASSERT_EQ(0u, crypto_framer.InputBytesRemaining()); |
101 | 96 |
102 for (vector<CryptoHandshakeMessage>::const_iterator | 97 for (vector<CryptoHandshakeMessage>::const_iterator i = |
103 i = crypto_visitor.messages().begin(); | 98 crypto_visitor.messages().begin(); |
104 i != crypto_visitor.messages().end(); ++i) { | 99 i != crypto_visitor.messages().end(); |
| 100 ++i) { |
105 dest_stream->OnHandshakeMessage(*i); | 101 dest_stream->OnHandshakeMessage(*i); |
106 } | 102 } |
107 } | 103 } |
108 | 104 |
109 // HexChar parses |c| as a hex character. If valid, it sets |*value| to the | 105 // HexChar parses |c| as a hex character. If valid, it sets |*value| to the |
110 // value of the hex character and returns true. Otherwise it returns false. | 106 // value of the hex character and returns true. Otherwise it returns false. |
111 bool HexChar(char c, uint8* value) { | 107 bool HexChar(char c, uint8* value) { |
112 if (c >= '0' && c <= '9') { | 108 if (c >= '0' && c <= '9') { |
113 *value = c - '0'; | 109 *value = c - '0'; |
114 return true; | 110 return true; |
115 } | 111 } |
116 if (c >= 'a' && c <= 'f') { | 112 if (c >= 'a' && c <= 'f') { |
117 *value = c - 'a' + 10; | 113 *value = c - 'a' + 10; |
118 return true; | 114 return true; |
119 } | 115 } |
120 if (c >= 'A' && c <= 'F') { | 116 if (c >= 'A' && c <= 'F') { |
121 *value = c - 'A' + 10; | 117 *value = c - 'A' + 10; |
122 return true; | 118 return true; |
123 } | 119 } |
124 return false; | 120 return false; |
125 } | 121 } |
126 | 122 |
127 } // anonymous namespace | 123 } // anonymous namespace |
128 | 124 |
129 CryptoTestUtils::FakeClientOptions::FakeClientOptions() | 125 CryptoTestUtils::FakeClientOptions::FakeClientOptions() |
130 : dont_verify_certs(false), | 126 : dont_verify_certs(false), channel_id_enabled(false) { |
131 channel_id_enabled(false) { | |
132 } | 127 } |
133 | 128 |
134 // static | 129 // static |
135 int CryptoTestUtils::HandshakeWithFakeServer( | 130 int CryptoTestUtils::HandshakeWithFakeServer( |
136 PacketSavingConnection* client_conn, | 131 PacketSavingConnection* client_conn, |
137 QuicCryptoClientStream* client) { | 132 QuicCryptoClientStream* client) { |
138 PacketSavingConnection* server_conn = | 133 PacketSavingConnection* server_conn = |
139 new PacketSavingConnection(true, client_conn->supported_versions()); | 134 new PacketSavingConnection(true, client_conn->supported_versions()); |
140 TestSession server_session(server_conn, DefaultQuicConfig()); | 135 TestSession server_session(server_conn, DefaultQuicConfig()); |
141 | 136 |
142 QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING, | 137 QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING, |
143 QuicRandom::GetInstance()); | 138 QuicRandom::GetInstance()); |
144 SetupCryptoServerConfigForTest( | 139 SetupCryptoServerConfigForTest( |
145 server_session.connection()->clock(), | 140 server_session.connection()->clock(), |
146 server_session.connection()->random_generator(), | 141 server_session.connection()->random_generator(), |
147 server_session.config(), &crypto_config); | 142 server_session.config(), |
| 143 &crypto_config); |
148 | 144 |
149 QuicCryptoServerStream server(crypto_config, &server_session); | 145 QuicCryptoServerStream server(crypto_config, &server_session); |
150 server_session.SetCryptoStream(&server); | 146 server_session.SetCryptoStream(&server); |
151 | 147 |
152 // The client's handshake must have been started already. | 148 // The client's handshake must have been started already. |
153 CHECK_NE(0u, client_conn->packets_.size()); | 149 CHECK_NE(0u, client_conn->packets_.size()); |
154 | 150 |
155 CommunicateHandshakeMessages(client_conn, client, server_conn, &server); | 151 CommunicateHandshakeMessages(client_conn, client, server_conn, &server); |
156 | 152 |
157 CompareClientAndServerKeys(client, &server); | 153 CompareClientAndServerKeys(client, &server); |
(...skipping 12 matching lines...) Expand all Loading... |
170 | 166 |
171 client_session.config()->SetDefaults(); | 167 client_session.config()->SetDefaults(); |
172 crypto_config.SetDefaults(); | 168 crypto_config.SetDefaults(); |
173 // TODO(rtenneti): Enable testing of ProofVerifier. | 169 // TODO(rtenneti): Enable testing of ProofVerifier. |
174 // if (!options.dont_verify_certs) { | 170 // if (!options.dont_verify_certs) { |
175 // crypto_config.SetProofVerifier(ProofVerifierForTesting()); | 171 // crypto_config.SetProofVerifier(ProofVerifierForTesting()); |
176 // } | 172 // } |
177 if (options.channel_id_enabled) { | 173 if (options.channel_id_enabled) { |
178 crypto_config.SetChannelIDSigner(ChannelIDSignerForTesting()); | 174 crypto_config.SetChannelIDSigner(ChannelIDSignerForTesting()); |
179 } | 175 } |
180 QuicServerId server_id(kServerHostname, kServerPort, false, | 176 QuicServerId server_id( |
181 PRIVACY_MODE_DISABLED); | 177 kServerHostname, kServerPort, false, PRIVACY_MODE_DISABLED); |
182 QuicCryptoClientStream client(server_id, &client_session, NULL, | 178 QuicCryptoClientStream client( |
183 &crypto_config); | 179 server_id, &client_session, NULL, &crypto_config); |
184 client_session.SetCryptoStream(&client); | 180 client_session.SetCryptoStream(&client); |
185 | 181 |
186 CHECK(client.CryptoConnect()); | 182 CHECK(client.CryptoConnect()); |
187 CHECK_EQ(1u, client_conn->packets_.size()); | 183 CHECK_EQ(1u, client_conn->packets_.size()); |
188 | 184 |
189 CommunicateHandshakeMessages(client_conn, &client, server_conn, server); | 185 CommunicateHandshakeMessages(client_conn, &client, server_conn, server); |
190 | 186 |
191 CompareClientAndServerKeys(&client, server); | 187 CompareClientAndServerKeys(&client, server); |
192 | 188 |
193 if (options.channel_id_enabled) { | 189 if (options.channel_id_enabled) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 QuicTagValueMap::const_iterator it = message.tag_value_map().find(tag); | 259 QuicTagValueMap::const_iterator it = message.tag_value_map().find(tag); |
264 if (it == message.tag_value_map().end()) { | 260 if (it == message.tag_value_map().end()) { |
265 return string(); | 261 return string(); |
266 } | 262 } |
267 return it->second; | 263 return it->second; |
268 } | 264 } |
269 | 265 |
270 class MockCommonCertSets : public CommonCertSets { | 266 class MockCommonCertSets : public CommonCertSets { |
271 public: | 267 public: |
272 MockCommonCertSets(StringPiece cert, uint64 hash, uint32 index) | 268 MockCommonCertSets(StringPiece cert, uint64 hash, uint32 index) |
273 : cert_(cert.as_string()), | 269 : cert_(cert.as_string()), hash_(hash), index_(index) {} |
274 hash_(hash), | |
275 index_(index) { | |
276 } | |
277 | 270 |
278 virtual StringPiece GetCommonHashes() const OVERRIDE { | 271 virtual StringPiece GetCommonHashes() const OVERRIDE { |
279 CHECK(false) << "not implemented"; | 272 CHECK(false) << "not implemented"; |
280 return StringPiece(); | 273 return StringPiece(); |
281 } | 274 } |
282 | 275 |
283 virtual StringPiece GetCert(uint64 hash, uint32 index) const OVERRIDE { | 276 virtual StringPiece GetCert(uint64 hash, uint32 index) const OVERRIDE { |
284 if (hash == hash_ && index == index_) { | 277 if (hash == hash_ && index == index_) { |
285 return cert_; | 278 return cert_; |
286 } | 279 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 } | 410 } |
418 | 411 |
419 // static | 412 // static |
420 QuicTag CryptoTestUtils::ParseTag(const char* tagstr) { | 413 QuicTag CryptoTestUtils::ParseTag(const char* tagstr) { |
421 const size_t len = strlen(tagstr); | 414 const size_t len = strlen(tagstr); |
422 CHECK_NE(0u, len); | 415 CHECK_NE(0u, len); |
423 | 416 |
424 QuicTag tag = 0; | 417 QuicTag tag = 0; |
425 | 418 |
426 if (tagstr[0] == '#') { | 419 if (tagstr[0] == '#') { |
427 CHECK_EQ(static_cast<size_t>(1 + 2*4), len); | 420 CHECK_EQ(static_cast<size_t>(1 + 2 * 4), len); |
428 tagstr++; | 421 tagstr++; |
429 | 422 |
430 for (size_t i = 0; i < 8; i++) { | 423 for (size_t i = 0; i < 8; i++) { |
431 tag <<= 4; | 424 tag <<= 4; |
432 | 425 |
433 uint8 v = 0; | 426 uint8 v = 0; |
434 CHECK(HexChar(tagstr[i], &v)); | 427 CHECK(HexChar(tagstr[i], &v)); |
435 tag |= v; | 428 tag |= v; |
436 } | 429 } |
437 | 430 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 | 479 |
487 const QuicTag tag = ParseTag(tagstr); | 480 const QuicTag tag = ParseTag(tagstr); |
488 const char* valuestr = va_arg(ap, const char*); | 481 const char* valuestr = va_arg(ap, const char*); |
489 | 482 |
490 size_t len = strlen(valuestr); | 483 size_t len = strlen(valuestr); |
491 if (len > 0 && valuestr[0] == '#') { | 484 if (len > 0 && valuestr[0] == '#') { |
492 valuestr++; | 485 valuestr++; |
493 len--; | 486 len--; |
494 | 487 |
495 CHECK_EQ(0u, len % 2); | 488 CHECK_EQ(0u, len % 2); |
496 scoped_ptr<uint8[]> buf(new uint8[len/2]); | 489 scoped_ptr<uint8[]> buf(new uint8[len / 2]); |
497 | 490 |
498 for (size_t i = 0; i < len/2; i++) { | 491 for (size_t i = 0; i < len / 2; i++) { |
499 uint8 v = 0; | 492 uint8 v = 0; |
500 CHECK(HexChar(valuestr[i*2], &v)); | 493 CHECK(HexChar(valuestr[i * 2], &v)); |
501 buf[i] = v << 4; | 494 buf[i] = v << 4; |
502 CHECK(HexChar(valuestr[i*2 + 1], &v)); | 495 CHECK(HexChar(valuestr[i * 2 + 1], &v)); |
503 buf[i] |= v; | 496 buf[i] |= v; |
504 } | 497 } |
505 | 498 |
506 msg.SetStringPiece( | 499 msg.SetStringPiece( |
507 tag, StringPiece(reinterpret_cast<char*>(buf.get()), len/2)); | 500 tag, StringPiece(reinterpret_cast<char*>(buf.get()), len / 2)); |
508 continue; | 501 continue; |
509 } | 502 } |
510 | 503 |
511 msg.SetStringPiece(tag, valuestr); | 504 msg.SetStringPiece(tag, valuestr); |
512 } | 505 } |
513 | 506 |
514 // The CryptoHandshakeMessage needs to be serialized and parsed to ensure | 507 // The CryptoHandshakeMessage needs to be serialized and parsed to ensure |
515 // that any padding is included. | 508 // that any padding is included. |
516 scoped_ptr<QuicData> bytes(CryptoFramer::ConstructHandshakeMessage(msg)); | 509 scoped_ptr<QuicData> bytes(CryptoFramer::ConstructHandshakeMessage(msg)); |
517 scoped_ptr<CryptoHandshakeMessage> parsed( | 510 scoped_ptr<CryptoHandshakeMessage> parsed( |
518 CryptoFramer::ParseMessage(bytes->AsStringPiece())); | 511 CryptoFramer::ParseMessage(bytes->AsStringPiece())); |
519 CHECK(parsed.get()); | 512 CHECK(parsed.get()); |
520 | 513 |
521 return *parsed; | 514 return *parsed; |
522 } | 515 } |
523 | 516 |
524 } // namespace test | 517 } // namespace test |
525 } // namespace net | 518 } // namespace net |
OLD | NEW |