xref: /aosp_15_r20/external/cronet/net/cert/test_root_certs.h (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 #ifndef NET_CERT_TEST_ROOT_CERTS_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_CERT_TEST_ROOT_CERTS_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <set>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/lazy_instance.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/memory/scoped_refptr.h"
13*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
15*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/trust_store.h"
16*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/trust_store_in_memory.h"
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_IOS)
19*6777b538SAndroid Build Coastguard Worker #include <CoreFoundation/CFArray.h>
20*6777b538SAndroid Build Coastguard Worker #include <Security/SecTrust.h>
21*6777b538SAndroid Build Coastguard Worker #include "base/apple/scoped_cftyperef.h"
22*6777b538SAndroid Build Coastguard Worker #endif
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker namespace net {
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker class X509Certificate;
27*6777b538SAndroid Build Coastguard Worker typedef std::vector<scoped_refptr<X509Certificate>> CertificateList;
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker // TestRootCerts is a helper class for unit tests that is used to
30*6777b538SAndroid Build Coastguard Worker // artificially mark a certificate as trusted, independent of the local
31*6777b538SAndroid Build Coastguard Worker // machine configuration.
32*6777b538SAndroid Build Coastguard Worker //
33*6777b538SAndroid Build Coastguard Worker // Test roots can be added using the ScopedTestRoot class below. See the
34*6777b538SAndroid Build Coastguard Worker // class documentation for usage and limitations.
35*6777b538SAndroid Build Coastguard Worker class NET_EXPORT TestRootCerts {
36*6777b538SAndroid Build Coastguard Worker  public:
37*6777b538SAndroid Build Coastguard Worker   // Obtains the Singleton instance to the trusted certificates.
38*6777b538SAndroid Build Coastguard Worker   static TestRootCerts* GetInstance();
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker   TestRootCerts(const TestRootCerts&) = delete;
41*6777b538SAndroid Build Coastguard Worker   TestRootCerts& operator=(const TestRootCerts&) = delete;
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker   // Returns true if an instance exists, without forcing an initialization.
44*6777b538SAndroid Build Coastguard Worker   static bool HasInstance();
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker   // Clears the trusted status of any certificates that were previously
47*6777b538SAndroid Build Coastguard Worker   // marked trusted via Add().
48*6777b538SAndroid Build Coastguard Worker   void Clear();
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   // Returns true if there are no certificates that have been marked trusted.
51*6777b538SAndroid Build Coastguard Worker   bool IsEmpty() const;
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker   // Returns true if `der_cert` has been marked as a known root for testing.
54*6777b538SAndroid Build Coastguard Worker   bool IsKnownRoot(base::span<const uint8_t> der_cert) const;
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_IOS)
temporary_roots()57*6777b538SAndroid Build Coastguard Worker   CFArrayRef temporary_roots() const { return temporary_roots_.get(); }
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker   // Modifies the root certificates of |trust_ref| to include the
60*6777b538SAndroid Build Coastguard Worker   // certificates stored in |temporary_roots_|. If IsEmpty() is true, this
61*6777b538SAndroid Build Coastguard Worker   // does not modify |trust_ref|.
62*6777b538SAndroid Build Coastguard Worker   OSStatus FixupSecTrustRef(SecTrustRef trust_ref) const;
63*6777b538SAndroid Build Coastguard Worker #endif
64*6777b538SAndroid Build Coastguard Worker 
test_trust_store()65*6777b538SAndroid Build Coastguard Worker   bssl::TrustStore* test_trust_store() { return &test_trust_store_; }
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker  private:
68*6777b538SAndroid Build Coastguard Worker   friend struct base::LazyInstanceTraitsBase<TestRootCerts>;
69*6777b538SAndroid Build Coastguard Worker   friend class ScopedTestRoot;
70*6777b538SAndroid Build Coastguard Worker   friend class ScopedTestKnownRoot;
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker   TestRootCerts();
73*6777b538SAndroid Build Coastguard Worker   ~TestRootCerts();
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker   // Marks |certificate| as trusted in the effective trust store
76*6777b538SAndroid Build Coastguard Worker   // used by CertVerifier::Verify(). Returns false if the
77*6777b538SAndroid Build Coastguard Worker   // certificate could not be marked trusted.
78*6777b538SAndroid Build Coastguard Worker   bool Add(X509Certificate* certificate, bssl::CertificateTrust trust);
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker   // Marks |der_cert| as a known root. Does not change trust.
81*6777b538SAndroid Build Coastguard Worker   void AddKnownRoot(base::span<const uint8_t> der_cert);
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   // Performs platform-dependent operations.
84*6777b538SAndroid Build Coastguard Worker   void Init();
85*6777b538SAndroid Build Coastguard Worker   bool AddImpl(X509Certificate* certificate);
86*6777b538SAndroid Build Coastguard Worker   void ClearImpl();
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_IOS)
89*6777b538SAndroid Build Coastguard Worker   base::apple::ScopedCFTypeRef<CFMutableArrayRef> temporary_roots_;
90*6777b538SAndroid Build Coastguard Worker #endif
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   bssl::TrustStoreInMemory test_trust_store_;
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker   std::set<std::string, std::less<>> test_known_roots_;
95*6777b538SAndroid Build Coastguard Worker };
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker // Scoped helper for unittests to handle safely managing trusted roots.
98*6777b538SAndroid Build Coastguard Worker //
99*6777b538SAndroid Build Coastguard Worker // Limitations:
100*6777b538SAndroid Build Coastguard Worker // Multiple instances of ScopedTestRoot may be created at once, which will
101*6777b538SAndroid Build Coastguard Worker // trust the union of the certs provided. However, when one of the
102*6777b538SAndroid Build Coastguard Worker // ScopedTestRoot instances removes its trust, either by going out of scope, or
103*6777b538SAndroid Build Coastguard Worker // by Reset() being called, *all* test root certs will be untrusted. (This
104*6777b538SAndroid Build Coastguard Worker // limitation could be removed if a reason arises.)
105*6777b538SAndroid Build Coastguard Worker class NET_EXPORT ScopedTestRoot {
106*6777b538SAndroid Build Coastguard Worker  public:
107*6777b538SAndroid Build Coastguard Worker   ScopedTestRoot();
108*6777b538SAndroid Build Coastguard Worker   // Creates a ScopedTestRoot that adds |cert| to the TestRootCerts store.
109*6777b538SAndroid Build Coastguard Worker   // |trust| may be specified to change the details of how the trust is
110*6777b538SAndroid Build Coastguard Worker   // interpreted (applies only to CertVerifyProcBuiltin).
111*6777b538SAndroid Build Coastguard Worker   explicit ScopedTestRoot(
112*6777b538SAndroid Build Coastguard Worker       scoped_refptr<X509Certificate> cert,
113*6777b538SAndroid Build Coastguard Worker       bssl::CertificateTrust trust = bssl::CertificateTrust::ForTrustAnchor());
114*6777b538SAndroid Build Coastguard Worker   // Creates a ScopedTestRoot that adds |certs| to the TestRootCerts store.
115*6777b538SAndroid Build Coastguard Worker   // |trust| may be specified to change the details of how the trust is
116*6777b538SAndroid Build Coastguard Worker   // interpreted (applies only to CertVerifyProcBuiltin).
117*6777b538SAndroid Build Coastguard Worker   explicit ScopedTestRoot(
118*6777b538SAndroid Build Coastguard Worker       CertificateList certs,
119*6777b538SAndroid Build Coastguard Worker       bssl::CertificateTrust trust = bssl::CertificateTrust::ForTrustAnchor());
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker   ScopedTestRoot(const ScopedTestRoot&) = delete;
122*6777b538SAndroid Build Coastguard Worker   ScopedTestRoot& operator=(const ScopedTestRoot&) = delete;
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker   ScopedTestRoot(ScopedTestRoot&& other);
125*6777b538SAndroid Build Coastguard Worker   ScopedTestRoot& operator=(ScopedTestRoot&& other);
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker   ~ScopedTestRoot();
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker   // Assigns |certs| to be the new test root certs. If |certs| is empty, undoes
130*6777b538SAndroid Build Coastguard Worker   // any work the ScopedTestRoot may have previously done.
131*6777b538SAndroid Build Coastguard Worker   // If |certs_| contains certificates (due to a prior call to Reset or due to
132*6777b538SAndroid Build Coastguard Worker   // certs being passed at construction), the existing TestRootCerts store is
133*6777b538SAndroid Build Coastguard Worker   // cleared.
134*6777b538SAndroid Build Coastguard Worker   void Reset(
135*6777b538SAndroid Build Coastguard Worker       CertificateList certs,
136*6777b538SAndroid Build Coastguard Worker       bssl::CertificateTrust trust = bssl::CertificateTrust::ForTrustAnchor());
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker   // Returns true if this ScopedTestRoot has no certs assigned.
139*6777b538SAndroid Build Coastguard Worker   bool IsEmpty() const { return certs_.empty(); }
140*6777b538SAndroid Build Coastguard Worker 
141*6777b538SAndroid Build Coastguard Worker  private:
142*6777b538SAndroid Build Coastguard Worker   CertificateList certs_;
143*6777b538SAndroid Build Coastguard Worker };
144*6777b538SAndroid Build Coastguard Worker 
145*6777b538SAndroid Build Coastguard Worker // Scoped helper for unittests to handle safely marking additional roots as
146*6777b538SAndroid Build Coastguard Worker // known roots. Note that this does not trust the root. If the root should be
147*6777b538SAndroid Build Coastguard Worker // trusted, a ScopedTestRoot should also be created.
148*6777b538SAndroid Build Coastguard Worker //
149*6777b538SAndroid Build Coastguard Worker // Limitations:
150*6777b538SAndroid Build Coastguard Worker // Same as for ScopedTestRoot, see comment above.
151*6777b538SAndroid Build Coastguard Worker class NET_EXPORT ScopedTestKnownRoot {
152*6777b538SAndroid Build Coastguard Worker  public:
153*6777b538SAndroid Build Coastguard Worker   ScopedTestKnownRoot();
154*6777b538SAndroid Build Coastguard Worker   explicit ScopedTestKnownRoot(X509Certificate* cert);
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker   ScopedTestKnownRoot(const ScopedTestKnownRoot&) = delete;
157*6777b538SAndroid Build Coastguard Worker   ScopedTestKnownRoot& operator=(const ScopedTestKnownRoot&) = delete;
158*6777b538SAndroid Build Coastguard Worker   ScopedTestKnownRoot(ScopedTestKnownRoot&& other) = delete;
159*6777b538SAndroid Build Coastguard Worker   ScopedTestKnownRoot& operator=(ScopedTestKnownRoot&& other) = delete;
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker   ~ScopedTestKnownRoot();
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker  private:
164*6777b538SAndroid Build Coastguard Worker   CertificateList certs_;
165*6777b538SAndroid Build Coastguard Worker };
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker }  // namespace net
168*6777b538SAndroid Build Coastguard Worker 
169*6777b538SAndroid Build Coastguard Worker #endif  // NET_CERT_TEST_ROOT_CERTS_H_
170