Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 #include "net/socket/tcp_client_socket.h" | 25 #include "net/socket/tcp_client_socket.h" |
| 26 #include "net/ssl/channel_id_service.h" | 26 #include "net/ssl/channel_id_service.h" |
| 27 #include "net/ssl/default_channel_id_store.h" | 27 #include "net/ssl/default_channel_id_store.h" |
| 28 #include "net/ssl/ssl_cert_request_info.h" | 28 #include "net/ssl/ssl_cert_request_info.h" |
| 29 #include "net/ssl/ssl_config_service.h" | 29 #include "net/ssl/ssl_config_service.h" |
| 30 #include "net/test/cert_test_util.h" | 30 #include "net/test/cert_test_util.h" |
| 31 #include "net/test/spawned_test_server/spawned_test_server.h" | 31 #include "net/test/spawned_test_server/spawned_test_server.h" |
| 32 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 33 #include "testing/platform_test.h" | 33 #include "testing/platform_test.h" |
| 34 | 34 |
| 35 #if defined(OS_WIN) | |
| 36 #include "base/win/windows_version.h" | |
| 37 #endif | |
| 38 | |
| 35 //----------------------------------------------------------------------------- | 39 //----------------------------------------------------------------------------- |
| 36 | 40 |
| 37 namespace net { | 41 namespace net { |
| 38 | 42 |
| 39 namespace { | 43 namespace { |
| 40 | 44 |
| 41 const SSLConfig kDefaultSSLConfig; | 45 const SSLConfig kDefaultSSLConfig; |
| 42 | 46 |
| 43 // WrappedStreamSocket is a base class that wraps an existing StreamSocket, | 47 // WrappedStreamSocket is a base class that wraps an existing StreamSocket, |
| 44 // forwarding the Socket and StreamSocket interfaces to the underlying | 48 // forwarding the Socket and StreamSocket interfaces to the underlying |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 559 } | 563 } |
| 560 | 564 |
| 561 int read_count() const { return read_count_; } | 565 int read_count() const { return read_count_; } |
| 562 int write_count() const { return write_count_; } | 566 int write_count() const { return write_count_; } |
| 563 | 567 |
| 564 private: | 568 private: |
| 565 int read_count_; | 569 int read_count_; |
| 566 int write_count_; | 570 int write_count_; |
| 567 }; | 571 }; |
| 568 | 572 |
| 573 // WriteCapturingSocket is a fake StreamSocket that captures all writes and | |
| 574 // fails any reads. It is intended to capture the ClientHello. | |
| 575 class WriteCapturingSocket : public StreamSocket { | |
| 576 public: | |
| 577 WriteCapturingSocket(net::NetLog* net_log) | |
| 578 : net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)) {} | |
| 579 | |
| 580 const std::vector<uint8_t>& bytes_written() const { return bytes_written_; } | |
| 581 | |
| 582 // StreamSocket implementation: | |
| 583 virtual int Connect(const CompletionCallback& callback) OVERRIDE { | |
| 584 return OK; | |
| 585 } | |
| 586 virtual void Disconnect() OVERRIDE { } | |
| 587 virtual bool IsConnected() const OVERRIDE { | |
| 588 return true; | |
| 589 } | |
| 590 virtual bool IsConnectedAndIdle() const OVERRIDE { | |
| 591 return true; | |
| 592 } | |
| 593 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE { | |
| 594 // NSS requires this method be functional. | |
| 595 IPAddressNumber number; | |
| 596 CHECK(ParseIPLiteralToNumber("127.0.0.1", &number)); | |
| 597 *address = IPEndPoint(number, 443); | |
| 598 return OK; | |
| 599 } | |
| 600 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE { | |
| 601 NOTIMPLEMENTED(); | |
| 602 return ERR_FAILED; | |
| 603 } | |
| 604 virtual const BoundNetLog& NetLog() const OVERRIDE { | |
| 605 return net_log_; | |
| 606 } | |
| 607 virtual void SetSubresourceSpeculation() OVERRIDE { | |
| 608 NOTIMPLEMENTED(); | |
| 609 } | |
| 610 virtual void SetOmniboxSpeculation() OVERRIDE { | |
| 611 NOTIMPLEMENTED(); | |
| 612 } | |
| 613 virtual bool WasEverUsed() const OVERRIDE { | |
| 614 NOTIMPLEMENTED(); | |
| 615 return false; | |
| 616 } | |
| 617 virtual bool UsingTCPFastOpen() const OVERRIDE { | |
| 618 return false; | |
| 619 } | |
| 620 virtual bool WasNpnNegotiated() const OVERRIDE { | |
| 621 return false; | |
| 622 } | |
| 623 virtual NextProto GetNegotiatedProtocol() const OVERRIDE { | |
| 624 return kProtoUnknown; | |
| 625 } | |
| 626 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { | |
| 627 return false; | |
| 628 } | |
| 629 | |
| 630 // Socket implementation: | |
| 631 virtual int Read(IOBuffer* buf, | |
| 632 int buf_len, | |
| 633 const CompletionCallback& callback) OVERRIDE { | |
| 634 // Fail the read to stop the handshake at ClientHello. | |
| 635 return ERR_FAILED; | |
| 636 } | |
| 637 virtual int Write(IOBuffer* buf, | |
| 638 int buf_len, | |
| 639 const CompletionCallback& callback) OVERRIDE { | |
| 640 for (int i = 0; i < buf_len; i++) { | |
| 641 bytes_written_.push_back(buf->data()[i]); | |
| 642 } | |
| 643 return buf_len; | |
| 644 } | |
| 645 virtual int SetReceiveBufferSize(int32 size) OVERRIDE { | |
| 646 return 0; | |
| 647 } | |
| 648 virtual int SetSendBufferSize(int32 size) OVERRIDE { | |
| 649 return 0; | |
| 650 } | |
| 651 | |
| 652 private: | |
| 653 BoundNetLog net_log_; | |
| 654 std::vector<uint8_t> bytes_written_; | |
| 655 }; | |
| 656 | |
| 569 // CompletionCallback that will delete the associated StreamSocket when | 657 // CompletionCallback that will delete the associated StreamSocket when |
| 570 // the callback is invoked. | 658 // the callback is invoked. |
| 571 class DeleteSocketCallback : public TestCompletionCallbackBase { | 659 class DeleteSocketCallback : public TestCompletionCallbackBase { |
| 572 public: | 660 public: |
| 573 explicit DeleteSocketCallback(StreamSocket* socket) | 661 explicit DeleteSocketCallback(StreamSocket* socket) |
| 574 : socket_(socket), | 662 : socket_(socket), |
| 575 callback_(base::Bind(&DeleteSocketCallback::OnComplete, | 663 callback_(base::Bind(&DeleteSocketCallback::OnComplete, |
| 576 base::Unretained(this))) {} | 664 base::Unretained(this))) {} |
| 577 virtual ~DeleteSocketCallback() {} | 665 virtual ~DeleteSocketCallback() {} |
| 578 | 666 |
| (...skipping 2098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2677 EXPECT_TRUE(sock->WasEverUsed()); | 2765 EXPECT_TRUE(sock->WasEverUsed()); |
| 2678 | 2766 |
| 2679 // TODO(davidben): Read one byte to ensure the test server has responded and | 2767 // TODO(davidben): Read one byte to ensure the test server has responded and |
| 2680 // then assert IsConnectedAndIdle is false. This currently doesn't work | 2768 // then assert IsConnectedAndIdle is false. This currently doesn't work |
| 2681 // because neither SSLClientSocketNSS nor SSLClientSocketOpenSSL check their | 2769 // because neither SSLClientSocketNSS nor SSLClientSocketOpenSSL check their |
| 2682 // SSL implementation's internal buffers. Either call PR_Available and | 2770 // SSL implementation's internal buffers. Either call PR_Available and |
| 2683 // SSL_pending, although the former isn't actually implemented or perhaps | 2771 // SSL_pending, although the former isn't actually implemented or perhaps |
| 2684 // attempt to read one byte extra. | 2772 // attempt to read one byte extra. |
| 2685 } | 2773 } |
| 2686 | 2774 |
| 2775 #if defined(OS_WIN) | |
| 2776 | |
| 2777 bool IsECDSACipherSuite(uint16_t cipher_suite) { | |
| 2778 // RFC 4492. | |
| 2779 if (0xc001 <= cipher_suite && cipher_suite <= 0xc00a) | |
| 2780 return true; | |
| 2781 // RFC 5289. | |
| 2782 if (0xc023 <= cipher_suite && cipher_suite <= 0xc026) | |
| 2783 return true; | |
| 2784 if (0xc02b <= cipher_suite && cipher_suite <= 0xc02e) | |
| 2785 return true; | |
| 2786 return false; | |
|
Ryan Sleevi
2014/09/02 23:45:01
SSLCipherSuiteToStrings(&key_exchange, ..., cipher
davidben
2014/09/03 17:10:41
Done.
| |
| 2787 } | |
| 2788 | |
| 2789 // Test that ECDSA is disabled on Windows XP, where ECDSA certificates cannot be | |
| 2790 // verified. | |
| 2791 TEST_F(SSLClientSocketTest, DisableECDSAOnXP) { | |
| 2792 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { | |
| 2793 LOG(INFO) << "Skipping test on this version."; | |
| 2794 return; | |
| 2795 } | |
| 2796 | |
| 2797 scoped_ptr<WriteCapturingSocket> transport(new WriteCapturingSocket(&log_)); | |
| 2798 WriteCapturingSocket* raw_transport = transport.get(); | |
| 2799 | |
| 2800 // Handshake up to trying to read the ServerHello. | |
| 2801 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
| 2802 transport.PassAs<StreamSocket>(), | |
| 2803 HostPortPair("example.com", 443), kDefaultSSLConfig)); | |
| 2804 TestCompletionCallback callback; | |
| 2805 EXPECT_EQ(ERR_FAILED, callback.GetResult(sock->Connect(callback.callback()))); | |
| 2806 base::RunLoop().RunUntilIdle(); | |
| 2807 | |
| 2808 // Parse out the cipher list. This will require that the ClientHello is not | |
| 2809 // fragmented before the cipher list because that would be an exceedingly long | |
| 2810 // cipher list. | |
| 2811 std::vector<uint8_t> client_hello = raw_transport->bytes_written(); | |
| 2812 | |
| 2813 // TLSPlaintext header: | |
| 2814 ASSERT_GE(client_hello.size(), 5u); | |
| 2815 EXPECT_EQ(22, client_hello[0]); // type | |
| 2816 // Next two bytes are the version. | |
| 2817 uint16_t record_length = (client_hello[3] << 8) | client_hello[4]; | |
| 2818 // Grab the record body. | |
| 2819 ASSERT_GE(client_hello.size(), 5u + record_length); | |
| 2820 std::vector<uint8_t> record_body(client_hello.begin() + 5, | |
| 2821 client_hello.begin() + 5 + record_length); | |
| 2822 | |
| 2823 // Handshake header: | |
| 2824 ASSERT_GE(record_body.size(), 4u); | |
| 2825 EXPECT_EQ(1, record_body[0]); // msg_type | |
| 2826 uint32_t length = | |
| 2827 (record_body[1] << 16) | (record_body[2] << 8) | record_body[3]; | |
| 2828 std::vector<uint8_t> message(record_body.begin() + 4, record_body.end()); | |
| 2829 // There cannot be a handshake message after ClientHello, though the | |
| 2830 // ClientHello could conceivably be fragmented across two records. | |
| 2831 ASSERT_LE(message.size(), length); | |
| 2832 | |
| 2833 // ClientHello: | |
| 2834 | |
| 2835 // Skip past the client_version and random. | |
| 2836 ASSERT_GE(message.size(), 2u + 32u); | |
| 2837 message.erase(message.begin(), message.begin() + 2 + 32); | |
| 2838 | |
| 2839 // Skip past the session id. | |
| 2840 ASSERT_GE(message.size(), 1u); | |
| 2841 uint8_t session_id_length = message[0]; | |
| 2842 ASSERT_GE(message.size(), 1u + session_id_length); | |
| 2843 message.erase(message.begin(), message.begin() + 1 + session_id_length); | |
| 2844 | |
| 2845 // Get the cipher suite list. | |
| 2846 ASSERT_GE(message.size(), 2u); | |
| 2847 uint16_t cipher_suites_length = (message[0] << 8) | message[1]; | |
| 2848 EXPECT_EQ(0, cipher_suites_length % 2); | |
| 2849 ASSERT_GE(message.size(), 2u + cipher_suites_length); | |
| 2850 std::vector<uint8_t> cipher_suites( | |
| 2851 message.begin() + 2, message.begin() + 2 + cipher_suites_length); | |
| 2852 | |
| 2853 // Finally, ensure there are no ECDSA cipher suites in there. | |
| 2854 for (size_t i = 0; i+1 < cipher_suites.size(); i+=2) { | |
| 2855 uint16_t cipher_suite = (cipher_suites[i] << 8) | cipher_suites[i+1]; | |
| 2856 EXPECT_FALSE(IsECDSACipherSuite(cipher_suite)) | |
| 2857 << "ClientHello advertised " << std::hex << cipher_suite; | |
| 2858 } | |
| 2859 } | |
| 2860 | |
| 2861 #endif // OS_WIN | |
| 2862 | |
| 2687 #if defined(USE_OPENSSL) | 2863 #if defined(USE_OPENSSL) |
| 2688 | 2864 |
| 2689 TEST_F(SSLClientSocketTest, HandshakeCallbackIsRun_WithFailure) { | 2865 TEST_F(SSLClientSocketTest, HandshakeCallbackIsRun_WithFailure) { |
| 2690 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 2866 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
| 2691 SpawnedTestServer::kLocalhost, | 2867 SpawnedTestServer::kLocalhost, |
| 2692 base::FilePath()); | 2868 base::FilePath()); |
| 2693 ASSERT_TRUE(test_server.Start()); | 2869 ASSERT_TRUE(test_server.Start()); |
| 2694 | 2870 |
| 2695 AddressList addr; | 2871 AddressList addr; |
| 2696 ASSERT_TRUE(test_server.GetAddressList(&addr)); | 2872 ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2990 ssl_config.channel_id_enabled = true; | 3166 ssl_config.channel_id_enabled = true; |
| 2991 | 3167 |
| 2992 int rv; | 3168 int rv; |
| 2993 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); | 3169 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); |
| 2994 | 3170 |
| 2995 EXPECT_EQ(ERR_UNEXPECTED, rv); | 3171 EXPECT_EQ(ERR_UNEXPECTED, rv); |
| 2996 EXPECT_FALSE(sock_->IsConnected()); | 3172 EXPECT_FALSE(sock_->IsConnected()); |
| 2997 } | 3173 } |
| 2998 | 3174 |
| 2999 } // namespace net | 3175 } // namespace net |
| OLD | NEW |