ssl_client_socket_unittest.cc revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
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" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/host_resolver.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/io_buffer.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_unittest.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/ssl_config_service.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/test_completion_callback.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_factory.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/socket_test_util.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/tcp_client_socket.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/test/test_server.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/platform_test.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//----------------------------------------------------------------------------- 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst net::SSLConfig kDefaultSSLConfig; 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SSLClientSocketTest : public PlatformTest { 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SSLClientSocketTest() 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) { 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::ClientSocketFactory* socket_factory_; 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//----------------------------------------------------------------------------- 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// LogContainsSSLConnectEndEvent returns true if the given index in the given 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// log is an SSL connect end event. The NSS sockets will cork in an attempt to 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// merge the first application data record with the Finished message when false 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// starting. However, in order to avoid the server timing out the handshake, 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// they'll give up waiting for application data and send the Finished after a 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// timeout. This means that an SSL connect end event may appear as a socket 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// write. 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic bool LogContainsSSLConnectEndEvent( 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const net::CapturingNetLog::EntryList& log, int i) { 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return net::LogContainsEndEvent(log, -1, net::NetLog::TYPE_SSL_CONNECT) || 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::LogContainsEvent(log, -1, net::NetLog::TYPE_SOCKET_BYTES_SENT, 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::NetLog::PHASE_NONE); 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Connect) { 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(sock->IsConnected()); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(net::LogContainsBeginEvent( 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT)); 774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(sock->IsConnected()); 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1)); 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sock->Disconnect(); 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(sock->IsConnected()); 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, ConnectExpired) { 88513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions https_options( 89513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions::CERT_EXPIRED); 90513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer test_server(https_options, FilePath()); 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 1064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 1074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(sock->IsConnected()); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(net::LogContainsBeginEvent( 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT)); 1144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv); 1184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Rather than testing whether or not the underlying socket is connected, 1204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // test that the handshake has finished. This is because it may be 1214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // desirable to disconnect the socket before showing a user prompt, since 1224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // the user may take indefinitely long to respond. 123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1)); 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, ConnectMismatched) { 127513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions https_options( 128513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions::CERT_MISMATCHED_NAME); 129513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer test_server(https_options, FilePath()); 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 1454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 1464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(sock->IsConnected()); 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(net::LogContainsBeginEvent( 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT)); 1544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv); 1584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Rather than testing whether or not the underlying socket is connected, 1604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // test that the handshake has finished. This is because it may be 1614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // desirable to disconnect the socket before showing a user prompt, since 1624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // the user may take indefinitely long to respond. 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1)); 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Attempt to connect to a page which requests a client certificate. It should 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// return an error code on connect. 168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Flaky: http://crbug.com/54445 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(SSLClientSocketTest, FLAKY_ConnectClientAuthCertRequested) { 170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions https_options; 171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch https_options.request_client_certificate = true; 172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer test_server(https_options, FilePath()); 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::AddressList addr; 1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv == net::ERR_IO_PENDING) 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(net::OK, rv); 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<net::SSLClientSocket> sock( 1884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 1894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(sock->IsConnected()); 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = sock->Connect(&callback); 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(net::LogContainsBeginEvent( 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT)); 1964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); 2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_FALSE(sock->IsConnected()); 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Connect to a server requesting optional client authentication. Send it a 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// null certificate. It should allow the connection. 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// TODO(davidben): Also test providing an actual certificate. 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) { 208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer::HTTPSOptions https_options; 209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch https_options.request_client_certificate = true; 210513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch net::TestServer test_server(https_options, FilePath()); 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::AddressList addr; 2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, &log, net::NetLog::Source()); 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv == net::ERR_IO_PENDING) 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(net::OK, rv); 2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::SSLConfig ssl_config = kDefaultSSLConfig; 2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_config.send_client_cert = true; 2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssl_config.client_cert = NULL; 2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<net::SSLClientSocket> sock( 2304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 2314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), ssl_config, NULL)); 2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(sock->IsConnected()); 2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Our test server accepts certificate-less connections. 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(davidben): Add a test which requires them and verify the error. 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = sock->Connect(&callback); 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(net::LogContainsBeginEvent( 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT)); 2404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = callback.WaitForResult(); 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(sock->IsConnected()); 245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1)); 2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sock->Disconnect(); 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(sock->IsConnected()); 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(wtc): Add unit tests for IsConnectedAndIdle: 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Server closes an SSL connection (with a close_notify alert message). 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Server closes the underlying TCP connection directly. 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Server sends data unexpectedly. 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Read) { 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, NULL, net::NetLog::Source()); 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 272731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick socket_factory_->CreateSSLClientSocket( 2734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 2764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 2784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(sock->IsConnected()); 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> request_buffer( 283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::IOBuffer(arraysize(request_text) - 1)); 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback); 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(4096)); 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (;;) { 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Read(buf, 4096, &callback); 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_GE(rv, 0); 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv <= 0) 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the full duplex mode, with Read and Write pending at the same time. 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This test also serves as a regression test for http://crbug.com/29815. 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Read_FullDuplex) { 3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback; // Used for everything except Write. 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompletionCallback callback2; // Used for Write only. 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, NULL, net::NetLog::Source()); 3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick socket_factory_->CreateSSLClientSocket( 3284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 3314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 3334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(sock->IsConnected()); 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Issue a "hanging" Read first. 337513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(4096)); 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Read(buf, 4096, &callback); 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We haven't written the request, so there should be no response yet. 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_EQ(net::ERR_IO_PENDING, rv); 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Write the request. 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The request is padded with a User-Agent header to a size that causes the 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around. 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This tests the fix for http://crbug.com/29815. 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name "; 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < 3800; ++i) 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_text.push_back('*'); 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_text.append("\r\n\r\n"); 350513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> request_buffer( 351513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::StringIOBuffer(request_text)); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Write(request_buffer, request_text.size(), &callback2); 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback2.WaitForResult(); 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(static_cast<int>(request_text.size()), rv); 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Now get the Read result. 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_GT(rv, 0); 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Read_SmallChunks) { 3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, NULL, net::NetLog::Source()); 3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 3814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 3824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 3854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 3874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 390513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> request_buffer( 391513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::IOBuffer(arraysize(request_text) - 1)); 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback); 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 401513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(1)); 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (;;) { 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Read(buf, 1, &callback); 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_GE(rv, 0); 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv <= 0) 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(SSLClientSocketTest, Read_Interrupted) { 4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::AddressList addr; 4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.GetAddressList(&addr)); 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TestCompletionCallback callback; 4233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::ClientSocket* transport = new net::TCPClientSocket( 4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr, NULL, net::NetLog::Source()); 4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = transport->Connect(&callback); 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(net::OK, rv); 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<net::SSLClientSocket> sock( 4314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 4324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 4354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 4374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 440513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> request_buffer( 441513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::IOBuffer(arraysize(request_text) - 1)); 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback); 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING); 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Do a partial read and then exit. This test should not crash! 452513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(512)); 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = sock->Read(buf, 512, &callback); 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(rv > 0 || rv == net::ERR_IO_PENDING); 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = callback.WaitForResult(); 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_GT(rv, 0); 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Regression test for http://crbug.com/42538 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(SSLClientSocketTest, PrematureApplicationData) { 4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath()); 4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(test_server.Start()); 4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::AddressList addr; 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback callback; 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const unsigned char application_data[] = { 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b, 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0xc2, 0xf8, 0xb2, 0xc1, 0x56, 0x42, 0xb9, 0x57, 0x7f, 0xde, 0x87, 0x46, 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0xf7, 0xa3, 0x52, 0x42, 0x21, 0xf0, 0x13, 0x1c, 0x9c, 0x83, 0x88, 0xd6, 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x93, 0x0c, 0xf6, 0x36, 0x30, 0x05, 0x7e, 0x20, 0xb5, 0xb5, 0x73, 0x36, 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x53, 0x83, 0x0a, 0xfc, 0x17, 0x63, 0xbf, 0xa0, 0xe4, 0x42, 0x90, 0x0d, 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x2f, 0x18, 0x6d, 0x20, 0xd8, 0x36, 0x3f, 0xfc, 0xe6, 0x01, 0xfa, 0x0f, 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0xa5, 0x75, 0x7f, 0x09, 0x00, 0x04, 0x00, 0x16, 0x03, 0x01, 0x11, 0x57, 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x0b, 0x00, 0x11, 0x53, 0x00, 0x11, 0x50, 0x00, 0x06, 0x22, 0x30, 0x82, 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0x0a 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All reads and writes complete synchronously (async=false). 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::MockRead data_reads[] = { 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::MockRead(false, reinterpret_cast<const char*>(application_data), 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arraysize(application_data)), 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::MockRead(false, net::OK), 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::StaticSocketDataProvider data(data_reads, arraysize(data_reads), 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 0); 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::ClientSocket* transport = 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new net::MockTCPClientSocket(addr, NULL, &data); 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = transport->Connect(&callback); 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = callback.WaitForResult(); 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(net::OK, rv); 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<net::SSLClientSocket> sock( 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch socket_factory_->CreateSSLClientSocket( 5024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), kDefaultSSLConfig, NULL)); 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = sock->Connect(&callback); 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv); 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 5074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#if defined(USE_OPENSSL) 5094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// TODO(rsleevi): Not implemented for Schannel or OpenSSL. Schannel is 5104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// controlled by the SSL client socket factory, rather than a define, so it 5114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// cannot be conditionally disabled here. As Schannel is only used when 5124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// performing client authentication, it will not be tested here. 5134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#define MAYBE_CipherSuiteDisables DISABLED_CipherSuiteDisables 5144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#else 5154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#define MAYBE_CipherSuiteDisables CipherSuiteDisables 5164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#endif 5174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST_F(SSLClientSocketTest, MAYBE_CipherSuiteDisables) { 5184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Rather than exhaustively disabling every RC4 ciphersuite defined at 5194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml, 5204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // only disabling those cipher suites that the test server actually 5214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // implements. 5224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const uint16 kCiphersToDisable[] = { 5234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 0x0005, // TLS_RSA_WITH_RC4_128_SHA 5244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 5254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::TestServer::HTTPSOptions https_options; 5274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Enable only RC4 on the test server. 5284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch https_options.bulk_ciphers = 5294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::TestServer::HTTPSOptions::BULK_CIPHER_RC4; 5304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::TestServer test_server(https_options, FilePath()); 5314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(test_server.Start()); 5324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::AddressList addr; 5344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ASSERT_TRUE(test_server.GetAddressList(&addr)); 5354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch TestCompletionCallback callback; 5374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::CapturingNetLog log(net::CapturingNetLog::kUnbounded); 5384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::ClientSocket* transport = new net::TCPClientSocket( 5394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch addr, &log, net::NetLog::Source()); 5404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int rv = transport->Connect(&callback); 5414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 5424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = callback.WaitForResult(); 5434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ(net::OK, rv); 5444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::SSLConfig ssl_config; 5464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (size_t i = 0; i < arraysize(kCiphersToDisable); ++i) 5474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ssl_config.disabled_cipher_suites.push_back(kCiphersToDisable[i]); 5484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<net::SSLClientSocket> sock( 5504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch socket_factory_->CreateSSLClientSocket( 5514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport, test_server.host_port_pair(), ssl_config, NULL)); 5524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_FALSE(sock->IsConnected()); 5544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = sock->Connect(&callback); 5564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(net::LogContainsBeginEvent( 5574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT)); 5584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // NSS has special handling that maps a handshake_failure alert received 5604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // immediately after a client_hello to be a mismatched cipher suite error, 5614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // leading to ERR_SSL_VERSION_OR_CIPHER_MISMATCH. When using OpenSSL or 5624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Secure Transport (OS X), the handshake_failure is bubbled up without any 5634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // interpretation, leading to ERR_SSL_PROTOCOL_ERROR. Either way, a failure 5644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // indicates that no cipher suite was negotiated with the test server. 5654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (rv == net::ERR_IO_PENDING) 5664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv = callback.WaitForResult(); 5674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(rv == net::ERR_SSL_VERSION_OR_CIPHER_MISMATCH || 5684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rv == net::ERR_SSL_PROTOCOL_ERROR); 5694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // The exact ordering differs between SSLClientSocketNSS (which issues an 5704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // extra read) and SSLClientSocketMac (which does not). Just make sure the 5714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // error appears somewhere in the log. 5724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::ExpectLogContainsSomewhere(log.entries(), 0, 5734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::NetLog::TYPE_SSL_HANDSHAKE_ERROR, 5744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch net::NetLog::PHASE_NONE); 5754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // We cannot test sock->IsConnected(), as the NSS implementation disconnects 5774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // the socket when it encounters an error, whereas other implementations 5784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // leave it connected. 5794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1)); 5804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 581