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