Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 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/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
| 6 | 6 |
| 7 #include <math.h> // ceil | 7 #include <math.h> // ceil |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/scoped_ptr.h" | 14 #include "base/scoped_ptr.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "net/base/auth.h" | 16 #include "net/base/auth.h" |
| 17 #include "net/base/capturing_net_log.h" | 17 #include "net/base/capturing_net_log.h" |
| 18 #include "net/base/completion_callback.h" | 18 #include "net/base/completion_callback.h" |
| 19 #include "net/base/mock_host_resolver.h" | 19 #include "net/base/mock_host_resolver.h" |
| 20 #include "net/base/net_log.h" | 20 #include "net/base/net_log.h" |
| 21 #include "net/base/net_log_unittest.h" | 21 #include "net/base/net_log_unittest.h" |
| 22 #include "net/base/request_priority.h" | 22 #include "net/base/request_priority.h" |
| 23 #include "net/base/ssl_cert_request_info.h" | |
| 23 #include "net/base/ssl_config_service_defaults.h" | 24 #include "net/base/ssl_config_service_defaults.h" |
| 24 #include "net/base/ssl_info.h" | 25 #include "net/base/ssl_info.h" |
| 25 #include "net/base/test_completion_callback.h" | 26 #include "net/base/test_completion_callback.h" |
| 26 #include "net/base/upload_data.h" | 27 #include "net/base/upload_data.h" |
| 27 #include "net/http/http_auth_handler_digest.h" | 28 #include "net/http/http_auth_handler_digest.h" |
| 28 #include "net/http/http_auth_handler_mock.h" | 29 #include "net/http/http_auth_handler_mock.h" |
| 29 #include "net/http/http_auth_handler_ntlm.h" | 30 #include "net/http/http_auth_handler_ntlm.h" |
| 30 #include "net/http/http_basic_stream.h" | 31 #include "net/http/http_basic_stream.h" |
| 31 #include "net/http/http_net_log_params.h" | 32 #include "net/http/http_net_log_params.h" |
| 32 #include "net/http/http_network_session.h" | 33 #include "net/http/http_network_session.h" |
| (...skipping 8167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8200 if (rv == net::ERR_IO_PENDING) | 8201 if (rv == net::ERR_IO_PENDING) |
| 8201 rv = callback.WaitForResult(); | 8202 rv = callback.WaitForResult(); |
| 8202 ASSERT_EQ(OK, rv); | 8203 ASSERT_EQ(OK, rv); |
| 8203 | 8204 |
| 8204 std::string contents; | 8205 std::string contents; |
| 8205 rv = ReadTransaction(trans.get(), &contents); | 8206 rv = ReadTransaction(trans.get(), &contents); |
| 8206 EXPECT_EQ(net::OK, rv); | 8207 EXPECT_EQ(net::OK, rv); |
| 8207 EXPECT_EQ("hello world", contents); | 8208 EXPECT_EQ("hello world", contents); |
| 8208 } | 8209 } |
| 8209 | 8210 |
| 8211 // Ensure that a client certificate is removed from the SSL client auth | |
| 8212 // cache when: | |
| 8213 // 1) No proxy is involved. | |
| 8214 // 2) TLS False Start is disabled. | |
| 8215 // 3) The initial TLS handshake requests a client certificate. | |
| 8216 // 4) The client supplies an invalid/unacceptable certificate. | |
| 8217 TEST_F(HttpNetworkTransactionTest, Direct_ClientAuthCertCache_NoFalseStart) { | |
|
wtc
2011/01/10 23:40:58
Nit: name the unit tests with "ClientAuthCertCache
| |
| 8218 SessionDependencies session_deps; | |
| 8219 | |
| 8220 // [ssl_]data1 represents the first TLS handshake. The handshake will fail | |
| 8221 // because a client certificate is requested | |
| 8222 // (net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED). A client certificate (NULL, in | |
| 8223 // this case) will then be supplied, and [ssl_]data2 will represent the | |
| 8224 // second handshake. Here, the handshake will fail because the | |
| 8225 // hypothetical server requires an actual certificate (or if this were a | |
| 8226 // real client certificate, a different certificate). Because the TLSv1 | |
| 8227 // handshake failed, HttpNetworkTransaction then tries an SSLv3 fallback, | |
| 8228 // [ssl_]data3, to try to distinguish if the reason for the failure was | |
| 8229 // client authentication (if so, it should fail again) or due to TLS | |
| 8230 // intolerance (in which case, it should succeed). Once the fallback | |
| 8231 // handshake fails, HttpNetworkTransaction will return the status to the | |
| 8232 // caller. | |
| 8233 SSLSocketDataProvider ssl_data1(true /* async */, | |
| 8234 net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | |
| 8235 SSLSocketDataProvider ssl_data2(true /* async */, | |
| 8236 net::ERR_SSL_PROTOCOL_ERROR); | |
| 8237 SSLSocketDataProvider ssl_data3(true /* async */, | |
| 8238 net::ERR_SSL_PROTOCOL_ERROR); | |
| 8239 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); | |
| 8240 cert_request->host_and_port = "www.example.com:443"; | |
| 8241 ssl_data1.cert_request_info = cert_request.get(); | |
| 8242 ssl_data2.cert_request_info = cert_request.get(); | |
| 8243 ssl_data3.cert_request_info = cert_request.get(); | |
| 8244 | |
| 8245 // Not particularly interested in the individual reads/writes, as the | |
| 8246 // SSL client auth cache is what is under inspection. | |
| 8247 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); | |
| 8248 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); | |
| 8249 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); | |
| 8250 | |
| 8251 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1); | |
| 8252 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2); | |
| 8253 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3); | |
| 8254 session_deps.socket_factory.AddSocketDataProvider(&data1); | |
| 8255 session_deps.socket_factory.AddSocketDataProvider(&data2); | |
| 8256 session_deps.socket_factory.AddSocketDataProvider(&data3); | |
| 8257 | |
| 8258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); | |
| 8259 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); | |
| 8260 | |
| 8261 net::HttpRequestInfo request_info; | |
| 8262 request_info.url = GURL("https://www.example.com/"); | |
| 8263 request_info.method = "GET"; | |
| 8264 request_info.load_flags = net::LOAD_NORMAL; | |
| 8265 | |
| 8266 TestCompletionCallback callback; | |
| 8267 int rv = trans->Start(&request_info, &callback, net::BoundNetLog()); | |
| 8268 ASSERT_EQ(net::ERR_IO_PENDING, rv); | |
| 8269 rv = callback.WaitForResult(); | |
| 8270 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); | |
| 8271 | |
| 8272 // Supply a dummy certificate. The SSLClientAuthCertCache tests ensure | |
| 8273 // this test should behave the same as if this test used a real cert. | |
| 8274 rv = trans->RestartWithCertificate(NULL, &callback); | |
| 8275 ASSERT_EQ(net::ERR_IO_PENDING, rv); | |
| 8276 | |
| 8277 // Ensure the certificate was added to the client auth cache before | |
| 8278 // allowing the connection to continue restarting. | |
| 8279 scoped_refptr<X509Certificate> client_cert; | |
| 8280 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", | |
| 8281 &client_cert)); | |
| 8282 ASSERT_EQ(NULL, client_cert.get()); | |
| 8283 rv = callback.WaitForResult(); | |
| 8284 | |
| 8285 // Now that the new handshake has failed, ensure that the client | |
| 8286 // certificate was removed from the client auth cache. | |
| 8287 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); | |
| 8288 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", | |
| 8289 &client_cert)); | |
| 8290 } | |
| 8291 | |
| 8292 // Ensure that a client certificate is removed from the SSL client auth | |
| 8293 // cache when: | |
| 8294 // 1) No proxy is involved. | |
| 8295 // 2) TLS False Start is enabled. | |
| 8296 // 3) The initial TLS handshake requests a client certificate. | |
| 8297 // 4) The client supplies an invalid/unacceptable certificate. | |
| 8298 TEST_F(HttpNetworkTransactionTest, Direct_ClientAuthCertCache_FalseStart) { | |
| 8299 SessionDependencies session_deps; | |
| 8300 | |
| 8301 // See Direct_ClientAuthCertCache_NoFalseStart for the explanation of | |
| 8302 // [ssl_]data[1-3]. | |
| 8303 // When False Start is used, the SSL Connect() calls artificially succeed, | |
| 8304 // because handshake errors involving client auth are not detected until | |
| 8305 // after the server has had a chance to process the client's Certificate | |
| 8306 // message and sends a response. With False Start, the response is | |
| 8307 // processed during the first Read() call on the SSL socket. | |
| 8308 SSLSocketDataProvider ssl_data1(true /* async */, net::OK); | |
| 8309 SSLSocketDataProvider ssl_data2(true /* async */, net::OK); | |
| 8310 SSLSocketDataProvider ssl_data3(true /* async */, net::OK); | |
| 8311 | |
| 8312 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); | |
| 8313 cert_request->host_and_port = "www.example.com:443"; | |
| 8314 ssl_data1.cert_request_info = cert_request.get(); | |
| 8315 ssl_data2.cert_request_info = cert_request.get(); | |
| 8316 ssl_data3.cert_request_info = cert_request.get(); | |
| 8317 | |
| 8318 // When TLS False Start is used, the SSL handshake is completed by the | |
| 8319 // first attempt to Read from the socket. Ensure that even if the error is | |
| 8320 // delayed until Read, the client cert is still evicted from the cache. | |
| 8321 net::MockRead data1_reads[] = { | |
| 8322 net::MockRead(true /* async */, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED), | |
| 8323 }; | |
| 8324 net::MockRead data2_reads[] = { | |
| 8325 net::MockRead(true /* async */, net::ERR_SSL_PROTOCOL_ERROR), | |
| 8326 }; | |
| 8327 net::StaticSocketDataProvider data1( | |
| 8328 data1_reads, arraysize(data1_reads), NULL, 0); | |
| 8329 net::StaticSocketDataProvider data2( | |
| 8330 data2_reads, arraysize(data2_reads), NULL, 0); | |
| 8331 net::StaticSocketDataProvider data3( | |
| 8332 data2_reads, arraysize(data2_reads), NULL, 0); | |
| 8333 | |
| 8334 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1); | |
| 8335 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2); | |
| 8336 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3); | |
| 8337 session_deps.socket_factory.AddSocketDataProvider(&data1); | |
| 8338 session_deps.socket_factory.AddSocketDataProvider(&data2); | |
| 8339 session_deps.socket_factory.AddSocketDataProvider(&data3); | |
| 8340 | |
| 8341 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); | |
| 8342 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); | |
| 8343 | |
| 8344 net::HttpRequestInfo request_info; | |
| 8345 request_info.url = GURL("https://www.example.com/"); | |
| 8346 request_info.method = "GET"; | |
| 8347 request_info.load_flags = net::LOAD_NORMAL; | |
| 8348 | |
| 8349 TestCompletionCallback callback; | |
| 8350 int rv = trans->Start(&request_info, &callback, net::BoundNetLog()); | |
| 8351 ASSERT_EQ(net::ERR_IO_PENDING, rv); | |
| 8352 rv = callback.WaitForResult(); | |
| 8353 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); | |
| 8354 | |
| 8355 // Supply a dummy certificate. The SSLClientAuthCertCache tests ensure | |
| 8356 // this test should behave the same as if this test used a real cert. | |
| 8357 rv = trans->RestartWithCertificate(NULL, &callback); | |
| 8358 ASSERT_EQ(net::ERR_IO_PENDING, rv); | |
| 8359 | |
| 8360 // Ensure the certificate was added to the client auth cache before | |
| 8361 // allowing the connection to continue restarting. | |
| 8362 scoped_refptr<X509Certificate> client_cert; | |
| 8363 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", | |
| 8364 &client_cert)); | |
| 8365 ASSERT_EQ(NULL, client_cert.get()); | |
| 8366 rv = callback.WaitForResult(); | |
| 8367 | |
| 8368 // Now that the new handshake has failed, ensure that the client | |
| 8369 // certificate was removed from the client auth cache. | |
| 8370 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); | |
| 8371 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443", | |
| 8372 &client_cert)); | |
| 8373 } | |
| 8374 | |
| 8210 } // namespace net | 8375 } // namespace net |
| OLD | NEW |