| // Copyright 2020 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CRYPTOHOME_AUTH_SESSION_H_ |
| #define CRYPTOHOME_AUTH_SESSION_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <optional> |
| #include <set> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include <base/containers/flat_set.h> |
| #include <base/containers/span.h> |
| #include <base/functional/callback_forward.h> |
| #include <base/functional/callback.h> |
| #include <base/memory/weak_ptr.h> |
| #include <base/timer/wall_clock_timer.h> |
| #include <base/unguessable_token.h> |
| #include <brillo/secure_blob.h> |
| #include <cryptohome/proto_bindings/rpc.pb.h> |
| #include <cryptohome/proto_bindings/UserDataAuth.pb.h> |
| #include <cryptohome/proto_bindings/auth_factor.pb.h> |
| #include <libhwsec/structures/explicit_init.h> |
| #include <libhwsec-foundation/status/status_chain_or.h> |
| |
| #include "cryptohome/auth_blocks/auth_block_utility.h" |
| #include "cryptohome/auth_blocks/prepare_token.h" |
| #include "cryptohome/auth_factor/auth_factor.h" |
| #include "cryptohome/auth_factor/auth_factor_manager.h" |
| #include "cryptohome/auth_factor/auth_factor_map.h" |
| #include "cryptohome/auth_factor/auth_factor_metadata.h" |
| #include "cryptohome/auth_factor/auth_factor_storage_type.h" |
| #include "cryptohome/auth_factor/auth_factor_type.h" |
| #include "cryptohome/auth_factor/types/manager.h" |
| #include "cryptohome/auth_factor_vault_keyset_converter.h" |
| #include "cryptohome/auth_intent.h" |
| #include "cryptohome/credential_verifier.h" |
| #include "cryptohome/crypto.h" |
| #include "cryptohome/error/cryptohome_crypto_error.h" |
| #include "cryptohome/error/cryptohome_error.h" |
| #include "cryptohome/error/cryptohome_mount_error.h" |
| #include "cryptohome/features.h" |
| #include "cryptohome/key_objects.h" |
| #include "cryptohome/keyset_management.h" |
| #include "cryptohome/platform.h" |
| #include "cryptohome/storage/file_system_keyset.h" |
| #include "cryptohome/user_secret_stash/storage.h" |
| #include "cryptohome/user_secret_stash/user_metadata.h" |
| #include "cryptohome/user_secret_stash/user_secret_stash.h" |
| #include "cryptohome/user_session/user_session_map.h" |
| #include "cryptohome/username.h" |
| |
| namespace cryptohome { |
| |
| using AuthFactorStatusUpdateCallback = base::RepeatingCallback<void( |
| user_data_auth::AuthFactorWithStatus, const std::string&)>; |
| |
| // The list of all intents satisfied when the auth session is "fully |
| // authenticated". Useful for places that want to set the "fully authenticated" |
| // state. |
| constexpr AuthIntent kAuthorizedIntentsForFullAuth[] = { |
| AuthIntent::kDecrypt, AuthIntent::kVerifyOnly}; |
| |
| // This class starts a session for the user to authenticate with their |
| // credentials. |
| class AuthSession final { |
| public: |
| using StatusCallback = base::OnceCallback<void(CryptohomeStatus)>; |
| |
| // Parameter struct used to specify all the base parameters of AuthSession. |
| // These parameters do not include the underlying interfaces that AuthSession |
| // depends on, which are defined below in a separate parameter struct. |
| struct Params { |
| hwsec::ExplicitInit<Username> username; |
| hwsec::ExplicitInit<bool> is_ephemeral_user; |
| hwsec::ExplicitInit<AuthIntent> intent; |
| std::unique_ptr<base::WallClockTimer> auth_factor_status_update_timer; |
| hwsec::ExplicitInit<bool> user_exists; |
| AuthFactorMap auth_factor_map; |
| }; |
| |
| // Parameter struct used to supply all of the backing APIs that AuthSession |
| // depends on. All of these pointers must be valid for the entire lifetime of |
| // the AuthSession object. |
| struct BackingApis { |
| Crypto* crypto = nullptr; |
| Platform* platform = nullptr; |
| UserSessionMap* user_session_map = nullptr; |
| KeysetManagement* keyset_management = nullptr; |
| AuthBlockUtility* auth_block_utility = nullptr; |
| AuthFactorDriverManager* auth_factor_driver_manager = nullptr; |
| AuthFactorManager* auth_factor_manager = nullptr; |
| UserSecretStashStorage* user_secret_stash_storage = nullptr; |
| UserMetadataReader* user_metadata_reader = nullptr; |
| AsyncInitFeatures* features = nullptr; |
| }; |
| |
| // Creates new auth session for account_id. This method returns a unique_ptr |
| // to the created AuthSession for the auth_session_manager to hold. |
| static std::unique_ptr<AuthSession> Create(Username username, |
| unsigned int flags, |
| AuthIntent intent, |
| BackingApis backing_apis); |
| |
| // Construct an AuthSession initialized with all of the given state. This |
| // should generally only be used directly in testing; production code should |
| // prefer to call the Create factory function. |
| AuthSession(Params params, BackingApis backing_apis); |
| |
| ~AuthSession(); |
| |
| // Returns the full unhashed user name. |
| const Username& username() const { return username_; } |
| // Returns the obfuscated (sanitized) user name. |
| const ObfuscatedUsername& obfuscated_username() const { |
| return obfuscated_username_; |
| } |
| |
| AuthIntent auth_intent() const { return auth_intent_; } |
| |
| // Returns the token which is used to identify the current AuthSession. |
| const base::UnguessableToken& token() const { return token_; } |
| const std::string& serialized_token() const { return serialized_token_; } |
| |
| // Returns the token which is used as the secondary identifier for the |
| // session. This is not used to identify the session internally in cryptohome |
| // but it is used in external APIs where the session needs to be identified |
| // without providing the ability to act on the session. |
| const base::UnguessableToken& public_token() const { return public_token_; } |
| const std::string& serialized_public_token() const { |
| return serialized_public_token_; |
| } |
| |
| // Returns the intents that the AuthSession has been authorized for. |
| const base::flat_set<AuthIntent>& authorized_intents() const { |
| return authorized_intents_; |
| } |
| |
| // Returns the file system keyset used to access the filesystem. This is set |
| // when the session gets into an authenticated state and so the caller must |
| // ensure that the AuthSession has been authenticated before accessing this. |
| const FileSystemKeyset& file_system_keyset() const; |
| |
| // This function returns if the user existed when the auth session started. |
| bool user_exists() const { return user_exists_; } |
| |
| // This function returns if the AuthSession is being setup for an ephemeral |
| // user. |
| bool ephemeral_user() const { return is_ephemeral_user_; } |
| |
| // Returns the key data with which this AuthSession is authenticated with. |
| const KeyData& current_key_data() const { return key_data_; } |
| |
| // Returns the map from the label to the auth factor. |
| const AuthFactorMap& auth_factor_map() const { return auth_factor_map_; } |
| |
| // Indicates if the session has a User Secret Stash enabled. |
| bool has_user_secret_stash() const { |
| return user_secret_stash_ && user_secret_stash_main_key_; |
| } |
| |
| // Indicates if the session has migration to User Secret Stash enabled. |
| bool has_migrate_to_user_secret_stash() const { |
| return has_user_secret_stash(); |
| } |
| |
| // Indicates if there is a reset_secret in session's User Secret Stash for |
| // the given label. |
| inline bool HasResetSecretInUssForTesting(const std::string& label) const { |
| return user_secret_stash_ && |
| user_secret_stash_->GetResetSecretForLabel(label).has_value(); |
| } |
| |
| // OnUserCreated is called when the user and their homedir are newly created. |
| // Must be called no more than once. |
| CryptohomeStatus OnUserCreated(); |
| |
| // AddAuthFactor is called when newly created or existing user wants to add |
| // new AuthFactor. |
| void AddAuthFactor(const user_data_auth::AddAuthFactorRequest& request, |
| StatusCallback on_done); |
| |
| // Whether the AuthenticateAuthFactor request should be forced to perform full |
| // auth. |
| enum class ForceFullAuthFlag : bool { |
| kNone = false, |
| kForce = true, |
| }; |
| |
| // Flags to adjust behavior of the AuthenticateAuthFactor request. |
| struct AuthenticateAuthFactorFlags { |
| ForceFullAuthFlag force_full_auth; |
| }; |
| |
| // Packs necessary input parameters of AuthenticateAuthFactor request into a |
| // struct. |
| struct AuthenticateAuthFactorRequest { |
| std::vector<std::string> auth_factor_labels; |
| user_data_auth::AuthInput auth_input_proto; |
| AuthenticateAuthFactorFlags flags; |
| }; |
| |
| // Action that needs to be performed after an AuthenticateAuthFactor request |
| // is completed. |
| enum class PostAuthActionType { |
| kNone, |
| // Repeat the request with |repeat_request|. This will be used to reset the |
| // credential lockouts. |
| kRepeat, |
| }; |
| struct PostAuthAction { |
| PostAuthActionType action_type; |
| std::optional<AuthenticateAuthFactorRequest> repeat_request; |
| }; |
| |
| using AuthenticateAuthFactorCallback = |
| base::OnceCallback<void(const PostAuthAction&, CryptohomeStatus)>; |
| |
| // Authenticate is called when the user wants to authenticate the current |
| // AuthSession via an auth factor. It may be called multiple times depending |
| // on errors or various steps involved in multi-factor authentication. |
| // Note: only USS users are supported currently. |
| void AuthenticateAuthFactor(const AuthenticateAuthFactorRequest& request, |
| AuthenticateAuthFactorCallback callback); |
| |
| // RemoveAuthFactor is called when the user wants to remove auth factor |
| // provided in the `request`. |
| void RemoveAuthFactor(const user_data_auth::RemoveAuthFactorRequest& request, |
| StatusCallback on_done); |
| |
| // PrepareUserForRemoval is called to perform the necessary steps before |
| // removing a user, like preparing each auth factor for removal. |
| void PrepareUserForRemoval(); |
| |
| // UpdateAuthFactor is called when the user wants to update auth factor |
| // provided in the `request`. |
| void UpdateAuthFactor(const user_data_auth::UpdateAuthFactorRequest& request, |
| StatusCallback on_done); |
| |
| // UpdateAuthFactorMetadata updates the auth factor without new credentials. |
| void UpdateAuthFactorMetadata( |
| const user_data_auth::UpdateAuthFactorMetadataRequest request, |
| StatusCallback on_done); |
| |
| // PrepareAuthFactor prepares an auth factor, e.g. fingerprint auth factor |
| // which is not directly associated with a knowledge factor. |
| void PrepareAuthFactor( |
| const user_data_auth::PrepareAuthFactorRequest& request, |
| StatusCallback on_done); |
| |
| // TerminatesAuthFactor stops an async auth factor, e.g. fingerprint auth |
| // factor. |
| void TerminateAuthFactor( |
| const user_data_auth::TerminateAuthFactorRequest& request, |
| StatusCallback on_done); |
| |
| // Generates a payload that will be sent to the server for cryptohome recovery |
| // AuthFactor authentication. GetRecoveryRequest saves data in the |
| // AuthSession state. This call is required before the AuthenticateAuthFactor |
| // call for cryptohome recovery AuthFactor. |
| void GetRecoveryRequest( |
| user_data_auth::GetRecoveryRequestRequest request, |
| base::OnceCallback<void(const user_data_auth::GetRecoveryRequestReply&)> |
| on_done); |
| |
| // OnMigrationUssCreated is the callback function to be called after |
| // migration secret is generated and added to UserSecretStash during the |
| // AuthenticateViaVaultKeysetAndMigrateToUss() operation. |
| void OnMigrationUssCreated(AuthBlockType auth_block_type, |
| AuthFactorType auth_factor_type, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const AuthInput& auth_input, |
| CryptohomeStatus pre_migration_status, |
| StatusCallback on_done, |
| std::unique_ptr<UserSecretStash> user_secret_stash, |
| brillo::SecureBlob uss_main_key); |
| |
| // OnMigrationUssCreatedForUpdate is the callback function to be called after |
| // migration secret is generated and added to UserSecretStash during the |
| // MigrateToUssDuringUpdateVaultKeyset() operation. |
| void OnMigrationUssCreatedForUpdate( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const AuthInput& auth_input, |
| StatusCallback on_done, |
| CryptohomeStatus callback_error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_state, |
| std::unique_ptr<UserSecretStash> user_secret_stash, |
| brillo::SecureBlob uss_main_key); |
| |
| // Sets |vault_keyset_| for testing purpose. |
| void set_vault_keyset_for_testing(std::unique_ptr<VaultKeyset> value) { |
| vault_keyset_ = std::move(value); |
| } |
| |
| // Static function which returns a serialized token in a vector format. The |
| // token is serialized into two uint64_t values which are stored in string of |
| // size 16 bytes. The first 8 bytes represent the high value of the serialized |
| // token, the next 8 represent the low value of the serialized token. |
| static std::optional<std::string> GetSerializedStringFromToken( |
| const base::UnguessableToken& token); |
| |
| // Static function which returns UnguessableToken object after deconstructing |
| // the string formed in GetSerializedStringFromToken. |
| static std::optional<base::UnguessableToken> GetTokenFromSerializedString( |
| const std::string& serialized_token); |
| |
| // Get the hibernate secret, derived from the file system keyset. |
| std::unique_ptr<brillo::SecureBlob> GetHibernateSecret(); |
| |
| // Add a callback to call when the AuthSession is authenticated. This callback |
| // is triggered immediately if the session is already authenticated. |
| void AddOnAuthCallback(base::OnceClosure on_auth); |
| |
| // Send the auth factor status update signal and also set the timer for the |
| // next signal based on |kAuthFactorStatusUpdateDelay|. |
| void SendAuthFactorStatusUpdateSignal(); |
| |
| // Set the auth factor status update callback. |
| void SetAuthFactorStatusUpdateCallback( |
| const AuthFactorStatusUpdateCallback& callback); |
| |
| private: |
| // Emits a debug log message with this Auth Session's initial state. |
| void RecordAuthSessionStart() const; |
| |
| // Switches the state to authorize the specified intents. Starts or restarts |
| // the timer when applicable. |
| void SetAuthorizedForIntents( |
| base::span<const AuthIntent> new_authorized_intents); |
| |
| // Sets the auth session as fully authenticated by the given factor type. What |
| // specific intents the session is authorized for depends on the factor type. |
| void SetAuthorizedForFullAuthIntents(AuthFactorType auth_factor_type); |
| |
| // Converts the D-Bus AuthInput proto into the C++ struct. Returns nullopt on |
| // failure. |
| CryptohomeStatusOr<AuthInput> CreateAuthInputForAuthentication( |
| const user_data_auth::AuthInput& auth_input_proto, |
| const AuthFactorMetadata& auth_factor_metadata); |
| // Same as above, but additionally sets extra fields for resettable factors. |
| // Can also be supplied with an already constructed AuthInput instead of the |
| // raw proto, for cases where you need to construct both and don't want to |
| // redo the same work. |
| CryptohomeStatusOr<AuthInput> CreateAuthInputForAdding( |
| const user_data_auth::AuthInput& auth_input_proto, |
| AuthFactorType auth_factor_type, |
| const AuthFactorMetadata& auth_factor_metadata); |
| CryptohomeStatusOr<AuthInput> CreateAuthInputForAdding( |
| AuthInput auth_input, |
| AuthFactorType auth_factor_type, |
| const AuthFactorMetadata& auth_factor_metadata); |
| |
| // Creates AuthInput for migration from an AuthInput by adding `reset_secret` |
| // if needed. If this is called during the AuthenticateAuthFactor, after the |
| // successful authentication of the PIN factor, reset secret is obtained |
| // directly from the decrypted PIN VaultKeyset. If this is called during the |
| // UpdateAuthFactor, when AuthSession has a decrypted password VaultKesyet |
| // available, |reset_secret| is derived from the |reset_seed| on the |
| // password VaultKeyset. In each case a new backend pinweaver node is created. |
| CryptohomeStatusOr<AuthInput> CreateAuthInputForMigration( |
| const AuthInput& auth_input, AuthFactorType auth_factor_type); |
| |
| // Creates AuthInput for selecting the correct auth factor to be used for |
| // authentication. As in this case the auth factor hasn't been decided yet, |
| // the AuthInput will typically be simpler than Add and Authenticate cases, |
| // and derivable from solely the |auth_factor_type|. |
| CryptohomeStatusOr<AuthInput> CreateAuthInputForSelectFactor( |
| AuthFactorType auth_factor_type); |
| |
| // Initializes a ChallengeCredentialAuthInput, i.e. |
| // {.public_key_spki_der, .challenge_signature_algorithms} from |
| // the challenge_response_key values in in authorization |
| std::optional<ChallengeCredentialAuthInput> |
| CreateChallengeCredentialAuthInput(const AuthorizationRequest& authorization); |
| |
| // This function attempts to add verifier for the given label based on the |
| // AuthInput. If it succeeds it will return a pointer to the verifier. |
| // Otherwise it will return null. |
| CredentialVerifier* AddCredentialVerifier( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthInput& auth_input); |
| |
| // Helper function to update a keyset on disk on KeyBlobs generated. If update |
| // succeeds |vault_keyset_| is also updated. Failure doesn't return error and |
| // doesn't block authentication operations. |
| void ResaveKeysetOnKeyBlobsGenerated( |
| VaultKeyset updated_vault_keyset, |
| CryptohomeStatus error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_block_state); |
| |
| // Adds VaultKeyset for the |obfuscated_username_| by calling |
| // KeysetManagement::AddInitialKeyset() or KeysetManagement::AddKeyset() |
| // based on |is_initial_keyset|. |
| CryptohomeStatus AddVaultKeyset(const std::string& key_label, |
| const KeyData& key_data, |
| bool is_initial_keyset, |
| VaultKeysetIntent vk_backup_intent, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_state); |
| |
| // Creates and persist VaultKeyset for the |obfuscated_username_|. This |
| // function is needed for processing callback results in an asynchronous |
| // manner through |on_done| callback. |
| void CreateAndPersistVaultKeyset(const KeyData& key_data, |
| AuthInput auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done, |
| CryptohomeStatus callback_error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_state); |
| |
| // Updates the secret of an AuthFactor backed by a VaultKeyset and migrates it |
| // to UserSecretStash. Failures during this operation fails to both update and |
| // migrate the factor. |
| void MigrateToUssDuringUpdateVaultKeyset( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const KeyData& key_data, |
| const AuthInput& auth_input, |
| StatusCallback on_done, |
| CryptohomeStatus callback_error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_state); |
| |
| // Persists key blocks for a new secret to the USS and onto disk. Upon |
| // completion the |on_done| callback will be called. Designed to be used in |
| // conjunction with an async CreateKeyBlobs call by binding all of the |
| // initial parameters to make an AuthBlock::CreateCallback. |
| void PersistAuthFactorToUserSecretStash( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const AuthInput& auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done, |
| CryptohomeStatus callback_error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_block_state); |
| |
| // Persists from a migrated VaultKeyset AuthFactor and USS key block. Upon |
| // completion the |on_done| callback will be called with the pre-migration |
| // state. |
| void PersistAuthFactorToUserSecretStashOnMigration( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const AuthInput& auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done, |
| CryptohomeStatus pre_migration_status, |
| CryptohomeStatus callback_error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_block_state); |
| |
| // The implementation function to persists an AuthFactor and a USS key |
| // block for a new secret. |
| CryptohomeStatus PersistAuthFactorToUserSecretStashImpl( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const AuthInput& auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| OverwriteExistingKeyBlock clobber_uss_key_block, |
| CryptohomeStatus callback_error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_block_state); |
| |
| // Migrates the reset secret for a PIN factor from VaultKeysets to |
| // UserSecretStash by calculating it from |reset_seed| of the authenticated |
| // VaultKeyset and the |reset_salt| of the Pinweaver VaultKeysets and adding |
| // to USS in memory. |
| bool MigrateResetSecretToUss(); |
| |
| // Adds reset secret to USS for not-migrated keysets and persist to disk. |
| bool PersistResetSecretToUss(); |
| |
| // Process the completion of a verify-only authentication attempt. The |
| // |on_done| callback will be called after the results of the verification are |
| // processed. This takes |auth_factor_type| parameter because it needs to |
| // determine whether the factor can be used for resetting credentials. |
| // Designed to be used in conjunction with CredentialVerifier::Verify as the |
| // CryptohomeStatusCallback. |
| void CompleteVerifyOnlyAuthentication( |
| AuthenticateAuthFactorCallback on_done, |
| AuthenticateAuthFactorRequest original_request, |
| AuthFactorType auth_factor_type, |
| CryptohomeStatus error); |
| |
| // Add the new factor into the USS in-memory. |
| CryptohomeStatus AddAuthFactorToUssInMemory( |
| AuthFactor& auth_factor, |
| const KeyBlobs& key_blobs, |
| OverwriteExistingKeyBlock override); |
| |
| // Returns the callback function to add and AuthFactor for the right key store |
| // type. |
| AuthBlock::CreateCallback GetAddAuthFactorCallback( |
| const AuthFactorType& auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const KeyData& key_data, |
| const AuthInput& auth_input, |
| const AuthFactorStorageType auth_factor_storage_type, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done); |
| |
| // Returns the callback function to update and AuthFactor for the right key |
| // store type. |
| AuthBlock::CreateCallback GetUpdateAuthFactorCallback( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const KeyData& key_data, |
| const AuthInput& auth_input, |
| const AuthFactorStorageType auth_factor_storage_type, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done); |
| |
| // Adds a credential verifier for the ephemeral user session. |
| void AddAuthFactorForEphemeral(AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthInput& auth_input, |
| StatusCallback on_done); |
| |
| // Loads and decrypts the USS payload with |auth_factor_label| using the |
| // given KeyBlobs. Designed to be used in conjunction with an async |
| // DeriveKeyBlobs call by binding all of the initial parameters to make an |
| // AuthBlock::DeriveCallback. |
| void LoadUSSMainKeyAndFsKeyset( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthInput& auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done, |
| CryptohomeStatus callback_error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::optional<AuthBlock::SuggestedAction> suggested_action); |
| |
| // This function is used after a load to re-create an auth factor. It is |
| // generally used after a post-authenticate load, when the key derivation |
| // suggests that the factor needs to be recreated. |
| void RecreateUssAuthFactor(AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| AuthInput auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| CryptohomeStatus original_status, |
| StatusCallback on_done); |
| |
| // This function is used to reset the attempt count for a low entropy |
| // credential. Currently, this resets all low entropy credentials both stored |
| // in USS and VK. In the USSv2 world, with passwords or even other auth types |
| // backed by PinWeaver, the code will need to reset specific LE credentials. |
| void ResetLECredentials(); |
| |
| // This function is used to reset the attempt count and expiration (depending |
| // on |capability|) for rate-limiters. Normally credentials guarded by |
| // rate-limiters will never be locked, but we still check them to see if |
| // they're accidentally locked. In that case, the reset secret is the same as |
| // the rate-limiter's. |
| void ResetRateLimiterCredentials( |
| AuthFactorDriver::ResetCapability capability); |
| |
| // Whether there are some credentials that can be reset after a full auth. |
| bool NeedsFullAuthForReset(AuthFactorDriver::ResetCapability capability); |
| |
| // Authenticate the user with the single given auth factor. Additional |
| // parameters are provided to aid legacy vault keyset authentication and |
| // migration. |
| void AuthenticateViaSingleFactor( |
| const AuthFactorType& request_auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthInput& auth_input, |
| const AuthFactorMetadata& metadata, |
| const AuthFactorMap::ValueView& stored_auth_factor, |
| StatusCallback on_done); |
| |
| // Authenticates the user using USS with the |auth_factor_label|, |auth_input| |
| // and the |auth_factor|. |
| void AuthenticateViaUserSecretStash( |
| const std::string& auth_factor_label, |
| const AuthInput auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| const AuthFactor& auth_factor, |
| StatusCallback on_done); |
| |
| // Authenticates the user using VaultKeysets with the given |auth_input|. |
| void AuthenticateViaVaultKeysetAndMigrateToUss( |
| AuthFactorType request_auth_factor_type, |
| const std::string& key_label, |
| const AuthInput& auth_input, |
| const AuthFactorMetadata& metadata, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done); |
| |
| // Authenticates the user using the selected |auth_factor|. Used when the |
| // auth factor type takes multiple labels during authentication, and used as |
| // the callback for AuthBlockUtility::SelectAuthFactorWithAuthBlock. |
| void AuthenticateViaSelectedAuthFactor( |
| StatusCallback on_done, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| CryptohomeStatus callback_error, |
| std::optional<AuthInput> auth_input, |
| std::optional<AuthFactor> auth_factor); |
| |
| // Fetches a valid VaultKeyset for |obfuscated_username_| that matches the |
| // label provided by key_data_.label(). The VaultKeyset is loaded and |
| // initialized into |vault_keyset_| through |
| // KeysetManagement::GetValidKeyset(). This function is needed for |
| // processing callback results in an asynchronous manner through the |on_done| |
| // callback. |
| void LoadVaultKeysetAndFsKeys( |
| AuthFactorType request_auth_factor_type, |
| const AuthInput& auth_input, |
| AuthBlockType auth_block_type, |
| const AuthFactorMetadata& metadata, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done, |
| CryptohomeStatus error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::optional<AuthBlock::SuggestedAction> suggested_action); |
| |
| // Updates, wraps and resaves |vault_keyset_| and restores on failure. |
| // |user_input| is needed to generate the AuthInput used for key blob creation |
| // to wrap the updated keyset. |
| AuthBlockType ResaveVaultKeysetIfNeeded( |
| const std::optional<brillo::SecureBlob> user_input, |
| AuthBlockType auth_block_type); |
| |
| // Removes the key block with the provided `auth_factor_label` from the USS |
| // and removes the `auth_factor` from disk. |
| void RemoveAuthFactorViaUserSecretStash(const std::string& auth_factor_label, |
| const AuthFactor& auth_factor, |
| StatusCallback on_done); |
| |
| // Removes the auth factor from the in-memory map, the existing keyset and |
| // verifier indexed by the `auth_factor_label`. |
| void ClearAuthFactorInMemoryObjects( |
| const std::string& auth_factor_label, |
| const AuthFactorMap::ValueView& stored_auth_factor, |
| const base::TimeTicks& remove_timer_start, |
| StatusCallback on_done, |
| CryptohomeStatus status); |
| |
| // Re-persists the USS and removes in memory objects related to the |
| // removed auth factor. |
| void ResaveUssWithFactorRemoved(const std::string& auth_factor_label, |
| const AuthFactor& auth_factor, |
| StatusCallback on_done, |
| CryptohomeStatus status); |
| |
| // Remove the factor from the USS in-memory. |
| CryptohomeStatus RemoveAuthFactorFromUssInMemory( |
| const std::string& auth_factor_label); |
| |
| // Creates a new per-credential secret, updates the secret in the USS and |
| // updates the auth block state on disk. |
| void UpdateAuthFactorViaUserSecretStash( |
| AuthFactorType auth_factor_type, |
| const std::string& auth_factor_label, |
| const AuthFactorMetadata& auth_factor_metadata, |
| const AuthInput& auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| StatusCallback on_done, |
| CryptohomeStatus callback_error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_block_state); |
| |
| // Persists the updated USS and |
| // re-creates the related credential verifier if applicable. |
| void ResaveUssWithFactorUpdated(AuthFactorType auth_factor_type, |
| std::unique_ptr<AuthFactor> auth_factor, |
| const AuthInput& auth_input, |
| std::unique_ptr<AuthSessionPerformanceTimer> |
| auth_session_performance_timer, |
| const brillo::Blob& encrypted_uss_container, |
| StatusCallback on_done, |
| CryptohomeStatus status); |
| |
| // Handles the completion of an async PrepareAuthFactor call. Captures the |
| // token and forwards the result to the given status callback. |
| void OnPrepareAuthFactorDone( |
| StatusCallback on_done, |
| CryptohomeStatusOr<std::unique_ptr<PreparedAuthFactorToken>> token); |
| |
| // Prepares the WebAuthn secret using file_system_keyset. |
| CryptohomeStatus PrepareWebAuthnSecret(); |
| |
| // RemoveRateLimiters remove all rate-limiter leaves in the UserMetadata. This |
| // doesn't leave the USS with a consistent state, and should only be called |
| // during PrepareUserForRemoval. |
| void RemoveRateLimiters(); |
| |
| Username username_; |
| ObfuscatedUsername obfuscated_username_; |
| |
| // AuthSession's flag configuration. |
| const bool is_ephemeral_user_; |
| const AuthIntent auth_intent_; |
| |
| // The intents which this session is currently authorized for. |
| base::flat_set<AuthIntent> authorized_intents_; |
| |
| // The wall clock timer object to send AuthFactor status update periodically. |
| std::unique_ptr<base::WallClockTimer> auth_factor_status_update_timer_; |
| |
| base::TimeTicks auth_session_creation_time_; |
| base::TimeTicks authenticated_time_; |
| |
| // Callbacks to be triggered when authentication occurs. |
| std::vector<base::OnceClosure> on_auth_; |
| // The repeating callback to send AuthFactorStatusUpdateSignal. |
| AuthFactorStatusUpdateCallback auth_factor_status_update_callback_; |
| |
| std::unique_ptr<AuthFactor> auth_factor_; |
| // The decrypted UserSecretStash. Only populated for users who have it (legacy |
| // users who only have vault keysets will have this field equal to null). |
| std::unique_ptr<UserSecretStash> user_secret_stash_; |
| // The UserSecretStash main key. Only populated iff |user_secret_stash_| is. |
| std::optional<brillo::SecureBlob> user_secret_stash_main_key_; |
| Crypto* const crypto_; |
| Platform* const platform_; |
| // The user session map and a verifier forwarder associated with it. |
| UserSessionMap* const user_session_map_; |
| UserSessionMap::VerifierForwarder verifier_forwarder_; |
| // TODO(crbug.com/1171024): Change KeysetManagement to use AuthBlock. |
| KeysetManagement* const keyset_management_; |
| AuthBlockUtility* const auth_block_utility_; |
| AuthFactorDriverManager* const auth_factor_driver_manager_; |
| AuthFactorManager* const auth_factor_manager_; |
| UserSecretStashStorage* const user_secret_stash_storage_; |
| UserMetadataReader* const user_metadata_reader_; |
| // Unowned pointer. |
| AsyncInitFeatures* const features_; |
| // A stateless object to convert AuthFactor API to VaultKeyset KeyData and |
| // VaultKeysets to AuthFactor API. |
| AuthFactorVaultKeysetConverter converter_; |
| |
| // Tokens (and their serialized forms) used to identify the session. |
| const base::UnguessableToken token_; |
| const std::string serialized_token_; |
| const base::UnguessableToken public_token_; |
| const std::string serialized_public_token_; |
| |
| // Used to decrypt/ encrypt & store credentials. |
| std::unique_ptr<VaultKeyset> vault_keyset_; |
| // Used to store key meta data. |
| KeyData key_data_; |
| // FileSystemKeyset is needed by cryptohome to mount a user. |
| std::optional<FileSystemKeyset> file_system_keyset_; |
| // Whether the user existed at the time this object was constructed. |
| bool user_exists_; |
| // Map containing the auth factors already configured for this user. |
| AuthFactorMap auth_factor_map_; |
| // Key used by AuthenticateAuthFactor for cryptohome recovery AuthFactor. |
| // It's set only after GetRecoveryRequest() call, and is std::nullopt in other |
| // cases. |
| std::optional<brillo::SecureBlob> cryptohome_recovery_ephemeral_pub_key_; |
| // Tokens from active auth factors, keyed off of the token's auth factor type. |
| std::map<AuthFactorType, std::unique_ptr<PreparedAuthFactorToken>> |
| active_auth_factor_tokens_; |
| |
| // Should be the last member. |
| base::WeakPtrFactory<AuthSession> weak_factory_{this}; |
| }; |
| |
| } // namespace cryptohome |
| |
| #endif // CRYPTOHOME_AUTH_SESSION_H_ |