123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- // Copyright 2018 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 DEVICE_FIDO_FIDO_AUTHENTICATOR_H_
- #define DEVICE_FIDO_FIDO_AUTHENTICATOR_H_
- #include <cstdint>
- #include <string>
- #include "base/callback_forward.h"
- #include "base/component_export.h"
- #include "base/containers/span.h"
- #include "base/memory/weak_ptr.h"
- #include "build/build_config.h"
- #include "build/chromeos_buildflags.h"
- #include "device/fido/authenticator_get_assertion_response.h"
- #include "device/fido/authenticator_make_credential_response.h"
- #include "device/fido/authenticator_supported_options.h"
- #include "device/fido/bio/enrollment.h"
- #include "device/fido/credential_management.h"
- #include "device/fido/discoverable_credential_metadata.h"
- #include "device/fido/fido_constants.h"
- #include "device/fido/fido_request_handler_base.h"
- #include "device/fido/fido_transport_protocol.h"
- #include "device/fido/large_blob.h"
- #include "device/fido/make_credential_request_handler.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace device {
- struct CtapGetAssertionRequest;
- struct CtapGetAssertionOptions;
- struct CtapMakeCredentialRequest;
- struct MakeCredentialOptions;
- namespace pin {
- struct RetriesResponse;
- struct EmptyResponse;
- class TokenResponse;
- } // namespace pin
- // FidoAuthenticator is an authenticator from the WebAuthn Authenticator model
- // (https://www.w3.org/TR/webauthn/#sctn-authenticator-model). It may be a
- // physical device, or a built-in (platform) authenticator.
- class COMPONENT_EXPORT(DEVICE_FIDO) FidoAuthenticator {
- public:
- using MakeCredentialCallback = base::OnceCallback<void(
- CtapDeviceResponseCode,
- absl::optional<AuthenticatorMakeCredentialResponse>)>;
- using GetAssertionCallback = base::OnceCallback<void(
- CtapDeviceResponseCode,
- absl::optional<AuthenticatorGetAssertionResponse>)>;
- using GetCredentialInformationForRequestCallback = base::OnceCallback<void(
- std::vector<DiscoverableCredentialMetadata> credentials,
- bool has_credentials)>;
- using GetRetriesCallback =
- base::OnceCallback<void(CtapDeviceResponseCode,
- absl::optional<pin::RetriesResponse>)>;
- using GetTokenCallback =
- base::OnceCallback<void(CtapDeviceResponseCode,
- absl::optional<pin::TokenResponse>)>;
- using SetPINCallback =
- base::OnceCallback<void(CtapDeviceResponseCode,
- absl::optional<pin::EmptyResponse>)>;
- using ResetCallback =
- base::OnceCallback<void(CtapDeviceResponseCode,
- absl::optional<pin::EmptyResponse>)>;
- using GetCredentialsMetadataCallback =
- base::OnceCallback<void(CtapDeviceResponseCode,
- absl::optional<CredentialsMetadataResponse>)>;
- using EnumerateCredentialsCallback = base::OnceCallback<void(
- CtapDeviceResponseCode,
- absl::optional<std::vector<AggregatedEnumerateCredentialsResponse>>)>;
- using DeleteCredentialCallback =
- base::OnceCallback<void(CtapDeviceResponseCode,
- absl::optional<DeleteCredentialResponse>)>;
- using UpdateUserInformationCallback =
- base::OnceCallback<void(CtapDeviceResponseCode,
- absl::optional<UpdateUserInformationResponse>)>;
- using BioEnrollmentCallback =
- base::OnceCallback<void(CtapDeviceResponseCode,
- absl::optional<BioEnrollmentResponse>)>;
- using LargeBlobReadCallback = base::OnceCallback<void(
- CtapDeviceResponseCode,
- absl::optional<std::vector<std::pair<LargeBlobKey, LargeBlob>>>
- callback)>;
- FidoAuthenticator() = default;
- FidoAuthenticator(const FidoAuthenticator&) = delete;
- FidoAuthenticator& operator=(const FidoAuthenticator&) = delete;
- virtual ~FidoAuthenticator() = default;
- // Sends GetInfo request to connected authenticator. Once response to GetInfo
- // call is received, |callback| is invoked. Below MakeCredential() and
- // GetAssertion() must only called after |callback| is invoked.
- virtual void InitializeAuthenticator(base::OnceClosure callback) = 0;
- // ExcludeAppIdCredentialsBeforeMakeCredential allows a device to probe for
- // credential IDs from a request that used the appidExclude extension. This
- // assumes that |MakeCredential| will be called afterwards with the same
- // request. I.e. this function may do nothing if it believes that it can
- // better handle the exclusion during |MakeCredential|.
- //
- // The optional bool is an unused response value as all the information is
- // contained in the response code, which will be |kCtap2ErrCredentialExcluded|
- // if an excluded credential is found. (An optional<void> is an error.)
- virtual void ExcludeAppIdCredentialsBeforeMakeCredential(
- CtapMakeCredentialRequest request,
- MakeCredentialOptions options,
- base::OnceCallback<void(CtapDeviceResponseCode, absl::optional<bool>)>);
- virtual void MakeCredential(CtapMakeCredentialRequest request,
- MakeCredentialOptions options,
- MakeCredentialCallback callback) = 0;
- virtual void GetAssertion(CtapGetAssertionRequest request,
- CtapGetAssertionOptions options,
- GetAssertionCallback callback) = 0;
- // GetNextAssertion fetches the next assertion from a device that indicated in
- // the response to |GetAssertion| that multiple results were available.
- virtual void GetNextAssertion(GetAssertionCallback callback);
- // GetCredentialInformationForRequest returns a boolean indicating whether
- // there are credentials applicable for |request|, and if supported, a list of
- // the corresponding resident credential metadata for empty allow list
- // requests.
- virtual void GetCredentialInformationForRequest(
- const CtapGetAssertionRequest& request,
- GetCredentialInformationForRequestCallback callback);
- // GetTouch causes an (external) authenticator to flash and wait for a touch.
- virtual void GetTouch(base::OnceCallback<void()> callback);
- // GetPinRetries gets the number of PIN attempts remaining before an
- // authenticator locks. It is only valid to call this method if |Options|
- // indicates that the authenticator supports PINs.
- virtual void GetPinRetries(GetRetriesCallback callback);
- // GetUvRetries gets the number of internal user verification attempts before
- // internal user verification locks. It is only valid to call this method if
- // |Options| indicates that the authenticator supports user verification.
- virtual void GetUvRetries(GetRetriesCallback callback);
- // GetPINToken uses the given PIN to request a PinUvAuthToken from an
- // authenticator. It is only valid to call this method if |Options| indicates
- // that the authenticator supports PINs.
- // |permissions| are flags indicating which commands the token may be used
- // for.
- // |rp_id| binds the token to operations related to a given RP ID. |rp_id|
- // must be set if |permissions| includes MakeCredential or GetAssertion.
- virtual void GetPINToken(std::string pin,
- std::vector<pin::Permissions> permissions,
- absl::optional<std::string> rp_id,
- GetTokenCallback callback);
- // Returns |true| if the authenticator supports GetUvToken.
- virtual bool CanGetUvToken();
- // GetUvToken uses internal user verification to request a PinUvAuthToken from
- // an authenticator. It is only valid to call this method if CanGetUvToken()
- // returns true.
- // |rp_id| must be set if the PinUvAuthToken will be used for MakeCredential
- // or GetAssertion.
- virtual void GetUvToken(std::vector<pin::Permissions> permissions,
- absl::optional<std::string> rp_id,
- GetTokenCallback callback);
- // Returns the minimum PIN length for this authenticator's currently set PIN.
- virtual uint32_t CurrentMinPINLength();
- // Returns the minimum PIN length required to set a new PIN for this
- // authenticator.
- virtual uint32_t NewMinPINLength();
- // Returns |true| if the PIN must be changed before attempting to obtain a PIN
- // token.
- virtual bool ForcePINChange();
- // SetPIN sets a new PIN on a device that does not currently have one. The
- // length of |pin| must respect |pin::kMinLength| and |pin::kMaxLength|. It is
- // only valid to call this method if |Options| indicates that the
- // authenticator supports PINs.
- virtual void SetPIN(const std::string& pin, SetPINCallback callback);
- // ChangePIN alters the PIN on a device that already has a PIN set. The
- // length of |pin| must respect |pin::kMinLength| and |pin::kMaxLength|. It is
- // only valid to call this method if |Options| indicates that the
- // authenticator supports PINs.
- virtual void ChangePIN(const std::string& old_pin,
- const std::string& new_pin,
- SetPINCallback callback);
- // PINUVDisposition enumerates the possible options for obtaining user
- // verification when making a CTAP2 request.
- enum class PINUVDisposition {
- // No UV (neither clientPIN nor internal) is needed to make this
- // credential.
- kNoUV,
- // A PIN/UV Auth Token should be used to make this credential. The token
- // needs to be obtained via clientPIN or internal UV, depending on which
- // modality the device supports. The modality may need to be set up first.
- kGetToken,
- // The request should be sent with the `uv` bit set to true, in order to
- // perform internal user verification without a PIN/UV Auth Token.
- kNoTokenInternalUV,
- // Same as kNoTokenInternalUV, but a PIN can be used as a fallback. (A PIN
- // may have to be set first.)
- kNoTokenInternalUVPINFallback,
- // The request cannot be satisfied by this authenticator.
- kUnsatisfiable,
- };
- // PINUVDisposition returns whether and how user verification
- // should be obtained in order to serve the given request on this
- // authenticator.
- virtual PINUVDisposition PINUVDispositionForMakeCredential(
- const CtapMakeCredentialRequest& request,
- const FidoRequestHandlerBase::Observer* observer);
- // WillNeedPINToGetAssertion returns whether a PIN prompt will be needed to
- // serve the given request on this authenticator.
- virtual PINUVDisposition PINUVDispositionForGetAssertion(
- const CtapGetAssertionRequest& request,
- const FidoRequestHandlerBase::Observer* observer);
- virtual void GetCredentialsMetadata(const pin::TokenResponse& pin_token,
- GetCredentialsMetadataCallback callback);
- virtual void EnumerateCredentials(const pin::TokenResponse& pin_token,
- EnumerateCredentialsCallback callback);
- virtual void DeleteCredential(
- const pin::TokenResponse& pin_token,
- const PublicKeyCredentialDescriptor& credential_id,
- DeleteCredentialCallback callback);
- virtual bool SupportsUpdateUserInformation() const;
- virtual void UpdateUserInformation(
- const pin::TokenResponse& pin_token,
- const PublicKeyCredentialDescriptor& credential_id,
- const PublicKeyCredentialUserEntity& updated_user,
- UpdateUserInformationCallback callback);
- // Biometric enrollment commands.
- virtual void GetModality(BioEnrollmentCallback callback);
- virtual void GetSensorInfo(BioEnrollmentCallback callback);
- virtual void BioEnrollFingerprint(
- const pin::TokenResponse&,
- absl::optional<std::vector<uint8_t>> template_id,
- BioEnrollmentCallback);
- virtual void BioEnrollCancel(BioEnrollmentCallback);
- virtual void BioEnrollEnumerate(const pin::TokenResponse&,
- BioEnrollmentCallback);
- virtual void BioEnrollRename(const pin::TokenResponse&,
- std::vector<uint8_t> template_id,
- std::string name,
- BioEnrollmentCallback);
- virtual void BioEnrollDelete(const pin::TokenResponse&,
- std::vector<uint8_t> template_id,
- BioEnrollmentCallback);
- // Large blob commands.
- // Attempts to write a |large_blob| into the credential. If there is an
- // existing credential for the |large_blob_key|, it will be overwritten.
- virtual void WriteLargeBlob(
- LargeBlob large_blob,
- const LargeBlobKey& large_blob_key,
- absl::optional<pin::TokenResponse> pin_uv_auth_token,
- base::OnceCallback<void(CtapDeviceResponseCode)> callback);
- // Attempts to read large blobs from the credential encrypted with
- // |large_blob_keys|. Returns a map of keys to their blobs.
- virtual void ReadLargeBlob(
- const std::vector<LargeBlobKey>& large_blob_keys,
- absl::optional<pin::TokenResponse> pin_uv_auth_token,
- LargeBlobReadCallback callback);
- // GetAlgorithms returns the list of supported COSEAlgorithmIdentifiers, or
- // |nullopt| if this is unknown and thus all requests should be tried in case
- // they work.
- virtual absl::optional<base::span<const int32_t>> GetAlgorithms();
- // DiscoverableCredentialStorageFull returns true if creation of a
- // discoverable credential is likely to fail because authenticator storage is
- // exhausted. Even if this method returns false, credential creation may still
- // fail with `CTAP2_ERR_KEY_STORE_FULL` on some authenticators.
- virtual bool DiscoverableCredentialStorageFull() const;
- // Reset triggers a reset operation on the authenticator. This erases all
- // stored resident keys and any configured PIN.
- virtual void Reset(ResetCallback callback);
- virtual void Cancel() = 0;
- enum class Type {
- kWinNative, // i.e. webauthn.dll
- kTouchID, // the Chrome-native Touch ID integration on macOS
- kChromeOS, // the platform authenticator on Chrome OS
- kOther,
- };
- // GetType returns the type of the authenticator.
- virtual Type GetType() const;
- // GetId returns a unique string representing this device. This string should
- // be distinct from all other devices concurrently discovered.
- virtual std::string GetId() const = 0;
- // GetDisplayName returns a string identifying a device to a human, which
- // might not be unique. For example, |GetDisplayName| could return the VID:PID
- // of a HID device, but |GetId| could not because two devices can share the
- // same VID:PID. It defaults to returning the value of |GetId|.
- virtual std::string GetDisplayName() const;
- virtual ProtocolVersion SupportedProtocol() const;
- virtual bool SupportsCredProtectExtension() const;
- virtual bool SupportsHMACSecretExtension() const;
- virtual bool SupportsEnterpriseAttestation() const;
- virtual bool SupportsCredBlobOfSize(size_t num_bytes) const;
- virtual const absl::optional<AuthenticatorSupportedOptions>& Options()
- const = 0;
- virtual absl::optional<FidoTransportProtocol> AuthenticatorTransport()
- const = 0;
- virtual bool IsInPairingMode() const = 0;
- virtual bool IsPaired() const = 0;
- virtual bool RequiresBlePairingPin() const = 0;
- virtual base::WeakPtr<FidoAuthenticator> GetWeakPtr() = 0;
- };
- } // namespace device
- #endif // DEVICE_FIDO_FIDO_AUTHENTICATOR_H_
|