Commit c1d1c370 authored by Matthew Webb's avatar Matthew Webb Committed by Commit Bot

fido/bio: add non-preview BE command and test

Adds the non-preview authenticatorBioEnrollment command and a related
test, which is not at all comprehensive. The functionality should be
the same, so the unit test does not need to be comprehensive. This may
change in the future.

Bug: 974046
Change-Id: Ie0bf030c63ad7633d8ba94a84374e6977da07962
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1665555Reviewed-by: default avatarKim Paulhamus <kpaulhamus@chromium.org>
Reviewed-by: default avatarMartin Kreichgauer <martinkr@google.com>
Commit-Queue: Matthew Webb <noviv@google.com>
Cr-Commit-Position: refs/heads/master@{#671935}
parent e677556d
......@@ -61,6 +61,17 @@ cbor::Value AsCBOR(const AuthenticatorSupportedOptions& options) {
using BioEnrollmentAvailability =
AuthenticatorSupportedOptions::BioEnrollmentAvailability;
switch (options.bio_enrollment_availability) {
case BioEnrollmentAvailability::kSupportedAndProvisioned:
option_map.emplace(kBioEnrollmentMapKey, true);
break;
case BioEnrollmentAvailability::kSupportedButUnprovisioned:
option_map.emplace(kBioEnrollmentMapKey, false);
break;
case BioEnrollmentAvailability::kNotSupported:
break;
}
switch (options.bio_enrollment_availability_preview) {
case BioEnrollmentAvailability::kSupportedAndProvisioned:
option_map.emplace(kBioEnrollmentPreviewMapKey, true);
......
......@@ -66,8 +66,12 @@ struct COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorSupportedOptions {
// Indicates whether the authenticator supports the vendor-specific preview of
// the CTAP2 authenticatorCredentialManagement command.
bool supports_credential_management_preview = false;
// Indicates whether the authenticator supports the vendor-specific preview of
// the CTAP 2.1 authenticatorBioEnrollment command
// Indicates whether the authenticator supports the CTAP 2.1
// authenticatorBioEnrollment command.
BioEnrollmentAvailability bio_enrollment_availability =
BioEnrollmentAvailability::kNotSupported;
// Indicates whether the authenticator supports the CTAP 2.1 vendor-specific
// authenticatorBioEnrollment command.
BioEnrollmentAvailability bio_enrollment_availability_preview =
BioEnrollmentAvailability::kNotSupported;
// supports_cred_protect is true if the authenticator supports the
......
......@@ -28,15 +28,15 @@ static void SetPinAuth(BioEnrollmentRequest* request,
}
// static
BioEnrollmentRequest BioEnrollmentRequest::ForGetModality() {
BioEnrollmentRequest request;
BioEnrollmentRequest BioEnrollmentRequest::ForGetModality(Version version) {
BioEnrollmentRequest request(version);
request.get_modality = true;
return request;
}
// static
BioEnrollmentRequest BioEnrollmentRequest::ForGetSensorInfo() {
BioEnrollmentRequest request;
BioEnrollmentRequest BioEnrollmentRequest::ForGetSensorInfo(Version version) {
BioEnrollmentRequest request(version);
request.modality = BioEnrollmentModality::kFingerprint;
request.subcommand = BioEnrollmentSubCommand::kGetFingerprintSensorInfo;
return request;
......@@ -44,8 +44,9 @@ BioEnrollmentRequest BioEnrollmentRequest::ForGetSensorInfo() {
// static
BioEnrollmentRequest BioEnrollmentRequest::ForEnrollBegin(
Version version,
const pin::TokenResponse& token) {
BioEnrollmentRequest request;
BioEnrollmentRequest request(version);
request.subcommand = BioEnrollmentSubCommand::kEnrollBegin;
SetPinAuth(&request, token);
return request;
......@@ -53,9 +54,10 @@ BioEnrollmentRequest BioEnrollmentRequest::ForEnrollBegin(
// static
BioEnrollmentRequest BioEnrollmentRequest::ForEnrollNextSample(
Version version,
const pin::TokenResponse& token,
std::vector<uint8_t> template_id) {
BioEnrollmentRequest request;
BioEnrollmentRequest request(version);
request.subcommand = BioEnrollmentSubCommand::kEnrollCaptureNextSample;
request.params = cbor::Value::MapValue();
request.params->emplace(
......@@ -66,8 +68,8 @@ BioEnrollmentRequest BioEnrollmentRequest::ForEnrollNextSample(
}
// static
BioEnrollmentRequest BioEnrollmentRequest::ForCancel() {
BioEnrollmentRequest request;
BioEnrollmentRequest BioEnrollmentRequest::ForCancel(Version version) {
BioEnrollmentRequest request(version);
request.modality = BioEnrollmentModality::kFingerprint;
request.subcommand = BioEnrollmentSubCommand::kCancelCurrentEnrollment;
return request;
......@@ -75,8 +77,9 @@ BioEnrollmentRequest BioEnrollmentRequest::ForCancel() {
// static
BioEnrollmentRequest BioEnrollmentRequest::ForEnumerate(
Version version,
const pin::TokenResponse& token) {
BioEnrollmentRequest request;
BioEnrollmentRequest request(version);
request.subcommand = BioEnrollmentSubCommand::kEnumerateEnrollments;
SetPinAuth(&request, token);
return request;
......@@ -84,10 +87,11 @@ BioEnrollmentRequest BioEnrollmentRequest::ForEnumerate(
// static
BioEnrollmentRequest BioEnrollmentRequest::ForRename(
Version version,
const pin::TokenResponse& token,
std::vector<uint8_t> id,
std::string name) {
BioEnrollmentRequest request;
BioEnrollmentRequest request(version);
request.subcommand = BioEnrollmentSubCommand::kSetFriendlyName;
request.params = cbor::Value::MapValue();
request.params->emplace(
......@@ -99,9 +103,10 @@ BioEnrollmentRequest BioEnrollmentRequest::ForRename(
// static
BioEnrollmentRequest BioEnrollmentRequest::ForDelete(
Version version,
const pin::TokenResponse& token,
std::vector<uint8_t> id) {
BioEnrollmentRequest request;
BioEnrollmentRequest request(version);
request.subcommand = BioEnrollmentSubCommand::kRemoveEnrollment;
request.params = cbor::Value::MapValue();
request.params->emplace(
......@@ -114,7 +119,7 @@ BioEnrollmentRequest BioEnrollmentRequest::ForDelete(
BioEnrollmentRequest::BioEnrollmentRequest(BioEnrollmentRequest&&) = default;
BioEnrollmentRequest& BioEnrollmentRequest::operator=(BioEnrollmentRequest&&) =
default;
BioEnrollmentRequest::BioEnrollmentRequest() = default;
BioEnrollmentRequest::BioEnrollmentRequest(Version v) : version(v) {}
BioEnrollmentRequest::~BioEnrollmentRequest() = default;
template <typename T>
......@@ -297,7 +302,9 @@ AsCTAPRequestValuePair(const BioEnrollmentRequest& request) {
map.emplace(static_cast<int>(Key::kGetModality), *request.get_modality);
}
return {CtapRequestCommand::kAuthenticatorBioEnrollmentPreview,
return {request.version == BioEnrollmentRequest::Version::kDefault
? CtapRequestCommand::kAuthenticatorBioEnrollment
: CtapRequestCommand::kAuthenticatorBioEnrollmentPreview,
cbor::Value(std::move(map))};
}
......
......@@ -97,24 +97,32 @@ enum class BioEnrollmentSampleStatus : uint8_t {
};
struct BioEnrollmentRequest {
static std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
EncodeAsCBOR(const BioEnrollmentRequest& request);
enum Version {
kDefault,
kPreview,
};
static BioEnrollmentRequest ForGetModality();
static BioEnrollmentRequest ForGetSensorInfo();
static BioEnrollmentRequest ForGetModality(Version);
static BioEnrollmentRequest ForGetSensorInfo(Version);
static BioEnrollmentRequest ForEnrollBegin(
Version,
const pin::TokenResponse& pin_token);
static BioEnrollmentRequest ForEnrollNextSample(
Version,
const pin::TokenResponse& pin_token,
std::vector<uint8_t> template_id);
static BioEnrollmentRequest ForCancel();
static BioEnrollmentRequest ForEnumerate(const pin::TokenResponse& token);
static BioEnrollmentRequest ForRename(const pin::TokenResponse& token,
static BioEnrollmentRequest ForCancel(Version);
static BioEnrollmentRequest ForEnumerate(Version,
const pin::TokenResponse& token);
static BioEnrollmentRequest ForRename(Version,
const pin::TokenResponse& token,
std::vector<uint8_t> id,
std::string name);
static BioEnrollmentRequest ForDelete(const pin::TokenResponse& token,
static BioEnrollmentRequest ForDelete(Version,
const pin::TokenResponse& token,
std::vector<uint8_t> id);
Version version;
base::Optional<BioEnrollmentModality> modality;
base::Optional<BioEnrollmentSubCommand> subcommand;
base::Optional<cbor::Value::MapValue> params;
......@@ -127,7 +135,7 @@ struct BioEnrollmentRequest {
~BioEnrollmentRequest();
private:
BioEnrollmentRequest();
BioEnrollmentRequest(Version);
};
struct COMPONENT_EXPORT(DEVICE_FIDO) BioEnrollmentResponse {
......
......@@ -32,30 +32,14 @@ BioEnrollmentHandler::~BioEnrollmentHandler() {
void BioEnrollmentHandler::GetModality(ResponseCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker);
if (!authenticator_ ||
authenticator_->Options()->bio_enrollment_availability_preview ==
AuthenticatorSupportedOptions::BioEnrollmentAvailability::
kNotSupported) {
std::move(callback).Run(CtapDeviceResponseCode::kCtap2ErrUnsupportedOption,
base::nullopt);
} else {
authenticator_->GetModality(std::move(callback));
}
DCHECK(authenticator_);
authenticator_->GetModality(std::move(callback));
}
void BioEnrollmentHandler::GetSensorInfo(ResponseCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker);
if (!authenticator_ ||
authenticator_->Options()->bio_enrollment_availability_preview ==
AuthenticatorSupportedOptions::BioEnrollmentAvailability::
kNotSupported) {
std::move(callback).Run(CtapDeviceResponseCode::kCtap2ErrUnsupportedOption,
base::nullopt);
} else {
authenticator_->GetSensorInfo(std::move(callback));
}
DCHECK(authenticator_);
authenticator_->GetSensorInfo(std::move(callback));
}
void BioEnrollmentHandler::EnrollTemplate(ResponseCallback callback) {
......@@ -135,9 +119,12 @@ void BioEnrollmentHandler::OnTouch(FidoAuthenticator* authenticator) {
CancelActiveAuthenticators(authenticator->GetId());
if (!authenticator->Options() ||
authenticator->Options()->bio_enrollment_availability_preview ==
AuthenticatorSupportedOptions::BioEnrollmentAvailability::
kNotSupported) {
(authenticator->Options()->bio_enrollment_availability ==
AuthenticatorSupportedOptions::BioEnrollmentAvailability::
kNotSupported &&
authenticator->Options()->bio_enrollment_availability_preview ==
AuthenticatorSupportedOptions::BioEnrollmentAvailability::
kNotSupported)) {
std::move(error_callback_)
.Run(FidoReturnCode::kAuthenticatorMissingBioEnrollment);
return;
......
......@@ -54,7 +54,7 @@ class BioEnrollmentHandlerTest : public ::testing::Test {
TEST_F(BioEnrollmentHandlerTest, Modality) {
VirtualCtap2Device::Config config;
config.pin_support = true;
config.bio_enrollment_support = true;
config.bio_enrollment_preview_support = true;
virtual_device_factory_.SetCtap2Config(config);
......@@ -85,7 +85,7 @@ TEST_F(BioEnrollmentHandlerTest, Modality) {
TEST_F(BioEnrollmentHandlerTest, FingerprintSensorInfo) {
VirtualCtap2Device::Config config;
config.pin_support = true;
config.bio_enrollment_support = true;
config.bio_enrollment_preview_support = true;
virtual_device_factory_.SetCtap2Config(config);
......@@ -122,33 +122,13 @@ TEST_F(BioEnrollmentHandlerTest, NoBioEnrollmentSupport) {
error_callback_.WaitForCallback();
EXPECT_EQ(error_callback_.value(),
FidoReturnCode::kAuthenticatorMissingBioEnrollment);
// Test unsupported bio-enrollment command.
test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode,
base::Optional<BioEnrollmentResponse>>
cb0;
handler->GetModality(cb0.callback());
cb0.WaitForCallback();
EXPECT_EQ(cb0.status(), CtapDeviceResponseCode::kCtap2ErrUnsupportedOption);
EXPECT_FALSE(cb0.value());
// Test second command - handler should not crash after last command.
test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode,
base::Optional<BioEnrollmentResponse>>
cb1;
handler->GetSensorInfo(cb1.callback());
cb1.WaitForCallback();
EXPECT_EQ(cb1.status(), CtapDeviceResponseCode::kCtap2ErrUnsupportedOption);
EXPECT_FALSE(cb1.value());
}
// Tests fingerprint enrollment lifecycle.
TEST_F(BioEnrollmentHandlerTest, Enroll) {
VirtualCtap2Device::Config config;
config.pin_support = true;
config.bio_enrollment_support = true;
config.bio_enrollment_preview_support = true;
virtual_device_factory_.SetCtap2Config(config);
......@@ -176,7 +156,7 @@ TEST_F(BioEnrollmentHandlerTest, Enroll) {
TEST_F(BioEnrollmentHandlerTest, CancelNoEnroll) {
VirtualCtap2Device::Config config;
config.pin_support = true;
config.bio_enrollment_support = true;
config.bio_enrollment_preview_support = true;
virtual_device_factory_.SetCtap2Config(config);
......@@ -194,7 +174,7 @@ TEST_F(BioEnrollmentHandlerTest, CancelNoEnroll) {
TEST_F(BioEnrollmentHandlerTest, Enumerate) {
VirtualCtap2Device::Config config;
config.pin_support = true;
config.bio_enrollment_support = true;
config.bio_enrollment_preview_support = true;
virtual_device_factory_.SetCtap2Config(config);
......@@ -223,7 +203,7 @@ TEST_F(BioEnrollmentHandlerTest, Enumerate) {
TEST_F(BioEnrollmentHandlerTest, Rename) {
VirtualCtap2Device::Config config;
config.pin_support = true;
config.bio_enrollment_support = true;
config.bio_enrollment_preview_support = true;
virtual_device_factory_.SetCtap2Config(config);
......@@ -249,7 +229,7 @@ TEST_F(BioEnrollmentHandlerTest, Rename) {
TEST_F(BioEnrollmentHandlerTest, Delete) {
VirtualCtap2Device::Config config;
config.pin_support = true;
config.bio_enrollment_support = true;
config.bio_enrollment_preview_support = true;
virtual_device_factory_.SetCtap2Config(config);
......@@ -271,5 +251,24 @@ TEST_F(BioEnrollmentHandlerTest, Delete) {
EXPECT_EQ(cb1.value(), CtapDeviceResponseCode::kCtap2ErrInvalidOption);
}
// Test cancelling using the non-preview command.
TEST_F(BioEnrollmentHandlerTest, NonPreviewCancel) {
VirtualCtap2Device::Config config;
config.pin_support = true;
config.bio_enrollment_support = true;
virtual_device_factory_.SetCtap2Config(config);
auto handler = MakeHandler();
ready_callback_.WaitForCallback();
// Cancel enrollment.
test::ValueCallbackReceiver<CtapDeviceResponseCode> cb;
handler->Cancel(cb.callback());
cb.WaitForCallback();
EXPECT_EQ(cb.value(), CtapDeviceResponseCode::kSuccess);
}
} // namespace
} // namespace device
......@@ -301,7 +301,20 @@ base::Optional<AuthenticatorGetInfoResponse> ReadCTAPGetInfoResponse(
option_map_it->second.GetBool();
}
// TODO(noviv) add support for kBioEnrollmentMapKey
option_map_it = option_map.find(CBOR(kBioEnrollmentMapKey));
if (option_map_it != option_map.end()) {
if (!option_map_it->second.is_bool()) {
return base::nullopt;
}
using Availability =
AuthenticatorSupportedOptions::BioEnrollmentAvailability;
options.bio_enrollment_availability =
option_map_it->second.GetBool()
? Availability::kSupportedAndProvisioned
: Availability::kSupportedButUnprovisioned;
}
option_map_it = option_map.find(CBOR(kBioEnrollmentPreviewMapKey));
if (option_map_it != option_map.end()) {
if (!option_map_it->second.is_bool()) {
......
......@@ -29,6 +29,7 @@ const char kCredentialTypeMapKey[] = "type";
const char kCredentialAlgorithmMapKey[] = "alg";
const char kCredentialManagementMapKey[] = "credMgmt";
const char kCredentialManagementPreviewMapKey[] = "credentialMgmtPreview";
const char kBioEnrollmentMapKey[] = "bioEnroll";
const char kBioEnrollmentPreviewMapKey[] = "userVerificationMgmtPreview";
const base::TimeDelta kDeviceTimeout = base::TimeDelta::FromSeconds(10);
......
......@@ -252,6 +252,7 @@ enum class CtapRequestCommand : uint8_t {
kAuthenticatorGetInfo = 0x04,
kAuthenticatorClientPin = 0x06,
kAuthenticatorReset = 0x07,
kAuthenticatorBioEnrollment = 0x09,
kAuthenticatorBioEnrollmentPreview = 0x40,
kAuthenticatorCredentialManagement = 0x0a,
kAuthenticatorCredentialManagementPreview = 0x41,
......@@ -325,6 +326,7 @@ COMPONENT_EXPORT(DEVICE_FIDO) extern const char kCredentialAlgorithmMapKey[];
COMPONENT_EXPORT(DEVICE_FIDO) extern const char kCredentialManagementMapKey[];
COMPONENT_EXPORT(DEVICE_FIDO)
extern const char kCredentialManagementPreviewMapKey[];
COMPONENT_EXPORT(DEVICE_FIDO) extern const char kBioEnrollmentMapKey[];
COMPONENT_EXPORT(DEVICE_FIDO) extern const char kBioEnrollmentPreviewMapKey[];
// HID transport specific constants.
......
......@@ -492,35 +492,36 @@ void FidoDeviceAuthenticator::DeleteCredential(
/*string_fixup_predicate=*/nullptr);
}
void FidoDeviceAuthenticator::GetModality(BioEnrollmentCallback callback) {
DCHECK(
Options()->bio_enrollment_availability_preview !=
AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported);
// Helper method for determining correct bio enrollment version.
static BioEnrollmentRequest::Version GetBioEnrollmentRequestVersion(
const AuthenticatorSupportedOptions& options) {
return options.bio_enrollment_availability !=
AuthenticatorSupportedOptions::BioEnrollmentAvailability::
kNotSupported
? BioEnrollmentRequest::kDefault
: BioEnrollmentRequest::kPreview;
}
void FidoDeviceAuthenticator::GetModality(BioEnrollmentCallback callback) {
RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>(
BioEnrollmentRequest::ForGetModality(), std::move(callback),
base::BindOnce(&BioEnrollmentResponse::Parse));
BioEnrollmentRequest::ForGetModality(
GetBioEnrollmentRequestVersion(*Options())),
std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse));
}
void FidoDeviceAuthenticator::GetSensorInfo(BioEnrollmentCallback callback) {
DCHECK(
Options()->bio_enrollment_availability_preview !=
AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported);
RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>(
BioEnrollmentRequest::ForGetSensorInfo(), std::move(callback),
base::BindOnce(&BioEnrollmentResponse::Parse));
BioEnrollmentRequest::ForGetSensorInfo(
GetBioEnrollmentRequestVersion(*Options())),
std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse));
}
void FidoDeviceAuthenticator::BioEnrollFingerprint(
const pin::TokenResponse& response,
BioEnrollmentCallback callback) {
DCHECK(
Options()->bio_enrollment_availability_preview !=
AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported);
RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>(
BioEnrollmentRequest::ForEnrollBegin(response),
BioEnrollmentRequest::ForEnrollBegin(
GetBioEnrollmentRequestVersion(*Options()), response),
base::BindOnce(&FidoDeviceAuthenticator::OnBioEnroll,
weak_factory_.GetWeakPtr(), std::move(response),
std::move(callback),
......@@ -530,16 +531,13 @@ void FidoDeviceAuthenticator::BioEnrollFingerprint(
void FidoDeviceAuthenticator::BioEnrollRename(
const pin::TokenResponse& response,
std::vector<uint8_t> template_id,
std::vector<uint8_t> id,
std::string name,
BioEnrollmentCallback callback) {
DCHECK(
Options()->bio_enrollment_availability_preview !=
AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported);
RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>(
BioEnrollmentRequest::ForRename(response, std::move(template_id),
std::move(name)),
BioEnrollmentRequest::ForRename(
GetBioEnrollmentRequestVersion(*Options()), response, std::move(id),
std::move(name)),
std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse));
}
......@@ -547,17 +545,15 @@ void FidoDeviceAuthenticator::BioEnrollDelete(
const pin::TokenResponse& response,
std::vector<uint8_t> template_id,
BioEnrollmentCallback callback) {
DCHECK(
Options()->bio_enrollment_availability_preview !=
AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported);
RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>(
BioEnrollmentRequest::ForDelete(response, std::move(template_id)),
BioEnrollmentRequest::ForDelete(
GetBioEnrollmentRequestVersion(*Options()), response,
std::move(template_id)),
std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse));
}
void FidoDeviceAuthenticator::OnBioEnroll(
pin::TokenResponse token,
pin::TokenResponse response,
BioEnrollmentCallback callback,
base::Optional<std::vector<uint8_t>> current_template_id,
CtapDeviceResponseCode code,
......@@ -577,36 +573,32 @@ void FidoDeviceAuthenticator::OnBioEnroll(
current_template_id = *bio->template_id;
}
auto request =
BioEnrollmentRequest::ForEnrollNextSample(token, *current_template_id);
auto request = BioEnrollmentRequest::ForEnrollNextSample(
GetBioEnrollmentRequestVersion(*Options()), response,
*current_template_id);
RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>(
std::move(request),
base::BindOnce(&FidoDeviceAuthenticator::OnBioEnroll,
weak_factory_.GetWeakPtr(), std::move(token),
weak_factory_.GetWeakPtr(), std::move(response),
std::move(callback), std::move(current_template_id)),
base::BindOnce(&BioEnrollmentResponse::Parse));
}
void FidoDeviceAuthenticator::BioEnrollCancel(BioEnrollmentCallback callback) {
DCHECK(
Options()->bio_enrollment_availability_preview !=
AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported);
RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>(
BioEnrollmentRequest::ForCancel(), std::move(callback),
base::BindOnce(&BioEnrollmentResponse::Parse));
BioEnrollmentRequest::ForCancel(
GetBioEnrollmentRequestVersion(*Options())),
std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse));
}
void FidoDeviceAuthenticator::BioEnrollEnumerate(
const pin::TokenResponse& token,
const pin::TokenResponse& response,
BioEnrollmentCallback callback) {
DCHECK(
Options()->bio_enrollment_availability_preview !=
AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported);
RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>(
BioEnrollmentRequest::ForEnumerate(std::move(token)), std::move(callback),
base::BindOnce(&BioEnrollmentResponse::Parse));
BioEnrollmentRequest::ForEnumerate(
GetBioEnrollmentRequestVersion(*Options()), std::move(response)),
std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse));
}
void FidoDeviceAuthenticator::Reset(ResetCallback callback) {
......
......@@ -500,6 +500,17 @@ VirtualCtap2Device::VirtualCtap2Device(scoped_refptr<State> state,
}
if (config.bio_enrollment_support) {
options_updated = true;
if (mutable_state()->bio_enrollment_provisioned) {
options.bio_enrollment_availability = AuthenticatorSupportedOptions::
BioEnrollmentAvailability::kSupportedAndProvisioned;
} else {
options.bio_enrollment_availability = AuthenticatorSupportedOptions::
BioEnrollmentAvailability::kSupportedButUnprovisioned;
}
}
if (config.bio_enrollment_preview_support) {
options_updated = true;
if (mutable_state()->bio_enrollment_provisioned) {
options.bio_enrollment_availability_preview =
......@@ -590,6 +601,7 @@ FidoDevice::CancelToken VirtualCtap2Device::DeviceTransact(
case CtapRequestCommand::kAuthenticatorCredentialManagement:
response_code = OnCredentialManagement(request_bytes, &response_data);
break;
case CtapRequestCommand::kAuthenticatorBioEnrollment:
case CtapRequestCommand::kAuthenticatorBioEnrollmentPreview:
response_code = OnBioEnrollment(request_bytes, &response_data);
break;
......@@ -1345,8 +1357,12 @@ CtapDeviceResponseCode VirtualCtap2Device::OnBioEnrollment(
base::span<const uint8_t> request_bytes,
std::vector<uint8_t>* response) {
// Check to ensure that device supports bio enrollment.
if (device_info_->options.bio_enrollment_availability_preview ==
AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported) {
if (device_info_->options.bio_enrollment_availability ==
AuthenticatorSupportedOptions::BioEnrollmentAvailability::
kNotSupported &&
device_info_->options.bio_enrollment_availability_preview ==
AuthenticatorSupportedOptions::BioEnrollmentAvailability::
kNotSupported) {
return CtapDeviceResponseCode::kCtap2ErrUnsupportedOption;
}
......@@ -1434,7 +1450,7 @@ CtapDeviceResponseCode VirtualCtap2Device::OnBioEnrollment(
case static_cast<int>(SubCmd::kEnrollBegin):
response_map.emplace(
static_cast<int>(BioEnrollmentResponseKey::kTemplateId),
cbor::Value(std::vector<uint8_t>{0, 0, 0, 1}));
std::vector<uint8_t>{0, 0, 0, 1});
response_map.emplace(
static_cast<int>(BioEnrollmentResponseKey::kLastEnrollSampleStatus),
static_cast<int>(BioEnrollmentSampleStatus::kGood));
......
......@@ -45,6 +45,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) VirtualCtap2Device
bool resident_key_support = false;
bool credential_management_support = false;
bool bio_enrollment_support = false;
bool bio_enrollment_preview_support = false;
bool cred_protect_support = false;
// resident_credential_storage is the number of resident credentials that
// the device will store before returning KEY_STORE_FULL.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment