• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_CERT_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
6 #define NET_CERT_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
7 
8 #include <algorithm>
9 
10 #include "net/cert/pki/cert_errors.h"
11 #include "net/cert/pki/cert_issuer_source.h"
12 #include "net/cert/pki/test_helpers.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/boringssl/src/include/openssl/pool.h"
15 
16 namespace net {
17 
18 namespace {
19 
ReadTestPem(const std::string & file_name,const std::string & block_name,std::string * result)20 ::testing::AssertionResult ReadTestPem(const std::string& file_name,
21                                        const std::string& block_name,
22                                        std::string* result) {
23   const PemBlockMapping mappings[] = {
24       {block_name.c_str(), result},
25   };
26 
27   return ReadTestDataFromPemFile(file_name, mappings);
28 }
29 
ReadTestCert(const std::string & file_name,std::shared_ptr<const ParsedCertificate> * result)30 ::testing::AssertionResult ReadTestCert(
31     const std::string& file_name,
32     std::shared_ptr<const ParsedCertificate>* result) {
33   std::string der;
34   ::testing::AssertionResult r =
35       ReadTestPem("net/data/cert_issuer_source_static_unittest/" + file_name,
36                   "CERTIFICATE", &der);
37   if (!r)
38     return r;
39   CertErrors errors;
40   *result = ParsedCertificate::Create(
41       bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
42           reinterpret_cast<const uint8_t*>(der.data()), der.size(), nullptr)),
43       {}, &errors);
44   if (!*result) {
45     return ::testing::AssertionFailure()
46            << "ParsedCertificate::Create() failed:\n"
47            << errors.ToDebugString();
48   }
49   return ::testing::AssertionSuccess();
50 }
51 
52 }  // namespace
53 
54 template <typename TestDelegate>
55 class CertIssuerSourceSyncTest : public ::testing::Test {
56  public:
SetUp()57   void SetUp() override {
58     ASSERT_TRUE(ReadTestCert("root.pem", &root_));
59     ASSERT_TRUE(ReadTestCert("i1_1.pem", &i1_1_));
60     ASSERT_TRUE(ReadTestCert("i1_2.pem", &i1_2_));
61     ASSERT_TRUE(ReadTestCert("i2.pem", &i2_));
62     ASSERT_TRUE(ReadTestCert("i3_1.pem", &i3_1_));
63     ASSERT_TRUE(ReadTestCert("i3_2.pem", &i3_2_));
64     ASSERT_TRUE(ReadTestCert("c1.pem", &c1_));
65     ASSERT_TRUE(ReadTestCert("c2.pem", &c2_));
66     ASSERT_TRUE(ReadTestCert("d.pem", &d_));
67     ASSERT_TRUE(ReadTestCert("e1.pem", &e1_));
68     ASSERT_TRUE(ReadTestCert("e2.pem", &e2_));
69   }
70 
AddCert(std::shared_ptr<const ParsedCertificate> cert)71   void AddCert(std::shared_ptr<const ParsedCertificate> cert) {
72     delegate_.AddCert(std::move(cert));
73   }
74 
AddAllCerts()75   void AddAllCerts() {
76     AddCert(root_);
77     AddCert(i1_1_);
78     AddCert(i1_2_);
79     AddCert(i2_);
80     AddCert(i3_1_);
81     AddCert(i3_2_);
82     AddCert(c1_);
83     AddCert(c2_);
84     AddCert(d_);
85     AddCert(e1_);
86     AddCert(e2_);
87   }
88 
source()89   CertIssuerSource& source() { return delegate_.source(); }
90 
91  protected:
IssuersMatch(std::shared_ptr<const ParsedCertificate> cert,ParsedCertificateList expected_matches)92   bool IssuersMatch(std::shared_ptr<const ParsedCertificate> cert,
93                     ParsedCertificateList expected_matches) {
94     ParsedCertificateList matches;
95     source().SyncGetIssuersOf(cert.get(), &matches);
96 
97     std::vector<der::Input> der_result_matches;
98     for (const auto& it : matches)
99       der_result_matches.push_back(it->der_cert());
100     std::sort(der_result_matches.begin(), der_result_matches.end());
101 
102     std::vector<der::Input> der_expected_matches;
103     for (const auto& it : expected_matches)
104       der_expected_matches.push_back(it->der_cert());
105     std::sort(der_expected_matches.begin(), der_expected_matches.end());
106 
107     if (der_expected_matches == der_result_matches)
108       return true;
109 
110     // Print some extra information for debugging.
111     EXPECT_EQ(der_expected_matches, der_result_matches);
112     return false;
113   }
114 
115   TestDelegate delegate_;
116   std::shared_ptr<const ParsedCertificate> root_;
117   std::shared_ptr<const ParsedCertificate> i1_1_;
118   std::shared_ptr<const ParsedCertificate> i1_2_;
119   std::shared_ptr<const ParsedCertificate> i2_;
120   std::shared_ptr<const ParsedCertificate> i3_1_;
121   std::shared_ptr<const ParsedCertificate> i3_2_;
122   std::shared_ptr<const ParsedCertificate> c1_;
123   std::shared_ptr<const ParsedCertificate> c2_;
124   std::shared_ptr<const ParsedCertificate> d_;
125   std::shared_ptr<const ParsedCertificate> e1_;
126   std::shared_ptr<const ParsedCertificate> e2_;
127 };
128 
129 TYPED_TEST_SUITE_P(CertIssuerSourceSyncTest);
130 
TYPED_TEST_P(CertIssuerSourceSyncTest,NoMatch)131 TYPED_TEST_P(CertIssuerSourceSyncTest, NoMatch) {
132   this->AddCert(this->root_);
133 
134   EXPECT_TRUE(this->IssuersMatch(this->c1_, ParsedCertificateList()));
135 }
136 
TYPED_TEST_P(CertIssuerSourceSyncTest,OneMatch)137 TYPED_TEST_P(CertIssuerSourceSyncTest, OneMatch) {
138   this->AddAllCerts();
139 
140   EXPECT_TRUE(this->IssuersMatch(this->i1_1_, {this->root_}));
141   EXPECT_TRUE(this->IssuersMatch(this->d_, {this->i2_}));
142 }
143 
TYPED_TEST_P(CertIssuerSourceSyncTest,MultipleMatches)144 TYPED_TEST_P(CertIssuerSourceSyncTest, MultipleMatches) {
145   this->AddAllCerts();
146 
147   EXPECT_TRUE(this->IssuersMatch(this->e1_, {this->i3_1_, this->i3_2_}));
148   EXPECT_TRUE(this->IssuersMatch(this->e2_, {this->i3_1_, this->i3_2_}));
149 }
150 
151 // Searching for the issuer of a self-issued cert returns the same cert if it
152 // happens to be in the CertIssuerSourceStatic.
153 // Conceptually this makes sense, though probably not very useful in practice.
154 // Doesn't hurt anything though.
TYPED_TEST_P(CertIssuerSourceSyncTest,SelfIssued)155 TYPED_TEST_P(CertIssuerSourceSyncTest, SelfIssued) {
156   this->AddAllCerts();
157 
158   EXPECT_TRUE(this->IssuersMatch(this->root_, {this->root_}));
159 }
160 
161 // CertIssuerSourceStatic never returns results asynchronously.
TYPED_TEST_P(CertIssuerSourceSyncTest,IsNotAsync)162 TYPED_TEST_P(CertIssuerSourceSyncTest, IsNotAsync) {
163   this->AddCert(this->i1_1_);
164   std::unique_ptr<CertIssuerSource::Request> request;
165   this->source().AsyncGetIssuersOf(this->c1_.get(), &request);
166   EXPECT_EQ(nullptr, request);
167 }
168 
169 // These are all the tests that should have the same result with or without
170 // normalization.
171 REGISTER_TYPED_TEST_SUITE_P(CertIssuerSourceSyncTest,
172                             NoMatch,
173                             OneMatch,
174                             MultipleMatches,
175                             SelfIssued,
176                             IsNotAsync);
177 
178 template <typename TestDelegate>
179 class CertIssuerSourceSyncNormalizationTest
180     : public CertIssuerSourceSyncTest<TestDelegate> {};
181 TYPED_TEST_SUITE_P(CertIssuerSourceSyncNormalizationTest);
182 
TYPED_TEST_P(CertIssuerSourceSyncNormalizationTest,MultipleMatchesAfterNormalization)183 TYPED_TEST_P(CertIssuerSourceSyncNormalizationTest,
184              MultipleMatchesAfterNormalization) {
185   this->AddAllCerts();
186 
187   EXPECT_TRUE(this->IssuersMatch(this->c1_, {this->i1_1_, this->i1_2_}));
188   EXPECT_TRUE(this->IssuersMatch(this->c2_, {this->i1_1_, this->i1_2_}));
189 }
190 
191 // These tests require (utf8) normalization.
192 REGISTER_TYPED_TEST_SUITE_P(CertIssuerSourceSyncNormalizationTest,
193                             MultipleMatchesAfterNormalization);
194 
195 template <typename TestDelegate>
196 class CertIssuerSourceSyncNotNormalizedTest
197     : public CertIssuerSourceSyncTest<TestDelegate> {};
198 TYPED_TEST_SUITE_P(CertIssuerSourceSyncNotNormalizedTest);
199 
TYPED_TEST_P(CertIssuerSourceSyncNotNormalizedTest,OneMatchWithoutNormalization)200 TYPED_TEST_P(CertIssuerSourceSyncNotNormalizedTest,
201              OneMatchWithoutNormalization) {
202   this->AddAllCerts();
203 
204   // Without normalization c1 and c2 should at least be able to find their
205   // exact matching issuer. (c1 should match i1_1, and c2 should match i1_2.)
206   EXPECT_TRUE(this->IssuersMatch(this->c1_, {this->i1_1_}));
207   EXPECT_TRUE(this->IssuersMatch(this->c2_, {this->i1_2_}));
208 }
209 
210 // These tests are for implementations which do not do utf8 normalization.
211 REGISTER_TYPED_TEST_SUITE_P(CertIssuerSourceSyncNotNormalizedTest,
212                             OneMatchWithoutNormalization);
213 
214 }  // namespace net
215 
216 #endif  // NET_CERT_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
217