OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/ssl_client_socket.h" | 5 #include "net/socket/ssl_client_socket.h" |
6 | 6 |
7 #include "net/base/address_list.h" | 7 #include "net/base/address_list.h" |
8 #include "net/base/host_resolver.h" | 8 #include "net/base/host_resolver.h" |
9 #include "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
11 #include "net/base/ssl_config_service.h" | 11 #include "net/base/ssl_config_service.h" |
12 #include "net/base/ssl_info.h" | |
12 #include "net/base/test_completion_callback.h" | 13 #include "net/base/test_completion_callback.h" |
13 #include "net/socket/client_socket_factory.h" | 14 #include "net/socket/client_socket_factory.h" |
14 #include "net/socket/ssl_test_util.h" | 15 #include "net/socket/ssl_test_util.h" |
15 #include "net/socket/tcp_client_socket.h" | 16 #include "net/socket/tcp_client_socket.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
17 #include "testing/platform_test.h" | 18 #include "testing/platform_test.h" |
18 | 19 |
19 //----------------------------------------------------------------------------- | 20 //----------------------------------------------------------------------------- |
20 | 21 |
21 const net::SSLConfig kDefaultSSLConfig; | 22 const net::SSLConfig kDefaultSSLConfig; |
(...skipping 20 matching lines...) Expand all Loading... | |
42 } | 43 } |
43 | 44 |
44 void StartExpiredServer() { | 45 void StartExpiredServer() { |
45 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP, | 46 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP, |
46 server_.kHostName, server_.kBadHTTPSPort, | 47 server_.kHostName, server_.kBadHTTPSPort, |
47 FilePath(), server_.GetExpiredCertPath(), std::wstring()); | 48 FilePath(), server_.GetExpiredCertPath(), std::wstring()); |
48 ASSERT_TRUE(success); | 49 ASSERT_TRUE(success); |
49 } | 50 } |
50 | 51 |
51 protected: | 52 protected: |
53 net::SSLClientSocket* CreateSSLClientSocket( | |
54 const net::AddressList& addr, | |
55 const net::SSLConfig& ssl_config) { | |
56 TestCompletionCallback callback; | |
57 net::ClientSocket *transport = new net::TCPClientSocket(addr); | |
eroman
2009/08/15 02:04:29
style-nit: move * to the left.
| |
58 int rv = transport->Connect(&callback); | |
59 if (rv == net::ERR_IO_PENDING) | |
60 rv = callback.WaitForResult(); | |
61 EXPECT_EQ(net::OK, rv); | |
62 | |
63 net::SSLClientSocket* sock = socket_factory_->CreateSSLClientSocket( | |
64 transport, server_.kHostName, ssl_config); | |
65 EXPECT_FALSE(sock->IsConnected()); | |
66 return sock; | |
67 } | |
68 | |
52 scoped_refptr<net::HostResolver> resolver_; | 69 scoped_refptr<net::HostResolver> resolver_; |
53 net::ClientSocketFactory* socket_factory_; | 70 net::ClientSocketFactory* socket_factory_; |
54 net::TestServerLauncher server_; | 71 net::TestServerLauncher server_; |
55 }; | 72 }; |
56 | 73 |
57 //----------------------------------------------------------------------------- | 74 //----------------------------------------------------------------------------- |
58 | 75 |
59 #if defined(OS_MACOSX) | 76 #if defined(OS_MAC) |
60 // Status 6/19/09: | 77 // Status 6/19/09: |
61 // | 78 // |
62 // If these tests are enabled on OSX, we choke at the point | 79 // If these tests are enabled on OSX, we choke at the point |
63 // SSLHandshake() (Security framework call) is called from | 80 // SSLHandshake() (Security framework call) is called from |
64 // SSLClientSocketMac::DoHandshake(). Return value is -9812 (cert | 81 // SSLClientSocketMac::DoHandshake(). Return value is -9812 (cert |
65 // valid but root not trusted), but if you don't have the cert in your | 82 // valid but root not trusted), but if you don't have the cert in your |
66 // keychain as documented on | 83 // keychain as documented on |
67 // http://dev.chromium.org/developers/testing, the -9812 becomes a | 84 // http://dev.chromium.org/developers/testing, the -9812 becomes a |
68 // -9813 (no root cert). | 85 // -9813 (no root cert). |
69 // | 86 // |
(...skipping 17 matching lines...) Expand all Loading... | |
87 TEST_F(SSLClientSocketTest, MAYBE_Connect) { | 104 TEST_F(SSLClientSocketTest, MAYBE_Connect) { |
88 StartOKServer(); | 105 StartOKServer(); |
89 | 106 |
90 net::AddressList addr; | 107 net::AddressList addr; |
91 TestCompletionCallback callback; | 108 TestCompletionCallback callback; |
92 | 109 |
93 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort); | 110 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort); |
94 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); | 111 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); |
95 EXPECT_EQ(net::OK, rv); | 112 EXPECT_EQ(net::OK, rv); |
96 | 113 |
97 net::ClientSocket *transport = new net::TCPClientSocket(addr); | |
98 rv = transport->Connect(&callback); | |
99 if (rv == net::ERR_IO_PENDING) | |
100 rv = callback.WaitForResult(); | |
101 EXPECT_EQ(net::OK, rv); | |
102 | |
103 scoped_ptr<net::SSLClientSocket> sock( | 114 scoped_ptr<net::SSLClientSocket> sock( |
104 socket_factory_->CreateSSLClientSocket(transport, | 115 CreateSSLClientSocket(addr, kDefaultSSLConfig)); |
105 server_.kHostName, kDefaultSSLConfig)); | |
106 | |
107 EXPECT_FALSE(sock->IsConnected()); | |
108 | 116 |
109 rv = sock->Connect(&callback); | 117 rv = sock->Connect(&callback); |
110 if (rv != net::OK) { | 118 if (rv != net::OK) { |
111 ASSERT_EQ(net::ERR_IO_PENDING, rv); | 119 ASSERT_EQ(net::ERR_IO_PENDING, rv); |
112 EXPECT_FALSE(sock->IsConnected()); | 120 EXPECT_FALSE(sock->IsConnected()); |
113 | 121 |
114 rv = callback.WaitForResult(); | 122 rv = callback.WaitForResult(); |
115 EXPECT_EQ(net::OK, rv); | 123 EXPECT_EQ(net::OK, rv); |
116 } | 124 } |
117 | 125 |
118 EXPECT_TRUE(sock->IsConnected()); | 126 EXPECT_TRUE(sock->IsConnected()); |
119 | 127 |
120 sock->Disconnect(); | 128 sock->Disconnect(); |
121 EXPECT_FALSE(sock->IsConnected()); | 129 EXPECT_FALSE(sock->IsConnected()); |
122 } | 130 } |
123 | 131 |
124 TEST_F(SSLClientSocketTest, MAYBE_ConnectExpired) { | 132 TEST_F(SSLClientSocketTest, MAYBE_ConnectExpired) { |
125 StartExpiredServer(); | 133 StartExpiredServer(); |
126 | 134 |
127 net::AddressList addr; | 135 net::AddressList addr; |
128 TestCompletionCallback callback; | 136 TestCompletionCallback callback; |
129 | 137 |
130 net::HostResolver::RequestInfo info(server_.kHostName, server_.kBadHTTPSPort); | 138 net::HostResolver::RequestInfo info(server_.kHostName, server_.kBadHTTPSPort); |
131 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); | 139 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); |
132 EXPECT_EQ(net::OK, rv); | 140 EXPECT_EQ(net::OK, rv); |
133 | 141 |
134 net::ClientSocket *transport = new net::TCPClientSocket(addr); | 142 net::SSLConfig ssl_config = kDefaultSSLConfig; |
135 rv = transport->Connect(&callback); | |
136 if (rv == net::ERR_IO_PENDING) | |
137 rv = callback.WaitForResult(); | |
138 EXPECT_EQ(net::OK, rv); | |
139 | 143 |
140 scoped_ptr<net::SSLClientSocket> sock( | 144 scoped_ptr<net::SSLClientSocket> sock; |
141 socket_factory_->CreateSSLClientSocket(transport, | |
142 server_.kHostName, kDefaultSSLConfig)); | |
143 | 145 |
144 EXPECT_FALSE(sock->IsConnected()); | 146 sock.reset(CreateSSLClientSocket(addr, ssl_config)); |
145 | 147 |
146 rv = sock->Connect(&callback); | 148 rv = sock->Connect(&callback); |
147 if (rv != net::OK) { | 149 if (rv != net::OK) { |
148 ASSERT_EQ(net::ERR_IO_PENDING, rv); | 150 ASSERT_EQ(net::ERR_IO_PENDING, rv); |
149 EXPECT_FALSE(sock->IsConnected()); | 151 EXPECT_FALSE(sock->IsConnected()); |
150 | 152 |
151 rv = callback.WaitForResult(); | 153 rv = callback.WaitForResult(); |
152 EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv); | 154 // TODO(wtc): This should be net::ERR_CERT_DATE_INVALID. |
155 EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, rv); | |
153 } | 156 } |
154 | 157 |
155 // We cannot test sock->IsConnected(), as the NSS implementation disconnects | 158 // We cannot test sock->IsConnected(), as the NSS implementation disconnects |
156 // the socket when it encounters an error, whereas other implementations | 159 // the socket when it encounters an error, whereas other implementations |
157 // leave it connected. | 160 // leave it connected. |
161 | |
162 //////////////////////// | |
163 //////////////////////// | |
164 | |
165 net::SSLInfo ssl_info; | |
166 sock->GetSSLInfo(&ssl_info); | |
167 EXPECT_TRUE(ssl_info.cert); | |
168 EXPECT_EQ(net::CERT_STATUS_AUTHORITY_INVALID, | |
eroman
2009/08/15 02:04:29
style-nit: why not just EXPECT_TRUE(ssl_info.cert_
| |
169 ssl_info.cert_status & net::CERT_STATUS_AUTHORITY_INVALID); | |
170 net::SSLConfig::CertAndStatus bad_cert; | |
171 bad_cert.cert = ssl_info.cert; | |
172 bad_cert.cert_status = ssl_info.cert_status; | |
173 ssl_config.allowed_bad_certs.push_back(bad_cert); | |
174 | |
175 /////////////////////// | |
176 /////////////////////// | |
eroman
2009/08/15 02:04:29
style-nit: i haven't really seen the //// style in
| |
177 | |
178 sock->Disconnect(); | |
179 EXPECT_FALSE(sock->IsConnected()); | |
180 | |
181 /////////////////////// | |
182 /////////////////////// | |
183 | |
184 sock.reset(CreateSSLClientSocket(addr, ssl_config)); | |
185 | |
186 rv = sock->Connect(&callback); | |
187 if (rv != net::OK) { | |
188 ASSERT_EQ(net::ERR_IO_PENDING, rv); | |
189 EXPECT_FALSE(sock->IsConnected()); | |
190 | |
191 rv = callback.WaitForResult(); | |
192 EXPECT_EQ(net::OK, rv); | |
193 } | |
194 | |
195 EXPECT_TRUE(sock->IsConnected()); | |
196 | |
197 ssl_info.Reset(); | |
198 sock->GetSSLInfo(&ssl_info); | |
199 EXPECT_TRUE(ssl_info.cert); | |
200 EXPECT_EQ(net::CERT_STATUS_AUTHORITY_INVALID, | |
201 ssl_info.cert_status & net::CERT_STATUS_AUTHORITY_INVALID); | |
202 | |
203 sock->Disconnect(); | |
204 EXPECT_FALSE(sock->IsConnected()); | |
158 } | 205 } |
159 | 206 |
160 TEST_F(SSLClientSocketTest, MAYBE_ConnectMismatched) { | 207 TEST_F(SSLClientSocketTest, MAYBE_ConnectMismatched) { |
161 StartMismatchedServer(); | 208 StartMismatchedServer(); |
162 | 209 |
163 net::AddressList addr; | 210 net::AddressList addr; |
164 TestCompletionCallback callback; | 211 TestCompletionCallback callback; |
165 | 212 |
166 net::HostResolver::RequestInfo info(server_.kMismatchedHostName, | 213 net::HostResolver::RequestInfo info(server_.kMismatchedHostName, |
167 server_.kOKHTTPSPort); | 214 server_.kOKHTTPSPort); |
168 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); | 215 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); |
169 EXPECT_EQ(net::OK, rv); | 216 EXPECT_EQ(net::OK, rv); |
170 | 217 |
171 net::ClientSocket *transport = new net::TCPClientSocket(addr); | |
172 rv = transport->Connect(&callback); | |
173 if (rv == net::ERR_IO_PENDING) | |
174 rv = callback.WaitForResult(); | |
175 EXPECT_EQ(net::OK, rv); | |
176 | |
177 scoped_ptr<net::SSLClientSocket> sock( | 218 scoped_ptr<net::SSLClientSocket> sock( |
178 socket_factory_->CreateSSLClientSocket(transport, | 219 CreateSSLClientSocket(addr, kDefaultSSLConfig)); |
eroman
2009/08/15 02:04:29
Is this intentional? This used to use server_.kMis
| |
179 server_.kMismatchedHostName, kDefaultSSLConfig)); | |
180 | |
181 EXPECT_FALSE(sock->IsConnected()); | |
182 | 220 |
183 rv = sock->Connect(&callback); | 221 rv = sock->Connect(&callback); |
184 if (rv != net::ERR_CERT_COMMON_NAME_INVALID) { | 222 if (rv != net::ERR_CERT_COMMON_NAME_INVALID) { |
185 ASSERT_EQ(net::ERR_IO_PENDING, rv); | 223 ASSERT_EQ(net::ERR_IO_PENDING, rv); |
186 EXPECT_FALSE(sock->IsConnected()); | 224 EXPECT_FALSE(sock->IsConnected()); |
187 | 225 |
188 rv = callback.WaitForResult(); | 226 rv = callback.WaitForResult(); |
189 EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv); | 227 EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv); |
190 } | 228 } |
191 | 229 |
(...skipping 13 matching lines...) Expand all Loading... | |
205 net::AddressList addr; | 243 net::AddressList addr; |
206 TestCompletionCallback callback; | 244 TestCompletionCallback callback; |
207 | 245 |
208 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort); | 246 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort); |
209 int rv = resolver_->Resolve(NULL, info, &addr, &callback, NULL); | 247 int rv = resolver_->Resolve(NULL, info, &addr, &callback, NULL); |
210 EXPECT_EQ(net::ERR_IO_PENDING, rv); | 248 EXPECT_EQ(net::ERR_IO_PENDING, rv); |
211 | 249 |
212 rv = callback.WaitForResult(); | 250 rv = callback.WaitForResult(); |
213 EXPECT_EQ(net::OK, rv); | 251 EXPECT_EQ(net::OK, rv); |
214 | 252 |
215 net::ClientSocket *transport = new net::TCPClientSocket(addr); | |
216 rv = transport->Connect(&callback); | |
217 if (rv == net::ERR_IO_PENDING) | |
218 rv = callback.WaitForResult(); | |
219 EXPECT_EQ(net::OK, rv); | |
220 | |
221 scoped_ptr<net::SSLClientSocket> sock( | 253 scoped_ptr<net::SSLClientSocket> sock( |
222 socket_factory_->CreateSSLClientSocket(transport, | 254 CreateSSLClientSocket(addr, kDefaultSSLConfig)); |
223 server_.kHostName, | |
224 kDefaultSSLConfig)); | |
225 | 255 |
226 rv = sock->Connect(&callback); | 256 rv = sock->Connect(&callback); |
227 if (rv != net::OK) { | 257 if (rv != net::OK) { |
228 ASSERT_EQ(net::ERR_IO_PENDING, rv); | 258 ASSERT_EQ(net::ERR_IO_PENDING, rv); |
229 | 259 |
230 rv = callback.WaitForResult(); | 260 rv = callback.WaitForResult(); |
231 EXPECT_EQ(net::OK, rv); | 261 EXPECT_EQ(net::OK, rv); |
232 } | 262 } |
233 EXPECT_TRUE(sock->IsConnected()); | 263 EXPECT_TRUE(sock->IsConnected()); |
234 | 264 |
(...skipping 27 matching lines...) Expand all Loading... | |
262 TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) { | 292 TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) { |
263 StartOKServer(); | 293 StartOKServer(); |
264 | 294 |
265 net::AddressList addr; | 295 net::AddressList addr; |
266 TestCompletionCallback callback; | 296 TestCompletionCallback callback; |
267 | 297 |
268 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort); | 298 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort); |
269 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); | 299 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); |
270 EXPECT_EQ(net::OK, rv); | 300 EXPECT_EQ(net::OK, rv); |
271 | 301 |
272 net::ClientSocket *transport = new net::TCPClientSocket(addr); | |
273 rv = transport->Connect(&callback); | |
274 if (rv == net::ERR_IO_PENDING) | |
275 rv = callback.WaitForResult(); | |
276 EXPECT_EQ(net::OK, rv); | |
277 | |
278 scoped_ptr<net::SSLClientSocket> sock( | 302 scoped_ptr<net::SSLClientSocket> sock( |
279 socket_factory_->CreateSSLClientSocket(transport, | 303 CreateSSLClientSocket(addr, kDefaultSSLConfig)); |
280 server_.kHostName, kDefaultSSLConfig)); | |
281 | 304 |
282 rv = sock->Connect(&callback); | 305 rv = sock->Connect(&callback); |
283 if (rv != net::OK) { | 306 if (rv != net::OK) { |
284 ASSERT_EQ(net::ERR_IO_PENDING, rv); | 307 ASSERT_EQ(net::ERR_IO_PENDING, rv); |
285 | 308 |
286 rv = callback.WaitForResult(); | 309 rv = callback.WaitForResult(); |
287 EXPECT_EQ(net::OK, rv); | 310 EXPECT_EQ(net::OK, rv); |
288 } | 311 } |
289 | 312 |
290 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | 313 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
(...skipping 26 matching lines...) Expand all Loading... | |
317 TEST_F(SSLClientSocketTest, MAYBE_Read_Interrupted) { | 340 TEST_F(SSLClientSocketTest, MAYBE_Read_Interrupted) { |
318 StartOKServer(); | 341 StartOKServer(); |
319 | 342 |
320 net::AddressList addr; | 343 net::AddressList addr; |
321 TestCompletionCallback callback; | 344 TestCompletionCallback callback; |
322 | 345 |
323 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort); | 346 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort); |
324 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); | 347 int rv = resolver_->Resolve(NULL, info, &addr, NULL, NULL); |
325 EXPECT_EQ(net::OK, rv); | 348 EXPECT_EQ(net::OK, rv); |
326 | 349 |
327 net::ClientSocket *transport = new net::TCPClientSocket(addr); | |
328 rv = transport->Connect(&callback); | |
329 if (rv == net::ERR_IO_PENDING) | |
330 rv = callback.WaitForResult(); | |
331 EXPECT_EQ(net::OK, rv); | |
332 | |
333 scoped_ptr<net::SSLClientSocket> sock( | 350 scoped_ptr<net::SSLClientSocket> sock( |
334 socket_factory_->CreateSSLClientSocket(transport, | 351 CreateSSLClientSocket(addr, kDefaultSSLConfig)); |
335 server_.kHostName, kDefaultSSLConfig)); | |
336 | 352 |
337 rv = sock->Connect(&callback); | 353 rv = sock->Connect(&callback); |
338 if (rv != net::OK) { | 354 if (rv != net::OK) { |
339 ASSERT_EQ(net::ERR_IO_PENDING, rv); | 355 ASSERT_EQ(net::ERR_IO_PENDING, rv); |
340 | 356 |
341 rv = callback.WaitForResult(); | 357 rv = callback.WaitForResult(); |
342 EXPECT_EQ(net::OK, rv); | 358 EXPECT_EQ(net::OK, rv); |
343 } | 359 } |
344 | 360 |
345 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | 361 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
(...skipping 12 matching lines...) Expand all Loading... | |
358 // Do a partial read and then exit. This test should not crash! | 374 // Do a partial read and then exit. This test should not crash! |
359 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(512); | 375 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(512); |
360 rv = sock->Read(buf, 512, &callback); | 376 rv = sock->Read(buf, 512, &callback); |
361 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); | 377 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); |
362 | 378 |
363 if (rv == net::ERR_IO_PENDING) | 379 if (rv == net::ERR_IO_PENDING) |
364 rv = callback.WaitForResult(); | 380 rv = callback.WaitForResult(); |
365 | 381 |
366 EXPECT_NE(rv, 0); | 382 EXPECT_NE(rv, 0); |
367 } | 383 } |
OLD | NEW |