123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- // 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_GET_ASSERTION_REQUEST_HANDLER_H_
- #define DEVICE_FIDO_GET_ASSERTION_REQUEST_HANDLER_H_
- #include <memory>
- #include <set>
- #include <string>
- #include <vector>
- #include "base/callback.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/weak_ptr.h"
- #include "device/fido/auth_token_requester.h"
- #include "device/fido/authenticator_get_assertion_response.h"
- #include "device/fido/ctap_get_assertion_request.h"
- #include "device/fido/fido_constants.h"
- #include "device/fido/fido_request_handler_base.h"
- #include "device/fido/fido_transport_protocol.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace base {
- class ElapsedTimer;
- }
- namespace device {
- class FidoAuthenticator;
- class FidoDiscoveryFactory;
- namespace pin {
- class TokenResponse;
- } // namespace pin
- enum class GetAssertionStatus {
- kSuccess,
- kAuthenticatorResponseInvalid,
- kUserConsentButCredentialNotRecognized,
- kUserConsentDenied,
- kAuthenticatorRemovedDuringPINEntry,
- kSoftPINBlock,
- kHardPINBlock,
- kAuthenticatorMissingResidentKeys,
- // TODO(agl): kAuthenticatorMissingUserVerification can
- // also be returned when the authenticator supports UV, but
- // there's no UI support for collecting a PIN. This could
- // be clearer.
- kAuthenticatorMissingUserVerification,
- kWinNotAllowedError,
- };
- class COMPONENT_EXPORT(DEVICE_FIDO) GetAssertionRequestHandler
- : public FidoRequestHandlerBase,
- public AuthTokenRequester::Delegate {
- public:
- using CompletionCallback = base::OnceCallback<void(
- GetAssertionStatus,
- absl::optional<std::vector<AuthenticatorGetAssertionResponse>>,
- const FidoAuthenticator*)>;
- GetAssertionRequestHandler(
- FidoDiscoveryFactory* fido_discovery_factory,
- const base::flat_set<FidoTransportProtocol>& supported_transports,
- CtapGetAssertionRequest request_parameter,
- CtapGetAssertionOptions request_options,
- bool allow_skipping_pin_touch,
- CompletionCallback completion_callback);
- GetAssertionRequestHandler(const GetAssertionRequestHandler&) = delete;
- GetAssertionRequestHandler& operator=(const GetAssertionRequestHandler&) =
- delete;
- ~GetAssertionRequestHandler() override;
- // Filters the allow list of the get assertion request to the given
- // |credential_id|. This is only valid to call for empty allow list requests.
- void PreselectAccount(std::vector<uint8_t> credential_id);
- base::WeakPtr<GetAssertionRequestHandler> GetWeakPtr();
- private:
- enum class State {
- kWaitingForTouch,
- kWaitingForToken,
- kWaitingForResponseWithToken,
- kReadingMultipleResponses,
- kFinished,
- };
- // FidoRequestHandlerBase:
- void OnBluetoothAdapterEnumerated(bool is_present,
- bool is_powered_on,
- bool can_power_on,
- bool is_peripheral_role_supported) override;
- void DispatchRequest(FidoAuthenticator* authenticator) override;
- void AuthenticatorRemoved(FidoDiscoveryBase* discovery,
- FidoAuthenticator* authenticator) override;
- void GetPlatformCredentialStatus(
- FidoAuthenticator* platform_authenticator) override;
- // AuthTokenRequester::Delegate:
- bool AuthenticatorSelectedForPINUVAuthToken(
- FidoAuthenticator* authenticator) override;
- void CollectPIN(pin::PINEntryReason reason,
- pin::PINEntryError error,
- uint32_t min_pin_length,
- int attempts,
- ProvidePINCallback provide_pin_cb) override;
- void PromptForInternalUVRetry(int attempts) override;
- void HavePINUVAuthTokenResultForAuthenticator(
- FidoAuthenticator* authenticator,
- AuthTokenRequester::Result result,
- absl::optional<pin::TokenResponse> response) override;
- void ObtainPINUVAuthToken(FidoAuthenticator* authenticator,
- std::set<pin::Permissions> permissions,
- bool skip_pin_touch,
- bool internal_uv_locked);
- void HandleResponse(
- FidoAuthenticator* authenticator,
- CtapGetAssertionRequest request,
- base::ElapsedTimer request_timer,
- CtapDeviceResponseCode response_code,
- absl::optional<AuthenticatorGetAssertionResponse> response);
- void HandleNextResponse(
- FidoAuthenticator* authenticator,
- CtapGetAssertionRequest request,
- CtapDeviceResponseCode response_code,
- absl::optional<AuthenticatorGetAssertionResponse> response);
- void TerminateUnsatisfiableRequestPostTouch(FidoAuthenticator* authenticator);
- void DispatchRequestWithToken(pin::TokenResponse token);
- void OnGetAssertionSuccess(FidoAuthenticator* authenticator,
- CtapGetAssertionRequest request);
- void OnReadLargeBlobs(
- FidoAuthenticator* authenticator,
- CtapDeviceResponseCode status,
- absl::optional<std::vector<std::pair<LargeBlobKey, LargeBlob>>> blobs);
- void OnWriteLargeBlob(FidoAuthenticator* authenticator,
- CtapDeviceResponseCode status);
- CompletionCallback completion_callback_;
- State state_ = State::kWaitingForTouch;
- CtapGetAssertionRequest request_;
- CtapGetAssertionOptions options_;
- absl::optional<pin::TokenResponse> pin_token_;
- // If true, and if at the time the request is dispatched to the first
- // authenticator no other authenticators are available, the request handler
- // will skip the initial touch that is usually required to select a PIN
- // protected authenticator.
- bool allow_skipping_pin_touch_;
- // selected_authenticator_for_pin_uv_auth_token_ points to the authenticator
- // that was tapped by the user while requesting a pinUvAuthToken from
- // connected authenticators. The object is owned by the underlying discovery
- // object and this pointer is cleared if it's removed during processing.
- raw_ptr<FidoAuthenticator> selected_authenticator_for_pin_uv_auth_token_ =
- nullptr;
- // responses_ holds the set of responses while they are incrementally read
- // from the device. Only used when more than one response is returned.
- std::vector<AuthenticatorGetAssertionResponse> responses_;
- // remaining_responses_ contains the number of responses that remain to be
- // read when multiple responses are returned.
- size_t remaining_responses_ = 0;
- // auth_token_requester_map_ holds active AuthTokenRequesters for
- // authenticators that need a pinUvAuthToken to service the request.
- std::map<FidoAuthenticator*, std::unique_ptr<AuthTokenRequester>>
- auth_token_requester_map_;
- // preselected_credential_ is set when the UI invokes `PreselectAccount()`. It
- // contains the ID of a platform authenticator credential chosen by the user
- // during a resident key request prior to dispatching to that platform
- // authenticator.
- absl::optional<std::vector<uint8_t>> preselected_credential_;
- SEQUENCE_CHECKER(my_sequence_checker_);
- base::WeakPtrFactory<GetAssertionRequestHandler> weak_factory_{this};
- };
- } // namespace device
- #endif // DEVICE_FIDO_GET_ASSERTION_REQUEST_HANDLER_H_
|