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
5 #ifndef DEVICE_FIDO_CREDENTIAL_MANAGEMENT_HANDLER_H_
6 #define DEVICE_FIDO_CREDENTIAL_MANAGEMENT_HANDLER_H_
7
8 #include <memory>
9 #include <vector>
10
11 #include "base/callback.h"
12 #include "base/component_export.h"
13 #include "base/containers/flat_set.h"
14 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/sequence_checker.h"
17 #include "device/fido/credential_management.h"
18 #include "device/fido/fido_constants.h"
19 #include "device/fido/fido_request_handler_base.h"
20 #include "device/fido/fido_transport_protocol.h"
21 #include "device/fido/pin.h"
22
23 namespace device {
24
25 class FidoAuthenticator;
26 class FidoDiscoveryFactory;
27
28 enum class CredentialManagementStatus {
29 kSuccess,
30 kAuthenticatorResponseInvalid,
31 kSoftPINBlock,
32 kHardPINBlock,
33 kAuthenticatorMissingCredentialManagement,
34 kNoPINSet,
35 };
36
37 // CredentialManagementHandler implements the authenticatorCredentialManagement
38 // protocol.
39 //
40 // Public methods on instances of this class may be called only after
41 // ReadyCallback has run, but not after FinishedCallback has run.
COMPONENT_EXPORT(DEVICE_FIDO)42 class COMPONENT_EXPORT(DEVICE_FIDO) CredentialManagementHandler
43 : public FidoRequestHandlerBase {
44 public:
45 using DeleteCredentialCallback =
46 base::OnceCallback<void(CtapDeviceResponseCode)>;
47 using FinishedCallback = base::OnceCallback<void(CredentialManagementStatus)>;
48 using GetCredentialsCallback = base::OnceCallback<void(
49 CtapDeviceResponseCode,
50 base::Optional<std::vector<AggregatedEnumerateCredentialsResponse>>,
51 base::Optional<size_t>)>;
52 using GetPINCallback =
53 base::RepeatingCallback<void(int64_t,
54 base::OnceCallback<void(std::string)>)>;
55 using ReadyCallback = base::OnceClosure;
56
57 CredentialManagementHandler(
58 FidoDiscoveryFactory* fido_discovery_factory,
59 const base::flat_set<FidoTransportProtocol>& supported_transports,
60 ReadyCallback ready_callback,
61 GetPINCallback get_pin_callback,
62 FinishedCallback finished_callback);
63 ~CredentialManagementHandler() override;
64
65 // GetCredentials invokes a series of commands to fetch all credentials stored
66 // on the device. The supplied callback receives the status returned by the
67 // device and, if successful, the resident credentials stored and remaining
68 // capacity left on the chosen authenticator.
69 //
70 // The returned AggregatedEnumerateCredentialsResponses will be sorted in
71 // ascending order by their RP ID. The |credentials| vector of each response
72 // will be sorted in ascending order by user name.
73 void GetCredentials(GetCredentialsCallback callback);
74
75 // DeleteCredential attempts to delete the credential with the given
76 // |credential_id|.
77 void DeleteCredential(const PublicKeyCredentialDescriptor& credential_id,
78 DeleteCredentialCallback callback);
79
80 // DeleteCredentials deletes a list of credentials. Each entry in
81 // |credential_ids| must be a CBOR-serialized PublicKeyCredentialDescriptor.
82 // If any individual deletion fails, |callback| is invoked with the
83 // respective error, and deletion of the remaining credentials will be
84 // aborted (but others may have been deleted successfully already).
85 void DeleteCredentials(std::vector<std::vector<uint8_t>> credential_ids,
86 DeleteCredentialCallback callback);
87
88 private:
89 enum class State {
90 kWaitingForTouch,
91 kGettingRetries,
92 kWaitingForPIN,
93 kGettingPINToken,
94 kReady,
95 kGettingMetadata,
96 kGettingRP,
97 kGettingCredentials,
98 kFinished,
99 };
100
101 // FidoRequestHandlerBase:
102 void DispatchRequest(FidoAuthenticator* authenticator) override;
103 void AuthenticatorRemoved(FidoDiscoveryBase* discovery,
104 FidoAuthenticator* authenticator) override;
105
106 void OnTouch(FidoAuthenticator* authenticator);
107 void OnRetriesResponse(CtapDeviceResponseCode status,
108 base::Optional<pin::RetriesResponse> response);
109 void OnHavePIN(std::string pin);
110 void OnHavePINToken(CtapDeviceResponseCode status,
111 base::Optional<pin::TokenResponse> response);
112 void OnCredentialsMetadata(
113 CtapDeviceResponseCode status,
114 base::Optional<CredentialsMetadataResponse> response);
115 void OnEnumerateCredentials(
116 CredentialsMetadataResponse metadata_response,
117 CtapDeviceResponseCode status,
118 base::Optional<std::vector<AggregatedEnumerateCredentialsResponse>>
119 responses);
120 void OnDeleteCredentials(
121 std::vector<std::vector<uint8_t>> remaining_credential_ids,
122 CredentialManagementHandler::DeleteCredentialCallback callback,
123 CtapDeviceResponseCode status,
124 base::Optional<DeleteCredentialResponse> response);
125
126 SEQUENCE_CHECKER(sequence_checker_);
127
128 State state_ = State::kWaitingForTouch;
129 FidoAuthenticator* authenticator_ = nullptr;
130 base::Optional<std::vector<uint8_t>> pin_token_;
131
132 ReadyCallback ready_callback_;
133 GetPINCallback get_pin_callback_;
134 GetCredentialsCallback get_credentials_callback_;
135 FinishedCallback finished_callback_;
136
137 base::WeakPtrFactory<CredentialManagementHandler> weak_factory_{this};
138
139 DISALLOW_COPY_AND_ASSIGN(CredentialManagementHandler);
140 };
141
142 } // namespace device
143
144 #endif // DEVICE_FIDO_CREDENTIAL_MANAGEMENT_HANDLER_H_
145