// 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 #include #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 TPMReadyCallback; typedef std::vector 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& 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 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 crypto_task_runner_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(TPMTokenLoader); }; } // namespace chromeos #endif // CHROMEOS_TPM_TPM_TOKEN_LOADER_H_