blob: aa94ff8c365649fdce4f4af0e7e108970773fb39 [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]b59ff372009-07-15 22:04:3226 : resolver_(net::CreateSystemHostResolver()),
27 socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) {
[email protected]73e0bba2009-02-19 22:57:0928 }
29
30 void StartOKServer() {
31 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
32 server_.kHostName, server_.kOKHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2233 FilePath(), server_.GetOKCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0934 ASSERT_TRUE(success);
35 }
36
37 void StartMismatchedServer() {
38 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
39 server_.kMismatchedHostName, server_.kOKHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2240 FilePath(), server_.GetOKCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0941 ASSERT_TRUE(success);
42 }
43
44 void StartExpiredServer() {
45 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
46 server_.kHostName, server_.kBadHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2247 FilePath(), server_.GetExpiredCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0948 ASSERT_TRUE(success);
[email protected]aaead502008-10-15 00:20:1149 }
[email protected]471822ca2009-01-29 11:32:2650
[email protected]aaead502008-10-15 00:20:1151 protected:
[email protected]b59ff372009-07-15 22:04:3252 scoped_refptr<net::HostResolver> resolver_;
[email protected]aaead502008-10-15 00:20:1153 net::ClientSocketFactory* socket_factory_;
[email protected]73e0bba2009-02-19 22:57:0954 net::TestServerLauncher server_;
initial.commit586acc5fe2008-07-26 22:42:5255};
56
initial.commit586acc5fe2008-07-26 22:42:5257//-----------------------------------------------------------------------------
58
[email protected]010e27e2009-08-27 17:49:4159TEST_F(SSLClientSocketTest, Connect) {
[email protected]73e0bba2009-02-19 22:57:0960 StartOKServer();
61
initial.commit586acc5fe2008-07-26 22:42:5262 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:5263 TestCompletionCallback callback;
64
[email protected]2884a462009-06-15 05:08:4265 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:4666 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
initial.commit586acc5fe2008-07-26 22:42:5267 EXPECT_EQ(net::OK, rv);
68
[email protected]bacff652009-03-31 17:50:3369 net::ClientSocket *transport = new net::TCPClientSocket(addr);
70 rv = transport->Connect(&callback);
71 if (rv == net::ERR_IO_PENDING)
72 rv = callback.WaitForResult();
73 EXPECT_EQ(net::OK, rv);
74
[email protected]aaead502008-10-15 00:20:1175 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:3376 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:0977 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:5278
[email protected]aaead502008-10-15 00:20:1179 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:5280
[email protected]aaead502008-10-15 00:20:1181 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:4582 if (rv != net::OK) {
83 ASSERT_EQ(net::ERR_IO_PENDING, rv);
[email protected]73e0bba2009-02-19 22:57:0984 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:5285
[email protected]7b822b2b2008-08-05 00:15:4586 rv = callback.WaitForResult();
87 EXPECT_EQ(net::OK, rv);
88 }
initial.commit586acc5fe2008-07-26 22:42:5289
[email protected]aaead502008-10-15 00:20:1190 EXPECT_TRUE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:5291
[email protected]aaead502008-10-15 00:20:1192 sock->Disconnect();
93 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:5294}
95
[email protected]010e27e2009-08-27 17:49:4196TEST_F(SSLClientSocketTest, ConnectExpired) {
[email protected]73e0bba2009-02-19 22:57:0997 StartExpiredServer();
98
initial.commit586acc5fe2008-07-26 22:42:5299 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52100 TestCompletionCallback callback;
101
[email protected]2884a462009-06-15 05:08:42102 net::HostResolver::RequestInfo info(server_.kHostName, server_.kBadHTTPSPort);
[email protected]684970b2009-08-14 04:54:46103 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
[email protected]73e0bba2009-02-19 22:57:09104 EXPECT_EQ(net::OK, rv);
105
[email protected]bacff652009-03-31 17:50:33106 net::ClientSocket *transport = new net::TCPClientSocket(addr);
107 rv = transport->Connect(&callback);
108 if (rv == net::ERR_IO_PENDING)
109 rv = callback.WaitForResult();
110 EXPECT_EQ(net::OK, rv);
111
[email protected]73e0bba2009-02-19 22:57:09112 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33113 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09114 server_.kHostName, kDefaultSSLConfig));
115
116 EXPECT_FALSE(sock->IsConnected());
117
118 rv = sock->Connect(&callback);
119 if (rv != net::OK) {
120 ASSERT_EQ(net::ERR_IO_PENDING, rv);
121 EXPECT_FALSE(sock->IsConnected());
122
123 rv = callback.WaitForResult();
124 EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv);
125 }
126
[email protected]bacff652009-03-31 17:50:33127 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
128 // the socket when it encounters an error, whereas other implementations
129 // leave it connected.
[email protected]73e0bba2009-02-19 22:57:09130}
131
[email protected]010e27e2009-08-27 17:49:41132TEST_F(SSLClientSocketTest, ConnectMismatched) {
[email protected]73e0bba2009-02-19 22:57:09133 StartMismatchedServer();
134
135 net::AddressList addr;
[email protected]73e0bba2009-02-19 22:57:09136 TestCompletionCallback callback;
137
[email protected]2884a462009-06-15 05:08:42138 net::HostResolver::RequestInfo info(server_.kMismatchedHostName,
139 server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:46140 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
[email protected]73e0bba2009-02-19 22:57:09141 EXPECT_EQ(net::OK, rv);
142
[email protected]bacff652009-03-31 17:50:33143 net::ClientSocket *transport = new net::TCPClientSocket(addr);
144 rv = transport->Connect(&callback);
145 if (rv == net::ERR_IO_PENDING)
146 rv = callback.WaitForResult();
147 EXPECT_EQ(net::OK, rv);
148
[email protected]73e0bba2009-02-19 22:57:09149 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33150 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09151 server_.kMismatchedHostName, kDefaultSSLConfig));
152
153 EXPECT_FALSE(sock->IsConnected());
154
155 rv = sock->Connect(&callback);
156 if (rv != net::ERR_CERT_COMMON_NAME_INVALID) {
157 ASSERT_EQ(net::ERR_IO_PENDING, rv);
158 EXPECT_FALSE(sock->IsConnected());
159
160 rv = callback.WaitForResult();
161 EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv);
162 }
163
[email protected]bacff652009-03-31 17:50:33164 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
165 // the socket when it encounters an error, whereas other implementations
166 // leave it connected.
[email protected]73e0bba2009-02-19 22:57:09167}
168
[email protected]b2197852009-02-19 23:27:33169// TODO(wtc): Add unit tests for IsConnectedAndIdle:
170// - Server closes an SSL connection (with a close_notify alert message).
171// - Server closes the underlying TCP connection directly.
172// - Server sends data unexpectedly.
173
[email protected]010e27e2009-08-27 17:49:41174TEST_F(SSLClientSocketTest, Read) {
[email protected]73e0bba2009-02-19 22:57:09175 StartOKServer();
176
177 net::AddressList addr;
[email protected]73e0bba2009-02-19 22:57:09178 TestCompletionCallback callback;
179
[email protected]2884a462009-06-15 05:08:42180 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:46181 int rv = resolver_->Resolve(info, &addr, &callback, NULL, NULL);
[email protected]b75523f2008-10-17 14:49:07182 EXPECT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52183
184 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07185 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52186
[email protected]bacff652009-03-31 17:50:33187 net::ClientSocket *transport = new net::TCPClientSocket(addr);
188 rv = transport->Connect(&callback);
189 if (rv == net::ERR_IO_PENDING)
190 rv = callback.WaitForResult();
191 EXPECT_EQ(net::OK, rv);
192
[email protected]aaead502008-10-15 00:20:11193 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33194 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09195 server_.kHostName,
196 kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52197
[email protected]aaead502008-10-15 00:20:11198 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45199 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07200 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52201
[email protected]7b822b2b2008-08-05 00:15:45202 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07203 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45204 }
[email protected]b43c97c2008-10-22 19:50:58205 EXPECT_TRUE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52206
207 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25208 scoped_refptr<net::IOBuffer> request_buffer =
209 new net::IOBuffer(arraysize(request_text) - 1);
210 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
211
212 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52213 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
214
215 if (rv == net::ERR_IO_PENDING) {
216 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07217 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52218 }
219
[email protected]ffeb0882009-04-30 21:51:25220 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(4096);
initial.commit586acc5fe2008-07-26 22:42:52221 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25222 rv = sock->Read(buf, 4096, &callback);
initial.commit586acc5fe2008-07-26 22:42:52223 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
224
225 if (rv == net::ERR_IO_PENDING)
226 rv = callback.WaitForResult();
227
[email protected]7b822b2b2008-08-05 00:15:45228 EXPECT_GE(rv, 0);
229 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52230 break;
231 }
232}
233
[email protected]010e27e2009-08-27 17:49:41234TEST_F(SSLClientSocketTest, Read_SmallChunks) {
[email protected]73e0bba2009-02-19 22:57:09235 StartOKServer();
236
initial.commit586acc5fe2008-07-26 22:42:52237 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52238 TestCompletionCallback callback;
239
[email protected]2884a462009-06-15 05:08:42240 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:46241 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
[email protected]b75523f2008-10-17 14:49:07242 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52243
[email protected]bacff652009-03-31 17:50:33244 net::ClientSocket *transport = new net::TCPClientSocket(addr);
245 rv = transport->Connect(&callback);
246 if (rv == net::ERR_IO_PENDING)
247 rv = callback.WaitForResult();
248 EXPECT_EQ(net::OK, rv);
249
[email protected]aaead502008-10-15 00:20:11250 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33251 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09252 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52253
[email protected]aaead502008-10-15 00:20:11254 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45255 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07256 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52257
[email protected]7b822b2b2008-08-05 00:15:45258 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07259 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45260 }
initial.commit586acc5fe2008-07-26 22:42:52261
262 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25263 scoped_refptr<net::IOBuffer> request_buffer =
264 new net::IOBuffer(arraysize(request_text) - 1);
265 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
266
267 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52268 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
269
270 if (rv == net::ERR_IO_PENDING) {
271 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07272 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52273 }
274
[email protected]ffeb0882009-04-30 21:51:25275 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(1);
initial.commit586acc5fe2008-07-26 22:42:52276 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25277 rv = sock->Read(buf, 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52278 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
279
280 if (rv == net::ERR_IO_PENDING)
281 rv = callback.WaitForResult();
282
[email protected]7b822b2b2008-08-05 00:15:45283 EXPECT_GE(rv, 0);
284 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52285 break;
286 }
287}
288
[email protected]010e27e2009-08-27 17:49:41289TEST_F(SSLClientSocketTest, Read_Interrupted) {
[email protected]73e0bba2009-02-19 22:57:09290 StartOKServer();
291
initial.commit586acc5fe2008-07-26 22:42:52292 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52293 TestCompletionCallback callback;
294
[email protected]2884a462009-06-15 05:08:42295 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:46296 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
[email protected]b75523f2008-10-17 14:49:07297 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52298
[email protected]bacff652009-03-31 17:50:33299 net::ClientSocket *transport = new net::TCPClientSocket(addr);
300 rv = transport->Connect(&callback);
301 if (rv == net::ERR_IO_PENDING)
302 rv = callback.WaitForResult();
303 EXPECT_EQ(net::OK, rv);
304
[email protected]aaead502008-10-15 00:20:11305 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33306 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09307 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52308
[email protected]aaead502008-10-15 00:20:11309 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45310 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07311 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52312
[email protected]7b822b2b2008-08-05 00:15:45313 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07314 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45315 }
initial.commit586acc5fe2008-07-26 22:42:52316
317 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25318 scoped_refptr<net::IOBuffer> request_buffer =
319 new net::IOBuffer(arraysize(request_text) - 1);
320 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
321
322 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52323 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
324
325 if (rv == net::ERR_IO_PENDING) {
326 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07327 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52328 }
329
330 // Do a partial read and then exit. This test should not crash!
[email protected]ffeb0882009-04-30 21:51:25331 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(512);
332 rv = sock->Read(buf, 512, &callback);
initial.commit586acc5fe2008-07-26 22:42:52333 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
334
335 if (rv == net::ERR_IO_PENDING)
336 rv = callback.WaitForResult();
337
[email protected]7b822b2b2008-08-05 00:15:45338 EXPECT_NE(rv, 0);
initial.commit586acc5fe2008-07-26 22:42:52339}