| // 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_TOKEN_LOADER_H_ |
| #define CHROMEOS_TPM_TOKEN_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 "base/time/time.h" |
| #include "chromeos/chromeos_export.h" |
| #include "chromeos/dbus/dbus_method_call_status.h" |
| #include "chromeos/login/login_state.h" |
| |
| namespace base { |
| class SequencedTaskRunner; |
| } |
| |
| namespace chromeos { |
| |
| // This class is responsible for loading the TPM token 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|. |
| class CHROMEOS_EXPORT TPMTokenLoader : public LoginState::Observer { |
| public: |
| class Observer { |
| public: |
| // Called when the TPM token initialization is done or the case where TPM |
| // should stay disabled is detected (e.g. on guest login). |
| virtual void OnTPMTokenReady() = 0; |
| |
| protected: |
| virtual ~Observer() {} |
| }; |
| |
| // 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); |
| |
| void AddObserver(TPMTokenLoader::Observer* observer); |
| void RemoveObserver(TPMTokenLoader::Observer* observer); |
| |
| // Checks if the TPM token in ready to be used. |
| bool IsTPMTokenReady() const; |
| |
| std::string tpm_user_pin() const { return tpm_user_pin_; } |
| |
| private: |
| explicit TPMTokenLoader(bool for_test); |
| virtual ~TPMTokenLoader(); |
| |
| // 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 OnPersistentNSSDBOpened(); |
| void OnTpmIsEnabled(DBusMethodCallStatus call_status, |
| bool tpm_is_enabled); |
| void OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status, |
| bool is_tpm_token_ready); |
| void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status, |
| const std::string& token_name, |
| const std::string& user_pin, |
| int token_slot_id); |
| void OnTPMTokenInitialized(bool success); |
| |
| // If token initialization step fails (e.g. if tpm token is not yet ready) |
| // schedules the initialization step retry attempt after a timeout. |
| void RetryTokenInitializationLater(); |
| |
| // Notifies observers that the TPM token is ready. |
| void NotifyTPMTokenReady(); |
| |
| // LoginState::Observer |
| virtual void LoggedInStateChanged() OVERRIDE; |
| |
| bool initialized_for_test_; |
| |
| ObserverList<Observer> observers_; |
| |
| // 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_DB_OPENED, |
| TPM_DISABLED, |
| TPM_ENABLED, |
| TPM_TOKEN_READY, |
| TPM_TOKEN_INFO_RECEIVED, |
| TPM_TOKEN_INITIALIZED, |
| }; |
| TPMTokenState tpm_token_state_; |
| |
| // The current request delay before the next attempt to initialize the |
| // TPM. Will be adapted after each attempt. |
| base::TimeDelta tpm_request_delay_; |
| |
| // Cached TPM token info. |
| std::string tpm_token_name_; |
| int tpm_token_slot_id_; |
| std::string tpm_user_pin_; |
| |
| 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_TOKEN_LOADER_H_ |