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 
     10 #include "base/basictypes.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/observer_list_threadsafe.h"
     15 #include "base/threading/thread_checker.h"
     16 #include "chromeos/chromeos_export.h"
     17 #include "chromeos/dbus/dbus_method_call_status.h"
     18 #include "chromeos/login/login_state.h"
     19 #include "net/cert/cert_database.h"
     20 #include "net/cert/x509_certificate.h"
     21 
     22 namespace base {
     23 class SequencedTaskRunner;
     24 class TaskRunner;
     25 }
     26 
     27 namespace crypto {
     28 class SymmetricKey;
     29 }
     30 
     31 namespace chromeos {
     32 
     33 // This class is responsible for initializing the TPM token and loading
     34 // certificates once the TPM is initialized. It is expected to be constructed
     35 // on the UI thread and public methods should all be called from the UI thread.
     36 // When certificates have been loaded (after login completes), or the cert
     37 // database changes, observers are called with OnCertificatesLoaded().
     38 class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer,
     39                                    public LoginState::Observer {
     40  public:
     41   class Observer {
     42    public:
     43     virtual ~Observer() {}
     44 
     45     // Called when the certificates, passed for convenience as |cert_list|,
     46     // have completed loading. |initial_load| is true the first time this
     47     // is called.
     48     virtual void OnCertificatesLoaded(const net::CertificateList& cert_list,
     49                                       bool initial_load) = 0;
     50 
     51    protected:
     52     Observer() {}
     53 
     54    private:
     55     DISALLOW_COPY_AND_ASSIGN(Observer);
     56   };
     57 
     58   // Sets the global instance. Must be called before any calls to Get().
     59   static void Initialize();
     60 
     61   // Destroys the global instance.
     62   static void Shutdown();
     63 
     64   // Gets the global instance. Initialize() must be called first.
     65   static CertLoader* Get();
     66 
     67   // Returns true if the global instance has been initialized.
     68   static bool IsInitialized();
     69 
     70   static std::string GetPkcs11IdForCert(const net::X509Certificate& cert);
     71 
     72   // |crypto_task_runner| is the task runner that any synchronous crypto calls
     73   // should be made from, e.g. in Chrome this is the IO thread. Must be called
     74   // after the thread is started. Certificate loading will not happen unless
     75   // this is set.
     76   void SetCryptoTaskRunner(
     77       const scoped_refptr<base::SequencedTaskRunner>& crypto_task_runner);
     78 
     79   // Sets the task runner that any slow calls will be made from, e.g. calls
     80   // to the NSS database. If not set, uses base::WorkerPool.
     81   void SetSlowTaskRunnerForTest(
     82       const scoped_refptr<base::TaskRunner>& task_runner);
     83 
     84   void AddObserver(CertLoader::Observer* observer);
     85   void RemoveObserver(CertLoader::Observer* observer);
     86 
     87   // Returns true when the certificate list has been requested but not loaded.
     88   bool CertificatesLoading() const;
     89 
     90   // Returns true if the TPM is available for hardware-backed certificates.
     91   bool IsHardwareBacked() const;
     92 
     93   bool certificates_loaded() const { return certificates_loaded_; }
     94 
     95   // TPM info is only valid once the TPM is available (IsHardwareBacked is
     96   // true). Otherwise empty strings will be returned.
     97   const std::string& tpm_token_name() const { return tpm_token_name_; }
     98   const std::string& tpm_token_slot() const { return tpm_token_slot_; }
     99   const std::string& tpm_user_pin() const { return tpm_user_pin_; }
    100 
    101   // This will be empty until certificates_loaded() is true.
    102   const net::CertificateList& cert_list() const { return cert_list_; }
    103 
    104  private:
    105   CertLoader();
    106   virtual ~CertLoader();
    107 
    108   void Init();
    109   void MaybeRequestCertificates();
    110 
    111   // This is the cyclic chain of callbacks to initialize the TPM token and to
    112   // kick off the update of the certificate list.
    113   void InitializeTokenAndLoadCertificates();
    114   void RetryTokenInitializationLater();
    115   void OnPersistentNSSDBOpened();
    116   void OnTpmIsEnabled(DBusMethodCallStatus call_status,
    117                       bool tpm_is_enabled);
    118   void OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status,
    119                                bool is_tpm_token_ready);
    120   void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status,
    121                                const std::string& token_name,
    122                                const std::string& user_pin);
    123   void OnTPMTokenInitialized(bool success);
    124 
    125   // These calls handle the updating of the certificate list after the TPM token
    126   // was initialized.
    127   void StartLoadCertificates();
    128   void UpdateCertificates(net::CertificateList* cert_list);
    129 
    130   void NotifyCertificatesLoaded(bool initial_load);
    131 
    132   // net::CertDatabase::Observer
    133   virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE;
    134   virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE;
    135   virtual void OnCertRemoved(const net::X509Certificate* cert) OVERRIDE;
    136 
    137   // LoginState::Observer
    138   virtual void LoggedInStateChanged(LoginState::LoggedInState state) OVERRIDE;
    139 
    140   ObserverList<Observer> observers_;
    141 
    142   bool certificates_requested_;
    143   bool certificates_loaded_;
    144   bool certificates_update_required_;
    145   bool certificates_update_running_;
    146 
    147   // The states are traversed in this order but some might get omitted or never
    148   // be left.
    149   enum TPMTokenState {
    150     TPM_STATE_UNKNOWN,
    151     TPM_DB_OPENED,
    152     TPM_DISABLED,
    153     TPM_ENABLED,
    154     TPM_TOKEN_READY,
    155     TPM_TOKEN_INFO_RECEIVED,
    156     TPM_TOKEN_INITIALIZED,
    157   };
    158   TPMTokenState tpm_token_state_;
    159 
    160   // The current request delay before the next attempt to initialize the
    161   // TPM. Will be adapted after each attempt.
    162   base::TimeDelta tpm_request_delay_;
    163 
    164   // Cached TPM token info.
    165   std::string tpm_token_name_;
    166   std::string tpm_token_slot_;
    167   std::string tpm_user_pin_;
    168 
    169   // Cached Certificates.
    170   net::CertificateList cert_list_;
    171 
    172   base::ThreadChecker thread_checker_;
    173 
    174   // TaskRunner for crypto calls.
    175   scoped_refptr<base::SequencedTaskRunner> crypto_task_runner_;
    176 
    177   // TaskRunner for other slow tasks. May be set in tests.
    178   scoped_refptr<base::TaskRunner> slow_task_runner_for_test_;
    179 
    180   // This factory should be used only for callbacks during TPMToken
    181   // initialization.
    182   base::WeakPtrFactory<CertLoader> initialize_token_factory_;
    183 
    184   // This factory should be used only for callbacks during updating the
    185   // certificate list.
    186   base::WeakPtrFactory<CertLoader> update_certificates_factory_;
    187 
    188   DISALLOW_COPY_AND_ASSIGN(CertLoader);
    189 };
    190 
    191 }  // namespace chromeos
    192 
    193 #endif  // CHROMEOS_CERT_LOADER_H_
    194