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