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

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

Issue 301283004: Add tests for session cache and false start behavior. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sleevi comments 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 bool StartTestServer(const SpawnedTestServer::SSLOptions& ssl_options) {
603 // handshake, follow up with call to CreateAndConnectSSLClientSocket() below.
604 bool ConnectToTestServer(SpawnedTestServer::SSLOptions& ssl_options) {
605 test_server_.reset(new SpawnedTestServer( 603 test_server_.reset(new SpawnedTestServer(
606 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath())); 604 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()));
607 if (!test_server_->Start()) { 605 if (!test_server_->Start()) {
608 LOG(ERROR) << "Could not start SpawnedTestServer"; 606 LOG(ERROR) << "Could not start SpawnedTestServer";
609 return false; 607 return false;
610 } 608 }
611 609
612 if (!test_server_->GetAddressList(&addr_)) { 610 if (!test_server_->GetAddressList(&addr_)) {
613 LOG(ERROR) << "Could not get SpawnedTestServer address list"; 611 LOG(ERROR) << "Could not get SpawnedTestServer address list";
614 return false; 612 return false;
615 } 613 }
614 return true;
615 }
616
617 // Sets up a TCP connection to a HTTPS server. To actually do the SSL
618 // handshake, follow up with call to CreateAndConnectSSLClientSocket() below.
619 bool ConnectToTestServer(const SpawnedTestServer::SSLOptions& ssl_options) {
620 if (!StartTestServer(ssl_options))
621 return false;
616 622
617 transport_.reset(new TCPClientSocket(addr_, &log_, NetLog::Source())); 623 transport_.reset(new TCPClientSocket(addr_, &log_, NetLog::Source()));
618 int rv = callback_.GetResult(transport_->Connect(callback_.callback())); 624 int rv = callback_.GetResult(transport_->Connect(callback_.callback()));
619 if (rv != OK) { 625 if (rv != OK) {
620 LOG(ERROR) << "Could not connect to SpawnedTestServer"; 626 LOG(ERROR) << "Could not connect to SpawnedTestServer";
621 return false; 627 return false;
622 } 628 }
623 return true; 629 return true;
624 } 630 }
625 631
(...skipping 27 matching lines...) Expand all
653 *result = callback_.GetResult(sock_->Connect(callback_.callback())); 659 *result = callback_.GetResult(sock_->Connect(callback_.callback()));
654 return true; 660 return true;
655 } 661 }
656 662
657 ClientSocketFactory* socket_factory_; 663 ClientSocketFactory* socket_factory_;
658 scoped_ptr<MockCertVerifier> cert_verifier_; 664 scoped_ptr<MockCertVerifier> cert_verifier_;
659 scoped_ptr<TransportSecurityState> transport_security_state_; 665 scoped_ptr<TransportSecurityState> transport_security_state_;
660 SSLClientSocketContext context_; 666 SSLClientSocketContext context_;
661 scoped_ptr<SSLClientSocket> sock_; 667 scoped_ptr<SSLClientSocket> sock_;
662 CapturingNetLog log_; 668 CapturingNetLog log_;
669 AddressList addr_;
670 scoped_ptr<SpawnedTestServer> test_server_;
Ryan Sleevi 2014/06/02 20:52:45 You don't actually need to expose these as protect
davidben 2014/06/03 19:02:47 Done.
663 671
664 private: 672 private:
665 scoped_ptr<StreamSocket> transport_; 673 scoped_ptr<StreamSocket> transport_;
666 scoped_ptr<SpawnedTestServer> test_server_;
667 TestCompletionCallback callback_; 674 TestCompletionCallback callback_;
668 AddressList addr_;
669 }; 675 };
670 676
671 // Verifies the correctness of GetSSLCertRequestInfo. 677 // Verifies the correctness of GetSSLCertRequestInfo.
672 class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest { 678 class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest {
673 protected: 679 protected:
674 // Creates a test server with the given SSLOptions, connects to it and returns 680 // Creates a test server with the given SSLOptions, connects to it and returns
675 // the SSLCertRequestInfo reported by the socket. 681 // the SSLCertRequestInfo reported by the socket.
676 scoped_refptr<SSLCertRequestInfo> GetCertRequest( 682 scoped_refptr<SSLCertRequestInfo> GetCertRequest(
677 SpawnedTestServer::SSLOptions ssl_options) { 683 SpawnedTestServer::SSLOptions ssl_options) {
678 SpawnedTestServer test_server( 684 SpawnedTestServer test_server(
(...skipping 27 matching lines...) Expand all
706 EXPECT_FALSE(sock->IsConnected()); 712 EXPECT_FALSE(sock->IsConnected());
707 EXPECT_TRUE( 713 EXPECT_TRUE(
708 test_server.host_port_pair().Equals(request_info->host_and_port)); 714 test_server.host_port_pair().Equals(request_info->host_and_port));
709 715
710 return request_info; 716 return request_info;
711 } 717 }
712 }; 718 };
713 719
714 class SSLClientSocketFalseStartTest : public SSLClientSocketTest { 720 class SSLClientSocketFalseStartTest : public SSLClientSocketTest {
715 protected: 721 protected:
716 void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options, 722 // Creates an SSLClientSocket with |client_config| attached to a
717 const SSLConfig& client_config, 723 // FakeBlockingStreamSocket, returning both in |*out_raw_transport| and
718 bool expect_false_start) { 724 // |*out_sock|. The FakeBlockingStreamSocket is owned by the SSLClientSocket,
719 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 725 // so |*out_raw_transport| is a raw pointer.
720 server_options, 726 //
721 base::FilePath()); 727 // The client socket will begin a connect using |callback| but
722 ASSERT_TRUE(test_server.Start()); 728 // stop before the server's finished message is received. The finished message
729 // will be blocked in |*out_raw_transport|.
730 //
731 // If the client successfully false started with the server,
732 // |callback.WaitForResult()| will return OK without unblocking transport
733 // reads.
734 //
735 // Must be called after StartTestServer is called.
Ryan Sleevi 2014/06/02 20:52:45 I'm guessing to continue the handshake, the caller
davidben 2014/06/03 19:02:47 Done.
736 void CreateAndConnectUntilServerFinishedReceived(
737 const SSLConfig& client_config,
738 TestCompletionCallback* callback,
739 FakeBlockingStreamSocket** out_raw_transport,
740 scoped_ptr<SSLClientSocket>* out_sock) {
741 CHECK(test_server_);
723 742
724 AddressList addr;
725 ASSERT_TRUE(test_server.GetAddressList(&addr));
726
727 TestCompletionCallback callback;
728 scoped_ptr<StreamSocket> real_transport( 743 scoped_ptr<StreamSocket> real_transport(
729 new TCPClientSocket(addr, NULL, NetLog::Source())); 744 new TCPClientSocket(addr_, NULL, NetLog::Source()));
730 scoped_ptr<FakeBlockingStreamSocket> transport( 745 scoped_ptr<FakeBlockingStreamSocket> transport(
731 new FakeBlockingStreamSocket(real_transport.Pass())); 746 new FakeBlockingStreamSocket(real_transport.Pass()));
732 int rv = callback.GetResult(transport->Connect(callback.callback())); 747 int rv = callback->GetResult(transport->Connect(callback->callback()));
733 EXPECT_EQ(OK, rv); 748 EXPECT_EQ(OK, rv);
734 749
735 FakeBlockingStreamSocket* raw_transport = transport.get(); 750 FakeBlockingStreamSocket* raw_transport = transport.get();
736 scoped_ptr<SSLClientSocket> sock( 751 scoped_ptr<SSLClientSocket> sock =
737 CreateSSLClientSocket(transport.PassAs<StreamSocket>(), 752 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
738 test_server.host_port_pair(), 753 test_server_->host_port_pair(),
739 client_config)); 754 client_config);
740 755
741 // Connect. Stop before the client processes the first server leg 756 // Connect. Stop before the client processes the first server leg
742 // (ServerHello, etc.) 757 // (ServerHello, etc.)
743 raw_transport->BlockReadResult(); 758 raw_transport->BlockReadResult();
744 rv = sock->Connect(callback.callback()); 759 rv = sock->Connect(callback->callback());
745 EXPECT_EQ(ERR_IO_PENDING, rv); 760 EXPECT_EQ(ERR_IO_PENDING, rv);
746 raw_transport->WaitForReadResult(); 761 raw_transport->WaitForReadResult();
747 762
748 // Release the ServerHello and wait for the client to write 763 // Release the ServerHello and wait for the client to write
749 // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the 764 // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the
750 // server's leg to complete, since it may span multiple reads.) 765 // server's leg to complete, since it may span multiple reads.)
751 EXPECT_FALSE(callback.have_result()); 766 EXPECT_FALSE(callback->have_result());
752 raw_transport->BlockWrite(); 767 raw_transport->BlockWrite();
753 raw_transport->UnblockReadResult(); 768 raw_transport->UnblockReadResult();
754 raw_transport->WaitForWrite(); 769 raw_transport->WaitForWrite();
755 770
756 // And, finally, release that and block the next server leg 771 // And, finally, release that and block the next server leg
757 // (ChangeCipherSpec, Finished). Note: callback.have_result() may or may not 772 // (ChangeCipherSpec, Finished). Note: callback->have_result() may or may
758 // be true at this point depending on whether the SSL implementation waits 773 // not be true at this point depending on whether the SSL implementation
759 // for the client second leg to clear the internal write buffer and hit the 774 // waits for the client second leg to clear the internal write buffer and
760 // network. 775 // hit the network.
761 raw_transport->BlockReadResult(); 776 raw_transport->BlockReadResult();
762 raw_transport->UnblockWrite(); 777 raw_transport->UnblockWrite();
763 778
779 *out_raw_transport = raw_transport;
780 *out_sock = sock.Pass();
781 }
782
783 void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options,
784 const SSLConfig& client_config,
785 bool expect_false_start) {
786 ASSERT_TRUE(StartTestServer(server_options));
787
788 TestCompletionCallback callback;
789 FakeBlockingStreamSocket* raw_transport;
790 scoped_ptr<SSLClientSocket> sock;
791 ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived(
792 client_config, &callback, &raw_transport, &sock));
793
764 if (expect_false_start) { 794 if (expect_false_start) {
765 // When False Starting, the handshake should complete before receiving the 795 // When False Starting, the handshake should complete before receiving the
766 // Change Cipher Spec and Finished messages. 796 // Change Cipher Spec and Finished messages.
767 rv = callback.GetResult(rv); 797 int rv = callback.WaitForResult();
Ryan Sleevi 2014/06/02 20:52:45 Should you first ASSERT_TRUE(callback.have_result(
davidben 2014/06/03 19:02:47 It didn't end up being true for NSS. There's a com
768 EXPECT_EQ(OK, rv); 798 EXPECT_EQ(OK, rv);
769 EXPECT_TRUE(sock->IsConnected()); 799 EXPECT_TRUE(sock->IsConnected());
770 800
771 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 801 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
772 static const int kRequestTextSize = 802 static const int kRequestTextSize =
773 static_cast<int>(arraysize(request_text) - 1); 803 static_cast<int>(arraysize(request_text) - 1);
774 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); 804 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize));
775 memcpy(request_buffer->data(), request_text, kRequestTextSize); 805 memcpy(request_buffer->data(), request_text, kRequestTextSize);
776 806
777 // Write the request. 807 // Write the request.
(...skipping 1673 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 } 2481 }
2452 2482
2453 TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) { 2483 TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) {
2454 // False Start requires NPN and a forward-secret cipher suite. 2484 // False Start requires NPN and a forward-secret cipher suite.
2455 SpawnedTestServer::SSLOptions server_options; 2485 SpawnedTestServer::SSLOptions server_options;
2456 server_options.key_exchanges = 2486 server_options.key_exchanges =
2457 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; 2487 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2458 server_options.enable_npn = true; 2488 server_options.enable_npn = true;
2459 SSLConfig client_config; 2489 SSLConfig client_config;
2460 client_config.next_protos.push_back("http/1.1"); 2490 client_config.next_protos.push_back("http/1.1");
2461 TestFalseStart(server_options, client_config, true); 2491 ASSERT_NO_FATAL_FAILURE(
2492 TestFalseStart(server_options, client_config, true));
2462 } 2493 }
2463 2494
2464 // Test that False Start is disabled without NPN. 2495 // Test that False Start is disabled without NPN.
2465 TEST_F(SSLClientSocketFalseStartTest, NoNPN) { 2496 TEST_F(SSLClientSocketFalseStartTest, NoNPN) {
2466 SpawnedTestServer::SSLOptions server_options; 2497 SpawnedTestServer::SSLOptions server_options;
2467 server_options.key_exchanges = 2498 server_options.key_exchanges =
2468 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; 2499 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2469 SSLConfig client_config; 2500 SSLConfig client_config;
2470 client_config.next_protos.clear(); 2501 client_config.next_protos.clear();
2471 TestFalseStart(server_options, client_config, false); 2502 ASSERT_NO_FATAL_FAILURE(
2503 TestFalseStart(server_options, client_config, false));
2472 } 2504 }
2473 2505
2474 // Test that False Start is disabled without a forward-secret cipher suite. 2506 // Test that False Start is disabled without a forward-secret cipher suite.
2475 TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) { 2507 TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) {
2476 SpawnedTestServer::SSLOptions server_options; 2508 SpawnedTestServer::SSLOptions server_options;
2477 server_options.key_exchanges = 2509 server_options.key_exchanges =
2478 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA; 2510 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA;
2479 server_options.enable_npn = true; 2511 server_options.enable_npn = true;
2480 SSLConfig client_config; 2512 SSLConfig client_config;
2481 client_config.next_protos.push_back("http/1.1"); 2513 client_config.next_protos.push_back("http/1.1");
2482 TestFalseStart(server_options, client_config, false); 2514 ASSERT_NO_FATAL_FAILURE(
2515 TestFalseStart(server_options, client_config, false));
2516 }
2517
2518 // Test that sessions are resumable after receiving the server Finished message.
2519 TEST_F(SSLClientSocketFalseStartTest, SessionResumption) {
2520 // Start a server.
2521 SpawnedTestServer::SSLOptions server_options;
2522 server_options.key_exchanges =
2523 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2524 server_options.enable_npn = true;
2525 SSLConfig client_config;
2526 client_config.next_protos.push_back("http/1.1");
2527
2528 // Let a full handshake complete with False Start.
2529 ASSERT_NO_FATAL_FAILURE(
2530 TestFalseStart(server_options, client_config, true));
2531
2532 // Make a second connection.
2533 TestCompletionCallback callback;
2534 scoped_ptr<StreamSocket> transport2(
2535 new TCPClientSocket(addr_, &log_, NetLog::Source()));
2536 EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
2537 scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
2538 transport2.Pass(), test_server_->host_port_pair(), client_config);
2539 EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
Ryan Sleevi 2014/06/02 20:52:45 ASSERT_TRUE(sock2.get())?
davidben 2014/06/03 19:02:47 Done.
2540
2541 // It should resume the session.
2542 SSLInfo ssl_info;
2543 EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
2544 EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
2545 }
2546
2547 // Test that sessions are not resumable before receiving the server Finished
2548 // message.
2549 TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinish) {
2550 // Start a server.
2551 SpawnedTestServer::SSLOptions server_options;
2552 server_options.key_exchanges =
2553 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2554 server_options.enable_npn = true;
2555 ASSERT_TRUE(StartTestServer(server_options));
2556
2557 SSLConfig client_config;
2558 client_config.next_protos.push_back("http/1.1");
2559
2560 // Start a handshake up to the server Finished message.
2561 TestCompletionCallback callback;
2562 FakeBlockingStreamSocket* raw_transport1;
2563 scoped_ptr<SSLClientSocket> sock1;
2564 ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived(
2565 client_config, &callback, &raw_transport1, &sock1));
2566 // Although raw_transport1 has the server Finished blocked, the handshake
2567 // still completes.
2568 EXPECT_EQ(OK, callback.WaitForResult());
Ryan Sleevi 2014/06/02 20:52:45 Is this meant to be testing false starting worked?
davidben 2014/06/03 19:02:47 More just for waiting for the connect callback to
2569
2570 // Drop the old socket. This is needed because the Python test server can't
2571 // service two sockets in parallel.
2572 sock1.reset();
2573
2574 // Start a second connection.
2575 scoped_ptr<StreamSocket> transport2(
2576 new TCPClientSocket(addr_, &log_, NetLog::Source()));
2577 EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
2578 scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
2579 transport2.Pass(), test_server_->host_port_pair(), client_config);
2580 EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
2581
2582 // No session resumption because the first connection never received a server
2583 // Finished message.
2584 SSLInfo ssl_info;
2585 EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
2586 EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
2483 } 2587 }
2484 2588
2485 // Connect to a server using channel id. It should allow the connection. 2589 // Connect to a server using channel id. It should allow the connection.
2486 TEST_F(SSLClientSocketChannelIDTest, SendChannelID) { 2590 TEST_F(SSLClientSocketChannelIDTest, SendChannelID) {
2487 SpawnedTestServer::SSLOptions ssl_options; 2591 SpawnedTestServer::SSLOptions ssl_options;
2488 2592
2489 ASSERT_TRUE(ConnectToTestServer(ssl_options)); 2593 ASSERT_TRUE(ConnectToTestServer(ssl_options));
2490 2594
2491 EnableChannelID(); 2595 EnableChannelID();
2492 SSLConfig ssl_config = kDefaultSSLConfig; 2596 SSLConfig ssl_config = kDefaultSSLConfig;
(...skipping 26 matching lines...) Expand all
2519 2623
2520 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns 2624 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns
2521 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all 2625 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all
2522 // error codes for now. 2626 // error codes for now.
2523 // http://crbug.com/373670 2627 // http://crbug.com/373670
2524 EXPECT_NE(OK, rv); 2628 EXPECT_NE(OK, rv);
2525 EXPECT_FALSE(sock_->IsConnected()); 2629 EXPECT_FALSE(sock_->IsConnected());
2526 } 2630 }
2527 2631
2528 } // namespace net 2632 } // 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