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

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

Issue 495663002: OpenSSL: Disable ECDSA cipher suites on Windows XP. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add a test. Created 6 years, 4 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 | « net/socket/ssl_client_socket_openssl.cc ('k') | no next file » | 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 "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 14 matching lines...) Expand all
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
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
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
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
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_openssl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698