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