1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_CERT_TEST_ROOT_CERTS_H_ 6 #define NET_CERT_TEST_ROOT_CERTS_H_ 7 8 #include "base/lazy_instance.h" 9 #include "base/macros.h" 10 #include "base/memory/ref_counted.h" 11 #include "build/build_config.h" 12 #include "net/base/net_export.h" 13 #include "net/cert/internal/trust_store_in_memory.h" 14 15 #if defined(OS_WIN) 16 #include <windows.h> 17 #include "base/win/wincrypt_shim.h" 18 #elif defined(OS_APPLE) 19 #include <CoreFoundation/CFArray.h> 20 #include <Security/SecTrust.h> 21 #include "base/mac/scoped_cftyperef.h" 22 #endif 23 24 namespace base { 25 class FilePath; 26 } 27 28 namespace net { 29 30 class X509Certificate; 31 typedef std::vector<scoped_refptr<X509Certificate>> CertificateList; 32 33 // TestRootCerts is a helper class for unit tests that is used to 34 // artificially mark a certificate as trusted, independent of the local 35 // machine configuration. 36 class NET_EXPORT TestRootCerts { 37 public: 38 // Obtains the Singleton instance to the trusted certificates. 39 static TestRootCerts* GetInstance(); 40 41 // Returns true if an instance exists, without forcing an initialization. 42 static bool HasInstance(); 43 44 // Marks |certificate| as trusted in the effective trust store 45 // used by CertVerifier::Verify(). Returns false if the 46 // certificate could not be marked trusted. 47 bool Add(X509Certificate* certificate); 48 49 // Reads a single certificate from |file| and marks it as trusted. Returns 50 // false if an error is encountered, such as being unable to read |file| 51 // or more than one certificate existing in |file|. 52 bool AddFromFile(const base::FilePath& file); 53 54 // Clears the trusted status of any certificates that were previously 55 // marked trusted via Add(). 56 void Clear(); 57 58 // Returns true if there are no certificates that have been marked trusted. 59 bool IsEmpty() const; 60 61 #if defined(OS_APPLE) temporary_roots()62 CFArrayRef temporary_roots() const { return temporary_roots_; } 63 64 // Modifies the root certificates of |trust_ref| to include the 65 // certificates stored in |temporary_roots_|. If IsEmpty() is true, this 66 // does not modify |trust_ref|. 67 OSStatus FixupSecTrustRef(SecTrustRef trust_ref) const; 68 test_trust_store()69 TrustStore* test_trust_store() { return &test_trust_store_; } 70 #elif defined(OS_WIN) temporary_roots()71 HCERTSTORE temporary_roots() const { return temporary_roots_; } 72 73 // Returns an HCERTCHAINENGINE suitable to be used for certificate 74 // validation routines, or NULL to indicate that the default system chain 75 // engine is appropriate. The caller is responsible for freeing the 76 // returned HCERTCHAINENGINE. 77 HCERTCHAINENGINE GetChainEngine() const; 78 #elif defined(OS_BSD) || defined(OS_FUCHSIA) || defined(OS_LINUX) || defined(OS_CHROMEOS) test_trust_store()79 TrustStore* test_trust_store() { return &test_trust_store_; } 80 #endif 81 82 private: 83 friend struct base::LazyInstanceTraitsBase<TestRootCerts>; 84 85 TestRootCerts(); 86 ~TestRootCerts(); 87 88 // Performs platform-dependent initialization. 89 void Init(); 90 91 #if defined(OS_WIN) 92 HCERTSTORE temporary_roots_; 93 #elif defined(OS_APPLE) 94 base::ScopedCFTypeRef<CFMutableArrayRef> temporary_roots_; 95 TrustStoreInMemory test_trust_store_; 96 #elif defined(OS_BSD) || defined(OS_FUCHSIA) || defined(OS_LINUX) || defined(OS_CHROMEOS) 97 TrustStoreInMemory test_trust_store_; 98 #endif 99 100 #if defined(OS_WIN) || defined(OS_ANDROID) || defined(OS_FUCHSIA) || \ 101 defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) 102 // True if there are no temporarily trusted root certificates. 103 bool empty_ = true; 104 #endif 105 106 DISALLOW_COPY_AND_ASSIGN(TestRootCerts); 107 }; 108 109 // Scoped helper for unittests to handle safely managing trusted roots. 110 class NET_EXPORT_PRIVATE ScopedTestRoot { 111 public: 112 ScopedTestRoot(); 113 // Creates a ScopedTestRoot that sets |cert| as the single root in the 114 // TestRootCerts store (if there were existing roots they are 115 // cleared). 116 explicit ScopedTestRoot(X509Certificate* cert); 117 // Creates a ScopedTestRoot that sets |certs| as the only roots in the 118 // TestRootCerts store (if there were existing roots they are 119 // cleared). 120 explicit ScopedTestRoot(CertificateList certs); 121 ~ScopedTestRoot(); 122 123 // Assigns |certs| to be the new test root certs. If |certs| is empty, undoes 124 // any work the ScopedTestRoot may have previously done. 125 // If |certs_| contains certificates (due to a prior call to Reset or due to 126 // certs being passed at construction), the existing TestRootCerts store is 127 // cleared. 128 void Reset(CertificateList certs); 129 130 private: 131 CertificateList certs_; 132 133 DISALLOW_COPY_AND_ASSIGN(ScopedTestRoot); 134 }; 135 136 } // namespace net 137 138 #endif // NET_CERT_TEST_ROOT_CERTS_H_ 139