summaryrefslogtreecommitdiffstats
path: root/chromeos/cert_loader.h
blob: 40934c0faaaa1ab52af03d68a6a351c7f33a28de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_CERT_LOADER_H_
#define CHROMEOS_CERT_LOADER_H_

#include <string>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/threading/thread_checker.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/tpm_token_loader.h"
#include "net/cert/cert_database.h"

namespace base {
class TaskRunner;
}

namespace net {
class X509Certificate;
}

namespace chromeos {

// This class is responsible for loading certificates once the TPM is
// initialized. It is expected to be constructed on the UI thread and public
// methods should all be called from the UI thread.
// When certificates have been loaded (after login completes and tpm token is
// initialized), or the cert database changes, observers are called with
// OnCertificatesLoaded().
// TODO(tbarzic): Remove direct dependency on TPMTokenLoader. The reason
//     TPMTokenLoader has to be observed is to make sure singleton NSS DB is
//     initialized before certificate loading starts. CertLoader should use
//     (primary) user specific NSS DB, whose loading already takes this into
//     account (crypto::GetPrivateSlotForChromeOSUser waits until TPM token is
//     ready).
class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer,
                                   public TPMTokenLoader::Observer {
 public:
  class Observer {
   public:
    // Called when the certificates, passed for convenience as |cert_list|,
    // have completed loading. |initial_load| is true the first time this
    // is called.
    virtual void OnCertificatesLoaded(const net::CertificateList& cert_list,
                                      bool initial_load) = 0;

   protected:
    virtual ~Observer() {}
  };

  // Sets the global instance. Must be called before any calls to Get().
  static void Initialize();

  // Destroys the global instance.
  static void Shutdown();

  // Gets the global instance. Initialize() must be called first.
  static CertLoader* Get();

  // Returns true if the global instance has been initialized.
  static bool IsInitialized();

  static std::string GetPkcs11IdForCert(const net::X509Certificate& cert);

  // Sets the task runner that any slow calls will be made from, e.g. calls
  // to the NSS database. If not set, uses base::WorkerPool.
  void SetSlowTaskRunnerForTest(
      const scoped_refptr<base::TaskRunner>& task_runner);

  void AddObserver(CertLoader::Observer* observer);
  void RemoveObserver(CertLoader::Observer* observer);

  // Returns true if the TPM is available for hardware-backed certificates.
  bool IsHardwareBacked() const;

  // Returns true when the certificate list has been requested but not loaded.
  bool CertificatesLoading() const;

  bool certificates_loaded() const { return certificates_loaded_; }

  // This will be empty until certificates_loaded() is true.
  const net::CertificateList& cert_list() const { return cert_list_; }

  // Getters for cached TPM token info.
  std::string tpm_user_pin() const { return tpm_user_pin_; }
  std::string tpm_token_name() const { return tpm_token_name_; }
  int tpm_token_slot_id() const { return tpm_token_slot_id_; }

 private:
  CertLoader();
  virtual ~CertLoader();

  // Starts certificate loading.
  void RequestCertificates();

  // Trigger a certificate load. If a certificate loading task is already in
  // progress, will start a reload once the current task finished.
  void LoadCertificates();

  // Called if a certificate load task is finished.
  void UpdateCertificates(net::CertificateList* cert_list);

  void NotifyCertificatesLoaded(bool initial_load);

  // net::CertDatabase::Observer
  virtual void OnCACertChanged(const net::X509Certificate* cert) OVERRIDE;
  virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE;
  virtual void OnCertRemoved(const net::X509Certificate* cert) OVERRIDE;

  // chromeos::TPMTokenLoader::Observer
  virtual void OnTPMTokenReady(const std::string& tpm_user_pin,
                               const std::string& tpm_token_name,
                               int tpm_token_slot_id) OVERRIDE;

  ObserverList<Observer> observers_;

  // Flags describing current CertLoader state.
  bool certificates_requested_;
  bool certificates_loaded_;
  bool certificates_update_required_;
  bool certificates_update_running_;

  // Cached TPM token info. Set when the |OnTPMTokenReady| gets called.
  std::string tpm_user_pin_;
  std::string tpm_token_name_;
  int tpm_token_slot_id_;

  // Cached Certificates.
  net::CertificateList cert_list_;

  base::ThreadChecker thread_checker_;

  // TaskRunner for other slow tasks. May be set in tests.
  scoped_refptr<base::TaskRunner> slow_task_runner_for_test_;

  base::WeakPtrFactory<CertLoader> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(CertLoader);
};

}  // namespace chromeos

#endif  // CHROMEOS_CERT_LOADER_H_