#include "device/fido/fido_device_authenticator.h"
#include <algorithm>
#include <numeric>
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/ranges/algorithm.h"
#include "base/task/sequenced_task_runner.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/cbor/values.h"
#include "device/fido/appid_exclude_probe_task.h"
#include "device/fido/authenticator_get_assertion_response.h"
#include "device/fido/authenticator_supported_options.h"
#include "device/fido/credential_management.h"
#include "device/fido/ctap2_device_operation.h"
#include "device/fido/ctap_authenticator_selection_request.h"
#include "device/fido/ctap_get_assertion_request.h"
#include "device/fido/ctap_make_credential_request.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_device.h"
#include "device/fido/fido_parsing_utils.h"
#include "device/fido/fido_transport_protocol.h"
#include "device/fido/fido_types.h"
#include "device/fido/get_assertion_task.h"
#include "device/fido/large_blob.h"
#include "device/fido/make_credential_task.h"
#include "device/fido/pin.h"
#include "device/fido/u2f_command_constructor.h"
namespace device {
ClientPinAvailability;
UserVerificationAvailability;
namespace {
BioEnrollmentRequest::Version GetBioEnrollmentRequestVersion(
const AuthenticatorSupportedOptions& options) { … }
CredentialManagementRequest::Version GetCredentialManagementRequestVersion(
const AuthenticatorSupportedOptions& options) { … }
GetAssertionStatus ConvertDeviceResponseCodeToGetAssertionStatus(
CtapDeviceResponseCode device_response_code) { … }
MakeCredentialStatus ConvertDeviceResponseCodeToMakeCredentialStatus(
CtapDeviceResponseCode device_response_code) { … }
}
FidoDeviceAuthenticator::FidoDeviceAuthenticator(
std::unique_ptr<FidoDevice> device)
: … { … }
FidoDeviceAuthenticator::~FidoDeviceAuthenticator() = default;
void FidoDeviceAuthenticator::InitializeAuthenticator(
base::OnceClosure callback) { … }
void FidoDeviceAuthenticator::InitializeAuthenticatorDone(
base::OnceClosure callback) { … }
void FidoDeviceAuthenticator::ExcludeAppIdCredentialsBeforeMakeCredential(
CtapMakeCredentialRequest request,
MakeCredentialOptions options,
base::OnceCallback<void(CtapDeviceResponseCode, std::optional<bool>)>
callback) { … }
void FidoDeviceAuthenticator::MakeCredential(
CtapMakeCredentialRequest request,
MakeCredentialOptions request_options,
MakeCredentialCallback callback) { … }
void FidoDeviceAuthenticator::MakeCredentialInternal(
CtapMakeCredentialRequest request,
MakeCredentialOptions request_options,
CtapMakeCredentialCallback callback) { … }
void FidoDeviceAuthenticator::GetAssertion(CtapGetAssertionRequest request,
CtapGetAssertionOptions options,
GetAssertionCallback callback) { … }
void FidoDeviceAuthenticator::OnHaveCompressedLargeBlobForGetAssertion(
CtapGetAssertionRequest request,
CtapGetAssertionOptions options,
CtapGetAssertionCallback callback,
size_t original_size,
base::expected<mojo_base::BigBuffer, std::string> result) { … }
void FidoDeviceAuthenticator::MaybeGetEphemeralKeyForGetAssertion(
CtapGetAssertionRequest request,
CtapGetAssertionOptions options,
CtapGetAssertionCallback callback) { … }
void FidoDeviceAuthenticator::OnHaveEphemeralKeyForGetAssertion(
CtapGetAssertionRequest request,
CtapGetAssertionOptions options,
CtapGetAssertionCallback callback,
CtapDeviceResponseCode status,
std::optional<pin::KeyAgreementResponse> key) { … }
void FidoDeviceAuthenticator::DoGetAssertion(
CtapGetAssertionRequest request,
CtapGetAssertionOptions options,
CtapGetAssertionCallback callback) { … }
void FidoDeviceAuthenticator::OnHaveAssertion(
CtapGetAssertionRequest request,
CtapGetAssertionOptions options,
CtapGetAssertionCallback callback,
CtapDeviceResponseCode status,
std::vector<AuthenticatorGetAssertionResponse> responses) { … }
void FidoDeviceAuthenticator::PerformGetAssertionLargeBlobOperation(
CtapGetAssertionRequest request,
CtapGetAssertionOptions options,
std::vector<AuthenticatorGetAssertionResponse> responses,
CtapGetAssertionCallback callback) { … }
void FidoDeviceAuthenticator::GetTouch(base::OnceClosure callback) { … }
void FidoDeviceAuthenticator::GetPinRetries(GetRetriesCallback callback) { … }
void FidoDeviceAuthenticator::GetEphemeralKey(
GetEphemeralKeyCallback callback) { … }
void FidoDeviceAuthenticator::GetPINToken(
std::string pin,
std::vector<pin::Permissions> permissions,
std::optional<std::string> rp_id,
GetTokenCallback callback) { … }
void FidoDeviceAuthenticator::OnHaveEphemeralKeyForGetPINToken(
std::string pin,
std::vector<pin::Permissions> permissions,
std::optional<std::string> rp_id,
GetTokenCallback callback,
CtapDeviceResponseCode status,
std::optional<pin::KeyAgreementResponse> key) { … }
void FidoDeviceAuthenticator::SetPIN(const std::string& pin,
SetPINCallback callback) { … }
void FidoDeviceAuthenticator::OnHaveEphemeralKeyForSetPIN(
std::string pin,
SetPINCallback callback,
CtapDeviceResponseCode status,
std::optional<pin::KeyAgreementResponse> key) { … }
void FidoDeviceAuthenticator::ChangePIN(const std::string& old_pin,
const std::string& new_pin,
SetPINCallback callback) { … }
void FidoDeviceAuthenticator::OnHaveEphemeralKeyForChangePIN(
std::string old_pin,
std::string new_pin,
SetPINCallback callback,
CtapDeviceResponseCode status,
std::optional<pin::KeyAgreementResponse> key) { … }
FidoAuthenticator::PINUVDisposition
FidoDeviceAuthenticator::PINUVDispositionForMakeCredential(
const CtapMakeCredentialRequest& request,
const FidoRequestHandlerBase::Observer* observer) { … }
FidoAuthenticator::PINUVDisposition
FidoDeviceAuthenticator::PINUVDispositionForGetAssertion(
const CtapGetAssertionRequest& request,
const FidoRequestHandlerBase::Observer* observer) { … }
void FidoDeviceAuthenticator::GetCredentialsMetadata(
const pin::TokenResponse& pin_token,
GetCredentialsMetadataCallback callback) { … }
struct FidoDeviceAuthenticator::EnumerateCredentialsState { … };
void FidoDeviceAuthenticator::EnumerateCredentials(
const pin::TokenResponse& pin_token,
EnumerateCredentialsCallback callback) { … }
template <typename... Args>
void FidoDeviceAuthenticator::TaskClearProxy(
base::OnceCallback<void(Args...)> callback,
Args... args) { … }
template <typename... Args>
void FidoDeviceAuthenticator::OperationClearProxy(
base::OnceCallback<void(Args...)> callback,
Args... args) { … }
template <typename Task, typename Response, typename... RequestArgs>
void FidoDeviceAuthenticator::RunTask(
RequestArgs&&... request_args,
base::OnceCallback<void(CtapDeviceResponseCode, Response)> callback) { … }
template <typename Request, typename Response>
void FidoDeviceAuthenticator::RunOperation(
Request request,
base::OnceCallback<void(CtapDeviceResponseCode, std::optional<Response>)>
callback,
base::OnceCallback<
std::optional<Response>(const std::optional<cbor::Value>&)> parser,
bool (*string_fixup_predicate)(const std::vector<const cbor::Value*>&)) { … }
void FidoDeviceAuthenticator::OnEnumerateRPsDone(
EnumerateCredentialsState state,
CtapDeviceResponseCode status,
std::optional<EnumerateRPsResponse> response) { … }
void FidoDeviceAuthenticator::OnEnumerateCredentialsDone(
EnumerateCredentialsState state,
CtapDeviceResponseCode status,
std::optional<EnumerateCredentialsResponse> response) { … }
void FidoDeviceAuthenticator::DeleteCredential(
const pin::TokenResponse& pin_token,
const PublicKeyCredentialDescriptor& credential_id,
DeleteCredentialCallback callback) { … }
bool FidoDeviceAuthenticator::SupportsUpdateUserInformation() const { … }
void FidoDeviceAuthenticator::UpdateUserInformation(
const pin::TokenResponse& pin_token,
const PublicKeyCredentialDescriptor& credential_id,
const PublicKeyCredentialUserEntity& updated_user,
UpdateUserInformationCallback callback) { … }
void FidoDeviceAuthenticator::GetModality(BioEnrollmentCallback callback) { … }
void FidoDeviceAuthenticator::GetSensorInfo(BioEnrollmentCallback callback) { … }
void FidoDeviceAuthenticator::BioEnrollFingerprint(
const pin::TokenResponse& pin_token,
std::optional<std::vector<uint8_t>> template_id,
BioEnrollmentCallback callback) { … }
void FidoDeviceAuthenticator::BioEnrollRename(
const pin::TokenResponse& pin_token,
std::vector<uint8_t> id,
std::string name,
BioEnrollmentCallback callback) { … }
void FidoDeviceAuthenticator::BioEnrollDelete(
const pin::TokenResponse& pin_token,
std::vector<uint8_t> template_id,
BioEnrollmentCallback callback) { … }
void FidoDeviceAuthenticator::BioEnrollCancel(BioEnrollmentCallback callback) { … }
void FidoDeviceAuthenticator::BioEnrollEnumerate(
const pin::TokenResponse& pin_token,
BioEnrollmentCallback callback) { … }
void FidoDeviceAuthenticator::OnWroteLargeBlobForGetAssertion(
std::vector<AuthenticatorGetAssertionResponse> responses,
CtapGetAssertionCallback callback,
CtapDeviceResponseCode status) { … }
void FidoDeviceAuthenticator::OnReadLargeBlobForGetAssertion(
std::vector<AuthenticatorGetAssertionResponse> responses,
CtapGetAssertionCallback callback,
CtapDeviceResponseCode status,
std::optional<std::vector<std::pair<LargeBlobKey, LargeBlob>>> blobs) { … }
void FidoDeviceAuthenticator::OnBlobUncompressed(
std::vector<AuthenticatorGetAssertionResponse> responses,
std::vector<std::pair<LargeBlobKey, LargeBlob>> blobs,
LargeBlobKey uncompressed_key,
CtapGetAssertionCallback callback,
base::expected<mojo_base::BigBuffer, std::string> result) { … }
void FidoDeviceAuthenticator::OnLargeBlobExtensionUncompressed(
std::vector<AuthenticatorGetAssertionResponse> responses,
CtapGetAssertionCallback callback,
base::expected<mojo_base::BigBuffer, std::string> result) { … }
void FidoDeviceAuthenticator::ReadLargeBlob(
const std::vector<LargeBlobKey>& large_blob_keys,
LargeBlobReadCallback callback) { … }
void FidoDeviceAuthenticator::GarbageCollectLargeBlob(
const pin::TokenResponse& pin_uv_auth_token,
base::OnceCallback<void(CtapDeviceResponseCode)> callback) { … }
void FidoDeviceAuthenticator::FetchLargeBlobArray(
LargeBlobArrayReader large_blob_array_reader,
base::OnceCallback<void(CtapDeviceResponseCode,
std::optional<LargeBlobArrayReader>)> callback) { … }
void FidoDeviceAuthenticator::OnReadLargeBlobFragment(
const size_t bytes_requested,
LargeBlobArrayReader large_blob_array_reader,
base::OnceCallback<void(CtapDeviceResponseCode,
std::optional<LargeBlobArrayReader>)> callback,
CtapDeviceResponseCode status,
std::optional<LargeBlobsResponse> response) { … }
void FidoDeviceAuthenticator::OnHaveLargeBlobArrayForWrite(
const LargeBlobKey& large_blob_key,
const std::optional<pin::TokenResponse> pin_uv_auth_token,
base::OnceCallback<void(CtapDeviceResponseCode)> callback,
CtapDeviceResponseCode status,
std::optional<LargeBlobArrayReader> large_blob_array_reader) { … }
void FidoDeviceAuthenticator::WriteLargeBlobArray(
const std::optional<pin::TokenResponse> pin_uv_auth_token,
LargeBlobArrayWriter large_blob_array_writer,
base::OnceCallback<void(CtapDeviceResponseCode)> callback) { … }
void FidoDeviceAuthenticator::OnWriteLargeBlobFragment(
LargeBlobArrayWriter large_blob_array_writer,
const std::optional<pin::TokenResponse> pin_uv_auth_token,
base::OnceCallback<void(CtapDeviceResponseCode)> callback,
CtapDeviceResponseCode status,
std::optional<LargeBlobsResponse> response) { … }
void FidoDeviceAuthenticator::OnHaveLargeBlobArrayForRead(
const std::vector<LargeBlobKey>& large_blob_keys,
LargeBlobReadCallback callback,
CtapDeviceResponseCode status,
std::optional<LargeBlobArrayReader> large_blob_array_reader) { … }
void FidoDeviceAuthenticator::OnCredentialsEnumeratedForGarbageCollect(
const pin::TokenResponse& pin_uv_auth_token,
base::OnceCallback<void(CtapDeviceResponseCode)> callback,
CtapDeviceResponseCode status,
std::optional<std::vector<AggregatedEnumerateCredentialsResponse>>
credentials) { … }
void FidoDeviceAuthenticator::OnHaveLargeBlobArrayForGarbageCollect(
std::vector<AggregatedEnumerateCredentialsResponse> credentials,
const pin::TokenResponse& pin_uv_auth_token,
base::OnceCallback<void(CtapDeviceResponseCode)> callback,
CtapDeviceResponseCode status,
std::optional<LargeBlobArrayReader> large_blob_array_reader) { … }
void FidoDeviceAuthenticator::OnGetAssertionResponse(
GetAssertionCallback callback,
CtapDeviceResponseCode status,
std::vector<AuthenticatorGetAssertionResponse> responses) { … }
void FidoDeviceAuthenticator::OnMakeCredentialResponse(
MakeCredentialCallback callback,
CtapDeviceResponseCode status,
std::optional<AuthenticatorMakeCredentialResponse> response) { … }
std::optional<base::span<const int32_t>>
FidoDeviceAuthenticator::GetAlgorithms() { … }
bool FidoDeviceAuthenticator::DiscoverableCredentialStorageFull() const { … }
void FidoDeviceAuthenticator::Reset(ResetCallback callback) { … }
void FidoDeviceAuthenticator::Cancel() { … }
AuthenticatorType FidoDeviceAuthenticator::GetType() const { … }
cablev2::FidoTunnelDevice* FidoDeviceAuthenticator::GetTunnelDevice() { … }
std::string FidoDeviceAuthenticator::GetId() const { … }
std::string FidoDeviceAuthenticator::GetDisplayName() const { … }
ProtocolVersion FidoDeviceAuthenticator::SupportedProtocol() const { … }
const AuthenticatorSupportedOptions& FidoDeviceAuthenticator::Options() const { … }
std::optional<FidoTransportProtocol>
FidoDeviceAuthenticator::AuthenticatorTransport() const { … }
void FidoDeviceAuthenticator::SetTaskForTesting(
std::unique_ptr<FidoTask> task) { … }
void FidoDeviceAuthenticator::GetUvRetries(GetRetriesCallback callback) { … }
bool FidoDeviceAuthenticator::CanGetUvToken() { … }
void FidoDeviceAuthenticator::GetUvToken(
std::vector<pin::Permissions> permissions,
std::optional<std::string> rp_id,
GetTokenCallback callback) { … }
uint32_t FidoDeviceAuthenticator::CurrentMinPINLength() { … }
uint32_t FidoDeviceAuthenticator::NewMinPINLength() { … }
bool FidoDeviceAuthenticator::ForcePINChange() { … }
void FidoDeviceAuthenticator::OnHaveEphemeralKeyForUvToken(
std::optional<std::string> rp_id,
std::vector<pin::Permissions> permissions,
GetTokenCallback callback,
CtapDeviceResponseCode status,
std::optional<pin::KeyAgreementResponse> key) { … }
size_t FidoDeviceAuthenticator::max_large_blob_fragment_length() { … }
base::WeakPtr<FidoAuthenticator> FidoDeviceAuthenticator::GetWeakPtr() { … }
}