xref: /aosp_15_r20/external/cronet/net/cert/test_root_certs_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 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 #include "net/cert/test_root_certs.h"
6 
7 #include "base/files/file_path.h"
8 #include "build/build_config.h"
9 #include "net/base/features.h"
10 #include "net/base/net_errors.h"
11 #include "net/cert/cert_net_fetcher.h"
12 #include "net/cert/cert_status_flags.h"
13 #include "net/cert/cert_verify_proc.h"
14 #include "net/cert/cert_verify_result.h"
15 #include "net/cert/crl_set.h"
16 #include "net/cert/do_nothing_ct_verifier.h"
17 #include "net/cert/x509_certificate.h"
18 #include "net/log/net_log_with_source.h"
19 #include "net/net_buildflags.h"
20 #include "net/test/cert_builder.h"
21 #include "net/test/cert_test_util.h"
22 #include "net/test/gtest_util.h"
23 #include "net/test/test_data_directory.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 
27 using net::test::IsOk;
28 
29 namespace net {
30 
31 namespace {
32 
33 // The local test root certificate.
34 const char kRootCertificateFile[] = "root_ca_cert.pem";
35 // A certificate issued by the local test root for 127.0.0.1.
36 const char kGoodCertificateFile[] = "ok_cert.pem";
37 
38 }  // namespace
39 
40 class TestRootCertsTest : public testing::TestWithParam<bool> {
41  public:
CreateCertVerifyProc()42   scoped_refptr<CertVerifyProc> CreateCertVerifyProc() {
43 #if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL)
44     // If CCV/CRS is optional, test with and without CCV/CRS.
45     if (use_chrome_cert_validator()) {
46       return CertVerifyProc::CreateBuiltinWithChromeRootStore(
47           /*cert_net_fetcher=*/nullptr, CRLSet::BuiltinCRLSet().get(),
48           std::make_unique<DoNothingCTVerifier>(),
49           base::MakeRefCounted<DefaultCTPolicyEnforcer>(),
50           /*root_store_data=*/nullptr, /*instance_params=*/{});
51     } else {
52       return CertVerifyProc::CreateSystemVerifyProc(
53           /*cert_net_fetcher=*/nullptr, CRLSet::BuiltinCRLSet().get());
54     }
55 #elif BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
56     return CertVerifyProc::CreateBuiltinWithChromeRootStore(
57         /*cert_net_fetcher=*/nullptr, CRLSet::BuiltinCRLSet().get(),
58         std::make_unique<DoNothingCTVerifier>(),
59         base::MakeRefCounted<DefaultCTPolicyEnforcer>(),
60         /*root_store_data=*/nullptr, /*instance_params=*/{});
61 #elif BUILDFLAG(IS_FUCHSIA)
62   return CertVerifyProc::CreateBuiltinVerifyProc(
63       /*cert_net_fetcher=*/nullptr, CRLSet::BuiltinCRLSet().get(),
64       std::make_unique<DoNothingCTVerifier>(),
65       base::MakeRefCounted<DefaultCTPolicyEnforcer>(),
66       /*instance_params=*/{});
67 #else
68   return CertVerifyProc::CreateSystemVerifyProc(/*cert_net_fetcher=*/nullptr,
69                                                 CRLSet::BuiltinCRLSet().get());
70 #endif
71   }
72 
73   // Whether we use Chrome Cert Validator or not. Only relevant for platforms
74   // where CHROME_ROOT_STORE_OPTIONAL is set; on other platforms both test
75   // params will run the same test.
use_chrome_cert_validator()76   bool use_chrome_cert_validator() { return GetParam(); }
77 };
78 
79 // Test basic functionality when adding from an existing X509Certificate.
TEST_P(TestRootCertsTest,AddFromPointer)80 TEST_P(TestRootCertsTest, AddFromPointer) {
81   scoped_refptr<X509Certificate> root_cert =
82       ImportCertFromFile(GetTestCertsDirectory(), kRootCertificateFile);
83   ASSERT_NE(static_cast<X509Certificate*>(nullptr), root_cert.get());
84 
85   TestRootCerts* test_roots = TestRootCerts::GetInstance();
86   ASSERT_NE(static_cast<TestRootCerts*>(nullptr), test_roots);
87   EXPECT_TRUE(test_roots->IsEmpty());
88 
89   {
90     ScopedTestRoot scoped_root(root_cert);
91     EXPECT_FALSE(test_roots->IsEmpty());
92   }
93   EXPECT_TRUE(test_roots->IsEmpty());
94 }
95 
96 // Test that TestRootCerts actually adds the appropriate trust status flags
97 // when requested, and that the trusted status is cleared once the root is
98 // removed the TestRootCerts. This test acts as a canary/sanity check for
99 // the results of the rest of net_unittests, ensuring that the trust status
100 // is properly being set and cleared.
TEST_P(TestRootCertsTest,OverrideTrust)101 TEST_P(TestRootCertsTest, OverrideTrust) {
102   TestRootCerts* test_roots = TestRootCerts::GetInstance();
103   ASSERT_NE(static_cast<TestRootCerts*>(nullptr), test_roots);
104   EXPECT_TRUE(test_roots->IsEmpty());
105 
106   scoped_refptr<X509Certificate> test_cert =
107       ImportCertFromFile(GetTestCertsDirectory(), kGoodCertificateFile);
108   ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get());
109 
110   // Test that the good certificate fails verification, because the root
111   // certificate should not yet be trusted.
112   int flags = 0;
113   CertVerifyResult bad_verify_result;
114   scoped_refptr<CertVerifyProc> verify_proc(CreateCertVerifyProc());
115   int bad_status = verify_proc->Verify(test_cert.get(), "127.0.0.1",
116                                        /*ocsp_response=*/std::string(),
117                                        /*sct_list=*/std::string(), flags,
118                                        &bad_verify_result, NetLogWithSource());
119   EXPECT_NE(OK, bad_status);
120   EXPECT_NE(0u, bad_verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
121   EXPECT_FALSE(bad_verify_result.is_issued_by_known_root);
122 
123   // Add the root certificate and mark it as trusted.
124   scoped_refptr<X509Certificate> root_cert =
125       ImportCertFromFile(GetTestCertsDirectory(), kRootCertificateFile);
126   ASSERT_TRUE(root_cert);
127   ScopedTestRoot scoped_root(root_cert);
128   EXPECT_FALSE(test_roots->IsEmpty());
129 
130   // Test that the certificate verification now succeeds, because the
131   // TestRootCerts is successfully imbuing trust.
132   CertVerifyResult good_verify_result;
133   int good_status = verify_proc->Verify(
134       test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
135       /*sct_list=*/std::string(), flags, &good_verify_result,
136       NetLogWithSource());
137   EXPECT_THAT(good_status, IsOk());
138   EXPECT_EQ(0u, good_verify_result.cert_status);
139   EXPECT_FALSE(good_verify_result.is_issued_by_known_root);
140 
141   test_roots->Clear();
142   EXPECT_TRUE(test_roots->IsEmpty());
143 
144   // Ensure that when the TestRootCerts is cleared, the trust settings
145   // revert to their original state, and don't linger. If trust status
146   // lingers, it will likely break other tests in net_unittests.
147   CertVerifyResult restored_verify_result;
148   int restored_status = verify_proc->Verify(
149       test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
150       /*sct_list=*/std::string(), flags, &restored_verify_result,
151       NetLogWithSource());
152   EXPECT_NE(OK, restored_status);
153   EXPECT_NE(0u,
154             restored_verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
155   EXPECT_EQ(bad_status, restored_status);
156   EXPECT_EQ(bad_verify_result.cert_status, restored_verify_result.cert_status);
157   EXPECT_FALSE(restored_verify_result.is_issued_by_known_root);
158 }
159 
TEST_P(TestRootCertsTest,OverrideKnownRoot)160 TEST_P(TestRootCertsTest, OverrideKnownRoot) {
161   TestRootCerts* test_roots = TestRootCerts::GetInstance();
162   ASSERT_NE(static_cast<TestRootCerts*>(nullptr), test_roots);
163   EXPECT_TRUE(test_roots->IsEmpty());
164 
165   // Use a runtime generated certificate chain so that the cert lifetime is not
166   // too long, and so that it will have an allowable hostname for a publicly
167   // trusted cert.
168   auto [leaf, root] = net::CertBuilder::CreateSimpleChain2();
169 
170   // Add the root certificate and mark it as trusted and as a known root.
171   ScopedTestRoot scoped_root(root->GetX509Certificate());
172   ScopedTestKnownRoot scoped_known_root(root->GetX509Certificate().get());
173   EXPECT_FALSE(test_roots->IsEmpty());
174 
175   // Test that the certificate verification sets the `is_issued_by_known_root`
176   // flag.
177   CertVerifyResult good_verify_result;
178   scoped_refptr<CertVerifyProc> verify_proc(CreateCertVerifyProc());
179   int flags = 0;
180   int good_status =
181       verify_proc->Verify(leaf->GetX509Certificate().get(), "www.example.com",
182                           /*ocsp_response=*/std::string(),
183                           /*sct_list=*/std::string(), flags,
184                           &good_verify_result, NetLogWithSource());
185   EXPECT_THAT(good_status, IsOk());
186   EXPECT_EQ(0u, good_verify_result.cert_status);
187   EXPECT_TRUE(good_verify_result.is_issued_by_known_root);
188 
189   test_roots->Clear();
190   EXPECT_TRUE(test_roots->IsEmpty());
191 
192   // Ensure that when the TestRootCerts is cleared, the test known root status
193   // revert to their original state, and don't linger. If known root status
194   // lingers, it will likely break other tests in net_unittests.
195   // Trust the root again so that the `is_issued_by_known_root` value will be
196   // calculated, and ensure that it is false now.
197   ScopedTestRoot scoped_root2(root->GetX509Certificate());
198   CertVerifyResult restored_verify_result;
199   int restored_status =
200       verify_proc->Verify(leaf->GetX509Certificate().get(), "www.example.com",
201                           /*ocsp_response=*/std::string(),
202                           /*sct_list=*/std::string(), flags,
203                           &restored_verify_result, NetLogWithSource());
204   EXPECT_THAT(restored_status, IsOk());
205   EXPECT_EQ(0u, restored_verify_result.cert_status);
206   EXPECT_FALSE(restored_verify_result.is_issued_by_known_root);
207 }
208 
TEST_P(TestRootCertsTest,Moveable)209 TEST_P(TestRootCertsTest, Moveable) {
210   TestRootCerts* test_roots = TestRootCerts::GetInstance();
211   ASSERT_NE(static_cast<TestRootCerts*>(nullptr), test_roots);
212   EXPECT_TRUE(test_roots->IsEmpty());
213 
214   scoped_refptr<X509Certificate> test_cert =
215       ImportCertFromFile(GetTestCertsDirectory(), kGoodCertificateFile);
216   ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get());
217 
218   int flags = 0;
219   CertVerifyResult bad_verify_result;
220   int bad_status;
221   scoped_refptr<CertVerifyProc> verify_proc(CreateCertVerifyProc());
222   {
223     // Empty ScopedTestRoot at outer scope has no effect.
224     ScopedTestRoot scoped_root_outer;
225     EXPECT_TRUE(test_roots->IsEmpty());
226 
227     // Test that the good certificate fails verification, because the root
228     // certificate should not yet be trusted.
229     bad_status = verify_proc->Verify(test_cert.get(), "127.0.0.1",
230                                      /*ocsp_response=*/std::string(),
231                                      /*sct_list=*/std::string(), flags,
232                                      &bad_verify_result, NetLogWithSource());
233     EXPECT_NE(OK, bad_status);
234     EXPECT_NE(0u,
235               bad_verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
236 
237     {
238       // Add the root certificate and mark it as trusted.
239       scoped_refptr<X509Certificate> root_cert =
240           ImportCertFromFile(GetTestCertsDirectory(), kRootCertificateFile);
241       ASSERT_TRUE(root_cert);
242       ScopedTestRoot scoped_root_inner(root_cert);
243       EXPECT_FALSE(test_roots->IsEmpty());
244 
245       // Test that the certificate verification now succeeds, because the
246       // TestRootCerts is successfully imbuing trust.
247       CertVerifyResult good_verify_result;
248       int good_status = verify_proc->Verify(
249           test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
250           /*sct_list=*/std::string(), flags, &good_verify_result,
251           NetLogWithSource());
252       EXPECT_THAT(good_status, IsOk());
253       EXPECT_EQ(0u, good_verify_result.cert_status);
254 
255       EXPECT_FALSE(scoped_root_inner.IsEmpty());
256       EXPECT_TRUE(scoped_root_outer.IsEmpty());
257       // Move from inner scoped root to outer
258       scoped_root_outer = std::move(scoped_root_inner);
259       EXPECT_FALSE(test_roots->IsEmpty());
260       EXPECT_FALSE(scoped_root_outer.IsEmpty());
261     }
262     // After inner scoper was freed, test root is still trusted since ownership
263     // was moved to the outer scoper.
264     EXPECT_FALSE(test_roots->IsEmpty());
265     EXPECT_FALSE(scoped_root_outer.IsEmpty());
266 
267     // Test that the certificate verification still succeeds, because the
268     // TestRootCerts is successfully imbuing trust.
269     CertVerifyResult good_verify_result;
270     int good_status = verify_proc->Verify(
271         test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
272         /*sct_list=*/std::string(), flags, &good_verify_result,
273         NetLogWithSource());
274     EXPECT_THAT(good_status, IsOk());
275     EXPECT_EQ(0u, good_verify_result.cert_status);
276   }
277   EXPECT_TRUE(test_roots->IsEmpty());
278 
279   // Ensure that when the TestRootCerts is cleared, the trust settings
280   // revert to their original state, and don't linger. If trust status
281   // lingers, it will likely break other tests in net_unittests.
282   CertVerifyResult restored_verify_result;
283   int restored_status = verify_proc->Verify(
284       test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
285       /*sct_list=*/std::string(), flags, &restored_verify_result,
286       NetLogWithSource());
287   EXPECT_NE(OK, restored_status);
288   EXPECT_NE(0u,
289             restored_verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
290   EXPECT_EQ(bad_status, restored_status);
291   EXPECT_EQ(bad_verify_result.cert_status, restored_verify_result.cert_status);
292 }
293 
294 INSTANTIATE_TEST_SUITE_P(All, TestRootCertsTest, ::testing::Bool());
295 
296 // TODO(rsleevi): Add tests for revocation checking via CRLs, ensuring that
297 // TestRootCerts properly injects itself into the validation process. See
298 // http://crbug.com/63958
299 
300 }  // namespace net
301