Home | History | Annotate | Download | only in chromeos
      1 // Copyright (c) 2013 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 CHROMEOS_CERT_LOADER_H_
      6 #define CHROMEOS_CERT_LOADER_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/observer_list.h"
     16 #include "base/threading/thread_checker.h"
     17 #include "chromeos/chromeos_export.h"
     18 #include "net/cert/cert_database.h"
     19 
     20 namespace net {
     21 class NSSCertDatabase;
     22 class X509Certificate;
     23 typedef std::vector<scoped_refptr<X509Certificate> > CertificateList;
     24 }
     25 
     26 namespace chromeos {
     27 
     28 // This class is responsible for loading certificates once the TPM is
     29 // initialized. It is expected to be constructed on the UI thread and public
     30 // methods should all be called from the UI thread.
     31 // When certificates have been loaded (after login completes and tpm token is
     32 // initialized), or the cert database changes, observers are called with
     33 // OnCertificatesLoaded().
     34 class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer {
     35  public:
     36   class Observer {
     37    public:
     38     // Called when the certificates, passed for convenience as |cert_list|,
     39     // have completed loading. |initial_load| is true the first time this
     40     // is called.
     41     virtual void OnCertificatesLoaded(const net::CertificateList& cert_list,
     42                                       bool initial_load) = 0;
     43 
     44    protected:
     45     virtual ~Observer() {}
     46   };
     47 
     48   // Sets the global instance. Must be called before any calls to Get().
     49   static void Initialize();
     50 
     51   // Destroys the global instance.
     52   static void Shutdown();
     53 
     54   // Gets the global instance. Initialize() must be called first.
     55   static CertLoader* Get();
     56 
     57   // Returns true if the global instance has been initialized.
     58   static bool IsInitialized();
     59 
     60   // Returns the PKCS#11 attribute CKA_ID for a certificate as an upper-case
     61   // hex string and sets |slot_id| to the id of the containing slot, or returns
     62   // an empty string and doesn't modify |slot_id| if the PKCS#11 id could not be
     63   // determined.
     64   static std::string GetPkcs11IdAndSlotForCert(const net::X509Certificate& cert,
     65                                                int* slot_id);
     66 
     67   // Starts the CertLoader with the NSS cert database.
     68   // The CertLoader will _not_ take the ownership of the database, but it
     69   // expects it to stay alive at least until the shutdown starts on the main
     70   // thread. This assumes that |StartWithNSSDB| and other methods directly
     71   // using |database_| are not called during shutdown.
     72   void StartWithNSSDB(net::NSSCertDatabase* database);
     73 
     74   void AddObserver(CertLoader::Observer* observer);
     75   void RemoveObserver(CertLoader::Observer* observer);
     76 
     77   bool IsHardwareBacked() const;
     78 
     79   // Whether the certificate is hardware backed. Returns false if the CertLoader
     80   // was not yet started (both |CertificatesLoading()| and
     81   // |certificates_loaded()| are false).
     82   bool IsCertificateHardwareBacked(const net::X509Certificate* cert) const;
     83 
     84   // Returns true when the certificate list has been requested but not loaded.
     85   bool CertificatesLoading() const;
     86 
     87   bool certificates_loaded() const { return certificates_loaded_; }
     88 
     89   // This will be empty until certificates_loaded() is true.
     90   const net::CertificateList& cert_list() const { return *cert_list_; }
     91 
     92   void force_hardware_backed_for_test() {
     93     force_hardware_backed_for_test_ = true;
     94   }
     95 
     96  private:
     97   CertLoader();
     98   virtual ~CertLoader();
     99 
    100   // Trigger a certificate load. If a certificate loading task is already in
    101   // progress, will start a reload once the current task is finished.
    102   void LoadCertificates();
    103 
    104   // Called if a certificate load task is finished.
    105   void UpdateCertificates(scoped_ptr<net::CertificateList> cert_list);
    106 
    107   void NotifyCertificatesLoaded(bool initial_load);
    108 
    109   // net::CertDatabase::Observer
    110   virtual void OnCACertChanged(const net::X509Certificate* cert) OVERRIDE;
    111   virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE;
    112   virtual void OnCertRemoved(const net::X509Certificate* cert) OVERRIDE;
    113 
    114   ObserverList<Observer> observers_;
    115 
    116   // Flags describing current CertLoader state.
    117   bool certificates_loaded_;
    118   bool certificates_update_required_;
    119   bool certificates_update_running_;
    120 
    121   // The user-specific NSS certificate database from which the certificates
    122   // should be loaded.
    123   net::NSSCertDatabase* database_;
    124 
    125   // Set during tests if |IsHardwareBacked()| should always return true.
    126   bool force_hardware_backed_for_test_;
    127 
    128   // Cached Certificates loaded from the database.
    129   scoped_ptr<net::CertificateList> cert_list_;
    130 
    131   base::ThreadChecker thread_checker_;
    132 
    133   base::WeakPtrFactory<CertLoader> weak_factory_;
    134 
    135   DISALLOW_COPY_AND_ASSIGN(CertLoader);
    136 };
    137 
    138 }  // namespace chromeos
    139 
    140 #endif  // CHROMEOS_CERT_LOADER_H_
    141