blob: 4ad7e8d622f6705a203f48cc83d792db3694c99b [file] [log] [blame]
// Copyright 2016 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/cert/caching_cert_verifier.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util.h"
#include "net/log/net_log_with_source.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using net::test::IsError;
using net::test::IsOk;
using testing::_;
using testing::Mock;
using testing::Return;
using testing::ReturnRef;
namespace net {
class CachingCertVerifierTest : public ::testing::Test {
public:
CachingCertVerifierTest() : verifier_(std::make_unique<MockCertVerifier>()) {}
~CachingCertVerifierTest() override = default;
protected:
CachingCertVerifier verifier_;
};
TEST_F(CachingCertVerifierTest, CacheHit) {
base::FilePath certs_dir = GetTestCertsDirectory();
scoped_refptr<X509Certificate> test_cert(
ImportCertFromFile(certs_dir, "ok_cert.pem"));
ASSERT_TRUE(test_cert.get());
int error;
CertVerifyResult verify_result;
TestCompletionCallback callback;
std::unique_ptr<CertVerifier::Request> request;
error = callback.GetResult(verifier_.Verify(
CertVerifier::RequestParams(test_cert, "www.example.com", 0,
std::string()),
&verify_result, callback.callback(), &request, NetLogWithSource()));
ASSERT_TRUE(IsCertificateError(error));
ASSERT_EQ(1u, verifier_.requests());
ASSERT_EQ(0u, verifier_.cache_hits());
ASSERT_EQ(1u, verifier_.GetCacheSize());
error = verifier_.Verify(CertVerifier::RequestParams(
test_cert, "www.example.com", 0, std::string()),
&verify_result, callback.callback(), &request,
NetLogWithSource());
// Synchronous completion.
ASSERT_NE(ERR_IO_PENDING, error);
ASSERT_TRUE(IsCertificateError(error));
ASSERT_FALSE(request);
ASSERT_EQ(2u, verifier_.requests());
ASSERT_EQ(1u, verifier_.cache_hits());
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(CachingCertVerifierTest, DifferentCACerts) {
base::FilePath certs_dir = GetTestCertsDirectory();
scoped_refptr<X509Certificate> server_cert =
ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
ASSERT_TRUE(server_cert);
scoped_refptr<X509Certificate> intermediate_cert1 =
ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem");
ASSERT_TRUE(intermediate_cert1);
scoped_refptr<X509Certificate> intermediate_cert2 =
ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
ASSERT_TRUE(intermediate_cert2);
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
intermediates.push_back(bssl::UpRef(intermediate_cert1->cert_buffer()));
scoped_refptr<X509Certificate> cert_chain1 =
X509Certificate::CreateFromBuffer(bssl::UpRef(server_cert->cert_buffer()),
std::move(intermediates));
ASSERT_TRUE(cert_chain1);
intermediates.clear();
intermediates.push_back(bssl::UpRef(intermediate_cert2->cert_buffer()));
scoped_refptr<X509Certificate> cert_chain2 =
X509Certificate::CreateFromBuffer(bssl::UpRef(server_cert->cert_buffer()),
std::move(intermediates));
ASSERT_TRUE(cert_chain2);
int error;
CertVerifyResult verify_result;
TestCompletionCallback callback;
std::unique_ptr<CertVerifier::Request> request;
error = callback.GetResult(verifier_.Verify(
CertVerifier::RequestParams(cert_chain1, "www.example.com", 0,
std::string()),
&verify_result, callback.callback(), &request, NetLogWithSource()));
ASSERT_TRUE(IsCertificateError(error));
ASSERT_EQ(1u, verifier_.requests());
ASSERT_EQ(0u, verifier_.cache_hits());
ASSERT_EQ(1u, verifier_.GetCacheSize());
error = callback.GetResult(verifier_.Verify(
CertVerifier::RequestParams(cert_chain2, "www.example.com", 0,
std::string()),
&verify_result, callback.callback(), &request, NetLogWithSource()));
ASSERT_TRUE(IsCertificateError(error));
ASSERT_EQ(2u, verifier_.requests());
ASSERT_EQ(0u, verifier_.cache_hits());
ASSERT_EQ(2u, verifier_.GetCacheSize());
}
} // namespace net