1 // Copyright 2022 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/internal/system_trust_store.h"
6
7 #include "net/cert/x509_certificate.h"
8 #include "net/cert/x509_util.h"
9 #include "net/net_buildflags.h"
10 #include "net/test/cert_test_util.h"
11 #include "net/test/test_data_directory.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/boringssl/src/pki/parsed_certificate.h"
14 #include "third_party/boringssl/src/pki/trust_store.h"
15
16 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
17 #include <vector>
18
19 #include "net/cert/internal/platform_trust_store.h"
20 #include "net/cert/internal/trust_store_chrome.h"
21 #endif // CHROME_ROOT_STORE_SUPPORTED
22
23 namespace net {
24
25 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
26 #include "net/data/ssl/chrome_root_store/chrome-root-store-test-data-inc.cc" // nogncheck
27
28 class TestPlatformTrustStore : public PlatformTrustStore {
29 public:
TestPlatformTrustStore(std::unique_ptr<bssl::TrustStore> trust_store)30 explicit TestPlatformTrustStore(std::unique_ptr<bssl::TrustStore> trust_store)
31 : trust_store_(std::move(trust_store)) {}
32
SyncGetIssuersOf(const bssl::ParsedCertificate * cert,bssl::ParsedCertificateList * issuers)33 void SyncGetIssuersOf(const bssl::ParsedCertificate* cert,
34 bssl::ParsedCertificateList* issuers) override {
35 trust_store_->SyncGetIssuersOf(cert, issuers);
36 }
37
38 // bssl::TrustStore implementation:
GetTrust(const bssl::ParsedCertificate * cert)39 bssl::CertificateTrust GetTrust(
40 const bssl::ParsedCertificate* cert) override {
41 return trust_store_->GetTrust(cert);
42 }
43
44 // net::PlatformTrustStore implementation:
GetAllUserAddedCerts()45 std::vector<net::PlatformTrustStore::CertWithTrust> GetAllUserAddedCerts()
46 override {
47 return {};
48 }
49
50 private:
51 std::unique_ptr<bssl::TrustStore> trust_store_;
52 };
53
TEST(SystemTrustStoreChrome,SystemDistrustOverridesChromeTrust)54 TEST(SystemTrustStoreChrome, SystemDistrustOverridesChromeTrust) {
55 CertificateList certs = CreateCertificateListFromFile(
56 GetTestNetDataDirectory().AppendASCII("ssl/chrome_root_store"),
57 "test_store.certs", X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
58 ASSERT_GE(certs.size(), 1u);
59
60 std::shared_ptr<const bssl::ParsedCertificate> root =
61 bssl::ParsedCertificate::Create(
62 bssl::UpRef(certs[0]->cert_buffer()),
63 x509_util::DefaultParseCertificateOptions(), nullptr);
64 ASSERT_TRUE(root);
65
66 auto test_system_trust_store = std::make_unique<bssl::TrustStoreInMemory>();
67 auto* test_system_trust_store_ptr = test_system_trust_store.get();
68
69 std::unique_ptr<TrustStoreChrome> test_trust_store_chrome =
70 TrustStoreChrome::CreateTrustStoreForTesting(
71 base::span<const ChromeRootCertInfo>(kChromeRootCertList),
72 /*version=*/1);
73
74 std::unique_ptr<net::PlatformTrustStore> test_platform_trust_store =
75 std::make_unique<TestPlatformTrustStore>(
76 std::move(test_system_trust_store));
77
78 std::unique_ptr<SystemTrustStore> system_trust_store_chrome =
79 CreateSystemTrustStoreChromeForTesting(
80 std::move(test_trust_store_chrome),
81 std::move(test_platform_trust_store));
82
83 // With no trust settings in the fake system trust store, the cert is trusted
84 // by the test chrome root store.
85 EXPECT_TRUE(system_trust_store_chrome->GetTrustStore()
86 ->GetTrust(root.get())
87 .IsTrustAnchor());
88
89 // Adding a distrust entry in the fake system trust store should override the
90 // trust in the chrome root store.
91 test_system_trust_store_ptr->AddDistrustedCertificateForTest(root);
92 EXPECT_TRUE(system_trust_store_chrome->GetTrustStore()
93 ->GetTrust(root.get())
94 .IsDistrusted());
95 }
96
TEST(SystemTrustStoreChrome,SystemLeafTrustDoesNotOverrideChromeTrust)97 TEST(SystemTrustStoreChrome, SystemLeafTrustDoesNotOverrideChromeTrust) {
98 CertificateList certs = CreateCertificateListFromFile(
99 GetTestNetDataDirectory().AppendASCII("ssl/chrome_root_store"),
100 "test_store.certs", X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
101 ASSERT_GE(certs.size(), 1u);
102
103 std::shared_ptr<const bssl::ParsedCertificate> root =
104 bssl::ParsedCertificate::Create(
105 bssl::UpRef(certs[0]->cert_buffer()),
106 x509_util::DefaultParseCertificateOptions(), nullptr);
107 ASSERT_TRUE(root);
108
109 auto test_system_trust_store = std::make_unique<bssl::TrustStoreInMemory>();
110 auto* test_system_trust_store_ptr = test_system_trust_store.get();
111
112 std::unique_ptr<TrustStoreChrome> test_trust_store_chrome =
113 TrustStoreChrome::CreateTrustStoreForTesting(
114 base::span<const ChromeRootCertInfo>(kChromeRootCertList),
115 /*version=*/1);
116
117 std::unique_ptr<net::PlatformTrustStore> test_platform_trust_store =
118 std::make_unique<TestPlatformTrustStore>(
119 std::move(test_system_trust_store));
120
121 std::unique_ptr<SystemTrustStore> system_trust_store_chrome =
122 CreateSystemTrustStoreChromeForTesting(
123 std::move(test_trust_store_chrome),
124 std::move(test_platform_trust_store));
125
126 // With no trust settings in the fake system trust store, the cert is trusted
127 // by the test chrome root store.
128 EXPECT_TRUE(system_trust_store_chrome->GetTrustStore()
129 ->GetTrust(root.get())
130 .IsTrustAnchor());
131
132 // Adding the certificate to the fake system store as a trusted leaf doesn't
133 // matter, the trust in the chrome root store is still preferred.
134 test_system_trust_store_ptr->AddCertificate(
135 root, bssl::CertificateTrust::ForTrustedLeaf());
136 EXPECT_TRUE(system_trust_store_chrome->GetTrustStore()
137 ->GetTrust(root.get())
138 .IsTrustAnchor());
139 EXPECT_FALSE(system_trust_store_chrome->GetTrustStore()
140 ->GetTrust(root.get())
141 .IsTrustLeaf());
142 }
143 #endif // CHROME_ROOT_STORE_SUPPORTED
144 //
145 } // namespace net
146