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

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: Fix win/mac failures. 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_;
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 void CreateAndConnectUpToServerFinished(
Ryan Sleevi 2014/05/31 00:46:11 s/UpToServerFinished/UntilServerFinishedReceived?
davidben 2014/06/02 18:45:38 Done.
717 const SSLConfig& client_config, 723 const SSLConfig& client_config,
718 bool expect_false_start) { 724 TestCompletionCallback* callback,
719 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 725 FakeBlockingStreamSocket** out_raw_transport,
Ryan Sleevi 2014/05/31 00:46:11 More documentation is needed here. My red alert al
davidben 2014/06/02 18:45:38 Documented. (The FakeBlockingStreamSocket annoying
720 server_options, 726 scoped_ptr<SSLClientSocket>* out_sock) {
721 base::FilePath());
722 ASSERT_TRUE(test_server.Start());
723
724 AddressList addr;
725 ASSERT_TRUE(test_server.GetAddressList(&addr));
726
727 TestCompletionCallback callback;
728 scoped_ptr<StreamSocket> real_transport( 727 scoped_ptr<StreamSocket> real_transport(
729 new TCPClientSocket(addr, NULL, NetLog::Source())); 728 new TCPClientSocket(addr_, NULL, NetLog::Source()));
730 scoped_ptr<FakeBlockingStreamSocket> transport( 729 scoped_ptr<FakeBlockingStreamSocket> transport(
731 new FakeBlockingStreamSocket(real_transport.Pass())); 730 new FakeBlockingStreamSocket(real_transport.Pass()));
732 int rv = callback.GetResult(transport->Connect(callback.callback())); 731 int rv = callback->GetResult(transport->Connect(callback->callback()));
733 EXPECT_EQ(OK, rv); 732 EXPECT_EQ(OK, rv);
734 733
735 FakeBlockingStreamSocket* raw_transport = transport.get(); 734 FakeBlockingStreamSocket* raw_transport = transport.get();
736 scoped_ptr<SSLClientSocket> sock( 735 scoped_ptr<SSLClientSocket> sock =
737 CreateSSLClientSocket(transport.PassAs<StreamSocket>(), 736 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
738 test_server.host_port_pair(), 737 test_server_->host_port_pair(),
739 client_config)); 738 client_config);
740 739
741 // Connect. Stop before the client processes the first server leg 740 // Connect. Stop before the client processes the first server leg
742 // (ServerHello, etc.) 741 // (ServerHello, etc.)
743 raw_transport->BlockReadResult(); 742 raw_transport->BlockReadResult();
744 rv = sock->Connect(callback.callback()); 743 rv = sock->Connect(callback->callback());
745 EXPECT_EQ(ERR_IO_PENDING, rv); 744 EXPECT_EQ(ERR_IO_PENDING, rv);
746 raw_transport->WaitForReadResult(); 745 raw_transport->WaitForReadResult();
747 746
748 // Release the ServerHello and wait for the client to write 747 // Release the ServerHello and wait for the client to write
749 // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the 748 // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the
750 // server's leg to complete, since it may span multiple reads.) 749 // server's leg to complete, since it may span multiple reads.)
751 EXPECT_FALSE(callback.have_result()); 750 EXPECT_FALSE(callback->have_result());
752 raw_transport->BlockWrite(); 751 raw_transport->BlockWrite();
753 raw_transport->UnblockReadResult(); 752 raw_transport->UnblockReadResult();
754 raw_transport->WaitForWrite(); 753 raw_transport->WaitForWrite();
755 754
756 // And, finally, release that and block the next server leg 755 // And, finally, release that and block the next server leg
757 // (ChangeCipherSpec, Finished). Note: callback.have_result() may or may not 756 // (ChangeCipherSpec, Finished). Note: callback->have_result() may or may
758 // be true at this point depending on whether the SSL implementation waits 757 // 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 758 // waits for the client second leg to clear the internal write buffer and
760 // network. 759 // hit the network.
761 raw_transport->BlockReadResult(); 760 raw_transport->BlockReadResult();
762 raw_transport->UnblockWrite(); 761 raw_transport->UnblockWrite();
763 762
763 *out_raw_transport = raw_transport;
764 *out_sock = sock.Pass();
765 }
766
767 void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options,
768 const SSLConfig& client_config,
769 bool expect_false_start) {
770 ASSERT_TRUE(StartTestServer(server_options));
771
772 TestCompletionCallback callback;
773 FakeBlockingStreamSocket* raw_transport;
774 scoped_ptr<SSLClientSocket> sock;
775 CreateAndConnectUpToServerFinished(
776 client_config, &callback, &raw_transport, &sock);
Ryan Sleevi 2014/05/31 00:46:11 DANGER: If you ever added an ASSERT_() to CreateAn
davidben 2014/06/02 18:45:38 Oh, so that's how you do it... done.
777
764 if (expect_false_start) { 778 if (expect_false_start) {
765 // When False Starting, the handshake should complete before receiving the 779 // When False Starting, the handshake should complete before receiving the
766 // Change Cipher Spec and Finished messages. 780 // Change Cipher Spec and Finished messages.
767 rv = callback.GetResult(rv); 781 int rv = callback.GetResult(ERR_IO_PENDING);
Ryan Sleevi 2014/05/31 00:46:11 Just use int rv = callback.WaitForResult(); no n
davidben 2014/06/02 18:45:38 Done.
768 EXPECT_EQ(OK, rv); 782 EXPECT_EQ(OK, rv);
769 EXPECT_TRUE(sock->IsConnected()); 783 EXPECT_TRUE(sock->IsConnected());
770 784
771 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 785 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
772 static const int kRequestTextSize = 786 static const int kRequestTextSize =
773 static_cast<int>(arraysize(request_text) - 1); 787 static_cast<int>(arraysize(request_text) - 1);
774 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); 788 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize));
775 memcpy(request_buffer->data(), request_text, kRequestTextSize); 789 memcpy(request_buffer->data(), request_text, kRequestTextSize);
776 790
777 // Write the request. 791 // Write the request.
(...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) { 2489 TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) {
2476 SpawnedTestServer::SSLOptions server_options; 2490 SpawnedTestServer::SSLOptions server_options;
2477 server_options.key_exchanges = 2491 server_options.key_exchanges =
2478 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA; 2492 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA;
2479 server_options.enable_npn = true; 2493 server_options.enable_npn = true;
2480 SSLConfig client_config; 2494 SSLConfig client_config;
2481 client_config.next_protos.push_back("http/1.1"); 2495 client_config.next_protos.push_back("http/1.1");
2482 TestFalseStart(server_options, client_config, false); 2496 TestFalseStart(server_options, client_config, false);
2483 } 2497 }
2484 2498
2499 // Test that sessions are resumable after receiving the server Finished message.
2500 TEST_F(SSLClientSocketFalseStartTest, SessionResumption) {
2501 // Start a server.
2502 SpawnedTestServer::SSLOptions server_options;
2503 server_options.key_exchanges =
2504 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2505 server_options.enable_npn = true;
2506 SSLConfig client_config;
2507 client_config.next_protos.push_back("http/1.1");
2508
2509 // Let a full handshake complete with False Start.
2510 TestFalseStart(server_options, client_config, true);
2511
2512 // Make a second connection.
2513 TestCompletionCallback callback;
2514 scoped_ptr<StreamSocket> transport2(
2515 new TCPClientSocket(addr_, &log_, NetLog::Source()));
2516 EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
2517 scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
2518 transport2.Pass(), test_server_->host_port_pair(), client_config);
2519 EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
2520
2521 // It should resume the session.
2522 SSLInfo ssl_info;
2523 EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
2524 EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
2525 }
2526
2527 // Test that sessions are not resumable before receiving the server Finished
2528 // message.
2529 TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinish) {
2530 // Start a server.
2531 SpawnedTestServer::SSLOptions server_options;
2532 server_options.key_exchanges =
2533 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2534 server_options.enable_npn = true;
2535 ASSERT_TRUE(StartTestServer(server_options));
2536
2537 SSLConfig client_config;
2538 client_config.next_protos.push_back("http/1.1");
2539
2540 // Start a handshake up to the server Finished message.
2541 TestCompletionCallback callback;
2542 FakeBlockingStreamSocket* raw_transport1;
2543 scoped_ptr<SSLClientSocket> sock1;
2544 CreateAndConnectUpToServerFinished(
2545 client_config, &callback, &raw_transport1, &sock1);
2546 // The handshake should False Start.
2547 EXPECT_EQ(OK, callback.GetResult(ERR_IO_PENDING));
Ryan Sleevi 2014/05/31 00:46:11 ditto WaitForResult() However, it's unclear to me
davidben 2014/06/02 18:45:38 Done. Also added a comment.
2548
2549 // Drop the old socket. This is needed because the Python test server can't
2550 // service two sockets in parallel.
2551 sock1.reset();
2552
2553 // Before the first connection receives ServerFinished, start a second
2554 // connection.
2555 scoped_ptr<StreamSocket> transport2(
2556 new TCPClientSocket(addr_, &log_, NetLog::Source()));
2557 EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
2558 scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
2559 transport2.Pass(), test_server_->host_port_pair(), client_config);
2560 EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
2561
2562 // No session resumption.
2563 SSLInfo ssl_info;
2564 EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
2565 EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
2566 }
2567
2485 // Connect to a server using channel id. It should allow the connection. 2568 // Connect to a server using channel id. It should allow the connection.
2486 TEST_F(SSLClientSocketChannelIDTest, SendChannelID) { 2569 TEST_F(SSLClientSocketChannelIDTest, SendChannelID) {
2487 SpawnedTestServer::SSLOptions ssl_options; 2570 SpawnedTestServer::SSLOptions ssl_options;
2488 2571
2489 ASSERT_TRUE(ConnectToTestServer(ssl_options)); 2572 ASSERT_TRUE(ConnectToTestServer(ssl_options));
2490 2573
2491 EnableChannelID(); 2574 EnableChannelID();
2492 SSLConfig ssl_config = kDefaultSSLConfig; 2575 SSLConfig ssl_config = kDefaultSSLConfig;
2493 ssl_config.channel_id_enabled = true; 2576 ssl_config.channel_id_enabled = true;
2494 2577
(...skipping 24 matching lines...) Expand all
2519 2602
2520 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns 2603 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns
2521 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all 2604 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all
2522 // error codes for now. 2605 // error codes for now.
2523 // http://crbug.com/373670 2606 // http://crbug.com/373670
2524 EXPECT_NE(OK, rv); 2607 EXPECT_NE(OK, rv);
2525 EXPECT_FALSE(sock_->IsConnected()); 2608 EXPECT_FALSE(sock_->IsConnected());
2526 } 2609 }
2527 2610
2528 } // namespace net 2611 } // 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