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