1 // Copyright 2014 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_TPM_TOKEN_LOADER_H_ 6 #define CHROMEOS_TPM_TOKEN_LOADER_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/weak_ptr.h" 13 #include "base/observer_list.h" 14 #include "base/threading/thread_checker.h" 15 #include "base/time/time.h" 16 #include "chromeos/chromeos_export.h" 17 #include "chromeos/dbus/dbus_method_call_status.h" 18 #include "chromeos/login/login_state.h" 19 20 namespace base { 21 class SequencedTaskRunner; 22 } 23 24 namespace chromeos { 25 26 // This class is responsible for loading the TPM backed token for the system 27 // slot when the user logs in. It is expected to be constructed on the UI thread 28 // and public methods should all be called from the UI thread. 29 // When the TPM token is loaded, or if the TPM should stay disabled for the 30 // session, the observers are notified using |OnTPMTokenReady|. 31 // Note: This currently initializes the token with the hard coded default id 0. 32 // See CryptohomeClient::OnPkcs11GetTpmTokenInfo. 33 class CHROMEOS_EXPORT TPMTokenLoader : public LoginState::Observer { 34 public: 35 enum TPMTokenStatus { 36 TPM_TOKEN_STATUS_UNDETERMINED, 37 TPM_TOKEN_STATUS_ENABLED, 38 TPM_TOKEN_STATUS_DISABLED 39 }; 40 41 typedef base::Callback<void(bool)> TPMReadyCallback; 42 typedef std::vector<TPMReadyCallback> TPMReadyCallbackList; 43 44 // Sets the global instance. Must be called before any calls to Get(). 45 // The global instance will immediately start observing |LoginState|. 46 static void Initialize(); 47 48 // Sets the global. stubbed out, instance. To be used in tests. 49 static void InitializeForTest(); 50 51 // Destroys the global instance. 52 static void Shutdown(); 53 54 // Gets the global instance. Initialize() must be called before this. 55 static TPMTokenLoader* Get(); 56 57 // Returns true if the global instance has been initialized. 58 static bool IsInitialized(); 59 60 // |crypto_task_runner| is the task runner that any synchronous crypto calls 61 // should be made from, e.g. in Chrome this is the IO thread. Must be called 62 // after the thread is started. When called, this will attempt to start TPM 63 // token loading. 64 void SetCryptoTaskRunner( 65 const scoped_refptr<base::SequencedTaskRunner>& crypto_task_runner); 66 67 // Checks if the TPM token is enabled. If the state is unknown, |callback| 68 // will be called back once the TPM state is known. 69 TPMTokenStatus IsTPMTokenEnabled(const TPMReadyCallback& callback); 70 tpm_user_pin()71 std::string tpm_user_pin() const { return tpm_user_pin_; } 72 73 private: 74 explicit TPMTokenLoader(bool for_test); 75 virtual ~TPMTokenLoader(); 76 77 bool IsTPMLoadingEnabled() const; 78 79 // Starts tpm token initialization if the user is logged in and the crypto 80 // task runner is set. 81 void MaybeStartTokenInitialization(); 82 83 // This is the cyclic chain of callbacks to initialize the TPM token. 84 void ContinueTokenInitialization(); 85 void OnTPMTokenEnabledForNSS(); 86 void OnTpmIsEnabled(DBusMethodCallStatus call_status, 87 bool tpm_is_enabled); 88 void OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status, 89 bool is_tpm_token_ready); 90 void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status, 91 const std::string& token_name, 92 const std::string& user_pin, 93 int token_slot_id); 94 void OnTPMTokenInitialized(bool success); 95 96 // If token initialization step fails (e.g. if tpm token is not yet ready) 97 // schedules the initialization step retry attempt after a timeout. 98 void RetryTokenInitializationLater(); 99 100 // Notifies observers that the TPM token is ready. 101 void NotifyTPMTokenReady(); 102 103 // LoginState::Observer 104 virtual void LoggedInStateChanged() OVERRIDE; 105 106 bool initialized_for_test_; 107 108 TPMReadyCallbackList tpm_ready_callback_list_; 109 110 // The states are traversed in this order but some might get omitted or never 111 // be left. 112 enum TPMTokenState { 113 TPM_STATE_UNKNOWN, 114 TPM_INITIALIZATION_STARTED, 115 TPM_TOKEN_ENABLED_FOR_NSS, 116 TPM_DISABLED, 117 TPM_ENABLED, 118 TPM_TOKEN_READY, 119 TPM_TOKEN_INFO_RECEIVED, 120 TPM_TOKEN_INITIALIZED, 121 }; 122 TPMTokenState tpm_token_state_; 123 124 // The current request delay before the next attempt to initialize the 125 // TPM. Will be adapted after each attempt. 126 base::TimeDelta tpm_request_delay_; 127 128 // Cached TPM token info. 129 int tpm_token_slot_id_; 130 std::string tpm_user_pin_; 131 132 base::ThreadChecker thread_checker_; 133 134 // TaskRunner for crypto calls. 135 scoped_refptr<base::SequencedTaskRunner> crypto_task_runner_; 136 137 base::WeakPtrFactory<TPMTokenLoader> weak_factory_; 138 139 DISALLOW_COPY_AND_ASSIGN(TPMTokenLoader); 140 }; 141 142 } // namespace chromeos 143 144 #endif // CHROMEOS_TPM_TOKEN_LOADER_H_ 145