blob: 58d6555715b7ee02581a7dbaec85afbfad788e0e [file]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_INTERFACE_H_
#define CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_INTERFACE_H_
#include "base/functional/callback_forward.h"
#include "base/observer_list.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/trusted_vault/trusted_vault_connection.h"
class EnclaveManager;
class GaiaId;
class EnclaveManagerInterface : public KeyedService {
public:
// Many actions report results using a `Callback`. The boolean argument
// is true if the operation is successful and false otherwise.
// These callbacks never hairpin. (I.e. are never called before the function
// that they were passed to returns.)
using Callback = base::OnceCallback<void(bool)>;
// LINT.IfChange(GpmPinAvailability)
//
// An enum that expresses whether a GPM PIN is set on an account.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class GpmPinAvailability {
// The PIN is set but not usable (there are 0 remaining attempts for
// entering the pin).
kGpmPinSetButNotUsable = 0,
// The PIN is set and usable (there are > 0 remaining attempts for entering
// the pin).
kGpmPinSetAndUsable = 1,
// The PIN is unset.
kGpmPinUnset = 2,
kMaxValue = kGpmPinUnset,
};
// LINT.ThenChange(//tools/metrics/histograms/metadata/webauthn/enums.xml:GpmPinAvailability)
using GpmPinAvailabilityCallback =
base::OnceCallback<void(GpmPinAvailability)>;
// An enum that expresses the outcome of the operation of storing the
// opportunistically retrieved keys.
enum class OutOfContextRecoveryOutcome {
// The key has been successfully stored and the device has been added to
// account.
kStoreKeysFromOpportunisticFlowSucceeded,
// There was a failure while adding the device to account.
kStoreKeysFromOpportunisticFlowFailed,
// The key has been ignored because the device has been already registered
// with the enclave.
kStoreKeysFromOpportunisticFlowIgnoredRedundant,
};
class Observer : public base::CheckedObserver {
public:
// `OnKeysStored` is called when MagicArch provides keys to the
// EnclaveManager by calling `StoreKeys`. `gaia_id` is the account
// identifier for the keys that were stored. Clients should verify this
// matches the account they expect.
virtual void OnKeysStored(const GaiaId& gaia_id) {}
// `OnStateUpdated` is called from `EnclaveManager::Stopped()` - indicating
// that the state machine reached its final state (so the state of the
// enclave manager might be updated now, e.g. it might become ready).
virtual void OnStateUpdated() {}
// `OnOutOfContextRecoveryCompletion` informs observers about the outcome of
// the operation of storing the opportunistically retrieved keys.
virtual void OnOutOfContextRecoveryCompletion(
OutOfContextRecoveryOutcome outcome) {}
};
EnclaveManagerInterface() = default;
EnclaveManagerInterface(const EnclaveManagerInterface&) = delete;
EnclaveManagerInterface& operator=(const EnclaveManagerInterface&) = delete;
~EnclaveManagerInterface() override = default;
// Return the full `EnclaveManager` interface. This will crash the address
// space if run on an `EnclaveManagerInterface` instance that is not backed
// by a real `EnclaveManager`, i.e. when it's a mock.
virtual EnclaveManager* GetEnclaveManager();
// Returns true if the current user has been registered with the enclave.
virtual bool IsRegistered() const = 0;
// Returns true if the persistent state has been loaded from the disk. (Or
// else the loading failed and an empty state is being used.)
virtual bool IsLoaded() const = 0;
// Returns true if the current user has joined the security domain and has one
// or more wrapped security domain secrets available. (This implies
// `IsRegistered`.)
virtual bool IsReady() const = 0;
// Send a request to the enclave to delete the registration for the current
// user, erase local keys, and erase local state for the user. Safe to call in
// any state and is a no-op if no registration exists.
virtual void Unenroll(Callback callback) = 0;
// Asynchronously checks if the current user has a GPM PIN. The caller must
// keep the returned Request object alive until the callback is run.
// Destroying the Request object will cancel the operation.
[[nodiscard]] virtual std::unique_ptr<
trusted_vault::TrustedVaultConnection::Request>
CheckGpmPinAvailability(GpmPinAvailabilityCallback callback) = 0;
virtual void LoadAfterDelay(base::TimeDelta delay,
base::OnceClosure closure) = 0;
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
};
#endif // CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_INTERFACE_H_