blob: c6308fab8e216dd44f3d15cb272bf6b4b591cf71 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]f7984fc62009-06-22 23:26:445#include "net/socket/ssl_client_socket.h"
6
initial.commit586acc5fe2008-07-26 22:42:527#include "net/base/address_list.h"
initial.commit586acc5fe2008-07-26 22:42:528#include "net/base/host_resolver.h"
[email protected]597cf6e2009-05-29 09:43:269#include "net/base/io_buffer.h"
[email protected]7b822b2b2008-08-05 00:15:4510#include "net/base/net_errors.h"
[email protected]aaead502008-10-15 00:20:1111#include "net/base/ssl_config_service.h"
initial.commit586acc5fe2008-07-26 22:42:5212#include "net/base/test_completion_callback.h"
[email protected]f7984fc62009-06-22 23:26:4413#include "net/socket/client_socket_factory.h"
14#include "net/socket/ssl_test_util.h"
15#include "net/socket/tcp_client_socket.h"
initial.commit586acc5fe2008-07-26 22:42:5216#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1517#include "testing/platform_test.h"
initial.commit586acc5fe2008-07-26 22:42:5218
19//-----------------------------------------------------------------------------
20
[email protected]aaead502008-10-15 00:20:1121const net::SSLConfig kDefaultSSLConfig;
[email protected]c5949a32008-10-08 17:28:2322
[email protected]b75523f2008-10-17 14:49:0723class SSLClientSocketTest : public PlatformTest {
[email protected]aaead502008-10-15 00:20:1124 public:
25 SSLClientSocketTest()
[email protected]73e0bba2009-02-19 22:57:0926 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) {
27 }
28
29 void StartOKServer() {
30 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
31 server_.kHostName, server_.kOKHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2232 FilePath(), server_.GetOKCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0933 ASSERT_TRUE(success);
34 }
35
36 void StartMismatchedServer() {
37 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
38 server_.kMismatchedHostName, server_.kOKHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2239 FilePath(), server_.GetOKCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0940 ASSERT_TRUE(success);
41 }
42
43 void StartExpiredServer() {
44 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
45 server_.kHostName, server_.kBadHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2246 FilePath(), server_.GetExpiredCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0947 ASSERT_TRUE(success);
[email protected]aaead502008-10-15 00:20:1148 }
[email protected]471822ca2009-01-29 11:32:2649
[email protected]aaead502008-10-15 00:20:1150 protected:
51 net::ClientSocketFactory* socket_factory_;
[email protected]73e0bba2009-02-19 22:57:0952 net::TestServerLauncher server_;
initial.commit586acc5fe2008-07-26 22:42:5253};
54
initial.commit586acc5fe2008-07-26 22:42:5255//-----------------------------------------------------------------------------
56
[email protected]73e0bba2009-02-19 22:57:0957#if defined(OS_MACOSX)
[email protected]3016ded2009-06-19 18:27:5958// Status 6/19/09:
59//
60// If these tests are enabled on OSX, we choke at the point
61// SSLHandshake() (Security framework call) is called from
62// SSLClientSocketMac::DoHandshake(). Return value is -9812 (cert
63// valid but root not trusted), but if you don't have the cert in your
64// keychain as documented on
65// http://dev.chromium.org/developers/testing, the -9812 becomes a
66// -9813 (no root cert).
67//
68// See related handshake failures exhibited by disabled tests in
69// net/url_request/url_request_unittest.cc.
[email protected]73e0bba2009-02-19 22:57:0970#define MAYBE_Connect DISABLED_Connect
71#define MAYBE_ConnectExpired DISABLED_ConnectExpired
72#define MAYBE_ConnectMismatched DISABLED_ConnectMismatched
73#define MAYBE_Read DISABLED_Read
74#define MAYBE_Read_SmallChunks DISABLED_Read_SmallChunks
75#define MAYBE_Read_Interrupted DISABLED_Read_Interrupted
76#else
77#define MAYBE_Connect Connect
78#define MAYBE_ConnectExpired ConnectExpired
79#define MAYBE_ConnectMismatched ConnectMismatched
80#define MAYBE_Read Read
81#define MAYBE_Read_SmallChunks Read_SmallChunks
82#define MAYBE_Read_Interrupted Read_Interrupted
83#endif
84
85TEST_F(SSLClientSocketTest, MAYBE_Connect) {
86 StartOKServer();
87
initial.commit586acc5fe2008-07-26 22:42:5288 net::AddressList addr;
89 net::HostResolver resolver;
90 TestCompletionCallback callback;
91
[email protected]2884a462009-06-15 05:08:4292 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
93 int rv = resolver.Resolve(info, &addr, NULL, NULL);
initial.commit586acc5fe2008-07-26 22:42:5294 EXPECT_EQ(net::OK, rv);
95
[email protected]bacff652009-03-31 17:50:3396 net::ClientSocket *transport = new net::TCPClientSocket(addr);
97 rv = transport->Connect(&callback);
98 if (rv == net::ERR_IO_PENDING)
99 rv = callback.WaitForResult();
100 EXPECT_EQ(net::OK, rv);
101
[email protected]aaead502008-10-15 00:20:11102 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33103 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09104 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52105
[email protected]aaead502008-10-15 00:20:11106 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52107
[email protected]aaead502008-10-15 00:20:11108 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45109 if (rv != net::OK) {
110 ASSERT_EQ(net::ERR_IO_PENDING, rv);
[email protected]73e0bba2009-02-19 22:57:09111 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52112
[email protected]7b822b2b2008-08-05 00:15:45113 rv = callback.WaitForResult();
114 EXPECT_EQ(net::OK, rv);
115 }
initial.commit586acc5fe2008-07-26 22:42:52116
[email protected]aaead502008-10-15 00:20:11117 EXPECT_TRUE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52118
[email protected]aaead502008-10-15 00:20:11119 sock->Disconnect();
120 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52121}
122
[email protected]73e0bba2009-02-19 22:57:09123TEST_F(SSLClientSocketTest, MAYBE_ConnectExpired) {
124 StartExpiredServer();
125
initial.commit586acc5fe2008-07-26 22:42:52126 net::AddressList addr;
127 net::HostResolver resolver;
128 TestCompletionCallback callback;
129
[email protected]2884a462009-06-15 05:08:42130 net::HostResolver::RequestInfo info(server_.kHostName, server_.kBadHTTPSPort);
131 int rv = resolver.Resolve(info, &addr, NULL, NULL);
[email protected]73e0bba2009-02-19 22:57:09132 EXPECT_EQ(net::OK, rv);
133
[email protected]bacff652009-03-31 17:50:33134 net::ClientSocket *transport = new net::TCPClientSocket(addr);
135 rv = transport->Connect(&callback);
136 if (rv == net::ERR_IO_PENDING)
137 rv = callback.WaitForResult();
138 EXPECT_EQ(net::OK, rv);
139
[email protected]73e0bba2009-02-19 22:57:09140 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33141 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09142 server_.kHostName, kDefaultSSLConfig));
143
144 EXPECT_FALSE(sock->IsConnected());
145
146 rv = sock->Connect(&callback);
147 if (rv != net::OK) {
148 ASSERT_EQ(net::ERR_IO_PENDING, rv);
149 EXPECT_FALSE(sock->IsConnected());
150
151 rv = callback.WaitForResult();
152 EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv);
153 }
154
[email protected]bacff652009-03-31 17:50:33155 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
156 // the socket when it encounters an error, whereas other implementations
157 // leave it connected.
[email protected]73e0bba2009-02-19 22:57:09158}
159
160TEST_F(SSLClientSocketTest, MAYBE_ConnectMismatched) {
161 StartMismatchedServer();
162
163 net::AddressList addr;
164 net::HostResolver resolver;
165 TestCompletionCallback callback;
166
[email protected]2884a462009-06-15 05:08:42167 net::HostResolver::RequestInfo info(server_.kMismatchedHostName,
168 server_.kOKHTTPSPort);
169 int rv = resolver.Resolve(info, &addr, NULL, NULL);
[email protected]73e0bba2009-02-19 22:57:09170 EXPECT_EQ(net::OK, rv);
171
[email protected]bacff652009-03-31 17:50:33172 net::ClientSocket *transport = new net::TCPClientSocket(addr);
173 rv = transport->Connect(&callback);
174 if (rv == net::ERR_IO_PENDING)
175 rv = callback.WaitForResult();
176 EXPECT_EQ(net::OK, rv);
177
[email protected]73e0bba2009-02-19 22:57:09178 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33179 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09180 server_.kMismatchedHostName, kDefaultSSLConfig));
181
182 EXPECT_FALSE(sock->IsConnected());
183
184 rv = sock->Connect(&callback);
185 if (rv != net::ERR_CERT_COMMON_NAME_INVALID) {
186 ASSERT_EQ(net::ERR_IO_PENDING, rv);
187 EXPECT_FALSE(sock->IsConnected());
188
189 rv = callback.WaitForResult();
190 EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv);
191 }
192
[email protected]bacff652009-03-31 17:50:33193 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
194 // the socket when it encounters an error, whereas other implementations
195 // leave it connected.
[email protected]73e0bba2009-02-19 22:57:09196}
197
[email protected]b2197852009-02-19 23:27:33198// TODO(wtc): Add unit tests for IsConnectedAndIdle:
199// - Server closes an SSL connection (with a close_notify alert message).
200// - Server closes the underlying TCP connection directly.
201// - Server sends data unexpectedly.
202
[email protected]73e0bba2009-02-19 22:57:09203TEST_F(SSLClientSocketTest, MAYBE_Read) {
204 StartOKServer();
205
206 net::AddressList addr;
207 net::HostResolver resolver;
208 TestCompletionCallback callback;
209
[email protected]2884a462009-06-15 05:08:42210 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
211 int rv = resolver.Resolve(info, &addr, &callback, NULL);
[email protected]b75523f2008-10-17 14:49:07212 EXPECT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52213
214 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07215 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52216
[email protected]bacff652009-03-31 17:50:33217 net::ClientSocket *transport = new net::TCPClientSocket(addr);
218 rv = transport->Connect(&callback);
219 if (rv == net::ERR_IO_PENDING)
220 rv = callback.WaitForResult();
221 EXPECT_EQ(net::OK, rv);
222
[email protected]aaead502008-10-15 00:20:11223 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33224 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09225 server_.kHostName,
226 kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52227
[email protected]aaead502008-10-15 00:20:11228 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45229 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07230 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52231
[email protected]7b822b2b2008-08-05 00:15:45232 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07233 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45234 }
[email protected]b43c97c2008-10-22 19:50:58235 EXPECT_TRUE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52236
237 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25238 scoped_refptr<net::IOBuffer> request_buffer =
239 new net::IOBuffer(arraysize(request_text) - 1);
240 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
241
242 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52243 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
244
245 if (rv == net::ERR_IO_PENDING) {
246 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07247 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52248 }
249
[email protected]ffeb0882009-04-30 21:51:25250 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(4096);
initial.commit586acc5fe2008-07-26 22:42:52251 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25252 rv = sock->Read(buf, 4096, &callback);
initial.commit586acc5fe2008-07-26 22:42:52253 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
254
255 if (rv == net::ERR_IO_PENDING)
256 rv = callback.WaitForResult();
257
[email protected]7b822b2b2008-08-05 00:15:45258 EXPECT_GE(rv, 0);
259 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52260 break;
261 }
262}
263
[email protected]73e0bba2009-02-19 22:57:09264TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) {
265 StartOKServer();
266
initial.commit586acc5fe2008-07-26 22:42:52267 net::AddressList addr;
268 net::HostResolver resolver;
269 TestCompletionCallback callback;
270
[email protected]2884a462009-06-15 05:08:42271 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
272 int rv = resolver.Resolve(info, &addr, NULL, NULL);
[email protected]b75523f2008-10-17 14:49:07273 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52274
[email protected]bacff652009-03-31 17:50:33275 net::ClientSocket *transport = new net::TCPClientSocket(addr);
276 rv = transport->Connect(&callback);
277 if (rv == net::ERR_IO_PENDING)
278 rv = callback.WaitForResult();
279 EXPECT_EQ(net::OK, rv);
280
[email protected]aaead502008-10-15 00:20:11281 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33282 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09283 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52284
[email protected]aaead502008-10-15 00:20:11285 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45286 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07287 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52288
[email protected]7b822b2b2008-08-05 00:15:45289 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07290 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45291 }
initial.commit586acc5fe2008-07-26 22:42:52292
293 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25294 scoped_refptr<net::IOBuffer> request_buffer =
295 new net::IOBuffer(arraysize(request_text) - 1);
296 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
297
298 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52299 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
300
301 if (rv == net::ERR_IO_PENDING) {
302 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07303 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52304 }
305
[email protected]ffeb0882009-04-30 21:51:25306 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(1);
initial.commit586acc5fe2008-07-26 22:42:52307 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25308 rv = sock->Read(buf, 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52309 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
310
311 if (rv == net::ERR_IO_PENDING)
312 rv = callback.WaitForResult();
313
[email protected]7b822b2b2008-08-05 00:15:45314 EXPECT_GE(rv, 0);
315 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52316 break;
317 }
318}
319
[email protected]73e0bba2009-02-19 22:57:09320TEST_F(SSLClientSocketTest, MAYBE_Read_Interrupted) {
321 StartOKServer();
322
initial.commit586acc5fe2008-07-26 22:42:52323 net::AddressList addr;
324 net::HostResolver resolver;
325 TestCompletionCallback callback;
326
[email protected]2884a462009-06-15 05:08:42327 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
328 int rv = resolver.Resolve(info, &addr, NULL, NULL);
[email protected]b75523f2008-10-17 14:49:07329 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52330
[email protected]bacff652009-03-31 17:50:33331 net::ClientSocket *transport = new net::TCPClientSocket(addr);
332 rv = transport->Connect(&callback);
333 if (rv == net::ERR_IO_PENDING)
334 rv = callback.WaitForResult();
335 EXPECT_EQ(net::OK, rv);
336
[email protected]aaead502008-10-15 00:20:11337 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33338 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09339 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52340
[email protected]aaead502008-10-15 00:20:11341 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45342 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07343 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52344
[email protected]7b822b2b2008-08-05 00:15:45345 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07346 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45347 }
initial.commit586acc5fe2008-07-26 22:42:52348
349 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25350 scoped_refptr<net::IOBuffer> request_buffer =
351 new net::IOBuffer(arraysize(request_text) - 1);
352 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
353
354 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52355 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
356
357 if (rv == net::ERR_IO_PENDING) {
358 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07359 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52360 }
361
362 // Do a partial read and then exit. This test should not crash!
[email protected]ffeb0882009-04-30 21:51:25363 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(512);
364 rv = sock->Read(buf, 512, &callback);
initial.commit586acc5fe2008-07-26 22:42:52365 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
366
367 if (rv == net::ERR_IO_PENDING)
368 rv = callback.WaitForResult();
369
[email protected]7b822b2b2008-08-05 00:15:45370 EXPECT_NE(rv, 0);
initial.commit586acc5fe2008-07-26 22:42:52371}