summaryrefslogtreecommitdiffstats
path: root/chromeos/tpm/tpm_token_loader.h
blob: 84f98b8052be9501cec096e380f53bdaceb04922 (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
// Copyright 2014 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_TPM_TPM_TOKEN_LOADER_H_
#define CHROMEOS_TPM_TPM_TOKEN_LOADER_H_

#include <string>
#include <vector>

#include "base/macros.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/login/login_state.h"

namespace base {
class SequencedTaskRunner;
}

namespace chromeos {

struct TPMTokenInfo;
class TPMTokenInfoGetter;

// This class is responsible for loading the TPM backed token for the system
// slot when the user logs in. It is expected to be constructed on the UI thread
// and public methods should all be called from the UI thread.
// When the TPM token is loaded, or if the TPM should stay disabled for the
// session, the observers are notified using |OnTPMTokenReady|.
// Note: This currently initializes the token with the hard coded default id 0.
// See CryptohomeClient::OnPkcs11GetTpmTokenInfo.
class CHROMEOS_EXPORT TPMTokenLoader : public LoginState::Observer {
 public:
  enum TPMTokenStatus {
    TPM_TOKEN_STATUS_UNDETERMINED,
    TPM_TOKEN_STATUS_ENABLED,
    TPM_TOKEN_STATUS_DISABLED
  };

  typedef base::Callback<void(bool)> TPMReadyCallback;
  typedef std::vector<TPMReadyCallback> TPMReadyCallbackList;

  // Sets the global instance. Must be called before any calls to Get().
  // The global instance will immediately start observing |LoginState|.
  static void Initialize();

  // Sets the global. stubbed out, instance. To be used in tests.
  static void InitializeForTest();

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

  // Gets the global instance. Initialize() must be called before this.
  static TPMTokenLoader* Get();

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

  // |crypto_task_runner| is the task runner that any synchronous crypto calls
  // should be made from, e.g. in Chrome this is the IO thread. Must be called
  // after the thread is started. When called, this will attempt to start TPM
  // token loading.
  void SetCryptoTaskRunner(
      const scoped_refptr<base::SequencedTaskRunner>& crypto_task_runner);

  // Starts loading TPM system token, if not yet started. It should be called
  // if the system token has to be loaded before a user logs in. By default (if
  // |EnsureStarted| is not called) system token loading will start when the
  // login state changes to LOGGED_IN_ACTIVE.
  void EnsureStarted();

  // Checks if the TPM token is enabled. If the state is unknown, |callback|
  // will be called back once the TPM state is known.
  TPMTokenStatus IsTPMTokenEnabled(const TPMReadyCallback& callback);

  std::string tpm_user_pin() const { return tpm_user_pin_; }

 private:
  explicit TPMTokenLoader(bool for_test);
  ~TPMTokenLoader() override;

  bool IsTPMLoadingEnabled() const;

  // Starts tpm token initialization if the user is logged in and the crypto
  // task runner is set.
  void MaybeStartTokenInitialization();

  // This is the cyclic chain of callbacks to initialize the TPM token.
  void ContinueTokenInitialization();
  void OnTPMTokenEnabledForNSS();
  void OnGotTpmTokenInfo(const TPMTokenInfo& token_info);
  void OnTPMTokenInitialized(bool success);

  // Notifies observers that the TPM token is ready.
  void NotifyTPMTokenReady();

  // LoginState::Observer
  void LoggedInStateChanged() override;

  bool initialized_for_test_;

  TPMReadyCallbackList tpm_ready_callback_list_;

  // The states are traversed in this order but some might get omitted or never
  // be left.
  enum TPMTokenState {
    TPM_STATE_UNKNOWN,
    TPM_INITIALIZATION_STARTED,
    TPM_TOKEN_ENABLED_FOR_NSS,
    TPM_DISABLED,
    TPM_TOKEN_INFO_RECEIVED,
    TPM_TOKEN_INITIALIZED,
  };
  TPMTokenState tpm_token_state_;

  scoped_ptr<TPMTokenInfoGetter> tpm_token_info_getter_;

  // Cached TPM token info.
  int tpm_token_slot_id_;
  std::string tpm_user_pin_;

  // Whether TPM system token loading may be started before user log in.
  // This will be true iff |EnsureStarted| was called.
  bool can_start_before_login_;

  base::ThreadChecker thread_checker_;

  // TaskRunner for crypto calls.
  scoped_refptr<base::SequencedTaskRunner> crypto_task_runner_;

  base::WeakPtrFactory<TPMTokenLoader> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(TPMTokenLoader);
};

}  // namespace chromeos

#endif  // CHROMEOS_TPM_TPM_TOKEN_LOADER_H_