xref: /aosp_15_r20/external/cronet/net/cert/test_root_certs.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/cert/test_root_certs.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <string>
8*6777b538SAndroid Build Coastguard Worker #include <string_view>
9*6777b538SAndroid Build Coastguard Worker #include <utility>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "net/cert/x509_certificate.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/cert/x509_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/pool.h"
14*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/cert_errors.h"
15*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/trust_store.h"
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker namespace net {
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker namespace {
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker bool g_has_instance = false;
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker base::LazyInstance<TestRootCerts>::Leaky
24*6777b538SAndroid Build Coastguard Worker     g_test_root_certs = LAZY_INSTANCE_INITIALIZER;
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker }  // namespace
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker // static
GetInstance()29*6777b538SAndroid Build Coastguard Worker TestRootCerts* TestRootCerts::GetInstance() {
30*6777b538SAndroid Build Coastguard Worker   return g_test_root_certs.Pointer();
31*6777b538SAndroid Build Coastguard Worker }
32*6777b538SAndroid Build Coastguard Worker 
HasInstance()33*6777b538SAndroid Build Coastguard Worker bool TestRootCerts::HasInstance() {
34*6777b538SAndroid Build Coastguard Worker   return g_has_instance;
35*6777b538SAndroid Build Coastguard Worker }
36*6777b538SAndroid Build Coastguard Worker 
Add(X509Certificate * certificate,bssl::CertificateTrust trust)37*6777b538SAndroid Build Coastguard Worker bool TestRootCerts::Add(X509Certificate* certificate,
38*6777b538SAndroid Build Coastguard Worker                         bssl::CertificateTrust trust) {
39*6777b538SAndroid Build Coastguard Worker   bssl::CertErrors errors;
40*6777b538SAndroid Build Coastguard Worker   std::shared_ptr<const bssl::ParsedCertificate> parsed =
41*6777b538SAndroid Build Coastguard Worker       bssl::ParsedCertificate::Create(
42*6777b538SAndroid Build Coastguard Worker           bssl::UpRef(certificate->cert_buffer()),
43*6777b538SAndroid Build Coastguard Worker           x509_util::DefaultParseCertificateOptions(), &errors);
44*6777b538SAndroid Build Coastguard Worker   if (!parsed) {
45*6777b538SAndroid Build Coastguard Worker     return false;
46*6777b538SAndroid Build Coastguard Worker   }
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   test_trust_store_.AddCertificate(std::move(parsed), trust);
49*6777b538SAndroid Build Coastguard Worker   if (trust.HasUnspecifiedTrust() || trust.IsDistrusted()) {
50*6777b538SAndroid Build Coastguard Worker     // TestRootCerts doesn't support passing the specific trust settings into
51*6777b538SAndroid Build Coastguard Worker     // the OS implementations in any case, but in the case of unspecified trust
52*6777b538SAndroid Build Coastguard Worker     // or explicit distrust, simply not passing the certs to the OS
53*6777b538SAndroid Build Coastguard Worker     // implementation is better than nothing.
54*6777b538SAndroid Build Coastguard Worker     return true;
55*6777b538SAndroid Build Coastguard Worker   }
56*6777b538SAndroid Build Coastguard Worker   return AddImpl(certificate);
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker 
AddKnownRoot(base::span<const uint8_t> der_cert)59*6777b538SAndroid Build Coastguard Worker void TestRootCerts::AddKnownRoot(base::span<const uint8_t> der_cert) {
60*6777b538SAndroid Build Coastguard Worker   test_known_roots_.insert(std::string(
61*6777b538SAndroid Build Coastguard Worker       reinterpret_cast<const char*>(der_cert.data()), der_cert.size()));
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker 
Clear()64*6777b538SAndroid Build Coastguard Worker void TestRootCerts::Clear() {
65*6777b538SAndroid Build Coastguard Worker   ClearImpl();
66*6777b538SAndroid Build Coastguard Worker   test_trust_store_.Clear();
67*6777b538SAndroid Build Coastguard Worker   test_known_roots_.clear();
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker 
IsEmpty() const70*6777b538SAndroid Build Coastguard Worker bool TestRootCerts::IsEmpty() const {
71*6777b538SAndroid Build Coastguard Worker   return test_trust_store_.IsEmpty();
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker 
IsKnownRoot(base::span<const uint8_t> der_cert) const74*6777b538SAndroid Build Coastguard Worker bool TestRootCerts::IsKnownRoot(base::span<const uint8_t> der_cert) const {
75*6777b538SAndroid Build Coastguard Worker   return test_known_roots_.find(
76*6777b538SAndroid Build Coastguard Worker              std::string_view(reinterpret_cast<const char*>(der_cert.data()),
77*6777b538SAndroid Build Coastguard Worker                               der_cert.size())) != test_known_roots_.end();
78*6777b538SAndroid Build Coastguard Worker }
79*6777b538SAndroid Build Coastguard Worker 
TestRootCerts()80*6777b538SAndroid Build Coastguard Worker TestRootCerts::TestRootCerts() {
81*6777b538SAndroid Build Coastguard Worker   Init();
82*6777b538SAndroid Build Coastguard Worker   g_has_instance = true;
83*6777b538SAndroid Build Coastguard Worker }
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker ScopedTestRoot::ScopedTestRoot() = default;
86*6777b538SAndroid Build Coastguard Worker 
ScopedTestRoot(scoped_refptr<X509Certificate> cert,bssl::CertificateTrust trust)87*6777b538SAndroid Build Coastguard Worker ScopedTestRoot::ScopedTestRoot(scoped_refptr<X509Certificate> cert,
88*6777b538SAndroid Build Coastguard Worker                                bssl::CertificateTrust trust) {
89*6777b538SAndroid Build Coastguard Worker   Reset({std::move(cert)}, trust);
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker 
ScopedTestRoot(CertificateList certs,bssl::CertificateTrust trust)92*6777b538SAndroid Build Coastguard Worker ScopedTestRoot::ScopedTestRoot(CertificateList certs,
93*6777b538SAndroid Build Coastguard Worker                                bssl::CertificateTrust trust) {
94*6777b538SAndroid Build Coastguard Worker   Reset(std::move(certs), trust);
95*6777b538SAndroid Build Coastguard Worker }
96*6777b538SAndroid Build Coastguard Worker 
ScopedTestRoot(ScopedTestRoot && other)97*6777b538SAndroid Build Coastguard Worker ScopedTestRoot::ScopedTestRoot(ScopedTestRoot&& other) {
98*6777b538SAndroid Build Coastguard Worker   *this = std::move(other);
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker 
operator =(ScopedTestRoot && other)101*6777b538SAndroid Build Coastguard Worker ScopedTestRoot& ScopedTestRoot::operator=(ScopedTestRoot&& other) {
102*6777b538SAndroid Build Coastguard Worker   CertificateList tmp_certs;
103*6777b538SAndroid Build Coastguard Worker   tmp_certs.swap(other.certs_);
104*6777b538SAndroid Build Coastguard Worker   Reset(std::move(tmp_certs));
105*6777b538SAndroid Build Coastguard Worker   return *this;
106*6777b538SAndroid Build Coastguard Worker }
107*6777b538SAndroid Build Coastguard Worker 
~ScopedTestRoot()108*6777b538SAndroid Build Coastguard Worker ScopedTestRoot::~ScopedTestRoot() {
109*6777b538SAndroid Build Coastguard Worker   Reset({});
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker 
Reset(CertificateList certs,bssl::CertificateTrust trust)112*6777b538SAndroid Build Coastguard Worker void ScopedTestRoot::Reset(CertificateList certs,
113*6777b538SAndroid Build Coastguard Worker                            bssl::CertificateTrust trust) {
114*6777b538SAndroid Build Coastguard Worker   if (!certs_.empty())
115*6777b538SAndroid Build Coastguard Worker     TestRootCerts::GetInstance()->Clear();
116*6777b538SAndroid Build Coastguard Worker   for (const auto& cert : certs)
117*6777b538SAndroid Build Coastguard Worker     TestRootCerts::GetInstance()->Add(cert.get(), trust);
118*6777b538SAndroid Build Coastguard Worker   certs_ = std::move(certs);
119*6777b538SAndroid Build Coastguard Worker }
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker ScopedTestKnownRoot::ScopedTestKnownRoot() = default;
122*6777b538SAndroid Build Coastguard Worker 
ScopedTestKnownRoot(X509Certificate * cert)123*6777b538SAndroid Build Coastguard Worker ScopedTestKnownRoot::ScopedTestKnownRoot(X509Certificate* cert) {
124*6777b538SAndroid Build Coastguard Worker   TestRootCerts::GetInstance()->AddKnownRoot(
125*6777b538SAndroid Build Coastguard Worker       x509_util::CryptoBufferAsSpan(cert->cert_buffer()));
126*6777b538SAndroid Build Coastguard Worker }
127*6777b538SAndroid Build Coastguard Worker 
~ScopedTestKnownRoot()128*6777b538SAndroid Build Coastguard Worker ScopedTestKnownRoot::~ScopedTestKnownRoot() {
129*6777b538SAndroid Build Coastguard Worker   TestRootCerts::GetInstance()->Clear();
130*6777b538SAndroid Build Coastguard Worker }
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker }  // namespace net
133