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 "net/base/address_list.h" | 9 #include "net/base/address_list.h" |
10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 return socket_factory_->CreateSSLClientSocket( | 517 return socket_factory_->CreateSSLClientSocket( |
518 connection.Pass(), host_and_port, ssl_config, context_); | 518 connection.Pass(), host_and_port, ssl_config, context_); |
519 } | 519 } |
520 | 520 |
521 ClientSocketFactory* socket_factory_; | 521 ClientSocketFactory* socket_factory_; |
522 scoped_ptr<MockCertVerifier> cert_verifier_; | 522 scoped_ptr<MockCertVerifier> cert_verifier_; |
523 scoped_ptr<TransportSecurityState> transport_security_state_; | 523 scoped_ptr<TransportSecurityState> transport_security_state_; |
524 SSLClientSocketContext context_; | 524 SSLClientSocketContext context_; |
525 }; | 525 }; |
526 | 526 |
| 527 // Verifies the correctness of GetSSLCertRequestInfo. |
| 528 class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest { |
| 529 protected: |
| 530 // Creates a test server with the given SSLOptions, connects to it and returns |
| 531 // the SSLCertRequestInfo reported by the socket. |
| 532 scoped_refptr<SSLCertRequestInfo> GetCertRequest( |
| 533 SpawnedTestServer::SSLOptions ssl_options) { |
| 534 SpawnedTestServer test_server( |
| 535 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); |
| 536 if (!test_server.Start()) |
| 537 return NULL; |
| 538 |
| 539 AddressList addr; |
| 540 if (!test_server.GetAddressList(&addr)) |
| 541 return NULL; |
| 542 |
| 543 TestCompletionCallback callback; |
| 544 CapturingNetLog log; |
| 545 scoped_ptr<StreamSocket> transport( |
| 546 new TCPClientSocket(addr, &log, NetLog::Source())); |
| 547 int rv = transport->Connect(callback.callback()); |
| 548 if (rv == ERR_IO_PENDING) |
| 549 rv = callback.WaitForResult(); |
| 550 EXPECT_EQ(OK, rv); |
| 551 |
| 552 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( |
| 553 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig)); |
| 554 EXPECT_FALSE(sock->IsConnected()); |
| 555 |
| 556 rv = sock->Connect(callback.callback()); |
| 557 if (rv == ERR_IO_PENDING) |
| 558 rv = callback.WaitForResult(); |
| 559 scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo(); |
| 560 sock->GetSSLCertRequestInfo(request_info.get()); |
| 561 sock->Disconnect(); |
| 562 EXPECT_FALSE(sock->IsConnected()); |
| 563 |
| 564 return request_info; |
| 565 } |
| 566 }; |
| 567 |
527 //----------------------------------------------------------------------------- | 568 //----------------------------------------------------------------------------- |
528 | 569 |
529 // LogContainsSSLConnectEndEvent returns true if the given index in the given | 570 // LogContainsSSLConnectEndEvent returns true if the given index in the given |
530 // log is an SSL connect end event. The NSS sockets will cork in an attempt to | 571 // log is an SSL connect end event. The NSS sockets will cork in an attempt to |
531 // merge the first application data record with the Finished message when false | 572 // merge the first application data record with the Finished message when false |
532 // starting. However, in order to avoid the server timing out the handshake, | 573 // starting. However, in order to avoid the server timing out the handshake, |
533 // they'll give up waiting for application data and send the Finished after a | 574 // they'll give up waiting for application data and send the Finished after a |
534 // timeout. This means that an SSL connect end event may appear as a socket | 575 // timeout. This means that an SSL connect end event may appear as a socket |
535 // write. | 576 // write. |
536 static bool LogContainsSSLConnectEndEvent( | 577 static bool LogContainsSSLConnectEndEvent( |
537 const CapturingNetLog::CapturedEntryList& log, | 578 const CapturingNetLog::CapturedEntryList& log, |
538 int i) { | 579 int i) { |
539 return LogContainsEndEvent(log, i, NetLog::TYPE_SSL_CONNECT) || | 580 return LogContainsEndEvent(log, i, NetLog::TYPE_SSL_CONNECT) || |
540 LogContainsEvent( | 581 LogContainsEvent( |
541 log, i, NetLog::TYPE_SOCKET_BYTES_SENT, NetLog::PHASE_NONE); | 582 log, i, NetLog::TYPE_SOCKET_BYTES_SENT, NetLog::PHASE_NONE); |
542 } | 583 } |
543 | 584 |
| 585 } // namespace |
| 586 |
544 TEST_F(SSLClientSocketTest, Connect) { | 587 TEST_F(SSLClientSocketTest, Connect) { |
545 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 588 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
546 SpawnedTestServer::kLocalhost, | 589 SpawnedTestServer::kLocalhost, |
547 base::FilePath()); | 590 base::FilePath()); |
548 ASSERT_TRUE(test_server.Start()); | 591 ASSERT_TRUE(test_server.Start()); |
549 | 592 |
550 AddressList addr; | 593 AddressList addr; |
551 ASSERT_TRUE(test_server.GetAddressList(&addr)); | 594 ASSERT_TRUE(test_server.GetAddressList(&addr)); |
552 | 595 |
553 TestCompletionCallback callback; | 596 TestCompletionCallback callback; |
(...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1701 EXPECT_EQ(rv, OK); | 1744 EXPECT_EQ(rv, OK); |
1702 EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0); | 1745 EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0); |
1703 } | 1746 } |
1704 | 1747 |
1705 // Verifies that SSLClientSocket::ClearSessionCache can be called without | 1748 // Verifies that SSLClientSocket::ClearSessionCache can be called without |
1706 // explicit NSS initialization. | 1749 // explicit NSS initialization. |
1707 TEST(SSLClientSocket, ClearSessionCache) { | 1750 TEST(SSLClientSocket, ClearSessionCache) { |
1708 SSLClientSocket::ClearSessionCache(); | 1751 SSLClientSocket::ClearSessionCache(); |
1709 } | 1752 } |
1710 | 1753 |
| 1754 // Test that the server certificates are properly retrieved from the underlying |
| 1755 // SSL stack. |
| 1756 TEST_F(SSLClientSocketTest, VerifyServerChainProperlyOrdered) { |
| 1757 // The connection does not have to be successful. |
| 1758 cert_verifier_->set_default_result(ERR_CERT_INVALID); |
| 1759 |
| 1760 // Set up a test server with CERT_CHAIN_WRONG_ROOT. |
| 1761 // This makes the server present redundant-server-chain.pem, which contains |
| 1762 // intermediate certificates. |
| 1763 SpawnedTestServer::SSLOptions ssl_options( |
| 1764 SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT); |
| 1765 SpawnedTestServer test_server( |
| 1766 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); |
| 1767 ASSERT_TRUE(test_server.Start()); |
| 1768 |
| 1769 AddressList addr; |
| 1770 ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| 1771 |
| 1772 TestCompletionCallback callback; |
| 1773 scoped_ptr<StreamSocket> transport( |
| 1774 new TCPClientSocket(addr, NULL, NetLog::Source())); |
| 1775 int rv = transport->Connect(callback.callback()); |
| 1776 rv = callback.GetResult(rv); |
| 1777 EXPECT_EQ(OK, rv); |
| 1778 |
| 1779 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( |
| 1780 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig)); |
| 1781 EXPECT_FALSE(sock->IsConnected()); |
| 1782 rv = sock->Connect(callback.callback()); |
| 1783 rv = callback.GetResult(rv); |
| 1784 |
| 1785 EXPECT_EQ(ERR_CERT_INVALID, rv); |
| 1786 EXPECT_TRUE(sock->IsConnected()); |
| 1787 |
| 1788 // When given option CERT_CHAIN_WRONG_ROOT, SpawnedTestServer will present |
| 1789 // certs from redundant-server-chain.pem. |
| 1790 CertificateList server_certs = |
| 1791 CreateCertificateListFromFile(GetTestCertsDirectory(), |
| 1792 "redundant-server-chain.pem", |
| 1793 X509Certificate::FORMAT_AUTO); |
| 1794 |
| 1795 // Get the server certificate as received client side. |
| 1796 scoped_refptr<X509Certificate> server_certificate = |
| 1797 sock->GetUnverifiedServerCertificateChain(); |
| 1798 |
| 1799 // Get the intermediates as received client side. |
| 1800 const X509Certificate::OSCertHandles& server_intermediates = |
| 1801 server_certificate->GetIntermediateCertificates(); |
| 1802 |
| 1803 // Check that the unverified server certificate chain is properly retrieved |
| 1804 // from the underlying ssl stack. |
| 1805 ASSERT_EQ(4U, server_certs.size()); |
| 1806 |
| 1807 EXPECT_TRUE(X509Certificate::IsSameOSCert( |
| 1808 server_certificate->os_cert_handle(), server_certs[0]->os_cert_handle())); |
| 1809 |
| 1810 ASSERT_EQ(3U, server_intermediates.size()); |
| 1811 |
| 1812 EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[0], |
| 1813 server_certs[1]->os_cert_handle())); |
| 1814 EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[1], |
| 1815 server_certs[2]->os_cert_handle())); |
| 1816 EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[2], |
| 1817 server_certs[3]->os_cert_handle())); |
| 1818 |
| 1819 sock->Disconnect(); |
| 1820 EXPECT_FALSE(sock->IsConnected()); |
| 1821 } |
| 1822 |
1711 // This tests that SSLInfo contains a properly re-constructed certificate | 1823 // This tests that SSLInfo contains a properly re-constructed certificate |
1712 // chain. That, in turn, verifies that GetSSLInfo is giving us the chain as | 1824 // chain. That, in turn, verifies that GetSSLInfo is giving us the chain as |
1713 // verified, not the chain as served by the server. (They may be different.) | 1825 // verified, not the chain as served by the server. (They may be different.) |
1714 // | 1826 // |
1715 // CERT_CHAIN_WRONG_ROOT is redundant-server-chain.pem. It contains A | 1827 // CERT_CHAIN_WRONG_ROOT is redundant-server-chain.pem. It contains A |
1716 // (end-entity) -> B -> C, and C is signed by D. redundant-validated-chain.pem | 1828 // (end-entity) -> B -> C, and C is signed by D. redundant-validated-chain.pem |
1717 // contains a chain of A -> B -> C2, where C2 is the same public key as C, but | 1829 // contains a chain of A -> B -> C2, where C2 is the same public key as C, but |
1718 // a self-signed root. Such a situation can occur when a new root (C2) is | 1830 // a self-signed root. Such a situation can occur when a new root (C2) is |
1719 // cross-certified by an old root (D) and has two different versions of its | 1831 // cross-certified by an old root (D) and has two different versions of its |
1720 // floating around. Servers may supply C2 as an intermediate, but the | 1832 // floating around. Servers may supply C2 as an intermediate, but the |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1799 certs[0]->os_cert_handle())); | 1911 certs[0]->os_cert_handle())); |
1800 EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[0], | 1912 EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[0], |
1801 certs[1]->os_cert_handle())); | 1913 certs[1]->os_cert_handle())); |
1802 EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[1], | 1914 EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[1], |
1803 certs[2]->os_cert_handle())); | 1915 certs[2]->os_cert_handle())); |
1804 | 1916 |
1805 sock->Disconnect(); | 1917 sock->Disconnect(); |
1806 EXPECT_FALSE(sock->IsConnected()); | 1918 EXPECT_FALSE(sock->IsConnected()); |
1807 } | 1919 } |
1808 | 1920 |
1809 // Verifies the correctness of GetSSLCertRequestInfo. | |
1810 class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest { | |
1811 protected: | |
1812 // Creates a test server with the given SSLOptions, connects to it and returns | |
1813 // the SSLCertRequestInfo reported by the socket. | |
1814 scoped_refptr<SSLCertRequestInfo> GetCertRequest( | |
1815 SpawnedTestServer::SSLOptions ssl_options) { | |
1816 SpawnedTestServer test_server( | |
1817 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
1818 if (!test_server.Start()) | |
1819 return NULL; | |
1820 | |
1821 AddressList addr; | |
1822 if (!test_server.GetAddressList(&addr)) | |
1823 return NULL; | |
1824 | |
1825 TestCompletionCallback callback; | |
1826 CapturingNetLog log; | |
1827 scoped_ptr<StreamSocket> transport( | |
1828 new TCPClientSocket(addr, &log, NetLog::Source())); | |
1829 int rv = transport->Connect(callback.callback()); | |
1830 if (rv == ERR_IO_PENDING) | |
1831 rv = callback.WaitForResult(); | |
1832 EXPECT_EQ(OK, rv); | |
1833 | |
1834 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1835 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig)); | |
1836 EXPECT_FALSE(sock->IsConnected()); | |
1837 | |
1838 rv = sock->Connect(callback.callback()); | |
1839 if (rv == ERR_IO_PENDING) | |
1840 rv = callback.WaitForResult(); | |
1841 scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo(); | |
1842 sock->GetSSLCertRequestInfo(request_info.get()); | |
1843 sock->Disconnect(); | |
1844 EXPECT_FALSE(sock->IsConnected()); | |
1845 | |
1846 return request_info; | |
1847 } | |
1848 }; | |
1849 | |
1850 TEST_F(SSLClientSocketCertRequestInfoTest, NoAuthorities) { | 1921 TEST_F(SSLClientSocketCertRequestInfoTest, NoAuthorities) { |
1851 SpawnedTestServer::SSLOptions ssl_options; | 1922 SpawnedTestServer::SSLOptions ssl_options; |
1852 ssl_options.request_client_certificate = true; | 1923 ssl_options.request_client_certificate = true; |
1853 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options); | 1924 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options); |
1854 ASSERT_TRUE(request_info.get()); | 1925 ASSERT_TRUE(request_info.get()); |
1855 EXPECT_EQ(0u, request_info->cert_authorities.size()); | 1926 EXPECT_EQ(0u, request_info->cert_authorities.size()); |
1856 } | 1927 } |
1857 | 1928 |
1858 TEST_F(SSLClientSocketCertRequestInfoTest, TwoAuthorities) { | 1929 TEST_F(SSLClientSocketCertRequestInfoTest, TwoAuthorities) { |
1859 const base::FilePath::CharType kThawteFile[] = | 1930 const base::FilePath::CharType kThawteFile[] = |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1891 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options); | 1962 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options); |
1892 ASSERT_TRUE(request_info.get()); | 1963 ASSERT_TRUE(request_info.get()); |
1893 ASSERT_EQ(2u, request_info->cert_authorities.size()); | 1964 ASSERT_EQ(2u, request_info->cert_authorities.size()); |
1894 EXPECT_EQ(std::string(reinterpret_cast<const char*>(kThawteDN), kThawteLen), | 1965 EXPECT_EQ(std::string(reinterpret_cast<const char*>(kThawteDN), kThawteLen), |
1895 request_info->cert_authorities[0]); | 1966 request_info->cert_authorities[0]); |
1896 EXPECT_EQ( | 1967 EXPECT_EQ( |
1897 std::string(reinterpret_cast<const char*>(kDiginotarDN), kDiginotarLen), | 1968 std::string(reinterpret_cast<const char*>(kDiginotarDN), kDiginotarLen), |
1898 request_info->cert_authorities[1]); | 1969 request_info->cert_authorities[1]); |
1899 } | 1970 } |
1900 | 1971 |
1901 } // namespace | |
1902 | |
1903 TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) { | 1972 TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) { |
1904 SpawnedTestServer::SSLOptions ssl_options; | 1973 SpawnedTestServer::SSLOptions ssl_options; |
1905 ssl_options.signed_cert_timestamps_tls_ext = "test"; | 1974 ssl_options.signed_cert_timestamps_tls_ext = "test"; |
1906 | 1975 |
1907 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1976 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
1908 ssl_options, | 1977 ssl_options, |
1909 base::FilePath()); | 1978 base::FilePath()); |
1910 ASSERT_TRUE(test_server.Start()); | 1979 ASSERT_TRUE(test_server.Start()); |
1911 | 1980 |
1912 AddressList addr; | 1981 AddressList addr; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 log.GetEntries(&entries); | 2121 log.GetEntries(&entries); |
2053 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); | 2122 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); |
2054 | 2123 |
2055 EXPECT_FALSE(sock->signed_cert_timestamps_received_); | 2124 EXPECT_FALSE(sock->signed_cert_timestamps_received_); |
2056 | 2125 |
2057 sock->Disconnect(); | 2126 sock->Disconnect(); |
2058 EXPECT_FALSE(sock->IsConnected()); | 2127 EXPECT_FALSE(sock->IsConnected()); |
2059 } | 2128 } |
2060 | 2129 |
2061 } // namespace net | 2130 } // namespace net |
OLD | NEW |