1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/ssl_client_socket.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/address_list.h" 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/cert_verifier.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/host_resolver.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/io_buffer.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_unittest.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/ssl_config_service.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/test_completion_callback.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_factory.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/socket_test_util.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/tcp_client_socket.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/test/test_server.h" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/platform_test.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//----------------------------------------------------------------------------- 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst net::SSLConfig kDefaultSSLConfig; 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SSLClientSocketTest : public PlatformTest { 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLClientSocketTest() 3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()), 3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen cert_verifier_(new net::CertVerifier) { 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::SSLClientSocket* CreateSSLClientSocket( 3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::ClientSocket* transport_socket, 3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const net::HostPortPair& host_and_port, 3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const net::SSLConfig& ssl_config) { 3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return socket_factory_->CreateSSLClientSocket(transport_socket, 4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen host_and_port, 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config, 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NULL, 4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen cert_verifier_.get()); 4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::ClientSocketFactory* socket_factory_; 4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<net::CertVerifier> cert_verifier_; 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//----------------------------------------------------------------------------- 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// LogContainsSSLConnectEndEvent returns true if the given index in the given 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// log is an SSL connect end event. The NSS sockets will cork in an attempt to 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// merge the first application data record with the Finished message when false 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// starting. However, in order to avoid the server timing out the handshake, 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// they'll give up waiting for application data and send the Finished after a 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// timeout. This means that an SSL connect end event may appear as a socket 58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// write. 59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic bool LogContainsSSLConnectEndEvent( 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const net::CapturingNetLog::EntryList& log, int i) { 613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return net::LogContainsEndEvent(log, i, net::NetLog::TYPE_SSL_CONNECT) || 623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net::LogContainsEvent(log, i, net::NetLog::TYPE_SOCKET_BYTES_SENT, 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::NetLog::PHASE_NONE); 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Connect) { 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport, test_server.host_port_pair(), kDefaultSSLConfig, 8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NULL, cert_verifier_.get())); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(sock->IsConnected()); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(net::LogContainsBeginEvent( 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 5, net::NetLog::TYPE_SSL_CONNECT)); 954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(sock->IsConnected()); 9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sock->Disconnect(); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(sock->IsConnected()); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, ConnectExpired) { 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions https_options( 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions::CERT_EXPIRED); 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer test_server(https_options, FilePath()); 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen kDefaultSSLConfig)); 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(sock->IsConnected()); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(net::LogContainsBeginEvent( 13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 5, net::NetLog::TYPE_SSL_CONNECT)); 1364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv); 1404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Rather than testing whether or not the underlying socket is connected, 1424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // test that the handshake has finished. This is because it may be 1434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // desirable to disconnect the socket before showing a user prompt, since 1444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // the user may take indefinitely long to respond. 14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, ConnectMismatched) { 150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions https_options( 151513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions::CERT_MISMATCHED_NAME); 152513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer test_server(https_options, FilePath()); 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen kDefaultSSLConfig)); 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(sock->IsConnected()); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(net::LogContainsBeginEvent( 17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 5, net::NetLog::TYPE_SSL_CONNECT)); 1794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv); 1834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Rather than testing whether or not the underlying socket is connected, 1854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // test that the handshake has finished. This is because it may be 1864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // desirable to disconnect the socket before showing a user prompt, since 1874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // the user may take indefinitely long to respond. 18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Attempt to connect to a page which requests a client certificate. It should 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// return an error code on connect. 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SSLClientSocketTest, ConnectClientAuthCertRequested) { 195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions https_options; 196513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch https_options.request_client_certificate = true; 197513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer test_server(https_options, FilePath()); 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::AddressList addr; 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv == net::ERR_IO_PENDING) 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(net::OK, rv); 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<net::SSLClientSocket> sock( 21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen kDefaultSSLConfig)); 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(sock->IsConnected()); 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = sock->Connect(&callback); 21921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 22021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(net::LogContainsBeginEvent( 22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 5, net::NetLog::TYPE_SSL_CONNECT)); 2244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Because we prematurely kill the handshake at CertificateRequest, 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the server may still send data (notably the ServerHelloDone) 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // after the error is returned. As a result, the SSL_CONNECT may not 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // be the last entry. See http://crbug.com/54445. We use 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // ExpectLogContainsSomewhere instead of 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // LogContainsSSLConnectEndEvent to avoid assuming, e.g., only one 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // extra read instead of two. This occurs before the handshake ends, 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // so the corking logic of LogContainsSSLConnectEndEvent isn't 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // necessary. 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(davidben): When SSL_RestartHandshakeAfterCertReq in NSS is 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // fixed and we can respond to the first CertificateRequest 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // without closing the socket, add a unit test for sending the 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // certificate. This test may still be useful as we'll want to close 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the socket on a timeout if the user takes a long time to pick a 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // cert. Related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=542832 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::ExpectLogContainsSomewhere( 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen entries, 0, net::NetLog::TYPE_SSL_CONNECT, net::NetLog::PHASE_END); 2464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 2474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_FALSE(sock->IsConnected()); 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Connect to a server requesting optional client authentication. Send it a 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// null certificate. It should allow the connection. 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// TODO(davidben): Also test providing an actual certificate. 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) { 255513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions https_options; 256513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch https_options.request_client_certificate = true; 257513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer test_server(https_options, FilePath()); 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::AddressList addr; 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv == net::ERR_IO_PENDING) 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(net::OK, rv); 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::SSLConfig ssl_config = kDefaultSSLConfig; 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_config.send_client_cert = true; 2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_config.client_cert = NULL; 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<net::SSLClientSocket> sock( 27721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 27821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config)); 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(sock->IsConnected()); 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Our test server accepts certificate-less connections. 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(davidben): Add a test which requires them and verify the error. 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = sock->Connect(&callback); 28521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 28621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 28721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 2883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(net::LogContainsBeginEvent( 28921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 5, net::NetLog::TYPE_SSL_CONNECT)); 2904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(sock->IsConnected()); 29521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 29621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); 2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sock->Disconnect(); 2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(sock->IsConnected()); 3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(wtc): Add unit tests for IsConnectedAndIdle: 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Server closes an SSL connection (with a close_notify alert message). 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Server closes the underlying TCP connection directly. 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Server sends data unexpectedly. 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Read) { 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 3123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, NULL, net::NetLog::Source()); 3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen kDefaultSSLConfig)); 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 3274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 3294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(sock->IsConnected()); 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 333513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> request_buffer( 334513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::IOBuffer(arraysize(request_text) - 1)); 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback); 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 344513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(4096)); 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (;;) { 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Read(buf, 4096, &callback); 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_GE(rv, 0); 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv <= 0) 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the full duplex mode, with Read and Write pending at the same time. 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This test also serves as a regression test for http://crbug.com/29815. 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Read_FullDuplex) { 3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; // Used for everything except Write. 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; // Used for Write only. 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, NULL, net::NetLog::Source()); 3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 378731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick socket_factory_->CreateSSLClientSocket( 37921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport, test_server.host_port_pair(), kDefaultSSLConfig, 38021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NULL, cert_verifier_.get())); 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 3834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 3854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(sock->IsConnected()); 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Issue a "hanging" Read first. 389513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(4096)); 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Read(buf, 4096, &callback); 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We haven't written the request, so there should be no response yet. 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_EQ(net::ERR_IO_PENDING, rv); 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Write the request. 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The request is padded with a User-Agent header to a size that causes the 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around. 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This tests the fix for http://crbug.com/29815. 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name "; 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < 3800; ++i) 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_text.push_back('*'); 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_text.append("\r\n\r\n"); 402513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> request_buffer( 403513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::StringIOBuffer(request_text)); 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Write(request_buffer, request_text.size(), &callback2); 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(static_cast<int>(request_text.size()), rv); 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Now get the Read result. 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_GT(rv, 0); 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Read_SmallChunks) { 4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, NULL, net::NetLog::Source()); 4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen kDefaultSSLConfig)); 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 4374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 442513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> request_buffer( 443513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::IOBuffer(arraysize(request_text) - 1)); 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback); 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 453513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(1)); 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (;;) { 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Read(buf, 1, &callback); 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_GE(rv, 0); 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv <= 0) 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Read_Interrupted) { 4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, NULL, net::NetLog::Source()); 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 48321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen kDefaultSSLConfig)); 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 4874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 492513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> request_buffer( 493513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::IOBuffer(arraysize(request_text) - 1)); 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback); 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Do a partial read and then exit. This test should not crash! 504513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(512)); 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Read(buf, 512, &callback); 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv > 0 || rv == net::ERR_IO_PENDING); 507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_GT(rv, 0); 512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Regression test for http://crbug.com/42538 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(SSLClientSocketTest, PrematureApplicationData) { 5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::AddressList addr; 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const unsigned char application_data[] = { 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b, 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0xc2, 0xf8, 0xb2, 0xc1, 0x56, 0x42, 0xb9, 0x57, 0x7f, 0xde, 0x87, 0x46, 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0xf7, 0xa3, 0x52, 0x42, 0x21, 0xf0, 0x13, 0x1c, 0x9c, 0x83, 0x88, 0xd6, 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x93, 0x0c, 0xf6, 0x36, 0x30, 0x05, 0x7e, 0x20, 0xb5, 0xb5, 0x73, 0x36, 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x53, 0x83, 0x0a, 0xfc, 0x17, 0x63, 0xbf, 0xa0, 0xe4, 0x42, 0x90, 0x0d, 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x2f, 0x18, 0x6d, 0x20, 0xd8, 0x36, 0x3f, 0xfc, 0xe6, 0x01, 0xfa, 0x0f, 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0xa5, 0x75, 0x7f, 0x09, 0x00, 0x04, 0x00, 0x16, 0x03, 0x01, 0x11, 0x57, 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x0b, 0x00, 0x11, 0x53, 0x00, 0x11, 0x50, 0x00, 0x06, 0x22, 0x30, 0x82, 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x0a 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All reads and writes complete synchronously (async=false). 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::MockRead data_reads[] = { 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::MockRead(false, reinterpret_cast<const char*>(application_data), 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(application_data)), 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::MockRead(false, net::OK), 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::StaticSocketDataProvider data(data_reads, arraysize(data_reads), 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 0); 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::ClientSocket* transport = 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new net::MockTCPClientSocket(addr, NULL, &data); 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = transport->Connect(&callback); 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(net::OK, rv); 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<net::SSLClientSocket> sock( 55321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 55421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen kDefaultSSLConfig)); 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 56021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TODO(rsleevi): Not implemented for Schannel. As Schannel is only used when 5614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// performing client authentication, it will not be tested here. 56221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(SSLClientSocketTest, CipherSuiteDisables) { 5634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Rather than exhaustively disabling every RC4 ciphersuite defined at 5644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml, 5654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // only disabling those cipher suites that the test server actually 5664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // implements. 5674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const uint16 kCiphersToDisable[] = { 5684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 0x0005, // TLS_RSA_WITH_RC4_128_SHA 5694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 5704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::TestServer::HTTPSOptions https_options; 5724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Enable only RC4 on the test server. 5734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch https_options.bulk_ciphers = 5744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::TestServer::HTTPSOptions::BULK_CIPHER_RC4; 5754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::TestServer test_server(https_options, FilePath()); 5764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(test_server.Start()); 5774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::AddressList addr; 5794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(test_server.GetAddressList(&addr)); 5804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch TestCompletionCallback callback; 5824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 5834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::ClientSocket* transport = new net::TCPClientSocket( 5844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch addr, &log, net::NetLog::Source()); 5854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int rv = transport->Connect(&callback); 5864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 5874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = callback.WaitForResult(); 5884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 5894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::SSLConfig ssl_config; 5914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (size_t i = 0; i < arraysize(kCiphersToDisable); ++i) 5924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ssl_config.disabled_cipher_suites.push_back(kCiphersToDisable[i]); 5934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<net::SSLClientSocket> sock( 59521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CreateSSLClientSocket(transport, test_server.host_port_pair(), 59621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config)); 5974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_FALSE(sock->IsConnected()); 5994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 6004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = sock->Connect(&callback); 60121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CapturingNetLog::EntryList entries; 60221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 6034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(net::LogContainsBeginEvent( 60421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen entries, 5, net::NetLog::TYPE_SSL_CONNECT)); 6054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 6064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // NSS has special handling that maps a handshake_failure alert received 6074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // immediately after a client_hello to be a mismatched cipher suite error, 6084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // leading to ERR_SSL_VERSION_OR_CIPHER_MISMATCH. When using OpenSSL or 6094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Secure Transport (OS X), the handshake_failure is bubbled up without any 6104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // interpretation, leading to ERR_SSL_PROTOCOL_ERROR. Either way, a failure 6114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // indicates that no cipher suite was negotiated with the test server. 6124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 6134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = callback.WaitForResult(); 6144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(rv == net::ERR_SSL_VERSION_OR_CIPHER_MISMATCH || 6154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv == net::ERR_SSL_PROTOCOL_ERROR); 6164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // The exact ordering differs between SSLClientSocketNSS (which issues an 6174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // extra read) and SSLClientSocketMac (which does not). Just make sure the 6184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // error appears somewhere in the log. 61921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log.GetEntries(&entries); 62021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::ExpectLogContainsSomewhere(entries, 0, 6214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::NetLog::TYPE_SSL_HANDSHAKE_ERROR, 6224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::NetLog::PHASE_NONE); 6234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 6244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // We cannot test sock->IsConnected(), as the NSS implementation disconnects 6254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // the socket when it encounters an error, whereas other implementations 6264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // leave it connected. 6273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Because this an error that the test server is mutually aware of, as opposed 6283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // to being an error such as a certificate name mismatch, which is 6293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // client-only, the exact index of the SSL connect end depends on how 6303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // quickly the test server closes the underlying socket. If the test server 6313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // closes before the IO message loop pumps messages, there may be a 0-byte 6323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Read event in the NetLog due to TCPClientSocket picking up the EOF. As a 6333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // result, the SSL connect end event will be the second-to-last entry, 6343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // rather than the last entry. 6353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1) || 6363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LogContainsSSLConnectEndEvent(entries, -2)); 6374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 638