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

Side by Side Diff: net/socket/ssl_client_socket_unittest.cc

Issue 337773003: Reland r276815: Add tests for session cache and false start behavior. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | third_party/tlslite/README.chromium » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/ssl_client_socket.h" 5 #include "net/socket/ssl_client_socket.h"
6 6
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "net/base/address_list.h" 10 #include "net/base/address_list.h"
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 SSLClientSocketTest() 592 SSLClientSocketTest()
593 : socket_factory_(ClientSocketFactory::GetDefaultFactory()), 593 : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
594 cert_verifier_(new MockCertVerifier), 594 cert_verifier_(new MockCertVerifier),
595 transport_security_state_(new TransportSecurityState) { 595 transport_security_state_(new TransportSecurityState) {
596 cert_verifier_->set_default_result(OK); 596 cert_verifier_->set_default_result(OK);
597 context_.cert_verifier = cert_verifier_.get(); 597 context_.cert_verifier = cert_verifier_.get();
598 context_.transport_security_state = transport_security_state_.get(); 598 context_.transport_security_state = transport_security_state_.get();
599 } 599 }
600 600
601 protected: 601 protected:
602 // Sets up a TCP connection to a HTTPS server. To actually do the SSL 602 // The address of the spawned test server, after calling StartTestServer().
603 // handshake, follow up with call to CreateAndConnectSSLClientSocket() below. 603 const AddressList& addr() const { return addr_; }
604 bool ConnectToTestServer(SpawnedTestServer::SSLOptions& ssl_options) { 604
605 // The SpawnedTestServer object, after calling StartTestServer().
606 const SpawnedTestServer* test_server() const { return test_server_.get(); }
607
608 // Starts the test server with SSL configuration |ssl_options|. Returns true
609 // on success.
610 bool StartTestServer(const SpawnedTestServer::SSLOptions& ssl_options) {
605 test_server_.reset(new SpawnedTestServer( 611 test_server_.reset(new SpawnedTestServer(
606 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath())); 612 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()));
607 if (!test_server_->Start()) { 613 if (!test_server_->Start()) {
608 LOG(ERROR) << "Could not start SpawnedTestServer"; 614 LOG(ERROR) << "Could not start SpawnedTestServer";
609 return false; 615 return false;
610 } 616 }
611 617
612 if (!test_server_->GetAddressList(&addr_)) { 618 if (!test_server_->GetAddressList(&addr_)) {
613 LOG(ERROR) << "Could not get SpawnedTestServer address list"; 619 LOG(ERROR) << "Could not get SpawnedTestServer address list";
614 return false; 620 return false;
615 } 621 }
622 return true;
623 }
624
625 // Sets up a TCP connection to a HTTPS server. To actually do the SSL
626 // handshake, follow up with call to CreateAndConnectSSLClientSocket() below.
627 bool ConnectToTestServer(const SpawnedTestServer::SSLOptions& ssl_options) {
628 if (!StartTestServer(ssl_options))
629 return false;
616 630
617 transport_.reset(new TCPClientSocket(addr_, &log_, NetLog::Source())); 631 transport_.reset(new TCPClientSocket(addr_, &log_, NetLog::Source()));
618 int rv = callback_.GetResult(transport_->Connect(callback_.callback())); 632 int rv = callback_.GetResult(transport_->Connect(callback_.callback()));
619 if (rv != OK) { 633 if (rv != OK) {
620 LOG(ERROR) << "Could not connect to SpawnedTestServer"; 634 LOG(ERROR) << "Could not connect to SpawnedTestServer";
621 return false; 635 return false;
622 } 636 }
623 return true; 637 return true;
624 } 638 }
625 639
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 EXPECT_FALSE(sock->IsConnected()); 720 EXPECT_FALSE(sock->IsConnected());
707 EXPECT_TRUE( 721 EXPECT_TRUE(
708 test_server.host_port_pair().Equals(request_info->host_and_port)); 722 test_server.host_port_pair().Equals(request_info->host_and_port));
709 723
710 return request_info; 724 return request_info;
711 } 725 }
712 }; 726 };
713 727
714 class SSLClientSocketFalseStartTest : public SSLClientSocketTest { 728 class SSLClientSocketFalseStartTest : public SSLClientSocketTest {
715 protected: 729 protected:
716 void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options, 730 // Creates an SSLClientSocket with |client_config| attached to a
717 const SSLConfig& client_config, 731 // FakeBlockingStreamSocket, returning both in |*out_raw_transport| and
718 bool expect_false_start) { 732 // |*out_sock|. The FakeBlockingStreamSocket is owned by the SSLClientSocket,
719 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 733 // so |*out_raw_transport| is a raw pointer.
720 server_options, 734 //
721 base::FilePath()); 735 // The client socket will begin a connect using |callback| but stop before the
722 ASSERT_TRUE(test_server.Start()); 736 // server's finished message is received. The finished message will be blocked
737 // in |*out_raw_transport|. To complete the handshake and successfully read
738 // data, the caller must unblock reads on |*out_raw_transport|. (Note that, if
739 // the client successfully false started, |callback.WaitForResult()| will
740 // return OK without unblocking transport reads. But Read() will still block.)
741 //
742 // Must be called after StartTestServer is called.
743 void CreateAndConnectUntilServerFinishedReceived(
744 const SSLConfig& client_config,
745 TestCompletionCallback* callback,
746 FakeBlockingStreamSocket** out_raw_transport,
747 scoped_ptr<SSLClientSocket>* out_sock) {
748 CHECK(test_server());
723 749
724 AddressList addr;
725 ASSERT_TRUE(test_server.GetAddressList(&addr));
726
727 TestCompletionCallback callback;
728 scoped_ptr<StreamSocket> real_transport( 750 scoped_ptr<StreamSocket> real_transport(
729 new TCPClientSocket(addr, NULL, NetLog::Source())); 751 new TCPClientSocket(addr(), NULL, NetLog::Source()));
730 scoped_ptr<FakeBlockingStreamSocket> transport( 752 scoped_ptr<FakeBlockingStreamSocket> transport(
731 new FakeBlockingStreamSocket(real_transport.Pass())); 753 new FakeBlockingStreamSocket(real_transport.Pass()));
732 int rv = callback.GetResult(transport->Connect(callback.callback())); 754 int rv = callback->GetResult(transport->Connect(callback->callback()));
733 EXPECT_EQ(OK, rv); 755 EXPECT_EQ(OK, rv);
734 756
735 FakeBlockingStreamSocket* raw_transport = transport.get(); 757 FakeBlockingStreamSocket* raw_transport = transport.get();
736 scoped_ptr<SSLClientSocket> sock( 758 scoped_ptr<SSLClientSocket> sock =
737 CreateSSLClientSocket(transport.PassAs<StreamSocket>(), 759 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
738 test_server.host_port_pair(), 760 test_server()->host_port_pair(),
739 client_config)); 761 client_config);
740 762
741 // Connect. Stop before the client processes the first server leg 763 // Connect. Stop before the client processes the first server leg
742 // (ServerHello, etc.) 764 // (ServerHello, etc.)
743 raw_transport->BlockReadResult(); 765 raw_transport->BlockReadResult();
744 rv = sock->Connect(callback.callback()); 766 rv = sock->Connect(callback->callback());
745 EXPECT_EQ(ERR_IO_PENDING, rv); 767 EXPECT_EQ(ERR_IO_PENDING, rv);
746 raw_transport->WaitForReadResult(); 768 raw_transport->WaitForReadResult();
747 769
748 // Release the ServerHello and wait for the client to write 770 // Release the ServerHello and wait for the client to write
749 // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the 771 // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the
750 // server's leg to complete, since it may span multiple reads.) 772 // server's leg to complete, since it may span multiple reads.)
751 EXPECT_FALSE(callback.have_result()); 773 EXPECT_FALSE(callback->have_result());
752 raw_transport->BlockWrite(); 774 raw_transport->BlockWrite();
753 raw_transport->UnblockReadResult(); 775 raw_transport->UnblockReadResult();
754 raw_transport->WaitForWrite(); 776 raw_transport->WaitForWrite();
755 777
756 // And, finally, release that and block the next server leg 778 // And, finally, release that and block the next server leg
757 // (ChangeCipherSpec, Finished). Note: callback.have_result() may or may not 779 // (ChangeCipherSpec, Finished).
758 // be true at this point depending on whether the SSL implementation waits
759 // for the client second leg to clear the internal write buffer and hit the
760 // network.
761 raw_transport->BlockReadResult(); 780 raw_transport->BlockReadResult();
762 raw_transport->UnblockWrite(); 781 raw_transport->UnblockWrite();
763 782
783 *out_raw_transport = raw_transport;
784 *out_sock = sock.Pass();
785 }
786
787 void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options,
788 const SSLConfig& client_config,
789 bool expect_false_start) {
790 ASSERT_TRUE(StartTestServer(server_options));
791
792 TestCompletionCallback callback;
793 FakeBlockingStreamSocket* raw_transport = NULL;
794 scoped_ptr<SSLClientSocket> sock;
795 ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived(
796 client_config, &callback, &raw_transport, &sock));
797
764 if (expect_false_start) { 798 if (expect_false_start) {
765 // When False Starting, the handshake should complete before receiving the 799 // When False Starting, the handshake should complete before receiving the
766 // Change Cipher Spec and Finished messages. 800 // Change Cipher Spec and Finished messages.
767 rv = callback.GetResult(rv); 801 //
802 // Note: callback.have_result() may not be true without waiting. The NSS
803 // state machine sometimes lives on a separate thread, so this thread may
804 // not yet have processed the signal that the handshake has completed.
805 int rv = callback.WaitForResult();
768 EXPECT_EQ(OK, rv); 806 EXPECT_EQ(OK, rv);
769 EXPECT_TRUE(sock->IsConnected()); 807 EXPECT_TRUE(sock->IsConnected());
770 808
771 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 809 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
772 static const int kRequestTextSize = 810 static const int kRequestTextSize =
773 static_cast<int>(arraysize(request_text) - 1); 811 static_cast<int>(arraysize(request_text) - 1);
774 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); 812 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize));
775 memcpy(request_buffer->data(), request_text, kRequestTextSize); 813 memcpy(request_buffer->data(), request_text, kRequestTextSize);
776 814
777 // Write the request. 815 // Write the request.
(...skipping 1673 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 } 2489 }
2452 2490
2453 TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) { 2491 TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) {
2454 // False Start requires NPN and a forward-secret cipher suite. 2492 // False Start requires NPN and a forward-secret cipher suite.
2455 SpawnedTestServer::SSLOptions server_options; 2493 SpawnedTestServer::SSLOptions server_options;
2456 server_options.key_exchanges = 2494 server_options.key_exchanges =
2457 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; 2495 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2458 server_options.enable_npn = true; 2496 server_options.enable_npn = true;
2459 SSLConfig client_config; 2497 SSLConfig client_config;
2460 client_config.next_protos.push_back("http/1.1"); 2498 client_config.next_protos.push_back("http/1.1");
2461 TestFalseStart(server_options, client_config, true); 2499 ASSERT_NO_FATAL_FAILURE(
2500 TestFalseStart(server_options, client_config, true));
2462 } 2501 }
2463 2502
2464 // Test that False Start is disabled without NPN. 2503 // Test that False Start is disabled without NPN.
2465 TEST_F(SSLClientSocketFalseStartTest, NoNPN) { 2504 TEST_F(SSLClientSocketFalseStartTest, NoNPN) {
2466 SpawnedTestServer::SSLOptions server_options; 2505 SpawnedTestServer::SSLOptions server_options;
2467 server_options.key_exchanges = 2506 server_options.key_exchanges =
2468 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; 2507 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2469 SSLConfig client_config; 2508 SSLConfig client_config;
2470 client_config.next_protos.clear(); 2509 client_config.next_protos.clear();
2471 TestFalseStart(server_options, client_config, false); 2510 ASSERT_NO_FATAL_FAILURE(
2511 TestFalseStart(server_options, client_config, false));
2472 } 2512 }
2473 2513
2474 // Test that False Start is disabled without a forward-secret cipher suite. 2514 // Test that False Start is disabled without a forward-secret cipher suite.
2475 TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) { 2515 TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) {
2476 SpawnedTestServer::SSLOptions server_options; 2516 SpawnedTestServer::SSLOptions server_options;
2477 server_options.key_exchanges = 2517 server_options.key_exchanges =
2478 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA; 2518 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA;
2479 server_options.enable_npn = true; 2519 server_options.enable_npn = true;
2480 SSLConfig client_config; 2520 SSLConfig client_config;
2481 client_config.next_protos.push_back("http/1.1"); 2521 client_config.next_protos.push_back("http/1.1");
2482 TestFalseStart(server_options, client_config, false); 2522 ASSERT_NO_FATAL_FAILURE(
2523 TestFalseStart(server_options, client_config, false));
2524 }
2525
2526 // Test that sessions are resumable after receiving the server Finished message.
2527 TEST_F(SSLClientSocketFalseStartTest, SessionResumption) {
2528 // Start a server.
2529 SpawnedTestServer::SSLOptions server_options;
2530 server_options.key_exchanges =
2531 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2532 server_options.enable_npn = true;
2533 SSLConfig client_config;
2534 client_config.next_protos.push_back("http/1.1");
2535
2536 // Let a full handshake complete with False Start.
2537 ASSERT_NO_FATAL_FAILURE(
2538 TestFalseStart(server_options, client_config, true));
2539
2540 // Make a second connection.
2541 TestCompletionCallback callback;
2542 scoped_ptr<StreamSocket> transport2(
2543 new TCPClientSocket(addr(), &log_, NetLog::Source()));
2544 EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
2545 scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
2546 transport2.Pass(), test_server()->host_port_pair(), client_config);
2547 ASSERT_TRUE(sock2.get());
2548 EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
2549
2550 // It should resume the session.
2551 SSLInfo ssl_info;
2552 EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
2553 EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
2554 }
2555
2556 // Test that sessions are not resumable before receiving the server Finished
2557 // message.
2558 TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinish) {
2559 // Start a server.
2560 SpawnedTestServer::SSLOptions server_options;
2561 server_options.key_exchanges =
2562 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2563 server_options.enable_npn = true;
2564 ASSERT_TRUE(StartTestServer(server_options));
2565
2566 SSLConfig client_config;
2567 client_config.next_protos.push_back("http/1.1");
2568
2569 // Start a handshake up to the server Finished message.
2570 TestCompletionCallback callback;
2571 FakeBlockingStreamSocket* raw_transport1;
2572 scoped_ptr<SSLClientSocket> sock1;
2573 ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived(
2574 client_config, &callback, &raw_transport1, &sock1));
2575 // Although raw_transport1 has the server Finished blocked, the handshake
2576 // still completes.
2577 EXPECT_EQ(OK, callback.WaitForResult());
2578
2579 // Drop the old socket. This is needed because the Python test server can't
2580 // service two sockets in parallel.
2581 sock1.reset();
2582
2583 // Start a second connection.
2584 scoped_ptr<StreamSocket> transport2(
2585 new TCPClientSocket(addr(), &log_, NetLog::Source()));
2586 EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
2587 scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
2588 transport2.Pass(), test_server()->host_port_pair(), client_config);
2589 EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
2590
2591 // No session resumption because the first connection never received a server
2592 // Finished message.
2593 SSLInfo ssl_info;
2594 EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
2595 EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
2483 } 2596 }
2484 2597
2485 // Connect to a server using channel id. It should allow the connection. 2598 // Connect to a server using channel id. It should allow the connection.
2486 TEST_F(SSLClientSocketChannelIDTest, SendChannelID) { 2599 TEST_F(SSLClientSocketChannelIDTest, SendChannelID) {
2487 SpawnedTestServer::SSLOptions ssl_options; 2600 SpawnedTestServer::SSLOptions ssl_options;
2488 2601
2489 ASSERT_TRUE(ConnectToTestServer(ssl_options)); 2602 ASSERT_TRUE(ConnectToTestServer(ssl_options));
2490 2603
2491 EnableChannelID(); 2604 EnableChannelID();
2492 SSLConfig ssl_config = kDefaultSSLConfig; 2605 SSLConfig ssl_config = kDefaultSSLConfig;
(...skipping 26 matching lines...) Expand all
2519 2632
2520 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns 2633 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns
2521 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all 2634 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all
2522 // error codes for now. 2635 // error codes for now.
2523 // http://crbug.com/373670 2636 // http://crbug.com/373670
2524 EXPECT_NE(OK, rv); 2637 EXPECT_NE(OK, rv);
2525 EXPECT_FALSE(sock_->IsConnected()); 2638 EXPECT_FALSE(sock_->IsConnected());
2526 } 2639 }
2527 2640
2528 } // namespace net 2641 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | third_party/tlslite/README.chromium » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698