| 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..4e844cd9daa5d4f00c2fe78b1cf881d59ecd93ec 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,45 @@ 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 {
|
| +
|
| +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 +2561,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 +2572,24 @@ 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 and well-formed. It should be the
|
| + // DER encoding of 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.
|
| + 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.
|
|
|