| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/quic/quic_client_session.h" | |
| 6 | |
| 7 #include <vector> | |
| 8 | |
| 9 #include "base/base64.h" | |
| 10 #include "base/files/file_path.h" | |
| 11 #include "base/rand_util.h" | |
| 12 #include "net/base/capturing_net_log.h" | |
| 13 #include "net/base/test_completion_callback.h" | |
| 14 #include "net/base/test_data_directory.h" | |
| 15 #include "net/cert/cert_verify_result.h" | |
| 16 #include "net/http/transport_security_state.h" | |
| 17 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" | |
| 18 #include "net/quic/crypto/crypto_protocol.h" | |
| 19 #include "net/quic/crypto/proof_verifier_chromium.h" | |
| 20 #include "net/quic/crypto/quic_decrypter.h" | |
| 21 #include "net/quic/crypto/quic_encrypter.h" | |
| 22 #include "net/quic/crypto/quic_server_info.h" | |
| 23 #include "net/quic/test_tools/crypto_test_utils.h" | |
| 24 #include "net/quic/test_tools/quic_client_session_peer.h" | |
| 25 #include "net/quic/test_tools/quic_test_utils.h" | |
| 26 #include "net/quic/test_tools/simple_quic_framer.h" | |
| 27 #include "net/socket/socket_test_util.h" | |
| 28 #include "net/spdy/spdy_test_utils.h" | |
| 29 #include "net/test/cert_test_util.h" | |
| 30 #include "net/udp/datagram_client_socket.h" | |
| 31 | |
| 32 using testing::_; | |
| 33 | |
| 34 namespace net { | |
| 35 namespace test { | |
| 36 namespace { | |
| 37 | |
| 38 const char kServerHostname[] = "www.example.org"; | |
| 39 const uint16 kServerPort = 80; | |
| 40 | |
| 41 class QuicClientSessionTest : public ::testing::TestWithParam<QuicVersion> { | |
| 42 protected: | |
| 43 QuicClientSessionTest() | |
| 44 : connection_( | |
| 45 new PacketSavingConnection(false, SupportedVersions(GetParam()))), | |
| 46 session_(connection_, GetSocket().Pass(), nullptr, | |
| 47 &transport_security_state_, | |
| 48 make_scoped_ptr((QuicServerInfo*)nullptr), DefaultQuicConfig(), | |
| 49 base::MessageLoop::current()->message_loop_proxy().get(), | |
| 50 &net_log_) { | |
| 51 session_.InitializeSession(QuicServerId(kServerHostname, kServerPort, | |
| 52 /*is_secure=*/false, | |
| 53 PRIVACY_MODE_DISABLED), | |
| 54 &crypto_config_, nullptr); | |
| 55 // Advance the time, because timers do not like uninitialized times. | |
| 56 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
| 57 } | |
| 58 | |
| 59 void TearDown() override { session_.CloseSessionOnError(ERR_ABORTED); } | |
| 60 | |
| 61 scoped_ptr<DatagramClientSocket> GetSocket() { | |
| 62 socket_factory_.AddSocketDataProvider(&socket_data_); | |
| 63 return socket_factory_.CreateDatagramClientSocket( | |
| 64 DatagramSocket::DEFAULT_BIND, base::Bind(&base::RandInt), | |
| 65 &net_log_, NetLog::Source()); | |
| 66 } | |
| 67 | |
| 68 void CompleteCryptoHandshake() { | |
| 69 ASSERT_EQ(ERR_IO_PENDING, | |
| 70 session_.CryptoConnect(false, callback_.callback())); | |
| 71 CryptoTestUtils::HandshakeWithFakeServer( | |
| 72 connection_, session_.GetCryptoStream()); | |
| 73 ASSERT_EQ(OK, callback_.WaitForResult()); | |
| 74 } | |
| 75 | |
| 76 PacketSavingConnection* connection_; | |
| 77 CapturingNetLog net_log_; | |
| 78 MockClientSocketFactory socket_factory_; | |
| 79 StaticSocketDataProvider socket_data_; | |
| 80 TransportSecurityState transport_security_state_; | |
| 81 QuicClientSession session_; | |
| 82 MockClock clock_; | |
| 83 MockRandom random_; | |
| 84 QuicConnectionVisitorInterface* visitor_; | |
| 85 TestCompletionCallback callback_; | |
| 86 QuicCryptoClientConfig crypto_config_; | |
| 87 }; | |
| 88 | |
| 89 INSTANTIATE_TEST_CASE_P(Tests, QuicClientSessionTest, | |
| 90 ::testing::ValuesIn(QuicSupportedVersions())); | |
| 91 | |
| 92 TEST_P(QuicClientSessionTest, CryptoConnect) { | |
| 93 CompleteCryptoHandshake(); | |
| 94 } | |
| 95 | |
| 96 TEST_P(QuicClientSessionTest, MaxNumStreams) { | |
| 97 CompleteCryptoHandshake(); | |
| 98 | |
| 99 std::vector<QuicReliableClientStream*> streams; | |
| 100 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) { | |
| 101 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream(); | |
| 102 EXPECT_TRUE(stream); | |
| 103 streams.push_back(stream); | |
| 104 } | |
| 105 EXPECT_FALSE(session_.CreateOutgoingDataStream()); | |
| 106 | |
| 107 // Close a stream and ensure I can now open a new one. | |
| 108 session_.CloseStream(streams[0]->id()); | |
| 109 EXPECT_TRUE(session_.CreateOutgoingDataStream()); | |
| 110 } | |
| 111 | |
| 112 TEST_P(QuicClientSessionTest, MaxNumStreamsViaRequest) { | |
| 113 CompleteCryptoHandshake(); | |
| 114 | |
| 115 std::vector<QuicReliableClientStream*> streams; | |
| 116 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) { | |
| 117 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream(); | |
| 118 EXPECT_TRUE(stream); | |
| 119 streams.push_back(stream); | |
| 120 } | |
| 121 | |
| 122 QuicReliableClientStream* stream; | |
| 123 QuicClientSession::StreamRequest stream_request; | |
| 124 TestCompletionCallback callback; | |
| 125 ASSERT_EQ(ERR_IO_PENDING, | |
| 126 stream_request.StartRequest(session_.GetWeakPtr(), &stream, | |
| 127 callback.callback())); | |
| 128 | |
| 129 // Close a stream and ensure I can now open a new one. | |
| 130 session_.CloseStream(streams[0]->id()); | |
| 131 ASSERT_TRUE(callback.have_result()); | |
| 132 EXPECT_EQ(OK, callback.WaitForResult()); | |
| 133 EXPECT_TRUE(stream != nullptr); | |
| 134 } | |
| 135 | |
| 136 TEST_P(QuicClientSessionTest, GoAwayReceived) { | |
| 137 CompleteCryptoHandshake(); | |
| 138 | |
| 139 // After receiving a GoAway, I should no longer be able to create outgoing | |
| 140 // streams. | |
| 141 session_.OnGoAway(QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away.")); | |
| 142 EXPECT_EQ(nullptr, session_.CreateOutgoingDataStream()); | |
| 143 } | |
| 144 | |
| 145 TEST_P(QuicClientSessionTest, CanPool) { | |
| 146 // Load a cert that is valid for: | |
| 147 // www.example.org | |
| 148 // mail.example.org | |
| 149 // www.example.com | |
| 150 | |
| 151 ProofVerifyDetailsChromium details; | |
| 152 details.cert_verify_result.verified_cert = | |
| 153 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); | |
| 154 ASSERT_TRUE(details.cert_verify_result.verified_cert.get()); | |
| 155 | |
| 156 session_.OnProofVerifyDetailsAvailable(details); | |
| 157 CompleteCryptoHandshake(); | |
| 158 | |
| 159 EXPECT_TRUE(session_.CanPool("www.example.org", PRIVACY_MODE_DISABLED)); | |
| 160 EXPECT_FALSE(session_.CanPool("www.example.org", PRIVACY_MODE_ENABLED)); | |
| 161 EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED)); | |
| 162 EXPECT_TRUE(session_.CanPool("mail.example.com", PRIVACY_MODE_DISABLED)); | |
| 163 EXPECT_FALSE(session_.CanPool("mail.google.com", PRIVACY_MODE_DISABLED)); | |
| 164 } | |
| 165 | |
| 166 TEST_P(QuicClientSessionTest, ConnectionPooledWithTlsChannelId) { | |
| 167 // Load a cert that is valid for: | |
| 168 // www.example.org | |
| 169 // mail.example.org | |
| 170 // www.example.com | |
| 171 | |
| 172 ProofVerifyDetailsChromium details; | |
| 173 details.cert_verify_result.verified_cert = | |
| 174 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); | |
| 175 ASSERT_TRUE(details.cert_verify_result.verified_cert.get()); | |
| 176 | |
| 177 session_.OnProofVerifyDetailsAvailable(details); | |
| 178 CompleteCryptoHandshake(); | |
| 179 QuicClientSessionPeer::SetChannelIDSent(&session_, true); | |
| 180 | |
| 181 EXPECT_TRUE(session_.CanPool("www.example.org", PRIVACY_MODE_DISABLED)); | |
| 182 EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED)); | |
| 183 EXPECT_FALSE(session_.CanPool("mail.example.com", PRIVACY_MODE_DISABLED)); | |
| 184 EXPECT_FALSE(session_.CanPool("mail.google.com", PRIVACY_MODE_DISABLED)); | |
| 185 } | |
| 186 | |
| 187 TEST_P(QuicClientSessionTest, ConnectionNotPooledWithDifferentPin) { | |
| 188 uint8 primary_pin = 1; | |
| 189 uint8 backup_pin = 2; | |
| 190 uint8 bad_pin = 3; | |
| 191 AddPin(&transport_security_state_, "mail.example.org", primary_pin, | |
| 192 backup_pin); | |
| 193 | |
| 194 ProofVerifyDetailsChromium details; | |
| 195 details.cert_verify_result.verified_cert = | |
| 196 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); | |
| 197 details.cert_verify_result.is_issued_by_known_root = true; | |
| 198 details.cert_verify_result.public_key_hashes.push_back( | |
| 199 GetTestHashValue(bad_pin)); | |
| 200 | |
| 201 ASSERT_TRUE(details.cert_verify_result.verified_cert.get()); | |
| 202 | |
| 203 session_.OnProofVerifyDetailsAvailable(details); | |
| 204 CompleteCryptoHandshake(); | |
| 205 QuicClientSessionPeer::SetChannelIDSent(&session_, true); | |
| 206 | |
| 207 EXPECT_FALSE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED)); | |
| 208 } | |
| 209 | |
| 210 TEST_P(QuicClientSessionTest, ConnectionPooledWithMatchingPin) { | |
| 211 uint8 primary_pin = 1; | |
| 212 uint8 backup_pin = 2; | |
| 213 AddPin(&transport_security_state_, "mail.example.org", primary_pin, | |
| 214 backup_pin); | |
| 215 | |
| 216 ProofVerifyDetailsChromium details; | |
| 217 details.cert_verify_result.verified_cert = | |
| 218 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); | |
| 219 details.cert_verify_result.is_issued_by_known_root = true; | |
| 220 details.cert_verify_result.public_key_hashes.push_back( | |
| 221 GetTestHashValue(primary_pin)); | |
| 222 | |
| 223 ASSERT_TRUE(details.cert_verify_result.verified_cert.get()); | |
| 224 | |
| 225 session_.OnProofVerifyDetailsAvailable(details); | |
| 226 CompleteCryptoHandshake(); | |
| 227 QuicClientSessionPeer::SetChannelIDSent(&session_, true); | |
| 228 | |
| 229 EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED)); | |
| 230 } | |
| 231 | |
| 232 } // namespace | |
| 233 } // namespace test | |
| 234 } // namespace net | |
| OLD | NEW |