• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 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 <string>
8 #include <utility>
9 
10 #include "net/cert/x509_certificate.h"
11 #include "net/cert/x509_util.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/trust_store.h"
15 
16 namespace net {
17 
18 namespace {
19 
20 bool g_has_instance = false;
21 
22 base::LazyInstance<TestRootCerts>::Leaky
23     g_test_root_certs = LAZY_INSTANCE_INITIALIZER;
24 
25 }  // namespace
26 
27 // static
GetInstance()28 TestRootCerts* TestRootCerts::GetInstance() {
29   return g_test_root_certs.Pointer();
30 }
31 
HasInstance()32 bool TestRootCerts::HasInstance() {
33   return g_has_instance;
34 }
35 
Add(X509Certificate * certificate,bssl::CertificateTrust trust)36 bool TestRootCerts::Add(X509Certificate* certificate,
37                         bssl::CertificateTrust trust) {
38   bssl::CertErrors errors;
39   std::shared_ptr<const bssl::ParsedCertificate> parsed =
40       bssl::ParsedCertificate::Create(
41           bssl::UpRef(certificate->cert_buffer()),
42           x509_util::DefaultParseCertificateOptions(), &errors);
43   if (!parsed) {
44     return false;
45   }
46 
47   test_trust_store_.AddCertificate(std::move(parsed), trust);
48   if (trust.HasUnspecifiedTrust() || trust.IsDistrusted()) {
49     // TestRootCerts doesn't support passing the specific trust settings into
50     // the OS implementations in any case, but in the case of unspecified trust
51     // or explicit distrust, simply not passing the certs to the OS
52     // implementation is better than nothing.
53     return true;
54   }
55   return AddImpl(certificate);
56 }
57 
AddKnownRoot(base::span<const uint8_t> der_cert)58 void TestRootCerts::AddKnownRoot(base::span<const uint8_t> der_cert) {
59   test_known_roots_.insert(std::string(
60       reinterpret_cast<const char*>(der_cert.data()), der_cert.size()));
61 }
62 
Clear()63 void TestRootCerts::Clear() {
64   ClearImpl();
65   test_trust_store_.Clear();
66   test_known_roots_.clear();
67 }
68 
IsEmpty() const69 bool TestRootCerts::IsEmpty() const {
70   return test_trust_store_.IsEmpty();
71 }
72 
IsKnownRoot(base::span<const uint8_t> der_cert) const73 bool TestRootCerts::IsKnownRoot(base::span<const uint8_t> der_cert) const {
74   return test_known_roots_.find(
75              base::StringPiece(reinterpret_cast<const char*>(der_cert.data()),
76                                der_cert.size())) != test_known_roots_.end();
77 }
78 
TestRootCerts()79 TestRootCerts::TestRootCerts() {
80   Init();
81   g_has_instance = true;
82 }
83 
84 ScopedTestRoot::ScopedTestRoot() = default;
85 
ScopedTestRoot(scoped_refptr<X509Certificate> cert,bssl::CertificateTrust trust)86 ScopedTestRoot::ScopedTestRoot(scoped_refptr<X509Certificate> cert,
87                                bssl::CertificateTrust trust) {
88   Reset({std::move(cert)}, trust);
89 }
90 
ScopedTestRoot(CertificateList certs,bssl::CertificateTrust trust)91 ScopedTestRoot::ScopedTestRoot(CertificateList certs,
92                                bssl::CertificateTrust trust) {
93   Reset(std::move(certs), trust);
94 }
95 
ScopedTestRoot(ScopedTestRoot && other)96 ScopedTestRoot::ScopedTestRoot(ScopedTestRoot&& other) {
97   *this = std::move(other);
98 }
99 
operator =(ScopedTestRoot && other)100 ScopedTestRoot& ScopedTestRoot::operator=(ScopedTestRoot&& other) {
101   CertificateList tmp_certs;
102   tmp_certs.swap(other.certs_);
103   Reset(std::move(tmp_certs));
104   return *this;
105 }
106 
~ScopedTestRoot()107 ScopedTestRoot::~ScopedTestRoot() {
108   Reset({});
109 }
110 
Reset(CertificateList certs,bssl::CertificateTrust trust)111 void ScopedTestRoot::Reset(CertificateList certs,
112                            bssl::CertificateTrust trust) {
113   if (!certs_.empty())
114     TestRootCerts::GetInstance()->Clear();
115   for (const auto& cert : certs)
116     TestRootCerts::GetInstance()->Add(cert.get(), trust);
117   certs_ = std::move(certs);
118 }
119 
120 ScopedTestKnownRoot::ScopedTestKnownRoot() = default;
121 
ScopedTestKnownRoot(X509Certificate * cert)122 ScopedTestKnownRoot::ScopedTestKnownRoot(X509Certificate* cert) {
123   TestRootCerts::GetInstance()->AddKnownRoot(
124       x509_util::CryptoBufferAsSpan(cert->cert_buffer()));
125 }
126 
~ScopedTestKnownRoot()127 ScopedTestKnownRoot::~ScopedTestKnownRoot() {
128   TestRootCerts::GetInstance()->Clear();
129 }
130 
131 }  // namespace net
132