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 |