Home | History | Annotate | Download | only in socket
      1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/socket/ssl_client_socket.h"
      6 
      7 #include "net/base/address_list.h"
      8 #include "net/base/cert_verifier.h"
      9 #include "net/base/host_resolver.h"
     10 #include "net/base/io_buffer.h"
     11 #include "net/base/net_log.h"
     12 #include "net/base/net_log_unittest.h"
     13 #include "net/base/net_errors.h"
     14 #include "net/base/ssl_config_service.h"
     15 #include "net/base/test_completion_callback.h"
     16 #include "net/socket/client_socket_factory.h"
     17 #include "net/socket/socket_test_util.h"
     18 #include "net/socket/tcp_client_socket.h"
     19 #include "net/test/test_server.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "testing/platform_test.h"
     22 
     23 //-----------------------------------------------------------------------------
     24 
     25 const net::SSLConfig kDefaultSSLConfig;
     26 
     27 class SSLClientSocketTest : public PlatformTest {
     28  public:
     29   SSLClientSocketTest()
     30       : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()),
     31         cert_verifier_(new net::CertVerifier) {
     32   }
     33 
     34  protected:
     35   net::SSLClientSocket* CreateSSLClientSocket(
     36       net::ClientSocket* transport_socket,
     37       const net::HostPortPair& host_and_port,
     38       const net::SSLConfig& ssl_config) {
     39     return socket_factory_->CreateSSLClientSocket(transport_socket,
     40                                                   host_and_port,
     41                                                   ssl_config,
     42                                                   NULL,
     43                                                   cert_verifier_.get());
     44   }
     45 
     46   net::ClientSocketFactory* socket_factory_;
     47   scoped_ptr<net::CertVerifier> cert_verifier_;
     48 };
     49 
     50 //-----------------------------------------------------------------------------
     51 
     52 // LogContainsSSLConnectEndEvent returns true if the given index in the given
     53 // log is an SSL connect end event. The NSS sockets will cork in an attempt to
     54 // merge the first application data record with the Finished message when false
     55 // starting. However, in order to avoid the server timing out the handshake,
     56 // they'll give up waiting for application data and send the Finished after a
     57 // timeout. This means that an SSL connect end event may appear as a socket
     58 // write.
     59 static bool LogContainsSSLConnectEndEvent(
     60     const net::CapturingNetLog::EntryList& log, int i) {
     61   return net::LogContainsEndEvent(log, i, net::NetLog::TYPE_SSL_CONNECT) ||
     62          net::LogContainsEvent(log, i, net::NetLog::TYPE_SOCKET_BYTES_SENT,
     63                                 net::NetLog::PHASE_NONE);
     64 };
     65 
     66 TEST_F(SSLClientSocketTest, Connect) {
     67   net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
     68   ASSERT_TRUE(test_server.Start());
     69 
     70   net::AddressList addr;
     71   ASSERT_TRUE(test_server.GetAddressList(&addr));
     72 
     73   TestCompletionCallback callback;
     74   net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
     75   net::ClientSocket* transport = new net::TCPClientSocket(
     76       addr, &log, net::NetLog::Source());
     77   int rv = transport->Connect(&callback);
     78   if (rv == net::ERR_IO_PENDING)
     79     rv = callback.WaitForResult();
     80   EXPECT_EQ(net::OK, rv);
     81 
     82   scoped_ptr<net::SSLClientSocket> sock(
     83       socket_factory_->CreateSSLClientSocket(
     84           transport, test_server.host_port_pair(), kDefaultSSLConfig,
     85           NULL, cert_verifier_.get()));
     86 
     87   EXPECT_FALSE(sock->IsConnected());
     88 
     89   rv = sock->Connect(&callback);
     90 
     91   net::CapturingNetLog::EntryList entries;
     92   log.GetEntries(&entries);
     93   EXPECT_TRUE(net::LogContainsBeginEvent(
     94       entries, 5, net::NetLog::TYPE_SSL_CONNECT));
     95   if (rv == net::ERR_IO_PENDING)
     96     rv = callback.WaitForResult();
     97   EXPECT_EQ(net::OK, rv);
     98   EXPECT_TRUE(sock->IsConnected());
     99   log.GetEntries(&entries);
    100   EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
    101 
    102   sock->Disconnect();
    103   EXPECT_FALSE(sock->IsConnected());
    104 }
    105 
    106 TEST_F(SSLClientSocketTest, ConnectExpired) {
    107   net::TestServer::HTTPSOptions https_options(
    108       net::TestServer::HTTPSOptions::CERT_EXPIRED);
    109   net::TestServer test_server(https_options, FilePath());
    110   ASSERT_TRUE(test_server.Start());
    111 
    112   net::AddressList addr;
    113   ASSERT_TRUE(test_server.GetAddressList(&addr));
    114 
    115   TestCompletionCallback callback;
    116   net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
    117   net::ClientSocket* transport = new net::TCPClientSocket(
    118       addr, &log, net::NetLog::Source());
    119   int rv = transport->Connect(&callback);
    120   if (rv == net::ERR_IO_PENDING)
    121     rv = callback.WaitForResult();
    122   EXPECT_EQ(net::OK, rv);
    123 
    124   scoped_ptr<net::SSLClientSocket> sock(
    125       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    126                             kDefaultSSLConfig));
    127 
    128   EXPECT_FALSE(sock->IsConnected());
    129 
    130   rv = sock->Connect(&callback);
    131 
    132   net::CapturingNetLog::EntryList entries;
    133   log.GetEntries(&entries);
    134   EXPECT_TRUE(net::LogContainsBeginEvent(
    135       entries, 5, net::NetLog::TYPE_SSL_CONNECT));
    136   if (rv == net::ERR_IO_PENDING)
    137     rv = callback.WaitForResult();
    138 
    139   EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv);
    140 
    141   // Rather than testing whether or not the underlying socket is connected,
    142   // test that the handshake has finished. This is because it may be
    143   // desirable to disconnect the socket before showing a user prompt, since
    144   // the user may take indefinitely long to respond.
    145   log.GetEntries(&entries);
    146   EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
    147 }
    148 
    149 TEST_F(SSLClientSocketTest, ConnectMismatched) {
    150   net::TestServer::HTTPSOptions https_options(
    151       net::TestServer::HTTPSOptions::CERT_MISMATCHED_NAME);
    152   net::TestServer test_server(https_options, FilePath());
    153   ASSERT_TRUE(test_server.Start());
    154 
    155   net::AddressList addr;
    156   ASSERT_TRUE(test_server.GetAddressList(&addr));
    157 
    158   TestCompletionCallback callback;
    159   net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
    160   net::ClientSocket* transport = new net::TCPClientSocket(
    161       addr, &log, net::NetLog::Source());
    162   int rv = transport->Connect(&callback);
    163   if (rv == net::ERR_IO_PENDING)
    164     rv = callback.WaitForResult();
    165   EXPECT_EQ(net::OK, rv);
    166 
    167   scoped_ptr<net::SSLClientSocket> sock(
    168       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    169                             kDefaultSSLConfig));
    170 
    171   EXPECT_FALSE(sock->IsConnected());
    172 
    173   rv = sock->Connect(&callback);
    174 
    175   net::CapturingNetLog::EntryList entries;
    176   log.GetEntries(&entries);
    177   EXPECT_TRUE(net::LogContainsBeginEvent(
    178       entries, 5, net::NetLog::TYPE_SSL_CONNECT));
    179   if (rv == net::ERR_IO_PENDING)
    180     rv = callback.WaitForResult();
    181 
    182   EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv);
    183 
    184   // Rather than testing whether or not the underlying socket is connected,
    185   // test that the handshake has finished. This is because it may be
    186   // desirable to disconnect the socket before showing a user prompt, since
    187   // the user may take indefinitely long to respond.
    188   log.GetEntries(&entries);
    189   EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
    190 }
    191 
    192 // Attempt to connect to a page which requests a client certificate. It should
    193 // return an error code on connect.
    194 TEST_F(SSLClientSocketTest, ConnectClientAuthCertRequested) {
    195   net::TestServer::HTTPSOptions https_options;
    196   https_options.request_client_certificate = true;
    197   net::TestServer test_server(https_options, FilePath());
    198   ASSERT_TRUE(test_server.Start());
    199 
    200   net::AddressList addr;
    201   ASSERT_TRUE(test_server.GetAddressList(&addr));
    202 
    203   TestCompletionCallback callback;
    204   net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
    205   net::ClientSocket* transport = new net::TCPClientSocket(
    206       addr, &log, net::NetLog::Source());
    207   int rv = transport->Connect(&callback);
    208   if (rv == net::ERR_IO_PENDING)
    209     rv = callback.WaitForResult();
    210   EXPECT_EQ(net::OK, rv);
    211 
    212   scoped_ptr<net::SSLClientSocket> sock(
    213       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    214                             kDefaultSSLConfig));
    215 
    216   EXPECT_FALSE(sock->IsConnected());
    217 
    218   rv = sock->Connect(&callback);
    219 
    220   net::CapturingNetLog::EntryList entries;
    221   log.GetEntries(&entries);
    222   EXPECT_TRUE(net::LogContainsBeginEvent(
    223       entries, 5, net::NetLog::TYPE_SSL_CONNECT));
    224   if (rv == net::ERR_IO_PENDING)
    225     rv = callback.WaitForResult();
    226 
    227   log.GetEntries(&entries);
    228   // Because we prematurely kill the handshake at CertificateRequest,
    229   // the server may still send data (notably the ServerHelloDone)
    230   // after the error is returned. As a result, the SSL_CONNECT may not
    231   // be the last entry. See http://crbug.com/54445. We use
    232   // ExpectLogContainsSomewhere instead of
    233   // LogContainsSSLConnectEndEvent to avoid assuming, e.g., only one
    234   // extra read instead of two. This occurs before the handshake ends,
    235   // so the corking logic of LogContainsSSLConnectEndEvent isn't
    236   // necessary.
    237   //
    238   // TODO(davidben): When SSL_RestartHandshakeAfterCertReq in NSS is
    239   // fixed and we can respond to the first CertificateRequest
    240   // without closing the socket, add a unit test for sending the
    241   // certificate. This test may still be useful as we'll want to close
    242   // the socket on a timeout if the user takes a long time to pick a
    243   // cert. Related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=542832
    244   net::ExpectLogContainsSomewhere(
    245       entries, 0, net::NetLog::TYPE_SSL_CONNECT, net::NetLog::PHASE_END);
    246   EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
    247   EXPECT_FALSE(sock->IsConnected());
    248 }
    249 
    250 // Connect to a server requesting optional client authentication. Send it a
    251 // null certificate. It should allow the connection.
    252 //
    253 // TODO(davidben): Also test providing an actual certificate.
    254 TEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) {
    255   net::TestServer::HTTPSOptions https_options;
    256   https_options.request_client_certificate = true;
    257   net::TestServer test_server(https_options, FilePath());
    258   ASSERT_TRUE(test_server.Start());
    259 
    260   net::AddressList addr;
    261   ASSERT_TRUE(test_server.GetAddressList(&addr));
    262 
    263   TestCompletionCallback callback;
    264   net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
    265   net::ClientSocket* transport = new net::TCPClientSocket(
    266       addr, &log, net::NetLog::Source());
    267   int rv = transport->Connect(&callback);
    268   if (rv == net::ERR_IO_PENDING)
    269     rv = callback.WaitForResult();
    270   EXPECT_EQ(net::OK, rv);
    271 
    272   net::SSLConfig ssl_config = kDefaultSSLConfig;
    273   ssl_config.send_client_cert = true;
    274   ssl_config.client_cert = NULL;
    275 
    276   scoped_ptr<net::SSLClientSocket> sock(
    277       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    278                             ssl_config));
    279 
    280   EXPECT_FALSE(sock->IsConnected());
    281 
    282   // Our test server accepts certificate-less connections.
    283   // TODO(davidben): Add a test which requires them and verify the error.
    284   rv = sock->Connect(&callback);
    285 
    286   net::CapturingNetLog::EntryList entries;
    287   log.GetEntries(&entries);
    288   EXPECT_TRUE(net::LogContainsBeginEvent(
    289       entries, 5, net::NetLog::TYPE_SSL_CONNECT));
    290   if (rv == net::ERR_IO_PENDING)
    291     rv = callback.WaitForResult();
    292 
    293   EXPECT_EQ(net::OK, rv);
    294   EXPECT_TRUE(sock->IsConnected());
    295   log.GetEntries(&entries);
    296   EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
    297 
    298   sock->Disconnect();
    299   EXPECT_FALSE(sock->IsConnected());
    300 }
    301 
    302 // TODO(wtc): Add unit tests for IsConnectedAndIdle:
    303 //   - Server closes an SSL connection (with a close_notify alert message).
    304 //   - Server closes the underlying TCP connection directly.
    305 //   - Server sends data unexpectedly.
    306 
    307 TEST_F(SSLClientSocketTest, Read) {
    308   net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
    309   ASSERT_TRUE(test_server.Start());
    310 
    311   net::AddressList addr;
    312   ASSERT_TRUE(test_server.GetAddressList(&addr));
    313 
    314   TestCompletionCallback callback;
    315   net::ClientSocket* transport = new net::TCPClientSocket(
    316       addr, NULL, net::NetLog::Source());
    317   int rv = transport->Connect(&callback);
    318   if (rv == net::ERR_IO_PENDING)
    319     rv = callback.WaitForResult();
    320   EXPECT_EQ(net::OK, rv);
    321 
    322   scoped_ptr<net::SSLClientSocket> sock(
    323       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    324                             kDefaultSSLConfig));
    325 
    326   rv = sock->Connect(&callback);
    327   if (rv == net::ERR_IO_PENDING)
    328     rv = callback.WaitForResult();
    329   EXPECT_EQ(net::OK, rv);
    330   EXPECT_TRUE(sock->IsConnected());
    331 
    332   const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
    333   scoped_refptr<net::IOBuffer> request_buffer(
    334       new net::IOBuffer(arraysize(request_text) - 1));
    335   memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
    336 
    337   rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
    338   EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
    339 
    340   if (rv == net::ERR_IO_PENDING)
    341     rv = callback.WaitForResult();
    342   EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
    343 
    344   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(4096));
    345   for (;;) {
    346     rv = sock->Read(buf, 4096, &callback);
    347     EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
    348 
    349     if (rv == net::ERR_IO_PENDING)
    350       rv = callback.WaitForResult();
    351 
    352     EXPECT_GE(rv, 0);
    353     if (rv <= 0)
    354       break;
    355   }
    356 }
    357 
    358 // Test the full duplex mode, with Read and Write pending at the same time.
    359 // This test also serves as a regression test for http://crbug.com/29815.
    360 TEST_F(SSLClientSocketTest, Read_FullDuplex) {
    361   net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
    362   ASSERT_TRUE(test_server.Start());
    363 
    364   net::AddressList addr;
    365   ASSERT_TRUE(test_server.GetAddressList(&addr));
    366 
    367   TestCompletionCallback callback;  // Used for everything except Write.
    368   TestCompletionCallback callback2;  // Used for Write only.
    369 
    370   net::ClientSocket* transport = new net::TCPClientSocket(
    371       addr, NULL, net::NetLog::Source());
    372   int rv = transport->Connect(&callback);
    373   if (rv == net::ERR_IO_PENDING)
    374     rv = callback.WaitForResult();
    375   EXPECT_EQ(net::OK, rv);
    376 
    377   scoped_ptr<net::SSLClientSocket> sock(
    378       socket_factory_->CreateSSLClientSocket(
    379           transport, test_server.host_port_pair(), kDefaultSSLConfig,
    380           NULL, cert_verifier_.get()));
    381 
    382   rv = sock->Connect(&callback);
    383   if (rv == net::ERR_IO_PENDING)
    384     rv = callback.WaitForResult();
    385   EXPECT_EQ(net::OK, rv);
    386   EXPECT_TRUE(sock->IsConnected());
    387 
    388   // Issue a "hanging" Read first.
    389   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(4096));
    390   rv = sock->Read(buf, 4096, &callback);
    391   // We haven't written the request, so there should be no response yet.
    392   ASSERT_EQ(net::ERR_IO_PENDING, rv);
    393 
    394   // Write the request.
    395   // The request is padded with a User-Agent header to a size that causes the
    396   // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around.
    397   // This tests the fix for http://crbug.com/29815.
    398   std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
    399   for (int i = 0; i < 3800; ++i)
    400     request_text.push_back('*');
    401   request_text.append("\r\n\r\n");
    402   scoped_refptr<net::IOBuffer> request_buffer(
    403       new net::StringIOBuffer(request_text));
    404 
    405   rv = sock->Write(request_buffer, request_text.size(), &callback2);
    406   EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
    407 
    408   if (rv == net::ERR_IO_PENDING)
    409     rv = callback2.WaitForResult();
    410   EXPECT_EQ(static_cast<int>(request_text.size()), rv);
    411 
    412   // Now get the Read result.
    413   rv = callback.WaitForResult();
    414   EXPECT_GT(rv, 0);
    415 }
    416 
    417 TEST_F(SSLClientSocketTest, Read_SmallChunks) {
    418   net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
    419   ASSERT_TRUE(test_server.Start());
    420 
    421   net::AddressList addr;
    422   ASSERT_TRUE(test_server.GetAddressList(&addr));
    423 
    424   TestCompletionCallback callback;
    425   net::ClientSocket* transport = new net::TCPClientSocket(
    426       addr, NULL, net::NetLog::Source());
    427   int rv = transport->Connect(&callback);
    428   if (rv == net::ERR_IO_PENDING)
    429     rv = callback.WaitForResult();
    430   EXPECT_EQ(net::OK, rv);
    431 
    432   scoped_ptr<net::SSLClientSocket> sock(
    433       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    434                             kDefaultSSLConfig));
    435 
    436   rv = sock->Connect(&callback);
    437   if (rv == net::ERR_IO_PENDING)
    438     rv = callback.WaitForResult();
    439   EXPECT_EQ(net::OK, rv);
    440 
    441   const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
    442   scoped_refptr<net::IOBuffer> request_buffer(
    443       new net::IOBuffer(arraysize(request_text) - 1));
    444   memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
    445 
    446   rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
    447   EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
    448 
    449   if (rv == net::ERR_IO_PENDING)
    450     rv = callback.WaitForResult();
    451   EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
    452 
    453   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(1));
    454   for (;;) {
    455     rv = sock->Read(buf, 1, &callback);
    456     EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
    457 
    458     if (rv == net::ERR_IO_PENDING)
    459       rv = callback.WaitForResult();
    460 
    461     EXPECT_GE(rv, 0);
    462     if (rv <= 0)
    463       break;
    464   }
    465 }
    466 
    467 TEST_F(SSLClientSocketTest, Read_Interrupted) {
    468   net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
    469   ASSERT_TRUE(test_server.Start());
    470 
    471   net::AddressList addr;
    472   ASSERT_TRUE(test_server.GetAddressList(&addr));
    473 
    474   TestCompletionCallback callback;
    475   net::ClientSocket* transport = new net::TCPClientSocket(
    476       addr, NULL, net::NetLog::Source());
    477   int rv = transport->Connect(&callback);
    478   if (rv == net::ERR_IO_PENDING)
    479     rv = callback.WaitForResult();
    480   EXPECT_EQ(net::OK, rv);
    481 
    482   scoped_ptr<net::SSLClientSocket> sock(
    483       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    484                             kDefaultSSLConfig));
    485 
    486   rv = sock->Connect(&callback);
    487   if (rv == net::ERR_IO_PENDING)
    488     rv = callback.WaitForResult();
    489   EXPECT_EQ(net::OK, rv);
    490 
    491   const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
    492   scoped_refptr<net::IOBuffer> request_buffer(
    493       new net::IOBuffer(arraysize(request_text) - 1));
    494   memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
    495 
    496   rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
    497   EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
    498 
    499   if (rv == net::ERR_IO_PENDING)
    500     rv = callback.WaitForResult();
    501   EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
    502 
    503   // Do a partial read and then exit.  This test should not crash!
    504   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(512));
    505   rv = sock->Read(buf, 512, &callback);
    506   EXPECT_TRUE(rv > 0 || rv == net::ERR_IO_PENDING);
    507 
    508   if (rv == net::ERR_IO_PENDING)
    509     rv = callback.WaitForResult();
    510 
    511   EXPECT_GT(rv, 0);
    512 }
    513 
    514 // Regression test for http://crbug.com/42538
    515 TEST_F(SSLClientSocketTest, PrematureApplicationData) {
    516   net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
    517   ASSERT_TRUE(test_server.Start());
    518 
    519   net::AddressList addr;
    520   TestCompletionCallback callback;
    521 
    522   static const unsigned char application_data[] = {
    523     0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b,
    524     0xc2, 0xf8, 0xb2, 0xc1, 0x56, 0x42, 0xb9, 0x57, 0x7f, 0xde, 0x87, 0x46,
    525     0xf7, 0xa3, 0x52, 0x42, 0x21, 0xf0, 0x13, 0x1c, 0x9c, 0x83, 0x88, 0xd6,
    526     0x93, 0x0c, 0xf6, 0x36, 0x30, 0x05, 0x7e, 0x20, 0xb5, 0xb5, 0x73, 0x36,
    527     0x53, 0x83, 0x0a, 0xfc, 0x17, 0x63, 0xbf, 0xa0, 0xe4, 0x42, 0x90, 0x0d,
    528     0x2f, 0x18, 0x6d, 0x20, 0xd8, 0x36, 0x3f, 0xfc, 0xe6, 0x01, 0xfa, 0x0f,
    529     0xa5, 0x75, 0x7f, 0x09, 0x00, 0x04, 0x00, 0x16, 0x03, 0x01, 0x11, 0x57,
    530     0x0b, 0x00, 0x11, 0x53, 0x00, 0x11, 0x50, 0x00, 0x06, 0x22, 0x30, 0x82,
    531     0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
    532     0x0a
    533   };
    534 
    535   // All reads and writes complete synchronously (async=false).
    536   net::MockRead data_reads[] = {
    537     net::MockRead(false, reinterpret_cast<const char*>(application_data),
    538                   arraysize(application_data)),
    539     net::MockRead(false, net::OK),
    540   };
    541 
    542   net::StaticSocketDataProvider data(data_reads, arraysize(data_reads),
    543                                      NULL, 0);
    544 
    545   net::ClientSocket* transport =
    546       new net::MockTCPClientSocket(addr, NULL, &data);
    547   int rv = transport->Connect(&callback);
    548   if (rv == net::ERR_IO_PENDING)
    549     rv = callback.WaitForResult();
    550   EXPECT_EQ(net::OK, rv);
    551 
    552   scoped_ptr<net::SSLClientSocket> sock(
    553       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    554                             kDefaultSSLConfig));
    555 
    556   rv = sock->Connect(&callback);
    557   EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
    558 }
    559 
    560 // TODO(rsleevi): Not implemented for Schannel. As Schannel is only used when
    561 // performing client authentication, it will not be tested here.
    562 TEST_F(SSLClientSocketTest, CipherSuiteDisables) {
    563   // Rather than exhaustively disabling every RC4 ciphersuite defined at
    564   // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml,
    565   // only disabling those cipher suites that the test server actually
    566   // implements.
    567   const uint16 kCiphersToDisable[] = {
    568     0x0005,  // TLS_RSA_WITH_RC4_128_SHA
    569   };
    570 
    571   net::TestServer::HTTPSOptions https_options;
    572   // Enable only RC4 on the test server.
    573   https_options.bulk_ciphers =
    574       net::TestServer::HTTPSOptions::BULK_CIPHER_RC4;
    575   net::TestServer test_server(https_options, FilePath());
    576   ASSERT_TRUE(test_server.Start());
    577 
    578   net::AddressList addr;
    579   ASSERT_TRUE(test_server.GetAddressList(&addr));
    580 
    581   TestCompletionCallback callback;
    582   net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
    583   net::ClientSocket* transport = new net::TCPClientSocket(
    584       addr, &log, net::NetLog::Source());
    585   int rv = transport->Connect(&callback);
    586   if (rv == net::ERR_IO_PENDING)
    587     rv = callback.WaitForResult();
    588   EXPECT_EQ(net::OK, rv);
    589 
    590   net::SSLConfig ssl_config;
    591   for (size_t i = 0; i < arraysize(kCiphersToDisable); ++i)
    592     ssl_config.disabled_cipher_suites.push_back(kCiphersToDisable[i]);
    593 
    594   scoped_ptr<net::SSLClientSocket> sock(
    595       CreateSSLClientSocket(transport, test_server.host_port_pair(),
    596                             ssl_config));
    597 
    598   EXPECT_FALSE(sock->IsConnected());
    599 
    600   rv = sock->Connect(&callback);
    601   net::CapturingNetLog::EntryList entries;
    602   log.GetEntries(&entries);
    603   EXPECT_TRUE(net::LogContainsBeginEvent(
    604       entries, 5, net::NetLog::TYPE_SSL_CONNECT));
    605 
    606   // NSS has special handling that maps a handshake_failure alert received
    607   // immediately after a client_hello to be a mismatched cipher suite error,
    608   // leading to ERR_SSL_VERSION_OR_CIPHER_MISMATCH. When using OpenSSL or
    609   // Secure Transport (OS X), the handshake_failure is bubbled up without any
    610   // interpretation, leading to ERR_SSL_PROTOCOL_ERROR. Either way, a failure
    611   // indicates that no cipher suite was negotiated with the test server.
    612   if (rv == net::ERR_IO_PENDING)
    613     rv = callback.WaitForResult();
    614   EXPECT_TRUE(rv == net::ERR_SSL_VERSION_OR_CIPHER_MISMATCH ||
    615               rv == net::ERR_SSL_PROTOCOL_ERROR);
    616   // The exact ordering differs between SSLClientSocketNSS (which issues an
    617   // extra read) and SSLClientSocketMac (which does not). Just make sure the
    618   // error appears somewhere in the log.
    619   log.GetEntries(&entries);
    620   net::ExpectLogContainsSomewhere(entries, 0,
    621                                   net::NetLog::TYPE_SSL_HANDSHAKE_ERROR,
    622                                   net::NetLog::PHASE_NONE);
    623 
    624   // We cannot test sock->IsConnected(), as the NSS implementation disconnects
    625   // the socket when it encounters an error, whereas other implementations
    626   // leave it connected.
    627   // Because this an error that the test server is mutually aware of, as opposed
    628   // to being an error such as a certificate name mismatch, which is
    629   // client-only, the exact index of the SSL connect end depends on how
    630   // quickly the test server closes the underlying socket. If the test server
    631   // closes before the IO message loop pumps messages, there may be a 0-byte
    632   // Read event in the NetLog due to TCPClientSocket picking up the EOF. As a
    633   // result, the SSL connect end event will be the second-to-last entry,
    634   // rather than the last entry.
    635   EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1) ||
    636               LogContainsSSLConnectEndEvent(entries, -2));
    637 }
    638