blob: f487f8d52a11c374056c4caec0d4ce9a4bafe4cb [file] [log] [blame]
[email protected]dd3fd0e2012-11-04 05:14:401// 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
[email protected]5db452202014-08-19 05:22:159#include "base/base64.h"
[email protected]f21ec372014-07-02 07:15:1210#include "base/files/file_path.h"
[email protected]4d283b32013-10-17 12:57:2711#include "base/rand_util.h"
skyostil4891b25b2015-06-11 11:43:4512#include "base/thread_task_runner_handle.h"
[email protected]8ee611b2012-11-20 01:48:1213#include "net/base/test_completion_callback.h"
[email protected]f21ec372014-07-02 07:15:1214#include "net/base/test_data_directory.h"
15#include "net/cert/cert_verify_result.h"
[email protected]5db452202014-08-19 05:22:1516#include "net/http/transport_security_state.h"
vishal.b62985ca92015-04-17 08:45:5117#include "net/log/test_net_log.h"
[email protected]0bbeb6972013-05-23 04:10:2118#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
[email protected]dd3fd0e2012-11-04 05:14:4019#include "net/quic/crypto/crypto_protocol.h"
[email protected]f21ec372014-07-02 07:15:1220#include "net/quic/crypto/proof_verifier_chromium.h"
[email protected]4df69842013-02-27 06:32:1621#include "net/quic/crypto/quic_decrypter.h"
22#include "net/quic/crypto/quic_encrypter.h"
[email protected]17bf15c2014-03-14 10:08:0423#include "net/quic/crypto/quic_server_info.h"
[email protected]ed3fc15d2013-03-08 18:37:4424#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]899951652013-05-16 12:52:3925#include "net/quic/test_tools/quic_client_session_peer.h"
[email protected]dd3fd0e2012-11-04 05:14:4026#include "net/quic/test_tools/quic_test_utils.h"
[email protected]c58a83ec2014-04-20 22:21:5027#include "net/quic/test_tools/simple_quic_framer.h"
[email protected]4d283b32013-10-17 12:57:2728#include "net/socket/socket_test_util.h"
[email protected]5db452202014-08-19 05:22:1529#include "net/spdy/spdy_test_utils.h"
[email protected]f21ec372014-07-02 07:15:1230#include "net/test/cert_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4431#include "net/udp/datagram_client_socket.h"
[email protected]dd3fd0e2012-11-04 05:14:4032
33using testing::_;
34
35namespace net {
36namespace test {
37namespace {
38
[email protected]f21ec372014-07-02 07:15:1239const char kServerHostname[] = "www.example.org";
[email protected]e4c3ea62014-03-15 00:45:1440const uint16 kServerPort = 80;
[email protected]41d6b172013-01-29 16:10:5741
[email protected]4d640792013-12-18 22:21:0842class QuicClientSessionTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]dd3fd0e2012-11-04 05:14:4043 protected:
44 QuicClientSessionTest()
rtenneti6f48aa92015-03-16 02:18:4845 : connection_(new PacketSavingConnection(Perspective::IS_CLIENT,
46 SupportedVersions(GetParam()))),
rtenneti041b2992015-02-23 23:03:2847 session_(connection_,
48 GetSocket().Pass(),
49 nullptr,
[email protected]5db452202014-08-19 05:22:1550 &transport_security_state_,
rtenneti041b2992015-02-23 23:03:2851 make_scoped_ptr((QuicServerInfo*)nullptr),
52 DefaultQuicConfig(),
53 "CONNECTION_UNKNOWN",
rtennetif4f08852015-02-27 17:50:0454 base::TimeTicks::Now(),
skyostil4891b25b2015-06-11 11:43:4555 base::ThreadTaskRunnerHandle::Get().get(),
[email protected]65768442014-06-06 23:37:0356 &net_log_) {
rtenneti4a5df262014-11-07 00:43:5857 session_.InitializeSession(QuicServerId(kServerHostname, kServerPort,
58 /*is_secure=*/false,
rtennetib998b322014-08-26 00:36:3359 PRIVACY_MODE_DISABLED),
rtenneti4a5df262014-11-07 00:43:5860 &crypto_config_, nullptr);
rtenneti85d89712014-11-20 03:32:2461 // Advance the time, because timers do not like uninitialized times.
62 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
[email protected]dd3fd0e2012-11-04 05:14:4063 }
64
rtenneti85dcfac22015-03-27 20:22:1965 void TearDown() override {
66 session_.CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
67 }
[email protected]4d283b32013-10-17 12:57:2768
69 scoped_ptr<DatagramClientSocket> GetSocket() {
70 socket_factory_.AddSocketDataProvider(&socket_data_);
71 return socket_factory_.CreateDatagramClientSocket(
72 DatagramSocket::DEFAULT_BIND, base::Bind(&base::RandInt),
73 &net_log_, NetLog::Source());
74 }
75
[email protected]ed3fc15d2013-03-08 18:37:4476 void CompleteCryptoHandshake() {
77 ASSERT_EQ(ERR_IO_PENDING,
[email protected]11c05872013-08-20 02:04:1278 session_.CryptoConnect(false, callback_.callback()));
[email protected]e8ff26842013-03-22 21:02:0579 CryptoTestUtils::HandshakeWithFakeServer(
80 connection_, session_.GetCryptoStream());
[email protected]ed3fc15d2013-03-08 18:37:4481 ASSERT_EQ(OK, callback_.WaitForResult());
[email protected]ed3fc15d2013-03-08 18:37:4482 }
83
[email protected]dd3fd0e2012-11-04 05:14:4084 PacketSavingConnection* connection_;
vishal.b62985ca92015-04-17 08:45:5185 TestNetLog net_log_;
[email protected]4d283b32013-10-17 12:57:2786 MockClientSocketFactory socket_factory_;
87 StaticSocketDataProvider socket_data_;
[email protected]5db452202014-08-19 05:22:1588 TransportSecurityState transport_security_state_;
[email protected]dd3fd0e2012-11-04 05:14:4089 QuicClientSession session_;
[email protected]ed3fc15d2013-03-08 18:37:4490 MockClock clock_;
91 MockRandom random_;
[email protected]dd3fd0e2012-11-04 05:14:4092 QuicConnectionVisitorInterface* visitor_;
[email protected]8ee611b2012-11-20 01:48:1293 TestCompletionCallback callback_;
[email protected]ef95114d2013-04-17 17:57:0194 QuicCryptoClientConfig crypto_config_;
[email protected]dd3fd0e2012-11-04 05:14:4095};
96
[email protected]4d640792013-12-18 22:21:0897INSTANTIATE_TEST_CASE_P(Tests, QuicClientSessionTest,
98 ::testing::ValuesIn(QuicSupportedVersions()));
99
100TEST_P(QuicClientSessionTest, CryptoConnect) {
[email protected]ed3fc15d2013-03-08 18:37:44101 CompleteCryptoHandshake();
[email protected]8ee611b2012-11-20 01:48:12102}
103
[email protected]4d640792013-12-18 22:21:08104TEST_P(QuicClientSessionTest, MaxNumStreams) {
[email protected]ed3fc15d2013-03-08 18:37:44105 CompleteCryptoHandshake();
[email protected]dd3fd0e2012-11-04 05:14:40106
107 std::vector<QuicReliableClientStream*> streams;
108 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
[email protected]457d6952013-12-13 09:24:58109 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream();
[email protected]dd3fd0e2012-11-04 05:14:40110 EXPECT_TRUE(stream);
[email protected]f702d572012-12-04 15:56:20111 streams.push_back(stream);
[email protected]dd3fd0e2012-11-04 05:14:40112 }
[email protected]457d6952013-12-13 09:24:58113 EXPECT_FALSE(session_.CreateOutgoingDataStream());
[email protected]dd3fd0e2012-11-04 05:14:40114
115 // Close a stream and ensure I can now open a new one.
116 session_.CloseStream(streams[0]->id());
[email protected]457d6952013-12-13 09:24:58117 EXPECT_TRUE(session_.CreateOutgoingDataStream());
[email protected]dd3fd0e2012-11-04 05:14:40118}
119
[email protected]4d640792013-12-18 22:21:08120TEST_P(QuicClientSessionTest, MaxNumStreamsViaRequest) {
[email protected]0b2294d32013-08-02 00:46:36121 CompleteCryptoHandshake();
122
123 std::vector<QuicReliableClientStream*> streams;
124 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
[email protected]457d6952013-12-13 09:24:58125 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream();
[email protected]0b2294d32013-08-02 00:46:36126 EXPECT_TRUE(stream);
127 streams.push_back(stream);
128 }
129
130 QuicReliableClientStream* stream;
131 QuicClientSession::StreamRequest stream_request;
132 TestCompletionCallback callback;
133 ASSERT_EQ(ERR_IO_PENDING,
134 stream_request.StartRequest(session_.GetWeakPtr(), &stream,
135 callback.callback()));
136
137 // Close a stream and ensure I can now open a new one.
138 session_.CloseStream(streams[0]->id());
139 ASSERT_TRUE(callback.have_result());
140 EXPECT_EQ(OK, callback.WaitForResult());
rtennetibe635732014-10-02 22:51:42141 EXPECT_TRUE(stream != nullptr);
[email protected]0b2294d32013-08-02 00:46:36142}
143
[email protected]4d640792013-12-18 22:21:08144TEST_P(QuicClientSessionTest, GoAwayReceived) {
[email protected]8ba81212013-05-03 13:11:48145 CompleteCryptoHandshake();
[email protected]9db443912013-02-25 05:27:03146
147 // After receiving a GoAway, I should no longer be able to create outgoing
148 // streams.
149 session_.OnGoAway(QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
rtennetibe635732014-10-02 22:51:42150 EXPECT_EQ(nullptr, session_.CreateOutgoingDataStream());
[email protected]9db443912013-02-25 05:27:03151}
152
[email protected]5db452202014-08-19 05:22:15153TEST_P(QuicClientSessionTest, CanPool) {
[email protected]f21ec372014-07-02 07:15:12154 // Load a cert that is valid for:
155 // www.example.org
156 // mail.example.org
157 // www.example.com
[email protected]f21ec372014-07-02 07:15:12158
[email protected]f21ec372014-07-02 07:15:12159 ProofVerifyDetailsChromium details;
160 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:15161 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:18162 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:12163
164 session_.OnProofVerifyDetailsAvailable(details);
165 CompleteCryptoHandshake();
166
rch09a730f2015-01-23 00:30:41167 EXPECT_TRUE(session_.CanPool("www.example.org", PRIVACY_MODE_DISABLED));
168 EXPECT_FALSE(session_.CanPool("www.example.org", PRIVACY_MODE_ENABLED));
169 EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
170 EXPECT_TRUE(session_.CanPool("mail.example.com", PRIVACY_MODE_DISABLED));
171 EXPECT_FALSE(session_.CanPool("mail.google.com", PRIVACY_MODE_DISABLED));
[email protected]f21ec372014-07-02 07:15:12172}
173
[email protected]5db452202014-08-19 05:22:15174TEST_P(QuicClientSessionTest, ConnectionPooledWithTlsChannelId) {
[email protected]f21ec372014-07-02 07:15:12175 // Load a cert that is valid for:
176 // www.example.org
177 // mail.example.org
178 // www.example.com
[email protected]f21ec372014-07-02 07:15:12179
[email protected]f21ec372014-07-02 07:15:12180 ProofVerifyDetailsChromium details;
181 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:15182 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:18183 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:12184
185 session_.OnProofVerifyDetailsAvailable(details);
186 CompleteCryptoHandshake();
[email protected]ed42a1e2014-07-16 23:17:47187 QuicClientSessionPeer::SetChannelIDSent(&session_, true);
[email protected]f21ec372014-07-02 07:15:12188
rch09a730f2015-01-23 00:30:41189 EXPECT_TRUE(session_.CanPool("www.example.org", PRIVACY_MODE_DISABLED));
190 EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
191 EXPECT_FALSE(session_.CanPool("mail.example.com", PRIVACY_MODE_DISABLED));
192 EXPECT_FALSE(session_.CanPool("mail.google.com", PRIVACY_MODE_DISABLED));
[email protected]f21ec372014-07-02 07:15:12193}
194
[email protected]5db452202014-08-19 05:22:15195TEST_P(QuicClientSessionTest, ConnectionNotPooledWithDifferentPin) {
196 uint8 primary_pin = 1;
197 uint8 backup_pin = 2;
198 uint8 bad_pin = 3;
199 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
200 backup_pin);
201
202 ProofVerifyDetailsChromium details;
203 details.cert_verify_result.verified_cert =
204 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
205 details.cert_verify_result.is_issued_by_known_root = true;
206 details.cert_verify_result.public_key_hashes.push_back(
207 GetTestHashValue(bad_pin));
208
dcheng4227c6d2014-08-25 23:58:18209 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:15210
211 session_.OnProofVerifyDetailsAvailable(details);
212 CompleteCryptoHandshake();
213 QuicClientSessionPeer::SetChannelIDSent(&session_, true);
214
rch09a730f2015-01-23 00:30:41215 EXPECT_FALSE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
[email protected]5db452202014-08-19 05:22:15216}
217
218TEST_P(QuicClientSessionTest, ConnectionPooledWithMatchingPin) {
219 uint8 primary_pin = 1;
220 uint8 backup_pin = 2;
221 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
222 backup_pin);
223
224 ProofVerifyDetailsChromium details;
225 details.cert_verify_result.verified_cert =
226 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
227 details.cert_verify_result.is_issued_by_known_root = true;
228 details.cert_verify_result.public_key_hashes.push_back(
229 GetTestHashValue(primary_pin));
230
dcheng4227c6d2014-08-25 23:58:18231 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:15232
233 session_.OnProofVerifyDetailsAvailable(details);
234 CompleteCryptoHandshake();
235 QuicClientSessionPeer::SetChannelIDSent(&session_, true);
236
rch09a730f2015-01-23 00:30:41237 EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
[email protected]5db452202014-08-19 05:22:15238}
239
[email protected]dd3fd0e2012-11-04 05:14:40240} // namespace
241} // namespace test
242} // namespace net