Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Side by Side Diff: net/http/http_network_transaction_unittest.cc

Issue 6017010: Ensure that when using False Start + client auth, bad client certificates are not cached (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix mac compile Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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, ClientAuthCertCache_Direct_NoFalseStart) {
8218 SessionDependencies session_deps;
8219
8220 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
8221 cert_request->host_and_port = "www.example.com:443";
8222
8223 // [ssl_]data1 contains the data for the first SSL handshake. When a
8224 // CertificateRequest is received for the first time, the handshake will
8225 // be aborted to allow the caller to provide a certificate.
8226 SSLSocketDataProvider ssl_data1(true /* async */,
8227 net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
8228 ssl_data1.cert_request_info = cert_request.get();
8229 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
8230 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
8231 session_deps.socket_factory.AddSocketDataProvider(&data1);
8232
8233 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
8234 // False Start is not being used, the result of the SSL handshake will be
8235 // returned as part of the SSLClientSocket::Connect() call. This test
8236 // matches the result of a server sending a handshake_failure alert,
8237 // rather than a Finished message, because it requires a client
8238 // certificate and none was supplied.
8239 SSLSocketDataProvider ssl_data2(true /* async */,
8240 net::ERR_SSL_PROTOCOL_ERROR);
8241 ssl_data2.cert_request_info = cert_request.get();
8242 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
8243 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
8244 session_deps.socket_factory.AddSocketDataProvider(&data2);
8245
8246 // [ssl_]data3 contains the data for the third SSL handshake. When a
8247 // connection to a server fails during an SSL handshake,
8248 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the initial
8249 // connection was attempted with TLSv1. This is transparent to the caller
8250 // of the HttpNetworkTransaction. Because this test failure is due to
8251 // requiring a client certificate, this fallback handshake should also
8252 // fail.
8253 SSLSocketDataProvider ssl_data3(true /* async */,
8254 net::ERR_SSL_PROTOCOL_ERROR);
8255 ssl_data3.cert_request_info = cert_request.get();
8256 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3);
8257 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
8258 session_deps.socket_factory.AddSocketDataProvider(&data3);
8259
8260 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8261 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
8262
8263 net::HttpRequestInfo request_info;
8264 request_info.url = GURL("https://www.example.com/");
8265 request_info.method = "GET";
8266 request_info.load_flags = net::LOAD_NORMAL;
8267
8268 // Begin the SSL handshake with the peer. This consumes ssl_data1.
8269 TestCompletionCallback callback;
8270 int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
8271 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8272
8273 // Complete the SSL handshake, which should abort due to requiring a
8274 // client certificate.
8275 rv = callback.WaitForResult();
8276 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
8277
8278 // Indicate that no certificate should be supplied. From the perspective
8279 // of SSLClientCertCache, NULL is just as meaningful as a real
8280 // certificate, so this is the same as supply a
8281 // legitimate-but-unacceptable certificate.
8282 rv = trans->RestartWithCertificate(NULL, &callback);
8283 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8284
8285 // Ensure the certificate was added to the client auth cache before
8286 // allowing the connection to continue restarting.
8287 scoped_refptr<X509Certificate> client_cert;
8288 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8289 &client_cert));
8290 ASSERT_EQ(NULL, client_cert.get());
8291
8292 // Restart the handshake. This will consume ssl_data2, which fails, and
8293 // then consume ssl_data3, which should also fail. The result code is
8294 // checked against what ssl_data3 should return.
8295 rv = callback.WaitForResult();
8296 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
8297
8298 // Ensure that the client certificate is removed from the cache on a
8299 // handshake failure.
8300 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8301 &client_cert));
8302 }
8303
8304 // Ensure that a client certificate is removed from the SSL client auth
8305 // cache when:
8306 // 1) No proxy is involved.
8307 // 2) TLS False Start is enabled.
8308 // 3) The initial TLS handshake requests a client certificate.
8309 // 4) The client supplies an invalid/unacceptable certificate.
8310 TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
8311 SessionDependencies session_deps;
8312
8313 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
8314 cert_request->host_and_port = "www.example.com:443";
8315
8316 // When TLS False Start is used, SSLClientSocket::Connect() calls will
8317 // return successfully after reading up to the peer's Certificate message.
8318 // This is to allow the caller to call SSLClientSocket::Write(), which can
8319 // enqueue application data to be sent in the same packet as the
8320 // ChangeCipherSpec and Finished messages.
8321 // The actual handshake will be finished when SSLClientSocket::Read() is
8322 // called, which expects to process the peer's ChangeCipherSpec and
8323 // Finished messages. If there was an error negotiating with the peer,
8324 // such as due to the peer requiring a client certificate when none was
8325 // supplied, the alert sent by the peer won't be processed until Read() is
8326 // called.
8327
8328 // Like the non-False Start case, when a client certificate is requested by
8329 // the peer, the handshake is aborted during the Connect() call.
8330 // [ssl_]data1 represents the initial SSL handshake with the peer.
8331 SSLSocketDataProvider ssl_data1(true /* async */,
8332 net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
8333 ssl_data1.cert_request_info = cert_request.get();
8334 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
8335 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
8336 session_deps.socket_factory.AddSocketDataProvider(&data1);
8337
8338 // When a client certificate is supplied, Connect() will not be aborted
8339 // when the peer requests the certificate. Instead, the handshake will
8340 // artificially succeed, allowing the caller to write the HTTP request to
8341 // the socket. The handshake messages are not processed until Read() is
8342 // called, which then detects that the handshake was aborted, due to the
8343 // peer sending a handshake_failure because it requires a client
8344 // certificate.
8345 SSLSocketDataProvider ssl_data2(true /* async */, net::OK);
8346 ssl_data2.cert_request_info = cert_request.get();
8347 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
8348 net::MockRead data2_reads[] = {
8349 net::MockRead(true /* async */, net::ERR_SSL_PROTOCOL_ERROR),
8350 };
8351 net::StaticSocketDataProvider data2(
8352 data2_reads, arraysize(data2_reads), NULL, 0);
8353 session_deps.socket_factory.AddSocketDataProvider(&data2);
8354
8355 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
8356 // the data for the SSL handshake once the TLSv1 connection falls back to
8357 // SSLv3. It has the same behaviour as [ssl_]data2.
8358 SSLSocketDataProvider ssl_data3(true /* async */, net::OK);
8359 ssl_data3.cert_request_info = cert_request.get();
8360 session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3);
8361 net::StaticSocketDataProvider data3(
8362 data2_reads, arraysize(data2_reads), NULL, 0);
8363 session_deps.socket_factory.AddSocketDataProvider(&data3);
8364
8365 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
8366 scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
8367
8368 net::HttpRequestInfo request_info;
8369 request_info.url = GURL("https://www.example.com/");
8370 request_info.method = "GET";
8371 request_info.load_flags = net::LOAD_NORMAL;
8372
8373 // Begin the initial SSL handshake.
8374 TestCompletionCallback callback;
8375 int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
8376 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8377
8378 // Complete the SSL handshake, which should abort due to requiring a
8379 // client certificate.
8380 rv = callback.WaitForResult();
8381 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
8382
8383 // Indicate that no certificate should be supplied. From the perspective
8384 // of SSLClientCertCache, NULL is just as meaningful as a real
8385 // certificate, so this is the same as supply a
8386 // legitimate-but-unacceptable certificate.
8387 rv = trans->RestartWithCertificate(NULL, &callback);
8388 ASSERT_EQ(net::ERR_IO_PENDING, rv);
8389
8390 // Ensure the certificate was added to the client auth cache before
8391 // allowing the connection to continue restarting.
8392 scoped_refptr<X509Certificate> client_cert;
8393 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8394 &client_cert));
8395 ASSERT_EQ(NULL, client_cert.get());
8396
8397
8398 // Restart the handshake. This will consume ssl_data2, which fails, and
8399 // then consume ssl_data3, which should also fail. The result code is
8400 // checked against what ssl_data3 should return.
8401 rv = callback.WaitForResult();
8402 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
8403
8404 // Ensure that the client certificate is removed from the cache on a
8405 // handshake failure.
8406 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
8407 &client_cert));
8408 }
8409
8210 } // namespace net 8410 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698