| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 const vector<CryptoHandshakeMessage>& messages() const { | 52 const vector<CryptoHandshakeMessage>& messages() const { |
| 53 return messages_; | 53 return messages_; |
| 54 } | 54 } |
| 55 | 55 |
| 56 private: | 56 private: |
| 57 bool error_; | 57 bool error_; |
| 58 vector<CryptoHandshakeMessage> messages_; | 58 vector<CryptoHandshakeMessage> messages_; |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 // MovePackets parses crypto handshake messages from packet number | |
| 62 // |*inout_packet_index| through to the last packet (or until a packet fails to | |
| 63 // decrypt) and has |dest_stream| process them. |*inout_packet_index| is updated | |
| 64 // with an index one greater than the last packet processed. | |
| 65 void MovePackets(PacketSavingConnection* source_conn, | |
| 66 size_t *inout_packet_index, | |
| 67 QuicCryptoStream* dest_stream, | |
| 68 PacketSavingConnection* dest_conn) { | |
| 69 SimpleQuicFramer framer(source_conn->supported_versions()); | |
| 70 CryptoFramer crypto_framer; | |
| 71 CryptoFramerVisitor crypto_visitor; | |
| 72 | |
| 73 // In order to properly test the code we need to perform encryption and | |
| 74 // decryption so that the crypters latch when expected. The crypters are in | |
| 75 // |dest_conn|, but we don't want to try and use them there. Instead we swap | |
| 76 // them into |framer|, perform the decryption with them, and then swap them | |
| 77 // back. | |
| 78 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer()); | |
| 79 | |
| 80 crypto_framer.set_visitor(&crypto_visitor); | |
| 81 | |
| 82 size_t index = *inout_packet_index; | |
| 83 for (; index < source_conn->encrypted_packets_.size(); index++) { | |
| 84 if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) { | |
| 85 // The framer will be unable to decrypt forward-secure packets sent after | |
| 86 // the handshake is complete. Don't treat them as handshake packets. | |
| 87 break; | |
| 88 } | |
| 89 | |
| 90 for (const QuicStreamFrame& stream_frame : framer.stream_frames()) { | |
| 91 ASSERT_TRUE(crypto_framer.ProcessInput(stream_frame.data)); | |
| 92 ASSERT_FALSE(crypto_visitor.error()); | |
| 93 } | |
| 94 } | |
| 95 *inout_packet_index = index; | |
| 96 | |
| 97 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer()); | |
| 98 | |
| 99 ASSERT_EQ(0u, crypto_framer.InputBytesRemaining()); | |
| 100 | |
| 101 for (const CryptoHandshakeMessage& message : crypto_visitor.messages()) { | |
| 102 dest_stream->OnHandshakeMessage(message); | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 // HexChar parses |c| as a hex character. If valid, it sets |*value| to the | 61 // HexChar parses |c| as a hex character. If valid, it sets |*value| to the |
| 107 // value of the hex character and returns true. Otherwise it returns false. | 62 // value of the hex character and returns true. Otherwise it returns false. |
| 108 bool HexChar(char c, uint8* value) { | 63 bool HexChar(char c, uint8* value) { |
| 109 if (c >= '0' && c <= '9') { | 64 if (c >= '0' && c <= '9') { |
| 110 *value = c - '0'; | 65 *value = c - '0'; |
| 111 return true; | 66 return true; |
| 112 } | 67 } |
| 113 if (c >= 'a' && c <= 'f') { | 68 if (c >= 'a' && c <= 'f') { |
| 114 *value = c - 'a' + 10; | 69 *value = c - 'a' + 10; |
| 115 return true; | 70 return true; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 } | 114 } |
| 160 | 115 |
| 161 private: | 116 private: |
| 162 scoped_ptr<ChannelIDSource> sync_source_; | 117 scoped_ptr<ChannelIDSource> sync_source_; |
| 163 scoped_ptr<ChannelIDSourceCallback> callback_; | 118 scoped_ptr<ChannelIDSourceCallback> callback_; |
| 164 scoped_ptr<ChannelIDKey> channel_id_key_; | 119 scoped_ptr<ChannelIDKey> channel_id_key_; |
| 165 }; | 120 }; |
| 166 | 121 |
| 167 } // anonymous namespace | 122 } // anonymous namespace |
| 168 | 123 |
| 124 CryptoTestUtils::FakeServerOptions::FakeServerOptions() |
| 125 : token_binding_enabled(false) {} |
| 126 |
| 169 CryptoTestUtils::FakeClientOptions::FakeClientOptions() | 127 CryptoTestUtils::FakeClientOptions::FakeClientOptions() |
| 170 : channel_id_enabled(false), channel_id_source_async(false) {} | 128 : channel_id_enabled(false), |
| 129 channel_id_source_async(false), |
| 130 token_binding_enabled(false) {} |
| 171 | 131 |
| 172 // static | 132 // static |
| 173 int CryptoTestUtils::HandshakeWithFakeServer( | 133 int CryptoTestUtils::HandshakeWithFakeServer( |
| 174 MockConnectionHelper* helper, | 134 MockConnectionHelper* helper, |
| 175 PacketSavingConnection* client_conn, | 135 PacketSavingConnection* client_conn, |
| 176 QuicCryptoClientStream* client) { | 136 QuicCryptoClientStream* client, |
| 137 const FakeServerOptions& options) { |
| 177 PacketSavingConnection* server_conn = new PacketSavingConnection( | 138 PacketSavingConnection* server_conn = new PacketSavingConnection( |
| 178 helper, Perspective::IS_SERVER, client_conn->supported_versions()); | 139 helper, Perspective::IS_SERVER, client_conn->supported_versions()); |
| 179 | 140 |
| 180 QuicConfig config = DefaultQuicConfig(); | 141 QuicConfig config = DefaultQuicConfig(); |
| 181 QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING, | 142 QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING, |
| 182 QuicRandom::GetInstance(), | 143 QuicRandom::GetInstance(), |
| 183 ProofSourceForTesting()); | 144 ProofSourceForTesting()); |
| 184 SetupCryptoServerConfigForTest(server_conn->clock(), | 145 SetupCryptoServerConfigForTest(server_conn->clock(), |
| 185 server_conn->random_generator(), &config, | 146 server_conn->random_generator(), &config, |
| 186 &crypto_config); | 147 &crypto_config, options); |
| 187 | 148 |
| 188 TestQuicSpdyServerSession server_session(server_conn, config, &crypto_config); | 149 TestQuicSpdyServerSession server_session(server_conn, config, &crypto_config); |
| 189 | 150 |
| 190 // The client's handshake must have been started already. | 151 // The client's handshake must have been started already. |
| 191 CHECK_NE(0u, client_conn->encrypted_packets_.size()); | 152 CHECK_NE(0u, client_conn->encrypted_packets_.size()); |
| 192 | 153 |
| 193 CommunicateHandshakeMessages(client_conn, client, server_conn, | 154 CommunicateHandshakeMessages(client_conn, client, server_conn, |
| 194 server_session.GetCryptoStream()); | 155 server_session.GetCryptoStream()); |
| 195 CompareClientAndServerKeys(client, server_session.GetCryptoStream()); | 156 CompareClientAndServerKeys(client, server_session.GetCryptoStream()); |
| 196 | 157 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 213 AsyncTestChannelIDSource* async_channel_id_source = nullptr; | 174 AsyncTestChannelIDSource* async_channel_id_source = nullptr; |
| 214 if (options.channel_id_enabled) { | 175 if (options.channel_id_enabled) { |
| 215 | 176 |
| 216 ChannelIDSource* source = ChannelIDSourceForTesting(); | 177 ChannelIDSource* source = ChannelIDSourceForTesting(); |
| 217 if (options.channel_id_source_async) { | 178 if (options.channel_id_source_async) { |
| 218 async_channel_id_source = new AsyncTestChannelIDSource(source); | 179 async_channel_id_source = new AsyncTestChannelIDSource(source); |
| 219 source = async_channel_id_source; | 180 source = async_channel_id_source; |
| 220 } | 181 } |
| 221 crypto_config.SetChannelIDSource(source); | 182 crypto_config.SetChannelIDSource(source); |
| 222 } | 183 } |
| 184 if (options.token_binding_enabled) { |
| 185 crypto_config.tb_key_params.push_back(kP256); |
| 186 } |
| 223 TestQuicSpdyClientSession client_session(client_conn, DefaultQuicConfig(), | 187 TestQuicSpdyClientSession client_session(client_conn, DefaultQuicConfig(), |
| 224 server_id, &crypto_config); | 188 server_id, &crypto_config); |
| 225 | 189 |
| 226 client_session.GetCryptoStream()->CryptoConnect(); | 190 client_session.GetCryptoStream()->CryptoConnect(); |
| 227 CHECK_EQ(1u, client_conn->encrypted_packets_.size()); | 191 CHECK_EQ(1u, client_conn->encrypted_packets_.size()); |
| 228 | 192 |
| 229 CommunicateHandshakeMessagesAndRunCallbacks( | 193 CommunicateHandshakeMessagesAndRunCallbacks( |
| 230 client_conn, client_session.GetCryptoStream(), server_conn, server, | 194 client_conn, client_session.GetCryptoStream(), server_conn, server, |
| 231 async_channel_id_source); | 195 async_channel_id_source); |
| 232 | 196 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 245 } | 209 } |
| 246 | 210 |
| 247 return client_session.GetCryptoStream()->num_sent_client_hellos(); | 211 return client_session.GetCryptoStream()->num_sent_client_hellos(); |
| 248 } | 212 } |
| 249 | 213 |
| 250 // static | 214 // static |
| 251 void CryptoTestUtils::SetupCryptoServerConfigForTest( | 215 void CryptoTestUtils::SetupCryptoServerConfigForTest( |
| 252 const QuicClock* clock, | 216 const QuicClock* clock, |
| 253 QuicRandom* rand, | 217 QuicRandom* rand, |
| 254 QuicConfig* config, | 218 QuicConfig* config, |
| 255 QuicCryptoServerConfig* crypto_config) { | 219 QuicCryptoServerConfig* crypto_config, |
| 220 const FakeServerOptions& fake_options) { |
| 256 QuicCryptoServerConfig::ConfigOptions options; | 221 QuicCryptoServerConfig::ConfigOptions options; |
| 257 options.channel_id_enabled = true; | 222 options.channel_id_enabled = true; |
| 223 options.token_binding_enabled = fake_options.token_binding_enabled; |
| 258 scoped_ptr<CryptoHandshakeMessage> scfg( | 224 scoped_ptr<CryptoHandshakeMessage> scfg( |
| 259 crypto_config->AddDefaultConfig(rand, clock, options)); | 225 crypto_config->AddDefaultConfig(rand, clock, options)); |
| 260 } | 226 } |
| 261 | 227 |
| 262 // static | 228 // static |
| 263 void CryptoTestUtils::CommunicateHandshakeMessages( | 229 void CryptoTestUtils::CommunicateHandshakeMessages( |
| 264 PacketSavingConnection* a_conn, | 230 PacketSavingConnection* a_conn, |
| 265 QuicCryptoStream* a, | 231 QuicCryptoStream* a, |
| 266 PacketSavingConnection* b_conn, | 232 PacketSavingConnection* b_conn, |
| 267 QuicCryptoStream* b) { | 233 QuicCryptoStream* b) { |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 // that any padding is included. | 567 // that any padding is included. |
| 602 scoped_ptr<QuicData> bytes(CryptoFramer::ConstructHandshakeMessage(msg)); | 568 scoped_ptr<QuicData> bytes(CryptoFramer::ConstructHandshakeMessage(msg)); |
| 603 scoped_ptr<CryptoHandshakeMessage> parsed( | 569 scoped_ptr<CryptoHandshakeMessage> parsed( |
| 604 CryptoFramer::ParseMessage(bytes->AsStringPiece())); | 570 CryptoFramer::ParseMessage(bytes->AsStringPiece())); |
| 605 CHECK(parsed.get()); | 571 CHECK(parsed.get()); |
| 606 | 572 |
| 607 va_end(ap); | 573 va_end(ap); |
| 608 return *parsed; | 574 return *parsed; |
| 609 } | 575 } |
| 610 | 576 |
| 577 // static |
| 578 void CryptoTestUtils::MovePackets(PacketSavingConnection* source_conn, |
| 579 size_t* inout_packet_index, |
| 580 QuicCryptoStream* dest_stream, |
| 581 PacketSavingConnection* dest_conn) { |
| 582 SimpleQuicFramer framer(source_conn->supported_versions()); |
| 583 CryptoFramer crypto_framer; |
| 584 CryptoFramerVisitor crypto_visitor; |
| 585 |
| 586 // In order to properly test the code we need to perform encryption and |
| 587 // decryption so that the crypters latch when expected. The crypters are in |
| 588 // |dest_conn|, but we don't want to try and use them there. Instead we swap |
| 589 // them into |framer|, perform the decryption with them, and then swap ther |
| 590 // back. |
| 591 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer()); |
| 592 |
| 593 crypto_framer.set_visitor(&crypto_visitor); |
| 594 |
| 595 size_t index = *inout_packet_index; |
| 596 for (; index < source_conn->encrypted_packets_.size(); index++) { |
| 597 if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) { |
| 598 // The framer will be unable to decrypt forward-secure packets sent after |
| 599 // the handshake is complete. Don't treat them as handshake packets. |
| 600 break; |
| 601 } |
| 602 |
| 603 for (const QuicStreamFrame& stream_frame : framer.stream_frames()) { |
| 604 ASSERT_TRUE(crypto_framer.ProcessInput(stream_frame.data)); |
| 605 ASSERT_FALSE(crypto_visitor.error()); |
| 606 } |
| 607 } |
| 608 *inout_packet_index = index; |
| 609 |
| 610 QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer()); |
| 611 |
| 612 ASSERT_EQ(0u, crypto_framer.InputBytesRemaining()); |
| 613 |
| 614 for (const CryptoHandshakeMessage& message : crypto_visitor.messages()) { |
| 615 dest_stream->OnHandshakeMessage(message); |
| 616 } |
| 617 } |
| 618 |
| 611 } // namespace test | 619 } // namespace test |
| 612 } // namespace net | 620 } // namespace net |
| OLD | NEW |