15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/multi_threaded_cert_verifier.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h"
105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_data_directory.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_trust_anchor_provider.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_proc.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_result.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/test/cert_test_util.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Mock;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::ReturnRef;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FailTest(int /* result */) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FAIL();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockCertVerifyProc : public CertVerifyProc {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCertVerifyProc() {}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MockCertVerifyProc() {}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CertVerifyProc implementation
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int VerifyInternal(X509Certificate* cert,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& hostname,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int flags,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CRLSet* crl_set,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const CertificateList& additional_trust_anchors,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CertVerifyResult* verify_result) OVERRIDE {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    verify_result->Reset();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    verify_result->verified_cert = cert;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_CERT_COMMON_NAME_INVALID;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockCertTrustAnchorProvider : public CertTrustAnchorProvider {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockCertTrustAnchorProvider() {}
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MockCertTrustAnchorProvider() {}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(GetAdditionalTrustAnchors, const CertificateList&());
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultiThreadedCertVerifierTest : public ::testing::Test {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MultiThreadedCertVerifierTest() {}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiThreadedCertVerifier verifier_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(MultiThreadedCertVerifierTest, CacheHit) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> test_cert(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifyResult verify_result;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifier::RequestHandle request_handle;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, error);
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_handle);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = callback.WaitForResult();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsCertificateError(error));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, verifier_.requests());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, verifier_.cache_hits());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, verifier_.inflight_joins());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, verifier_.GetCacheSize());
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Synchronous completion.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(ERR_IO_PENDING, error);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsCertificateError(error));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(request_handle == NULL);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, verifier_.requests());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, verifier_.cache_hits());
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, verifier_.inflight_joins());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, verifier_.GetCacheSize());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the same server certificate with different intermediate CA
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// certificates.  These should be treated as different certificate chains even
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// though the two X509Certificate objects contain the same server certificate.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(MultiThreadedCertVerifierTest, DifferentCACerts) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> server_cert =
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> intermediate_cert1 =
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem");
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1.get());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> intermediate_cert2 =
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert2.get());
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  X509Certificate::OSCertHandles intermediates;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  intermediates.push_back(intermediate_cert1->os_cert_handle());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> cert_chain1 =
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        intermediates);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  intermediates.clear();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  intermediates.push_back(intermediate_cert2->os_cert_handle());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> cert_chain2 =
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        intermediates);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifyResult verify_result;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifier::RequestHandle request_handle;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(cert_chain1.get(),
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, error);
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_handle);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = callback.WaitForResult();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsCertificateError(error));
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, verifier_.requests());
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, verifier_.cache_hits());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, verifier_.inflight_joins());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, verifier_.GetCacheSize());
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(cert_chain2.get(),
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, error);
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_handle);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = callback.WaitForResult();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsCertificateError(error));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, verifier_.requests());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, verifier_.cache_hits());
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, verifier_.inflight_joins());
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, verifier_.GetCacheSize());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests an inflight join.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(MultiThreadedCertVerifierTest, InflightJoin) {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> test_cert(
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifyResult verify_result;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifier::RequestHandle request_handle;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifyResult verify_result2;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifier::RequestHandle request_handle2;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, error);
218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_handle);
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result2,
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback2.callback(),
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle2,
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, error);
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_handle2 != NULL);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = callback.WaitForResult();
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(IsCertificateError(error));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = callback2.WaitForResult();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsCertificateError(error));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, verifier_.requests());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, verifier_.cache_hits());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, verifier_.inflight_joins());
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the callback of a canceled request is never made.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(MultiThreadedCertVerifierTest, CancelRequest) {
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> test_cert(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifyResult verify_result;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifier::RequestHandle request_handle;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           base::Bind(&FailTest),
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, error);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(request_handle != NULL);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  verifier_.CancelRequest(request_handle);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue a few more requests to the worker pool and wait for their
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // completion, so that the task of the canceled request (which runs on a
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // worker thread) is likely to complete by the end of this test.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 5; ++i) {
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    error = verifier_.Verify(test_cert.get(),
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             "www2.example.com",
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             0,
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             NULL,
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             &verify_result,
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             callback.callback(),
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             &request_handle,
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             BoundNetLog());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(ERR_IO_PENDING, error);
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_handle);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error = callback.WaitForResult();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    verifier_.ClearCache();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that a canceled request is not leaked.
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if !defined(LEAK_SANITIZER)
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define MAYBE_CancelRequestThenQuit CancelRequestThenQuit
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// See PR303886. LeakSanitizer flags a leak here.
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define MAYBE_CancelRequestThenQuit DISABLED_CancelRequestThenQuit
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(MultiThreadedCertVerifierTest, MAYBE_CancelRequestThenQuit) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> test_cert(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifyResult verify_result;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifier::RequestHandle request_handle;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, error);
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_handle);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  verifier_.CancelRequest(request_handle);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy |verifier| by going out of scope.
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(MultiThreadedCertVerifierTest, RequestParamsComparators) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SHA1HashValue a_key;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a_key.data, 'a', sizeof(a_key.data));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SHA1HashValue z_key;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(z_key.data, 'z', sizeof(z_key.data));
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const CertificateList empty_list;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CertificateList test_list;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test_list.push_back(
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Keys to test
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MultiThreadedCertVerifier::RequestParams key1;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MultiThreadedCertVerifier::RequestParams key2;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Expectation:
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // -1 means key1 is less than key2
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //  0 means key1 equals key2
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //  1 means key1 is greater than key2
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_result;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  // Test for basic equivalence.
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, test_list),
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, test_list),
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  // Test that different certificates but with the same CA and for
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       // the same host are different validation keys.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, test_list),
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(z_key, a_key, "www.example.test",
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, test_list),
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  // Test that the same EE certificate for the same host, but with
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       // different chains are different validation keys.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, z_key, "www.example.test",
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, test_list),
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, test_list),
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  // The same certificate, with the same chain, but for different
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       // hosts are different validation keys.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key,
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               "www1.example.test", 0,
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               test_list),
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               "www2.example.test", 0,
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               test_list),
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  // The same certificate, chain, and host, but with different flags
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       // are different validation keys.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               CertVerifier::VERIFY_EV_CERT,
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               test_list),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, test_list),
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    },
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {  // Different additional_trust_anchors.
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, empty_list),
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test",
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               0, test_list),
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      -1,
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    },
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]", i));
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MultiThreadedCertVerifier::RequestParams& key1 = tests[i].key1;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MultiThreadedCertVerifier::RequestParams& key2 = tests[i].key2;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (tests[i].expected_result) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case -1:
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(key1 < key2);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(key2 < key1);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 0:
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(key1 < key2);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(key2 < key1);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 1:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(key1 < key2);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(key2 < key1);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FAIL() << "Invalid expectation. Can be only -1, 0, 1";
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(MultiThreadedCertVerifierTest, CertTrustAnchorProvider) {
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockCertTrustAnchorProvider trust_provider;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  verifier_.SetCertTrustAnchorProvider(&trust_provider);
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<X509Certificate> test_cert(
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(test_cert.get());
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const CertificateList empty_cert_list;
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CertificateList cert_list;
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cert_list.push_back(test_cert);
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that Verify() asks the |trust_provider| for the current list of
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // additional trust anchors.
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int error;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CertVerifyResult verify_result;
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CertVerifier::RequestHandle request_handle;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(ReturnRef(empty_cert_list));
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&trust_provider);
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, error);
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_handle);
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  error = callback.WaitForResult();
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, verifier_.requests());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(0u, verifier_.cache_hits());
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The next Verify() uses the cached result.
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(ReturnRef(empty_cert_list));
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&trust_provider);
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(request_handle);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2u, verifier_.requests());
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, verifier_.cache_hits());
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Another Verify() for the same certificate but with a different list of
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // trust anchors will not reuse the cache.
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(ReturnRef(cert_list));
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  error = verifier_.Verify(test_cert.get(),
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           "www.example.com",
470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           0,
471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           NULL,
472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &verify_result,
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           callback.callback(),
474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &request_handle,
475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           BoundNetLog());
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&trust_provider);
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, error);
478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_handle);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  error = callback.WaitForResult();
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3u, verifier_.requests());
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, verifier_.cache_hits());
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
486