| 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 |