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.
5 #include "net/quic/quic_chromium_client_session.h"
9 #include "base/base64.h"
10 #include "base/files/file_path.h"
11 #include "base/rand_util.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "net/base/socket_performance_watcher.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/base/test_data_directory.h"
16 #include "net/cert/cert_verify_result.h"
17 #include "net/http/transport_security_state.h"
18 #include "net/log/test_net_log.h"
19 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
20 #include "net/quic/crypto/crypto_protocol.h"
21 #include "net/quic/crypto/proof_verifier_chromium.h"
22 #include "net/quic/crypto/quic_decrypter.h"
23 #include "net/quic/crypto/quic_encrypter.h"
24 #include "net/quic/crypto/quic_server_info.h"
25 #include "net/quic/test_tools/crypto_test_utils.h"
26 #include "net/quic/test_tools/quic_chromium_client_session_peer.h"
27 #include "net/quic/test_tools/quic_spdy_session_peer.h"
28 #include "net/quic/test_tools/quic_test_utils.h"
29 #include "net/quic/test_tools/simple_quic_framer.h"
30 #include "net/socket/socket_test_util.h"
31 #include "net/spdy/spdy_test_utils.h"
32 #include "net/test/cert_test_util.h"
33 #include "net/udp/datagram_client_socket.h"
41 const char kServerHostname
[] = "www.example.org";
42 const uint16 kServerPort
= 80;
44 class QuicChromiumClientSessionTest
45 : public ::testing::TestWithParam
<QuicVersion
> {
47 QuicChromiumClientSessionTest()
48 : connection_(new PacketSavingConnection(Perspective::IS_CLIENT
,
49 SupportedVersions(GetParam()))),
52 /*stream_factory=*/nullptr,
53 /*crypto_client_stream_factory=*/nullptr,
54 &transport_security_state_
,
55 make_scoped_ptr((QuicServerInfo
*)nullptr),
56 QuicServerId(kServerHostname
,
59 PRIVACY_MODE_DISABLED
),
60 /*cert_verify_flags=*/0,
64 base::TimeTicks::Now(),
65 base::ThreadTaskRunnerHandle::Get().get(),
66 /*socket_performance_watcher=*/nullptr,
68 session_
.Initialize();
69 // Advance the time, because timers do not like uninitialized times.
70 connection_
->AdvanceTime(QuicTime::Delta::FromSeconds(1));
73 void TearDown() override
{
74 session_
.CloseSessionOnError(ERR_ABORTED
, QUIC_INTERNAL_ERROR
);
77 scoped_ptr
<DatagramClientSocket
> GetSocket() {
78 socket_factory_
.AddSocketDataProvider(&socket_data_
);
79 return socket_factory_
.CreateDatagramClientSocket(
80 DatagramSocket::DEFAULT_BIND
, base::Bind(&base::RandInt
), &net_log_
,
84 void CompleteCryptoHandshake() {
85 ASSERT_EQ(ERR_IO_PENDING
,
86 session_
.CryptoConnect(false, callback_
.callback()));
87 CryptoTestUtils::HandshakeWithFakeServer(connection_
,
88 session_
.GetCryptoStream());
89 ASSERT_EQ(OK
, callback_
.WaitForResult());
92 PacketSavingConnection
* connection_
;
94 MockClientSocketFactory socket_factory_
;
95 StaticSocketDataProvider socket_data_
;
96 TransportSecurityState transport_security_state_
;
97 QuicChromiumClientSession session_
;
100 QuicConnectionVisitorInterface
* visitor_
;
101 TestCompletionCallback callback_
;
102 QuicCryptoClientConfig crypto_config_
;
105 INSTANTIATE_TEST_CASE_P(Tests
,
106 QuicChromiumClientSessionTest
,
107 ::testing::ValuesIn(QuicSupportedVersions()));
109 TEST_P(QuicChromiumClientSessionTest
, CryptoConnect
) {
110 CompleteCryptoHandshake();
113 TEST_P(QuicChromiumClientSessionTest
, MaxNumStreams
) {
114 CompleteCryptoHandshake();
116 std::vector
<QuicReliableClientStream
*> streams
;
117 for (size_t i
= 0; i
< kDefaultMaxStreamsPerConnection
; i
++) {
118 QuicReliableClientStream
* stream
= session_
.CreateOutgoingDynamicStream();
120 streams
.push_back(stream
);
122 EXPECT_FALSE(session_
.CreateOutgoingDynamicStream());
124 // Close a stream and ensure I can now open a new one.
125 session_
.CloseStream(streams
[0]->id());
126 EXPECT_TRUE(session_
.CreateOutgoingDynamicStream());
129 TEST_P(QuicChromiumClientSessionTest
, MaxNumStreamsViaRequest
) {
130 CompleteCryptoHandshake();
132 std::vector
<QuicReliableClientStream
*> streams
;
133 for (size_t i
= 0; i
< kDefaultMaxStreamsPerConnection
; i
++) {
134 QuicReliableClientStream
* stream
= session_
.CreateOutgoingDynamicStream();
136 streams
.push_back(stream
);
139 QuicReliableClientStream
* stream
;
140 QuicChromiumClientSession::StreamRequest stream_request
;
141 TestCompletionCallback callback
;
142 ASSERT_EQ(ERR_IO_PENDING
,
143 stream_request
.StartRequest(session_
.GetWeakPtr(), &stream
,
144 callback
.callback()));
146 // Close a stream and ensure I can now open a new one.
147 session_
.CloseStream(streams
[0]->id());
148 ASSERT_TRUE(callback
.have_result());
149 EXPECT_EQ(OK
, callback
.WaitForResult());
150 EXPECT_TRUE(stream
!= nullptr);
153 TEST_P(QuicChromiumClientSessionTest
, GoAwayReceived
) {
154 CompleteCryptoHandshake();
156 // After receiving a GoAway, I should no longer be able to create outgoing
158 session_
.connection()->OnGoAwayFrame(
159 QuicGoAwayFrame(QUIC_PEER_GOING_AWAY
, 1u, "Going away."));
160 EXPECT_EQ(nullptr, session_
.CreateOutgoingDynamicStream());
163 TEST_P(QuicChromiumClientSessionTest
, CanPool
) {
164 // Load a cert that is valid for:
169 ProofVerifyDetailsChromium details
;
170 details
.cert_verify_result
.verified_cert
=
171 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
172 ASSERT_TRUE(details
.cert_verify_result
.verified_cert
.get());
174 session_
.OnProofVerifyDetailsAvailable(details
);
175 CompleteCryptoHandshake();
177 EXPECT_TRUE(session_
.CanPool("www.example.org", PRIVACY_MODE_DISABLED
));
178 EXPECT_FALSE(session_
.CanPool("www.example.org", PRIVACY_MODE_ENABLED
));
179 EXPECT_TRUE(session_
.CanPool("mail.example.org", PRIVACY_MODE_DISABLED
));
180 EXPECT_TRUE(session_
.CanPool("mail.example.com", PRIVACY_MODE_DISABLED
));
181 EXPECT_FALSE(session_
.CanPool("mail.google.com", PRIVACY_MODE_DISABLED
));
184 TEST_P(QuicChromiumClientSessionTest
, ConnectionPooledWithTlsChannelId
) {
185 // Load a cert that is valid for:
190 ProofVerifyDetailsChromium details
;
191 details
.cert_verify_result
.verified_cert
=
192 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
193 ASSERT_TRUE(details
.cert_verify_result
.verified_cert
.get());
195 session_
.OnProofVerifyDetailsAvailable(details
);
196 CompleteCryptoHandshake();
197 QuicChromiumClientSessionPeer::SetChannelIDSent(&session_
, true);
199 EXPECT_TRUE(session_
.CanPool("www.example.org", PRIVACY_MODE_DISABLED
));
200 EXPECT_TRUE(session_
.CanPool("mail.example.org", PRIVACY_MODE_DISABLED
));
201 EXPECT_FALSE(session_
.CanPool("mail.example.com", PRIVACY_MODE_DISABLED
));
202 EXPECT_FALSE(session_
.CanPool("mail.google.com", PRIVACY_MODE_DISABLED
));
205 TEST_P(QuicChromiumClientSessionTest
, ConnectionNotPooledWithDifferentPin
) {
206 uint8 primary_pin
= 1;
207 uint8 backup_pin
= 2;
209 AddPin(&transport_security_state_
, "mail.example.org", primary_pin
,
212 ProofVerifyDetailsChromium details
;
213 details
.cert_verify_result
.verified_cert
=
214 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
215 details
.cert_verify_result
.is_issued_by_known_root
= true;
216 details
.cert_verify_result
.public_key_hashes
.push_back(
217 GetTestHashValue(bad_pin
));
219 ASSERT_TRUE(details
.cert_verify_result
.verified_cert
.get());
221 session_
.OnProofVerifyDetailsAvailable(details
);
222 CompleteCryptoHandshake();
223 QuicChromiumClientSessionPeer::SetChannelIDSent(&session_
, true);
225 EXPECT_FALSE(session_
.CanPool("mail.example.org", PRIVACY_MODE_DISABLED
));
228 TEST_P(QuicChromiumClientSessionTest
, ConnectionPooledWithMatchingPin
) {
229 uint8 primary_pin
= 1;
230 uint8 backup_pin
= 2;
231 AddPin(&transport_security_state_
, "mail.example.org", primary_pin
,
234 ProofVerifyDetailsChromium details
;
235 details
.cert_verify_result
.verified_cert
=
236 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
237 details
.cert_verify_result
.is_issued_by_known_root
= true;
238 details
.cert_verify_result
.public_key_hashes
.push_back(
239 GetTestHashValue(primary_pin
));
241 ASSERT_TRUE(details
.cert_verify_result
.verified_cert
.get());
243 session_
.OnProofVerifyDetailsAvailable(details
);
244 CompleteCryptoHandshake();
245 QuicChromiumClientSessionPeer::SetChannelIDSent(&session_
, true);
247 EXPECT_TRUE(session_
.CanPool("mail.example.org", PRIVACY_MODE_DISABLED
));