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