enrollment_handler.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef DEVICE_FIDO_BIO_ENROLLMENT_HANDLER_H_
  5. #define DEVICE_FIDO_BIO_ENROLLMENT_HANDLER_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include "base/component_export.h"
  12. #include "base/containers/flat_set.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "device/fido/bio/enroller.h"
  15. #include "device/fido/bio/enrollment.h"
  16. #include "device/fido/fido_constants.h"
  17. #include "device/fido/fido_discovery_factory.h"
  18. #include "device/fido/fido_request_handler_base.h"
  19. namespace device {
  20. // BioEnrollmentHandler exercises the CTAP2.1 authenticatorBioEnrollment
  21. // sub-protocol for enrolling biometric templates on external authenticators
  22. // supporting internal UV.
  23. class COMPONENT_EXPORT(DEVICE_FIDO) BioEnrollmentHandler
  24. : public FidoRequestHandlerBase,
  25. public BioEnroller::Delegate {
  26. public:
  27. enum class Error {
  28. kAuthenticatorRemoved,
  29. kAuthenticatorResponseInvalid,
  30. kSoftPINBlock,
  31. kHardPINBlock,
  32. kNoPINSet,
  33. kAuthenticatorMissingBioEnrollment,
  34. kForcePINChange,
  35. };
  36. struct COMPONENT_EXPORT(DEVICE_FIDO) SensorInfo {
  37. SensorInfo();
  38. SensorInfo(const SensorInfo&) = delete;
  39. SensorInfo(SensorInfo&&);
  40. SensorInfo& operator=(const SensorInfo&) = delete;
  41. SensorInfo& operator=(SensorInfo&&);
  42. absl::optional<uint8_t> max_samples_for_enroll;
  43. uint32_t max_template_friendly_name;
  44. };
  45. using TemplateId = std::vector<uint8_t>;
  46. // ReadyCallback is invoked once the handler has completed initialization for
  47. // the authenticator, i.e. obtained a PIN/UV token and read |SensorInfo|.
  48. // Methods on the handler may be invoked at that point.
  49. using ReadyCallback = base::OnceCallback<void(SensorInfo)>;
  50. // ErrorCallback is invoked if the handler has encountered an error. No
  51. // further methods may be called on the handler be made at that point.
  52. using ErrorCallback = base::OnceCallback<void(Error)>;
  53. // GetPINCallback is invoked to obtain a PIN for the authenticator.
  54. using GetPINCallback =
  55. base::RepeatingCallback<void(uint32_t min_pin_length,
  56. int64_t retries,
  57. base::OnceCallback<void(std::string)>)>;
  58. // StatusCallback provides the CTAP response code for an operation.
  59. using StatusCallback = base::OnceCallback<void(CtapDeviceResponseCode)>;
  60. // EnumerationCallback is invoked upon the completion of EnumerateTemplates.
  61. using EnumerationCallback = base::OnceCallback<void(
  62. CtapDeviceResponseCode,
  63. absl::optional<std::map<TemplateId, std::string>>)>;
  64. // SampleCallback is invoked repeatedly during an ongoing EnrollTemplate()
  65. // operation to indicate the status of a single sample collection (i.e. user
  66. // touched the sensor). It receives a status value and the number of remaining
  67. // samples to be collected.
  68. using SampleCallback =
  69. base::RepeatingCallback<void(BioEnrollmentSampleStatus, uint8_t)>;
  70. // EnrollmentCallback is invoked upon completion of EnrollTemplate().
  71. using EnrollmentCallback =
  72. base::OnceCallback<void(CtapDeviceResponseCode, TemplateId)>;
  73. BioEnrollmentHandler(
  74. const base::flat_set<FidoTransportProtocol>& supported_transports,
  75. ReadyCallback ready_callback,
  76. ErrorCallback error_callback,
  77. GetPINCallback get_pin_callback,
  78. FidoDiscoveryFactory* factory);
  79. ~BioEnrollmentHandler() override;
  80. BioEnrollmentHandler(const BioEnrollmentHandler&) = delete;
  81. BioEnrollmentHandler(BioEnrollmentHandler&&) = delete;
  82. // Enrolls a new fingerprint template. The user must provide the required
  83. // number of samples by touching the authenticator's sensor repeatedly. For
  84. // each sample, |sample_callback| is invoked with a status and the remaining
  85. // number of samples. Once all samples have been collected or the operation
  86. // has been cancelled, |enrollment_callback| is invoked with the result.
  87. void EnrollTemplate(SampleCallback sample_callback,
  88. EnrollmentCallback enrollment_callback);
  89. // Cancels an ongoing enrollment, if any, and invokes the
  90. // |completion_callback| passed to EnrollTemplate() with
  91. // |CtapDeviceResponseCode::kCtap2ErrKeepAliveCancel|.
  92. void CancelEnrollment();
  93. // Requests a map of current enrollments from the authenticator. On success,
  94. // the callback is invoked with a map from template IDs to human-readable
  95. // names. On failure, the callback is invoked with absl::nullopt.
  96. void EnumerateTemplates(EnumerationCallback);
  97. // Renames the enrollment identified by |template_id| to |name|.
  98. void RenameTemplate(std::vector<uint8_t> template_id,
  99. std::string name,
  100. StatusCallback);
  101. // Deletes the enrollment identified by |template_id|.
  102. void DeleteTemplate(std::vector<uint8_t> template_id, StatusCallback);
  103. private:
  104. enum class State {
  105. kWaitingForTouch,
  106. kGettingRetries,
  107. kWaitingForPIN,
  108. kGettingPINToken,
  109. kGettingSensorInfo,
  110. kReady,
  111. kEnrolling,
  112. kCancellingEnrollment,
  113. kEnumerating,
  114. kRenaming,
  115. kDeleting,
  116. kFinished,
  117. };
  118. // FidoRequestHandlerBase:
  119. void DispatchRequest(FidoAuthenticator*) override;
  120. void AuthenticatorRemoved(FidoDiscoveryBase*, FidoAuthenticator*) override;
  121. // BioEnroller::Delegate:
  122. void OnSampleCollected(BioEnrollmentSampleStatus status,
  123. int samples_remaining) override;
  124. void OnEnrollmentDone(
  125. absl::optional<std::vector<uint8_t>> template_id) override;
  126. void OnEnrollmentError(CtapDeviceResponseCode status) override;
  127. void OnTouch(FidoAuthenticator* authenticator);
  128. void OnRetriesResponse(CtapDeviceResponseCode,
  129. absl::optional<pin::RetriesResponse>);
  130. void OnHavePIN(std::string pin);
  131. void OnHavePINToken(CtapDeviceResponseCode,
  132. absl::optional<pin::TokenResponse>);
  133. void OnGetSensorInfo(CtapDeviceResponseCode,
  134. absl::optional<BioEnrollmentResponse>);
  135. void OnEnumerateTemplates(EnumerationCallback,
  136. CtapDeviceResponseCode,
  137. absl::optional<BioEnrollmentResponse>);
  138. void OnRenameTemplate(StatusCallback,
  139. CtapDeviceResponseCode,
  140. absl::optional<BioEnrollmentResponse>);
  141. void OnDeleteTemplate(StatusCallback,
  142. CtapDeviceResponseCode,
  143. absl::optional<BioEnrollmentResponse>);
  144. void RunErrorCallback(Error error);
  145. SEQUENCE_CHECKER(sequence_checker_);
  146. State state_ = State::kWaitingForTouch;
  147. raw_ptr<FidoAuthenticator> authenticator_ = nullptr;
  148. std::unique_ptr<BioEnroller> bio_enroller_;
  149. ReadyCallback ready_callback_;
  150. ErrorCallback error_callback_;
  151. GetPINCallback get_pin_callback_;
  152. EnrollmentCallback enrollment_callback_;
  153. SampleCallback sample_callback_;
  154. absl::optional<pin::TokenResponse> pin_token_response_;
  155. base::WeakPtrFactory<BioEnrollmentHandler> weak_factory_{this};
  156. };
  157. } // namespace device
  158. #endif // DEVICE_FIDO_BIO_ENROLLMENT_HANDLER_H_