| Index: net/base/multi_threaded_cert_verifier_unittest.cc
|
| diff --git a/net/base/multi_threaded_cert_verifier_unittest.cc b/net/base/multi_threaded_cert_verifier_unittest.cc
|
| deleted file mode 100644
|
| index 8dea5967ec1a731e0b82b27007dc24d302a61c68..0000000000000000000000000000000000000000
|
| --- a/net/base/multi_threaded_cert_verifier_unittest.cc
|
| +++ /dev/null
|
| @@ -1,419 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/base/multi_threaded_cert_verifier.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/files/file_path.h"
|
| -#include "base/format_macros.h"
|
| -#include "base/stringprintf.h"
|
| -#include "net/base/cert_test_util.h"
|
| -#include "net/base/cert_trust_anchor_provider.h"
|
| -#include "net/base/cert_verify_proc.h"
|
| -#include "net/base/cert_verify_result.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/net_log.h"
|
| -#include "net/base/test_completion_callback.h"
|
| -#include "net/base/test_data_directory.h"
|
| -#include "net/base/x509_certificate.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using testing::Mock;
|
| -using testing::ReturnRef;
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -void FailTest(int /* result */) {
|
| - FAIL();
|
| -}
|
| -
|
| -class MockCertVerifyProc : public CertVerifyProc {
|
| - public:
|
| - MockCertVerifyProc() {}
|
| -
|
| - private:
|
| - virtual ~MockCertVerifyProc() {}
|
| -
|
| - // CertVerifyProc implementation
|
| - virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE {
|
| - return false;
|
| - }
|
| -
|
| - virtual int VerifyInternal(X509Certificate* cert,
|
| - const std::string& hostname,
|
| - int flags,
|
| - CRLSet* crl_set,
|
| - const CertificateList& additional_trust_anchors,
|
| - CertVerifyResult* verify_result) OVERRIDE {
|
| - verify_result->Reset();
|
| - verify_result->verified_cert = cert;
|
| - verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID;
|
| - return ERR_CERT_COMMON_NAME_INVALID;
|
| - }
|
| -};
|
| -
|
| -class MockCertTrustAnchorProvider : public CertTrustAnchorProvider {
|
| - public:
|
| - MockCertTrustAnchorProvider() {}
|
| - virtual ~MockCertTrustAnchorProvider() {}
|
| -
|
| - MOCK_METHOD0(GetAdditionalTrustAnchors, const CertificateList&());
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -class MultiThreadedCertVerifierTest : public ::testing::Test {
|
| - public:
|
| - MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {}
|
| - virtual ~MultiThreadedCertVerifierTest() {}
|
| -
|
| - protected:
|
| - MultiThreadedCertVerifier verifier_;
|
| -};
|
| -
|
| -TEST_F(MultiThreadedCertVerifierTest, CacheHit) {
|
| - base::FilePath certs_dir = GetTestCertsDirectory();
|
| - scoped_refptr<X509Certificate> test_cert(
|
| - ImportCertFromFile(certs_dir, "ok_cert.pem"));
|
| - ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
|
| -
|
| - int error;
|
| - CertVerifyResult verify_result;
|
| - TestCompletionCallback callback;
|
| - CertVerifier::RequestHandle request_handle;
|
| -
|
| - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle != NULL);
|
| - error = callback.WaitForResult();
|
| - ASSERT_TRUE(IsCertificateError(error));
|
| - ASSERT_EQ(1u, verifier_.requests());
|
| - ASSERT_EQ(0u, verifier_.cache_hits());
|
| - ASSERT_EQ(0u, verifier_.inflight_joins());
|
| - ASSERT_EQ(1u, verifier_.GetCacheSize());
|
| -
|
| - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - // Synchronous completion.
|
| - ASSERT_NE(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(IsCertificateError(error));
|
| - ASSERT_TRUE(request_handle == NULL);
|
| - ASSERT_EQ(2u, verifier_.requests());
|
| - ASSERT_EQ(1u, verifier_.cache_hits());
|
| - ASSERT_EQ(0u, verifier_.inflight_joins());
|
| - ASSERT_EQ(1u, verifier_.GetCacheSize());
|
| -}
|
| -
|
| -// Tests the same server certificate with different intermediate CA
|
| -// certificates. These should be treated as different certificate chains even
|
| -// though the two X509Certificate objects contain the same server certificate.
|
| -TEST_F(MultiThreadedCertVerifierTest, DifferentCACerts) {
|
| - base::FilePath certs_dir = GetTestCertsDirectory();
|
| -
|
| - scoped_refptr<X509Certificate> server_cert =
|
| - ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
|
| - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
|
| -
|
| - scoped_refptr<X509Certificate> intermediate_cert1 =
|
| - ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem");
|
| - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1);
|
| -
|
| - scoped_refptr<X509Certificate> intermediate_cert2 =
|
| - ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
|
| - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert2);
|
| -
|
| - X509Certificate::OSCertHandles intermediates;
|
| - intermediates.push_back(intermediate_cert1->os_cert_handle());
|
| - scoped_refptr<X509Certificate> cert_chain1 =
|
| - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
|
| - intermediates);
|
| -
|
| - intermediates.clear();
|
| - intermediates.push_back(intermediate_cert2->os_cert_handle());
|
| - scoped_refptr<X509Certificate> cert_chain2 =
|
| - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
|
| - intermediates);
|
| -
|
| - int error;
|
| - CertVerifyResult verify_result;
|
| - TestCompletionCallback callback;
|
| - CertVerifier::RequestHandle request_handle;
|
| -
|
| - error = verifier_.Verify(cert_chain1, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle != NULL);
|
| - error = callback.WaitForResult();
|
| - ASSERT_TRUE(IsCertificateError(error));
|
| - ASSERT_EQ(1u, verifier_.requests());
|
| - ASSERT_EQ(0u, verifier_.cache_hits());
|
| - ASSERT_EQ(0u, verifier_.inflight_joins());
|
| - ASSERT_EQ(1u, verifier_.GetCacheSize());
|
| -
|
| - error = verifier_.Verify(cert_chain2, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle != NULL);
|
| - error = callback.WaitForResult();
|
| - ASSERT_TRUE(IsCertificateError(error));
|
| - ASSERT_EQ(2u, verifier_.requests());
|
| - ASSERT_EQ(0u, verifier_.cache_hits());
|
| - ASSERT_EQ(0u, verifier_.inflight_joins());
|
| - ASSERT_EQ(2u, verifier_.GetCacheSize());
|
| -}
|
| -
|
| -// Tests an inflight join.
|
| -TEST_F(MultiThreadedCertVerifierTest, InflightJoin) {
|
| - base::FilePath certs_dir = GetTestCertsDirectory();
|
| - scoped_refptr<X509Certificate> test_cert(
|
| - ImportCertFromFile(certs_dir, "ok_cert.pem"));
|
| - ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
|
| -
|
| - int error;
|
| - CertVerifyResult verify_result;
|
| - TestCompletionCallback callback;
|
| - CertVerifier::RequestHandle request_handle;
|
| - CertVerifyResult verify_result2;
|
| - TestCompletionCallback callback2;
|
| - CertVerifier::RequestHandle request_handle2;
|
| -
|
| - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle != NULL);
|
| - error = verifier_.Verify(
|
| - test_cert, "www.example.com", 0, NULL, &verify_result2,
|
| - callback2.callback(), &request_handle2, BoundNetLog());
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle2 != NULL);
|
| - error = callback.WaitForResult();
|
| - ASSERT_TRUE(IsCertificateError(error));
|
| - error = callback2.WaitForResult();
|
| - ASSERT_TRUE(IsCertificateError(error));
|
| - ASSERT_EQ(2u, verifier_.requests());
|
| - ASSERT_EQ(0u, verifier_.cache_hits());
|
| - ASSERT_EQ(1u, verifier_.inflight_joins());
|
| -}
|
| -
|
| -// Tests that the callback of a canceled request is never made.
|
| -TEST_F(MultiThreadedCertVerifierTest, CancelRequest) {
|
| - base::FilePath certs_dir = GetTestCertsDirectory();
|
| - scoped_refptr<X509Certificate> test_cert(
|
| - ImportCertFromFile(certs_dir, "ok_cert.pem"));
|
| - ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
|
| -
|
| - int error;
|
| - CertVerifyResult verify_result;
|
| - CertVerifier::RequestHandle request_handle;
|
| -
|
| - error = verifier_.Verify(
|
| - test_cert, "www.example.com", 0, NULL, &verify_result,
|
| - base::Bind(&FailTest), &request_handle, BoundNetLog());
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle != NULL);
|
| - verifier_.CancelRequest(request_handle);
|
| -
|
| - // Issue a few more requests to the worker pool and wait for their
|
| - // completion, so that the task of the canceled request (which runs on a
|
| - // worker thread) is likely to complete by the end of this test.
|
| - TestCompletionCallback callback;
|
| - for (int i = 0; i < 5; ++i) {
|
| - error = verifier_.Verify(
|
| - test_cert, "www2.example.com", 0, NULL, &verify_result,
|
| - callback.callback(), &request_handle, BoundNetLog());
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle != NULL);
|
| - error = callback.WaitForResult();
|
| - verifier_.ClearCache();
|
| - }
|
| -}
|
| -
|
| -// Tests that a canceled request is not leaked.
|
| -TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) {
|
| - base::FilePath certs_dir = GetTestCertsDirectory();
|
| - scoped_refptr<X509Certificate> test_cert(
|
| - ImportCertFromFile(certs_dir, "ok_cert.pem"));
|
| - ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
|
| -
|
| - int error;
|
| - CertVerifyResult verify_result;
|
| - TestCompletionCallback callback;
|
| - CertVerifier::RequestHandle request_handle;
|
| -
|
| - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle != NULL);
|
| - verifier_.CancelRequest(request_handle);
|
| - // Destroy |verifier| by going out of scope.
|
| -}
|
| -
|
| -TEST_F(MultiThreadedCertVerifierTest, RequestParamsComparators) {
|
| - SHA1HashValue a_key;
|
| - memset(a_key.data, 'a', sizeof(a_key.data));
|
| -
|
| - SHA1HashValue z_key;
|
| - memset(z_key.data, 'z', sizeof(z_key.data));
|
| -
|
| - const CertificateList empty_list;
|
| - CertificateList test_list;
|
| - test_list.push_back(
|
| - ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
|
| -
|
| - struct {
|
| - // Keys to test
|
| - MultiThreadedCertVerifier::RequestParams key1;
|
| - MultiThreadedCertVerifier::RequestParams key2;
|
| -
|
| - // Expectation:
|
| - // -1 means key1 is less than key2
|
| - // 0 means key1 equals key2
|
| - // 1 means key1 is greater than key2
|
| - int expected_result;
|
| - } tests[] = {
|
| - { // Test for basic equivalence.
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
|
| - 0, test_list),
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
|
| - 0, test_list),
|
| - 0,
|
| - },
|
| - { // Test that different certificates but with the same CA and for
|
| - // the same host are different validation keys.
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
|
| - 0, test_list),
|
| - MultiThreadedCertVerifier::RequestParams(z_key, a_key, "www.example.test",
|
| - 0, test_list),
|
| - -1,
|
| - },
|
| - { // Test that the same EE certificate for the same host, but with
|
| - // different chains are different validation keys.
|
| - MultiThreadedCertVerifier::RequestParams(a_key, z_key, "www.example.test",
|
| - 0, test_list),
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
|
| - 0, test_list),
|
| - 1,
|
| - },
|
| - { // The same certificate, with the same chain, but for different
|
| - // hosts are different validation keys.
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key,
|
| - "www1.example.test", 0,
|
| - test_list),
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key,
|
| - "www2.example.test", 0,
|
| - test_list),
|
| - -1,
|
| - },
|
| - { // The same certificate, chain, and host, but with different flags
|
| - // are different validation keys.
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
|
| - CertVerifier::VERIFY_EV_CERT,
|
| - test_list),
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
|
| - 0, test_list),
|
| - 1,
|
| - },
|
| - { // Different additional_trust_anchors.
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
|
| - 0, empty_list),
|
| - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
|
| - 0, test_list),
|
| - -1,
|
| - },
|
| - };
|
| - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
|
| - SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]", i));
|
| -
|
| - const MultiThreadedCertVerifier::RequestParams& key1 = tests[i].key1;
|
| - const MultiThreadedCertVerifier::RequestParams& key2 = tests[i].key2;
|
| -
|
| - switch (tests[i].expected_result) {
|
| - case -1:
|
| - EXPECT_TRUE(key1 < key2);
|
| - EXPECT_FALSE(key2 < key1);
|
| - break;
|
| - case 0:
|
| - EXPECT_FALSE(key1 < key2);
|
| - EXPECT_FALSE(key2 < key1);
|
| - break;
|
| - case 1:
|
| - EXPECT_FALSE(key1 < key2);
|
| - EXPECT_TRUE(key2 < key1);
|
| - break;
|
| - default:
|
| - FAIL() << "Invalid expectation. Can be only -1, 0, 1";
|
| - }
|
| - }
|
| -}
|
| -
|
| -TEST_F(MultiThreadedCertVerifierTest, CertTrustAnchorProvider) {
|
| - MockCertTrustAnchorProvider trust_provider;
|
| - verifier_.SetCertTrustAnchorProvider(&trust_provider);
|
| -
|
| - scoped_refptr<X509Certificate> test_cert(
|
| - ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
|
| - ASSERT_TRUE(test_cert);
|
| -
|
| - const CertificateList empty_cert_list;
|
| - CertificateList cert_list;
|
| - cert_list.push_back(test_cert);
|
| -
|
| - // Check that Verify() asks the |trust_provider| for the current list of
|
| - // additional trust anchors.
|
| - int error;
|
| - CertVerifyResult verify_result;
|
| - TestCompletionCallback callback;
|
| - CertVerifier::RequestHandle request_handle;
|
| - EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
|
| - .WillOnce(ReturnRef(empty_cert_list));
|
| - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - Mock::VerifyAndClearExpectations(&trust_provider);
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle);
|
| - error = callback.WaitForResult();
|
| - EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
|
| - ASSERT_EQ(1u, verifier_.requests());
|
| - ASSERT_EQ(0u, verifier_.cache_hits());
|
| -
|
| - // The next Verify() uses the cached result.
|
| - EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
|
| - .WillOnce(ReturnRef(empty_cert_list));
|
| - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - Mock::VerifyAndClearExpectations(&trust_provider);
|
| - EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
|
| - EXPECT_FALSE(request_handle);
|
| - ASSERT_EQ(2u, verifier_.requests());
|
| - ASSERT_EQ(1u, verifier_.cache_hits());
|
| -
|
| - // Another Verify() for the same certificate but with a different list of
|
| - // trust anchors will not reuse the cache.
|
| - EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
|
| - .WillOnce(ReturnRef(cert_list));
|
| - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL,
|
| - &verify_result, callback.callback(),
|
| - &request_handle, BoundNetLog());
|
| - Mock::VerifyAndClearExpectations(&trust_provider);
|
| - ASSERT_EQ(ERR_IO_PENDING, error);
|
| - ASSERT_TRUE(request_handle != NULL);
|
| - error = callback.WaitForResult();
|
| - EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
|
| - ASSERT_EQ(3u, verifier_.requests());
|
| - ASSERT_EQ(1u, verifier_.cache_hits());
|
| -}
|
| -
|
| -} // namespace net
|
|
|