OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2010 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 // This test suite uses SSLClientSocket to test the implementation of | |
6 // SSLServerSocket. In order to establish connections between the sockets | |
7 // we need two additional classes: | |
8 // 1. FakeSocket | |
9 // Connects SSL socket to FakeDataChannel. This class is just a stub. | |
10 // | |
11 // 2. FakeDataChannel | |
12 // Implements the actual exchange of data between two FakeSockets. | |
13 // | |
14 // Implementations of these two classes are included in this file. | |
15 | |
16 #include "net/socket/ssl_server_socket.h" | |
17 | |
18 #include <queue> | |
19 | |
20 #include "base/crypto/rsa_private_key.h" | |
21 #include "net/base/address_list.h" | |
22 #include "net/base/cert_verifier.h" | |
23 #include "net/base/host_port_pair.h" | |
24 #include "net/base/io_buffer.h" | |
25 #include "net/base/net_errors.h" | |
26 #include "net/base/net_log.h" | |
27 #include "net/base/ssl_config_service.h" | |
28 #include "net/base/x509_certificate.h" | |
29 #include "net/socket/client_socket.h" | |
30 #include "net/socket/client_socket_factory.h" | |
31 #include "net/socket/socket_test_util.h" | |
32 #include "net/socket/ssl_client_socket.h" | |
33 #include "testing/gtest/include/gtest/gtest.h" | |
34 #include "testing/platform_test.h" | |
35 | |
36 namespace net { | |
37 | |
38 namespace { | |
39 | |
40 class FakeDataChannel { | |
41 public: | |
42 FakeDataChannel() : read_callback_(NULL), read_buf_len_(0) { | |
43 } | |
44 | |
45 virtual int Read(IOBuffer* buf, int buf_len, | |
46 CompletionCallback* callback) { | |
47 if (data_.empty()) { | |
48 read_callback_ = callback; | |
49 read_buf_ = buf; | |
50 read_buf_len_ = buf_len; | |
51 return net::ERR_IO_PENDING; | |
52 } | |
53 return PropogateData(buf, buf_len); | |
54 } | |
55 | |
56 virtual int Write(IOBuffer* buf, int buf_len, | |
57 CompletionCallback* callback) { | |
58 data_.push(new net::DrainableIOBuffer(buf, buf_len)); | |
59 DoReadCallback(); | |
60 return buf_len; | |
61 } | |
62 | |
63 private: | |
64 void DoReadCallback() { | |
65 if (!read_callback_) | |
66 return; | |
67 | |
68 int copied = PropogateData(read_buf_, read_buf_len_); | |
69 net::CompletionCallback* callback = read_callback_; | |
70 read_callback_ = NULL; | |
71 read_buf_ = NULL; | |
72 read_buf_len_ = 0; | |
73 callback->Run(copied); | |
74 } | |
75 | |
76 int PropogateData(scoped_refptr<net::IOBuffer> read_buf, int read_buf_len) { | |
77 scoped_refptr<net::DrainableIOBuffer> buf = data_.front(); | |
78 int copied = std::min(buf->BytesRemaining(), read_buf_len); | |
79 memcpy(read_buf->data(), buf->data(), copied); | |
80 buf->DidConsume(copied); | |
81 | |
82 if (!buf->BytesRemaining()) | |
83 data_.pop(); | |
84 return copied; | |
85 } | |
86 | |
87 net::CompletionCallback* read_callback_; | |
88 scoped_refptr<net::IOBuffer> read_buf_; | |
89 int read_buf_len_; | |
90 | |
91 std::queue<scoped_refptr<net::DrainableIOBuffer> > data_; | |
92 | |
93 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel); | |
94 }; | |
95 | |
96 class FakeSocket : public ClientSocket { | |
97 public: | |
98 FakeSocket(FakeDataChannel* incoming_channel, | |
99 FakeDataChannel* outgoing_channel) | |
100 : incoming_(incoming_channel), | |
101 outgoing_(outgoing_channel) { | |
102 } | |
103 | |
104 virtual ~FakeSocket() { | |
105 | |
106 } | |
107 | |
108 virtual int Read(IOBuffer* buf, int buf_len, | |
109 CompletionCallback* callback) { | |
110 return incoming_->Read(buf, buf_len, callback); | |
111 } | |
112 | |
113 virtual int Write(IOBuffer* buf, int buf_len, | |
114 CompletionCallback* callback) { | |
115 return outgoing_->Write(buf, buf_len, callback); | |
116 } | |
117 | |
118 virtual bool SetReceiveBufferSize(int32 size) { | |
119 return true; | |
120 } | |
121 | |
122 virtual bool SetSendBufferSize(int32 size) { | |
123 return true; | |
124 } | |
125 | |
126 virtual int Connect(CompletionCallback* callback) { | |
127 return net::OK; | |
128 } | |
129 | |
130 virtual void Disconnect() {} | |
131 | |
132 virtual bool IsConnected() const { | |
133 return true; | |
134 } | |
135 | |
136 virtual bool IsConnectedAndIdle() const { | |
137 return true; | |
138 } | |
139 | |
140 virtual int GetPeerAddress(AddressList* address) const { | |
141 net::IPAddressNumber ip_address(4); | |
142 *address = net::AddressList(ip_address, 0, false); | |
143 return net::OK; | |
144 } | |
145 | |
146 virtual const BoundNetLog& NetLog() const { | |
147 return net_log_; | |
148 } | |
149 | |
150 virtual void SetSubresourceSpeculation() {} | |
151 virtual void SetOmniboxSpeculation() {} | |
152 | |
153 virtual bool WasEverUsed() const { | |
154 return true; | |
155 } | |
156 | |
157 virtual bool UsingTCPFastOpen() const { | |
158 return false; | |
159 } | |
160 | |
161 private: | |
162 net::BoundNetLog net_log_; | |
163 FakeDataChannel* incoming_; | |
164 FakeDataChannel* outgoing_; | |
165 | |
166 DISALLOW_COPY_AND_ASSIGN(FakeSocket); | |
167 }; | |
168 | |
169 } // namespace | |
170 | |
171 // Verify the correctness of the test helper classes first. | |
172 TEST(FakeSocketTest, DataTransfer) { | |
173 // Establish channels between two sockets. | |
174 FakeDataChannel channel_1; | |
175 FakeDataChannel channel_2; | |
176 FakeSocket client(&channel_1, &channel_2); | |
177 FakeSocket server(&channel_2, &channel_1); | |
178 | |
179 const char kTestData[] = "testing123"; | |
180 const int kTestDataSize = strlen(kTestData); | |
181 const int kReadBufSize = 1024; | |
182 scoped_refptr<net::IOBuffer> write_buf = new net::StringIOBuffer(kTestData); | |
183 scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(kReadBufSize); | |
184 | |
185 // Write then read. | |
186 EXPECT_EQ(kTestDataSize, server.Write(write_buf, kTestDataSize, NULL)); | |
187 EXPECT_EQ(kTestDataSize, client.Read(read_buf, kReadBufSize, NULL)); | |
188 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), kTestDataSize)); | |
189 | |
190 // Read then write. | |
191 TestCompletionCallback callback; | |
192 EXPECT_EQ(net::ERR_IO_PENDING, | |
193 server.Read(read_buf, kReadBufSize, &callback)); | |
194 EXPECT_EQ(kTestDataSize, client.Write(write_buf, kTestDataSize, NULL)); | |
195 EXPECT_EQ(kTestDataSize, callback.WaitForResult()); | |
196 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), kTestDataSize)); | |
197 } | |
198 | |
199 class SSLServerSocketTest : public PlatformTest { | |
200 public: | |
201 SSLServerSocketTest() | |
202 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()), | |
203 cert_verifier_(new net::CertVerifier()) { | |
204 } | |
205 | |
206 protected: | |
207 void Initialize() { | |
208 FakeSocket* fake_client_socket = new FakeSocket(&channel_1_, &channel_2_); | |
209 FakeSocket* fake_server_socket = new FakeSocket(&channel_2_, &channel_1_); | |
210 | |
211 // Generate private key and certificate. | |
212 scoped_ptr<base::RSAPrivateKey> private_key( | |
213 base::RSAPrivateKey::Create(1024)); | |
214 | |
215 std::string subject = "CN=net-unittest"; | |
216 net::X509Certificate* cert = | |
wtc
2010/12/17 18:08:04
BUG: you should use a scoped_refptr<net::X509Certi
Alpha Left Google
2010/12/17 20:31:12
Done.
| |
217 net::X509Certificate::CreateSelfSigned( | |
218 private_key.get(), subject, 0, base::TimeDelta::FromDays(1)); | |
219 | |
220 net::SSLConfig ssl_config; | |
221 ssl_config.false_start_enabled = false; | |
222 ssl_config.snap_start_enabled = false; | |
223 ssl_config.ssl3_enabled = true; | |
224 ssl_config.tls1_enabled = true; | |
225 ssl_config.session_cache_disabled = true; | |
226 | |
227 // Certificate provided by the host doesn't need authority. | |
228 net::SSLConfig::CertAndStatus cert_and_status; | |
229 cert_and_status.cert_status = net::ERR_CERT_AUTHORITY_INVALID; | |
230 cert_and_status.cert = cert; | |
231 ssl_config.allowed_bad_certs.push_back(cert_and_status); | |
232 | |
233 net::HostPortPair host_and_pair("net-unittest", 0); | |
234 client_socket_.reset( | |
235 socket_factory_->CreateSSLClientSocket( | |
236 fake_client_socket, host_and_pair, ssl_config, NULL, | |
237 cert_verifier_.get())); | |
238 server_socket_.reset(net::CreateSSLServerSocket(fake_server_socket, | |
239 cert, private_key.get())); | |
240 } | |
241 | |
242 FakeDataChannel channel_1_; | |
243 FakeDataChannel channel_2_; | |
244 scoped_ptr<net::SSLClientSocket> client_socket_; | |
245 scoped_ptr<net::SSLServerSocket> server_socket_; | |
246 net::ClientSocketFactory* socket_factory_; | |
247 scoped_ptr<net::CertVerifier> cert_verifier_; | |
wtc
2010/12/17 18:08:04
You can use
net::CertVerifier cert_verifier_;
he
Alpha Left Google
2010/12/17 20:31:12
Done.
| |
248 }; | |
249 | |
250 // SSLServerSocket is only implemented using NSS. | |
251 #if defined(USE_NSS) | |
252 | |
253 // This test only executes creation of client and server sockets. This is to | |
254 // test that creation of sockets doesn't crash and have minimal code to run | |
255 // under valgrind in order to help debugging memory problems. | |
256 TEST_F(SSLServerSocketTest, Initialize) { | |
257 Initialize(); | |
258 } | |
259 | |
260 // This test executes Connect() of SSLClientSocket and Accept() of | |
261 // SSLServerSocket to make sure handshaking between the two sockets are | |
262 // completed successfully. | |
263 TEST_F(SSLServerSocketTest, Handshake) { | |
264 Initialize(); | |
265 | |
266 TestCompletionCallback connect_callback; | |
267 TestCompletionCallback accept_callback; | |
268 | |
269 int client_ret = client_socket_->Connect(&connect_callback); | |
270 EXPECT_TRUE(client_ret == net::OK || client_ret == net::ERR_IO_PENDING); | |
271 | |
272 int server_ret = server_socket_->Accept(&accept_callback); | |
273 EXPECT_TRUE(server_ret == net::OK || server_ret == net::ERR_IO_PENDING); | |
274 | |
275 if (client_ret == net::ERR_IO_PENDING) { | |
276 EXPECT_EQ(net::OK, connect_callback.WaitForResult()); | |
277 } | |
278 if (server_ret == net::ERR_IO_PENDING) { | |
279 EXPECT_EQ(net::OK, accept_callback.WaitForResult()); | |
280 } | |
281 } | |
282 | |
283 TEST_F(SSLServerSocketTest, DataTransfer) { | |
284 Initialize(); | |
285 | |
286 TestCompletionCallback connect_callback; | |
287 TestCompletionCallback accept_callback; | |
288 | |
289 // Establish connection. | |
290 int client_ret = client_socket_->Connect(&connect_callback); | |
291 EXPECT_TRUE(client_ret == net::OK || client_ret == net::ERR_IO_PENDING); | |
292 | |
293 int server_ret = server_socket_->Accept(&accept_callback); | |
294 EXPECT_TRUE(server_ret == net::OK || server_ret == net::ERR_IO_PENDING); | |
295 | |
296 if (client_ret == net::ERR_IO_PENDING) { | |
297 EXPECT_EQ(net::OK, connect_callback.WaitForResult()); | |
298 } | |
299 if (server_ret == net::ERR_IO_PENDING) { | |
300 EXPECT_EQ(net::OK, accept_callback.WaitForResult()); | |
301 } | |
302 | |
303 const int kReadBufSize = 1024; | |
304 scoped_refptr<net::StringIOBuffer> write_buf = | |
305 new net::StringIOBuffer("testing123"); | |
306 scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(kReadBufSize); | |
307 | |
308 // Write then read. | |
309 TestCompletionCallback write_callback; | |
310 TestCompletionCallback read_callback; | |
311 server_ret = server_socket_->Write(write_buf, write_buf->size(), | |
312 &write_callback); | |
313 EXPECT_TRUE(server_ret > 0 || server_ret == net::ERR_IO_PENDING); | |
314 client_ret = client_socket_->Read(read_buf, kReadBufSize, &read_callback); | |
315 EXPECT_TRUE(client_ret > 0 || client_ret == net::ERR_IO_PENDING); | |
316 | |
317 if (server_ret == net::ERR_IO_PENDING) { | |
318 EXPECT_GT(write_callback.WaitForResult(), 0); | |
319 } | |
320 if (client_ret == net::ERR_IO_PENDING) { | |
321 EXPECT_GT(read_callback.WaitForResult(), 0); | |
322 } | |
323 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size())); | |
324 | |
325 // Read then write. | |
326 write_buf = new net::StringIOBuffer("hello123"); | |
327 server_ret = server_socket_->Read(read_buf, kReadBufSize, &read_callback); | |
328 EXPECT_TRUE(server_ret > 0 || server_ret == net::ERR_IO_PENDING); | |
329 client_ret = client_socket_->Write(write_buf, write_buf->size(), | |
330 &write_callback); | |
331 EXPECT_TRUE(client_ret > 0 || client_ret == net::ERR_IO_PENDING); | |
332 | |
333 if (server_ret == net::ERR_IO_PENDING) { | |
334 EXPECT_GT(read_callback.WaitForResult(), 0); | |
335 } | |
336 if (client_ret == net::ERR_IO_PENDING) { | |
337 EXPECT_GT(write_callback.WaitForResult(), 0); | |
338 } | |
339 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size())); | |
340 } | |
341 #endif | |
342 | |
343 } // namespace net | |
OLD | NEW |