Home | History | Annotate | Download | only in cert
      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/memory/ref_counted.h"
     10 #include "build/build_config.h"
     11 #include "net/base/net_export.h"
     12 
     13 #if defined(USE_NSS) || defined(OS_IOS)
     14 #include <list>
     15 #elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
     16 #include <vector>
     17 #elif defined(OS_WIN)
     18 #include <windows.h>
     19 #include <wincrypt.h>
     20 #elif defined(OS_MACOSX)
     21 #include <CoreFoundation/CFArray.h>
     22 #include <Security/SecTrust.h>
     23 #include "base/mac/scoped_cftyperef.h"
     24 #endif
     25 
     26 #if defined(USE_NSS)
     27 typedef struct CERTCertificateStr CERTCertificate;
     28 #elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
     29 typedef struct x509_st X509;
     30 #endif
     31 
     32 namespace base {
     33 class FilePath;
     34 }
     35 
     36 namespace net {
     37 
     38 class X509Certificate;
     39 
     40 // TestRootCerts is a helper class for unit tests that is used to
     41 // artificially mark a certificate as trusted, independent of the local
     42 // machine configuration.
     43 class NET_EXPORT TestRootCerts {
     44  public:
     45   // Obtains the Singleton instance to the trusted certificates.
     46   static TestRootCerts* GetInstance();
     47 
     48   // Returns true if an instance exists, without forcing an initialization.
     49   static bool HasInstance();
     50 
     51   // Marks |certificate| as trusted for X509Certificate::Verify(). Returns
     52   // false if the certificate could not be marked trusted.
     53   bool Add(X509Certificate* certificate);
     54 
     55   // Reads a single certificate from |file| and marks it as trusted. Returns
     56   // false if an error is encountered, such as being unable to read |file|
     57   // or more than one certificate existing in |file|.
     58   bool AddFromFile(const base::FilePath& file);
     59 
     60   // Clears the trusted status of any certificates that were previously
     61   // marked trusted via Add().
     62   void Clear();
     63 
     64   // Returns true if there are no certificates that have been marked trusted.
     65   bool IsEmpty() const;
     66 
     67 #if defined(USE_NSS)
     68   bool Contains(CERTCertificate* cert) const;
     69 #elif defined(OS_MACOSX) && !defined(OS_IOS)
     70   CFArrayRef temporary_roots() const { return temporary_roots_; }
     71 
     72   // Modifies the root certificates of |trust_ref| to include the
     73   // certificates stored in |temporary_roots_|. If IsEmpty() is true, this
     74   // does not modify |trust_ref|.
     75   OSStatus FixupSecTrustRef(SecTrustRef trust_ref) const;
     76 
     77   // Configures whether or not the default/system root store should also
     78   // be trusted. By default, this is true, indicating that the TestRootCerts
     79   // are used in addition to OS trust store.
     80   void SetAllowSystemTrust(bool allow_system_trust);
     81 #elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
     82   const std::vector<scoped_refptr<X509Certificate> >&
     83       temporary_roots() const { return temporary_roots_; }
     84   bool Contains(X509* cert) const;
     85 #elif defined(OS_WIN)
     86   HCERTSTORE temporary_roots() const { return temporary_roots_; }
     87 
     88   // Returns an HCERTCHAINENGINE suitable to be used for certificate
     89   // validation routines, or NULL to indicate that the default system chain
     90   // engine is appropriate. The caller is responsible for freeing the
     91   // returned HCERTCHAINENGINE.
     92   HCERTCHAINENGINE GetChainEngine() const;
     93 #endif
     94 
     95  private:
     96   friend struct base::DefaultLazyInstanceTraits<TestRootCerts>;
     97 
     98   TestRootCerts();
     99   ~TestRootCerts();
    100 
    101   // Performs platform-dependent initialization.
    102   void Init();
    103 
    104 #if defined(USE_NSS) || defined(OS_IOS)
    105   // It is necessary to maintain a cache of the original certificate trust
    106   // settings, in order to restore them when Clear() is called.
    107   class TrustEntry;
    108   std::list<TrustEntry*> trust_cache_;
    109 #elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
    110   std::vector<scoped_refptr<X509Certificate> > temporary_roots_;
    111 #elif defined(OS_WIN)
    112   HCERTSTORE temporary_roots_;
    113 #elif defined(OS_MACOSX)
    114   base::ScopedCFTypeRef<CFMutableArrayRef> temporary_roots_;
    115   bool allow_system_trust_;
    116 #endif
    117 
    118 #if defined(OS_WIN) || defined(OS_ANDROID)
    119   // True if there are no temporarily trusted root certificates.
    120   bool empty_;
    121 #endif
    122 
    123   DISALLOW_COPY_AND_ASSIGN(TestRootCerts);
    124 };
    125 
    126 // Scoped helper for unittests to handle safely managing trusted roots.
    127 class NET_EXPORT_PRIVATE ScopedTestRoot {
    128  public:
    129   ScopedTestRoot();
    130   // Creates a ScopedTestRoot that will adds|cert| to the TestRootCerts store.
    131   explicit ScopedTestRoot(X509Certificate* cert);
    132   ~ScopedTestRoot();
    133 
    134   // Assigns |cert| to be the new test root cert. If |cert| is NULL, undoes
    135   // any work the ScopedTestRoot may have previously done.
    136   // If |cert_| contains a certificate (due to a prior call to Reset or due to
    137   // a cert being passed at construction), the existing TestRootCerts store is
    138   // cleared.
    139   void Reset(X509Certificate* cert);
    140 
    141  private:
    142   scoped_refptr<X509Certificate> cert_;
    143 
    144   DISALLOW_COPY_AND_ASSIGN(ScopedTestRoot);
    145 };
    146 
    147 }  // namespace net
    148 
    149 #endif  // NET_CERT_TEST_ROOT_CERTS_H_
    150