Chromium Code Reviews| Index: net/socket/ssl_client_socket_unittest.cc |
| diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc |
| index f695e27c240f9edff7d8f4397f9f32f854190f2d..9f0dc9450f4cf279a6c5d321c39e91604fdc7b26 100644 |
| --- a/net/socket/ssl_client_socket_unittest.cc |
| +++ b/net/socket/ssl_client_socket_unittest.cc |
| @@ -15,6 +15,8 @@ |
| #include "net/base/net_log_unittest.h" |
| #include "net/base/test_completion_callback.h" |
| #include "net/base/test_data_directory.h" |
| +#include "net/cert/asn1_util.h" |
| +#include "net/cert/ct_verifier.h" |
| #include "net/cert/mock_cert_verifier.h" |
| #include "net/cert/test_root_certs.h" |
| #include "net/dns/host_resolver.h" |
| @@ -29,11 +31,16 @@ |
| #include "net/ssl/ssl_config_service.h" |
| #include "net/test/cert_test_util.h" |
| #include "net/test/spawned_test_server/spawned_test_server.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "testing/platform_test.h" |
| //----------------------------------------------------------------------------- |
| +using testing::_; |
| +using testing::Return; |
| +using testing::Truly; |
| + |
| namespace net { |
| namespace { |
| @@ -656,6 +663,17 @@ class AsyncFailingChannelIDStore : public ChannelIDStore { |
| virtual void SetForceKeepSessionState() OVERRIDE {} |
| }; |
| +// A mock CTVerifier that records every call to Verify but doesn't verify |
| +// anything. |
| +class MockCTVerifier : public CTVerifier { |
| + public: |
| + MOCK_METHOD5(Verify, int(X509Certificate*, |
| + const std::string&, |
| + const std::string&, |
| + ct::CTVerifyResult*, |
| + const BoundNetLog&)); |
| +}; |
| + |
| class SSLClientSocketTest : public PlatformTest { |
| public: |
| SSLClientSocketTest() |
| @@ -677,6 +695,10 @@ class SSLClientSocketTest : public PlatformTest { |
| // The SpawnedTestServer object, after calling StartTestServer(). |
| const SpawnedTestServer* test_server() const { return test_server_.get(); } |
| + void SetCTVerifier(CTVerifier* ct_verifier) { |
| + context_.cert_transparency_verifier = ct_verifier; |
| + } |
| + |
| // Starts the test server with SSL configuration |ssl_options|. Returns true |
| // on success. |
| bool StartTestServer(const SpawnedTestServer::SSLOptions& ssl_options) { |
| @@ -2483,45 +2505,49 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) { |
| ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| TestCompletionCallback callback; |
| - CapturingNetLog log; |
| scoped_ptr<StreamSocket> transport( |
| - new TCPClientSocket(addr, &log, NetLog::Source())); |
| - int rv = transport->Connect(callback.callback()); |
| - if (rv == ERR_IO_PENDING) |
| - rv = callback.WaitForResult(); |
| + new TCPClientSocket(addr, &log_, NetLog::Source())); |
| + int rv = callback.GetResult(transport->Connect(callback.callback())); |
| EXPECT_EQ(OK, rv); |
| SSLConfig ssl_config; |
| ssl_config.signed_cert_timestamps_enabled = true; |
| - scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( |
| - transport.Pass(), test_server.host_port_pair(), ssl_config)); |
| - |
| - EXPECT_FALSE(sock->IsConnected()); |
| + MockCTVerifier ct_verifier; |
| + SetCTVerifier(&ct_verifier); |
| - rv = sock->Connect(callback.callback()); |
| + // Check that the SCT list is extracted as expected. |
| + EXPECT_CALL(ct_verifier, Verify(_, "", "test", _, _)).WillRepeatedly( |
| + Return(ERR_CT_NO_SCTS_VERIFIED_OK)); |
| - CapturingNetLog::CapturedEntryList entries; |
| - log.GetEntries(&entries); |
| - EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); |
| - if (rv == ERR_IO_PENDING) |
| - rv = callback.WaitForResult(); |
| + scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( |
| + transport.Pass(), test_server.host_port_pair(), ssl_config)); |
| + rv = callback.GetResult(sock->Connect(callback.callback())); |
| EXPECT_EQ(OK, rv); |
| - EXPECT_TRUE(sock->IsConnected()); |
| - log.GetEntries(&entries); |
| - EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); |
| -#if !defined(USE_OPENSSL) |
| EXPECT_TRUE(sock->signed_cert_timestamps_received_); |
| -#else |
| - // Enabling CT for OpenSSL is currently a noop. |
| - EXPECT_FALSE(sock->signed_cert_timestamps_received_); |
| -#endif |
| +} |
| - sock->Disconnect(); |
| - EXPECT_FALSE(sock->IsConnected()); |
| +namespace { |
| + |
| +// Check that the OCSP response is well-formed. It should be the DER encoding of |
|
Ryan Sleevi
2014/09/02 23:05:11
Move to line 1007
davidben
2014/09/02 23:38:43
Done.
|
| +// an OCSPResponse (RFC 2560), so check that it consists of a SEQUENCE of an |
| +// ENUMERATED type and an element tagged with [0] EXPLICIT. In particular, it |
| +// should not include the overall two-byte length prefix from TLS. |
| +bool IsValidOCSPResponse(const base::StringPiece& input) { |
| + base::StringPiece ocsp_response = input; |
| + base::StringPiece sequence, response_status, response_bytes; |
| + return asn1::GetElement(&ocsp_response, asn1::kSEQUENCE, &sequence) && |
| + ocsp_response.empty() && |
| + asn1::GetElement(&sequence, asn1::kENUMERATED, &response_status) && |
| + asn1::GetElement(&sequence, |
| + asn1::kContextSpecific | asn1::kConstructed | 0, |
| + &response_status) && |
| + sequence.empty(); |
| } |
| +} // namespace |
| + |
| // Test that enabling Signed Certificate Timestamps enables OCSP stapling. |
| TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) { |
| SpawnedTestServer::SSLOptions ssl_options; |
| @@ -2539,12 +2565,9 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) { |
| ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| TestCompletionCallback callback; |
| - CapturingNetLog log; |
| scoped_ptr<StreamSocket> transport( |
| - new TCPClientSocket(addr, &log, NetLog::Source())); |
| - int rv = transport->Connect(callback.callback()); |
| - if (rv == ERR_IO_PENDING) |
| - rv = callback.WaitForResult(); |
| + new TCPClientSocket(addr, &log_, NetLog::Source())); |
| + int rv = callback.GetResult(transport->Connect(callback.callback())); |
| EXPECT_EQ(OK, rv); |
| SSLConfig ssl_config; |
| @@ -2553,32 +2576,20 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) { |
| // is able to process the OCSP status itself. |
| ssl_config.signed_cert_timestamps_enabled = true; |
| - scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( |
| - transport.Pass(), test_server.host_port_pair(), ssl_config)); |
| - |
| - EXPECT_FALSE(sock->IsConnected()); |
| + MockCTVerifier ct_verifier; |
| + SetCTVerifier(&ct_verifier); |
| - rv = sock->Connect(callback.callback()); |
| + // Check that the OCSP response is extracted as expected. |
| + EXPECT_CALL(ct_verifier, |
| + Verify(_, Truly(IsValidOCSPResponse), "", _, _)).WillRepeatedly( |
| + Return(ERR_CT_NO_SCTS_VERIFIED_OK)); |
| - CapturingNetLog::CapturedEntryList entries; |
| - log.GetEntries(&entries); |
| - EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); |
| - if (rv == ERR_IO_PENDING) |
| - rv = callback.WaitForResult(); |
| + scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( |
| + transport.Pass(), test_server.host_port_pair(), ssl_config)); |
| + rv = callback.GetResult(sock->Connect(callback.callback())); |
| EXPECT_EQ(OK, rv); |
| - EXPECT_TRUE(sock->IsConnected()); |
| - log.GetEntries(&entries); |
| - EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); |
| -#if !defined(USE_OPENSSL) |
| EXPECT_TRUE(sock->stapled_ocsp_response_received_); |
| -#else |
| - // OCSP stapling isn't currently supported in the OpenSSL socket. |
| - EXPECT_FALSE(sock->stapled_ocsp_response_received_); |
| -#endif |
| - |
| - sock->Disconnect(); |
| - EXPECT_FALSE(sock->IsConnected()); |
| } |
| TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsDisabled) { |
| @@ -2594,12 +2605,9 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsDisabled) { |
| ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| TestCompletionCallback callback; |
| - CapturingNetLog log; |
| scoped_ptr<StreamSocket> transport( |
| - new TCPClientSocket(addr, &log, NetLog::Source())); |
| - int rv = transport->Connect(callback.callback()); |
| - if (rv == ERR_IO_PENDING) |
| - rv = callback.WaitForResult(); |
| + new TCPClientSocket(addr, &log_, NetLog::Source())); |
| + int rv = callback.GetResult(transport->Connect(callback.callback())); |
| EXPECT_EQ(OK, rv); |
| SSLConfig ssl_config; |
| @@ -2607,25 +2615,10 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsDisabled) { |
| scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( |
| transport.Pass(), test_server.host_port_pair(), ssl_config)); |
| - |
| - EXPECT_FALSE(sock->IsConnected()); |
| - |
| - rv = sock->Connect(callback.callback()); |
| - |
| - CapturingNetLog::CapturedEntryList entries; |
| - log.GetEntries(&entries); |
| - EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); |
| - if (rv == ERR_IO_PENDING) |
| - rv = callback.WaitForResult(); |
| + rv = callback.GetResult(sock->Connect(callback.callback())); |
| EXPECT_EQ(OK, rv); |
| - EXPECT_TRUE(sock->IsConnected()); |
| - log.GetEntries(&entries); |
| - EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); |
| EXPECT_FALSE(sock->signed_cert_timestamps_received_); |
| - |
| - sock->Disconnect(); |
| - EXPECT_FALSE(sock->IsConnected()); |
| } |
| // Tests that IsConnectedAndIdle and WasEverUsed behave as expected. |