Commit fffbb799 authored by Martin Kreichgauer's avatar Martin Kreichgauer Committed by Commit Bot

fido: make FidoAuthenticator::Options optional.

This changes the return type of FidoAuthenticator::Options() from
AuthenticatorSupportedOptions to
base::Optional<AuthenticatorSupportedOptions>.

The FidoAuthenticator subclass for the Windows WebAuthn API can
potentially talk to a number of different authenticators with
different capabilities and hence cannot return a sensible value for
this method. It previously returned a "maximum possible" Options
value; but that lead to a bug where GetAssertionHandler assumed it
could set the user verification requirement of a request from
"preferred" to "required" because the Windows authenticator reported
itself as having a PIN set up (while the actual physical device might
not even support PINs).

By returning an Optional, we make the Windows case more explicit.

The aforementioned bug is fixed by moving the "effective uv
requirement" computation for GetAssertion into
FidoDeviceAuthenticator.

For MakeCredential, we have a similar bug: Because
CtapMakeCredentialRequest only stores the UV requirement as a bool
rather than the full enum, we currently default to uv=false for
authenticators that *do* support UV (even in the non-Windows case),
which is wrong. I'm going to address this in an immediate follow up CL.

Bug: 898718
Change-Id: I3e40296578929c75585e820aa5764bd623e1fe79
Reviewed-on: https://chromium-review.googlesource.com/c/1321852
Commit-Queue: Martin Kreichgauer <martinkr@google.com>
Reviewed-by: default avatarKim Paulhamus <kpaulhamus@chromium.org>
Cr-Commit-Position: refs/heads/master@{#606973}
parent be041911
...@@ -224,6 +224,19 @@ device::CtapMakeCredentialRequest CreateCtapMakeCredentialRequest( ...@@ -224,6 +224,19 @@ device::CtapMakeCredentialRequest CreateCtapMakeCredentialRequest(
make_credential_param.SetExcludeList(std::move(exclude_list)); make_credential_param.SetExcludeList(std::move(exclude_list));
make_credential_param.SetIsIndividualAttestation(is_individual_attestation); make_credential_param.SetIsIndividualAttestation(is_individual_attestation);
make_credential_param.SetHmacSecret(options->hmac_create_secret); make_credential_param.SetHmacSecret(options->hmac_create_secret);
// TODO(martinkr): Rename to (Set)ResidentKeyRequired.
make_credential_param.SetResidentKeySupported(
options->authenticator_selection &&
options->authenticator_selection->require_resident_key);
// TODO(martinkr): Change CtapMakeCredentialRequest to store the
// enum-valued UV requirement; then compute the "effective" requirement for
// CTAP devices in FidoDeviceAuthenticator, as it is already done for
// GetAssertion. As it is, this will default to uv=false for kPreferred,
// which is wrong if the authenticator actually does support UV.
make_credential_param.SetUserVerificationRequired(
options->authenticator_selection &&
options->authenticator_selection->user_verification ==
blink::mojom::UserVerificationRequirement::REQUIRED);
return make_credential_param; return make_credential_param;
} }
......
...@@ -11,13 +11,14 @@ ...@@ -11,13 +11,14 @@
namespace device { namespace device {
AuthenticatorSupportedOptions::AuthenticatorSupportedOptions() = default; AuthenticatorSupportedOptions::AuthenticatorSupportedOptions() = default;
AuthenticatorSupportedOptions::AuthenticatorSupportedOptions(
const AuthenticatorSupportedOptions& other) = default;
AuthenticatorSupportedOptions::AuthenticatorSupportedOptions( AuthenticatorSupportedOptions::AuthenticatorSupportedOptions(
AuthenticatorSupportedOptions&& other) = default; AuthenticatorSupportedOptions&& other) = default;
AuthenticatorSupportedOptions& AuthenticatorSupportedOptions::operator=(
const AuthenticatorSupportedOptions& other) = default;
AuthenticatorSupportedOptions& AuthenticatorSupportedOptions::operator=( AuthenticatorSupportedOptions& AuthenticatorSupportedOptions::operator=(
AuthenticatorSupportedOptions&& other) = default; AuthenticatorSupportedOptions&& other) = default;
AuthenticatorSupportedOptions::~AuthenticatorSupportedOptions() = default; AuthenticatorSupportedOptions::~AuthenticatorSupportedOptions() = default;
AuthenticatorSupportedOptions& AuthenticatorSupportedOptions&
......
...@@ -33,7 +33,10 @@ class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorSupportedOptions { ...@@ -33,7 +33,10 @@ class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorSupportedOptions {
}; };
AuthenticatorSupportedOptions(); AuthenticatorSupportedOptions();
AuthenticatorSupportedOptions(const AuthenticatorSupportedOptions& other);
AuthenticatorSupportedOptions(AuthenticatorSupportedOptions&& other); AuthenticatorSupportedOptions(AuthenticatorSupportedOptions&& other);
AuthenticatorSupportedOptions& operator=(
const AuthenticatorSupportedOptions& other);
AuthenticatorSupportedOptions& operator=( AuthenticatorSupportedOptions& operator=(
AuthenticatorSupportedOptions&& other); AuthenticatorSupportedOptions&& other);
~AuthenticatorSupportedOptions(); ~AuthenticatorSupportedOptions();
...@@ -74,8 +77,6 @@ class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorSupportedOptions { ...@@ -74,8 +77,6 @@ class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorSupportedOptions {
// optional if client pin capability is not supported by the authenticator. // optional if client pin capability is not supported by the authenticator.
ClientPinAvailability client_pin_availability_ = ClientPinAvailability client_pin_availability_ =
ClientPinAvailability::kNotSupported; ClientPinAvailability::kNotSupported;
DISALLOW_COPY_AND_ASSIGN(AuthenticatorSupportedOptions);
}; };
COMPONENT_EXPORT(DEVICE_FIDO) COMPONENT_EXPORT(DEVICE_FIDO)
......
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "device/fido/authenticator_get_assertion_response.h" #include "device/fido/authenticator_get_assertion_response.h"
#include "device/fido/authenticator_make_credential_response.h" #include "device/fido/authenticator_make_credential_response.h"
#include "device/fido/authenticator_supported_options.h"
#include "device/fido/fido_transport_protocol.h" #include "device/fido/fido_transport_protocol.h"
namespace device { namespace device {
class AuthenticatorSupportedOptions;
class CtapGetAssertionRequest; class CtapGetAssertionRequest;
class CtapMakeCredentialRequest; class CtapMakeCredentialRequest;
...@@ -42,15 +42,15 @@ class COMPONENT_EXPORT(DEVICE_FIDO) FidoAuthenticator { ...@@ -42,15 +42,15 @@ class COMPONENT_EXPORT(DEVICE_FIDO) FidoAuthenticator {
// call is received, |callback| is invoked. Below MakeCredential() and // call is received, |callback| is invoked. Below MakeCredential() and
// GetAssertion() must only called after |callback| is invoked. // GetAssertion() must only called after |callback| is invoked.
virtual void InitializeAuthenticator(base::OnceClosure callback) = 0; virtual void InitializeAuthenticator(base::OnceClosure callback) = 0;
virtual void MakeCredential( virtual void MakeCredential(CtapMakeCredentialRequest request,
CtapMakeCredentialRequest request, MakeCredentialCallback callback) = 0;
MakeCredentialCallback callback) = 0;
virtual void GetAssertion(CtapGetAssertionRequest request, virtual void GetAssertion(CtapGetAssertionRequest request,
GetAssertionCallback callback) = 0; GetAssertionCallback callback) = 0;
virtual void Cancel() = 0; virtual void Cancel() = 0;
virtual std::string GetId() const = 0; virtual std::string GetId() const = 0;
virtual base::string16 GetDisplayName() const = 0; virtual base::string16 GetDisplayName() const = 0;
virtual const AuthenticatorSupportedOptions& Options() const = 0; virtual const base::Optional<AuthenticatorSupportedOptions>& Options()
const = 0;
virtual FidoTransportProtocol AuthenticatorTransport() const = 0; virtual FidoTransportProtocol AuthenticatorTransport() const = 0;
virtual bool IsInPairingMode() const = 0; virtual bool IsInPairingMode() const = 0;
virtual base::WeakPtr<FidoAuthenticator> GetWeakPtr() = 0; virtual base::WeakPtr<FidoAuthenticator> GetWeakPtr() = 0;
......
...@@ -27,8 +27,29 @@ void FidoDeviceAuthenticator::InitializeAuthenticator( ...@@ -27,8 +27,29 @@ void FidoDeviceAuthenticator::InitializeAuthenticator(
base::OnceClosure callback) { base::OnceClosure callback) {
base::SequencedTaskRunnerHandle::Get()->PostTask( base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&FidoDevice::DiscoverSupportedProtocolAndDeviceInfo, base::BindOnce(
device()->GetWeakPtr(), std::move(callback))); &FidoDevice::DiscoverSupportedProtocolAndDeviceInfo,
device()->GetWeakPtr(),
base::BindOnce(&FidoDeviceAuthenticator::InitializeAuthenticatorDone,
weak_factory_.GetWeakPtr(), std::move(callback))));
}
void FidoDeviceAuthenticator::InitializeAuthenticatorDone(
base::OnceClosure callback) {
DCHECK(!options_);
switch (device_->supported_protocol()) {
case ProtocolVersion::kU2f:
options_ = AuthenticatorSupportedOptions();
break;
case ProtocolVersion::kCtap:
DCHECK(device_->device_info()) << "uninitialized device";
options_ = device_->device_info()->options();
break;
case ProtocolVersion::kUnknown:
NOTREACHED() << "uninitialized device";
options_ = AuthenticatorSupportedOptions();
}
std::move(callback).Run();
} }
void FidoDeviceAuthenticator::MakeCredential(CtapMakeCredentialRequest request, void FidoDeviceAuthenticator::MakeCredential(CtapMakeCredentialRequest request,
...@@ -36,6 +57,9 @@ void FidoDeviceAuthenticator::MakeCredential(CtapMakeCredentialRequest request, ...@@ -36,6 +57,9 @@ void FidoDeviceAuthenticator::MakeCredential(CtapMakeCredentialRequest request,
DCHECK(!task_); DCHECK(!task_);
DCHECK(device_->SupportedProtocolIsInitialized()) DCHECK(device_->SupportedProtocolIsInitialized())
<< "InitializeAuthenticator() must be called first."; << "InitializeAuthenticator() must be called first.";
DCHECK(Options());
// TODO(martinkr): Change FidoTasks to take all request parameters by const // TODO(martinkr): Change FidoTasks to take all request parameters by const
// reference, so we can avoid copying these from the RequestHandler. // reference, so we can avoid copying these from the RequestHandler.
task_ = std::make_unique<MakeCredentialTask>( task_ = std::make_unique<MakeCredentialTask>(
...@@ -46,6 +70,18 @@ void FidoDeviceAuthenticator::GetAssertion(CtapGetAssertionRequest request, ...@@ -46,6 +70,18 @@ void FidoDeviceAuthenticator::GetAssertion(CtapGetAssertionRequest request,
GetAssertionCallback callback) { GetAssertionCallback callback) {
DCHECK(device_->SupportedProtocolIsInitialized()) DCHECK(device_->SupportedProtocolIsInitialized())
<< "InitializeAuthenticator() must be called first."; << "InitializeAuthenticator() must be called first.";
// Update the request to the "effective" user verification requirement.
// https://w3c.github.io/webauthn/#effective-user-verification-requirement-for-assertion
DCHECK(Options());
if (Options()->user_verification_availability() ==
AuthenticatorSupportedOptions::UserVerificationAvailability::
kSupportedAndConfigured) {
request.SetUserVerification(UserVerificationRequirement::kRequired);
} else {
request.SetUserVerification(UserVerificationRequirement::kDiscouraged);
}
task_ = std::make_unique<GetAssertionTask>(device_.get(), std::move(request), task_ = std::make_unique<GetAssertionTask>(device_.get(), std::move(request),
std::move(callback)); std::move(callback));
} }
...@@ -65,19 +101,9 @@ base::string16 FidoDeviceAuthenticator::GetDisplayName() const { ...@@ -65,19 +101,9 @@ base::string16 FidoDeviceAuthenticator::GetDisplayName() const {
return device_->GetDisplayName(); return device_->GetDisplayName();
} }
const AuthenticatorSupportedOptions& FidoDeviceAuthenticator::Options() const { const base::Optional<AuthenticatorSupportedOptions>&
static const AuthenticatorSupportedOptions default_options; FidoDeviceAuthenticator::Options() const {
switch (device_->supported_protocol()) { return options_;
case ProtocolVersion::kU2f:
return default_options;
case ProtocolVersion::kCtap:
DCHECK(device_->device_info()) << "uninitialized device";
return device_->device_info()->options();
case ProtocolVersion::kUnknown:
NOTREACHED() << "uninitialized device";
}
NOTREACHED();
return default_options;
} }
FidoTransportProtocol FidoDeviceAuthenticator::AuthenticatorTransport() const { FidoTransportProtocol FidoDeviceAuthenticator::AuthenticatorTransport() const {
......
...@@ -41,7 +41,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) FidoDeviceAuthenticator ...@@ -41,7 +41,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) FidoDeviceAuthenticator
void Cancel() override; void Cancel() override;
std::string GetId() const override; std::string GetId() const override;
base::string16 GetDisplayName() const override; base::string16 GetDisplayName() const override;
const AuthenticatorSupportedOptions& Options() const override; const base::Optional<AuthenticatorSupportedOptions>& Options() const override;
FidoTransportProtocol AuthenticatorTransport() const override; FidoTransportProtocol AuthenticatorTransport() const override;
bool IsInPairingMode() const override; bool IsInPairingMode() const override;
base::WeakPtr<FidoAuthenticator> GetWeakPtr() override; base::WeakPtr<FidoAuthenticator> GetWeakPtr() override;
...@@ -59,7 +59,10 @@ class COMPONENT_EXPORT(DEVICE_FIDO) FidoDeviceAuthenticator ...@@ -59,7 +59,10 @@ class COMPONENT_EXPORT(DEVICE_FIDO) FidoDeviceAuthenticator
void SetTaskForTesting(std::unique_ptr<FidoTask> task); void SetTaskForTesting(std::unique_ptr<FidoTask> task);
private: private:
void InitializeAuthenticatorDone(base::OnceClosure callback);
const std::unique_ptr<FidoDevice> device_; const std::unique_ptr<FidoDevice> device_;
base::Optional<AuthenticatorSupportedOptions> options_;
std::unique_ptr<FidoTask> task_; std::unique_ptr<FidoTask> task_;
base::WeakPtrFactory<FidoDeviceAuthenticator> weak_factory_; base::WeakPtrFactory<FidoDeviceAuthenticator> weak_factory_;
......
...@@ -71,7 +71,8 @@ bool CheckResponseCredentialIdMatchesRequestAllowList( ...@@ -71,7 +71,8 @@ bool CheckResponseCredentialIdMatchesRequestAllowList(
const auto& allow_list = request.allow_list(); const auto& allow_list = request.allow_list();
if (!allow_list || allow_list->empty()) { if (!allow_list || allow_list->empty()) {
// Allow list can't be empty for authenticators w/o resident key support. // Allow list can't be empty for authenticators w/o resident key support.
return authenticator.Options().supports_resident_key(); return !authenticator.Options() ||
authenticator.Options()->supports_resident_key();
} }
// Credential ID may be omitted if allow list has size 1. Otherwise, it needs // Credential ID may be omitted if allow list has size 1. Otherwise, it needs
// to match. // to match.
...@@ -98,36 +99,22 @@ void SetCredentialIdForResponseWithEmptyCredential( ...@@ -98,36 +99,22 @@ void SetCredentialIdForResponseWithEmptyCredential(
} }
// Checks UserVerificationRequirement enum passed from the relying party is // Checks UserVerificationRequirement enum passed from the relying party is
// compatible with the authenticator, and updates the request to the // compatible with the authenticator.
// "effective" user verification requirement.
// https://w3c.github.io/webauthn/#effective-user-verification-requirement-for-assertion
bool CheckUserVerificationCompatible(FidoAuthenticator* authenticator, bool CheckUserVerificationCompatible(FidoAuthenticator* authenticator,
CtapGetAssertionRequest* request) { const CtapGetAssertionRequest& request) {
const auto uv_availability = const auto& opt_options = authenticator->Options();
authenticator->Options().user_verification_availability(); if (!opt_options) {
// This authenticator doesn't know its capabilities yet, so we need
// to assume it can handle the request. This is the case for Windows,
// where we proxy the request to the native API.
return true;
}
switch (request->user_verification()) { return request.user_verification() !=
case UserVerificationRequirement::kRequired: UserVerificationRequirement::kRequired ||
return uv_availability == opt_options->user_verification_availability() ==
AuthenticatorSupportedOptions::UserVerificationAvailability:: AuthenticatorSupportedOptions::UserVerificationAvailability::
kSupportedAndConfigured; kSupportedAndConfigured;
case UserVerificationRequirement::kDiscouraged:
return true;
case UserVerificationRequirement::kPreferred:
if (uv_availability ==
AuthenticatorSupportedOptions::UserVerificationAvailability::
kSupportedAndConfigured) {
request->SetUserVerification(UserVerificationRequirement::kRequired);
} else {
request->SetUserVerification(UserVerificationRequirement::kDiscouraged);
}
return true;
}
NOTREACHED();
return false;
} }
base::flat_set<FidoTransportProtocol> GetTransportsAllowedByRP( base::flat_set<FidoTransportProtocol> GetTransportsAllowedByRP(
...@@ -201,17 +188,12 @@ GetAssertionRequestHandler::~GetAssertionRequestHandler() = default; ...@@ -201,17 +188,12 @@ GetAssertionRequestHandler::~GetAssertionRequestHandler() = default;
void GetAssertionRequestHandler::DispatchRequest( void GetAssertionRequestHandler::DispatchRequest(
FidoAuthenticator* authenticator) { FidoAuthenticator* authenticator) {
// The user verification field of the request may be adjusted to the if (!CheckUserVerificationCompatible(authenticator, request_))
// authenticator, so we need to make a copy.
CtapGetAssertionRequest request_copy = request_;
if (!CheckUserVerificationCompatible(authenticator, &request_copy)) {
return; return;
}
authenticator->GetAssertion( authenticator->GetAssertion(
std::move(request_copy), request_, base::BindOnce(&GetAssertionRequestHandler::HandleResponse,
base::BindOnce(&GetAssertionRequestHandler::HandleResponse, weak_factory_.GetWeakPtr(), authenticator));
weak_factory_.GetWeakPtr(), authenticator));
} }
void GetAssertionRequestHandler::HandleResponse( void GetAssertionRequestHandler::HandleResponse(
......
...@@ -58,7 +58,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) TouchIdAuthenticator ...@@ -58,7 +58,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) TouchIdAuthenticator
void Cancel() override; void Cancel() override;
std::string GetId() const override; std::string GetId() const override;
base::string16 GetDisplayName() const override; base::string16 GetDisplayName() const override;
const AuthenticatorSupportedOptions& Options() const override; const base::Optional<AuthenticatorSupportedOptions>& Options() const override;
FidoTransportProtocol AuthenticatorTransport() const override; FidoTransportProtocol AuthenticatorTransport() const override;
bool IsInPairingMode() const override; bool IsInPairingMode() const override;
base::WeakPtr<FidoAuthenticator> GetWeakPtr() override; base::WeakPtr<FidoAuthenticator> GetWeakPtr() override;
......
...@@ -155,8 +155,9 @@ AuthenticatorSupportedOptions TouchIdAuthenticatorOptions() { ...@@ -155,8 +155,9 @@ AuthenticatorSupportedOptions TouchIdAuthenticatorOptions() {
} // namespace } // namespace
const AuthenticatorSupportedOptions& TouchIdAuthenticator::Options() const { const base::Optional<AuthenticatorSupportedOptions>&
static const AuthenticatorSupportedOptions options = TouchIdAuthenticator::Options() const {
static const base::Optional<AuthenticatorSupportedOptions> options =
TouchIdAuthenticatorOptions(); TouchIdAuthenticatorOptions();
return options; return options;
} }
......
...@@ -22,39 +22,35 @@ namespace { ...@@ -22,39 +22,35 @@ namespace {
bool CheckIfAuthenticatorSelectionCriteriaAreSatisfied( bool CheckIfAuthenticatorSelectionCriteriaAreSatisfied(
FidoAuthenticator* authenticator, FidoAuthenticator* authenticator,
const AuthenticatorSelectionCriteria& authenticator_selection_criteria, const AuthenticatorSelectionCriteria& authenticator_selection_criteria) {
CtapMakeCredentialRequest* request) {
using AuthenticatorAttachment = using AuthenticatorAttachment =
AuthenticatorSelectionCriteria::AuthenticatorAttachment; AuthenticatorSelectionCriteria::AuthenticatorAttachment;
using UvAvailability = using UvAvailability =
AuthenticatorSupportedOptions::UserVerificationAvailability; AuthenticatorSupportedOptions::UserVerificationAvailability;
const auto& options = authenticator->Options(); const auto& opt_options = authenticator->Options();
if (!opt_options) {
// This authenticator doesn't know its capabilities yet, so we need
// to assume it can handle the request. This is the case for Windows,
// where we proxy the request to the native API.
return true;
}
if ((authenticator_selection_criteria.authenticator_attachement() == if ((authenticator_selection_criteria.authenticator_attachement() ==
AuthenticatorAttachment::kPlatform && AuthenticatorAttachment::kPlatform &&
!options.is_platform_device()) || !opt_options->is_platform_device()) ||
(authenticator_selection_criteria.authenticator_attachement() == (authenticator_selection_criteria.authenticator_attachement() ==
AuthenticatorAttachment::kCrossPlatform && AuthenticatorAttachment::kCrossPlatform &&
options.is_platform_device())) { opt_options->is_platform_device()))
return false; return false;
}
if (authenticator_selection_criteria.require_resident_key() && if (authenticator_selection_criteria.require_resident_key() &&
!options.supports_resident_key()) { !opt_options->supports_resident_key())
return false; return false;
}
request->SetResidentKeySupported(
authenticator_selection_criteria.require_resident_key());
const auto& user_verification_requirement =
authenticator_selection_criteria.user_verification_requirement();
if (user_verification_requirement == UserVerificationRequirement::kRequired) {
request->SetUserVerificationRequired(true);
}
return user_verification_requirement != return authenticator_selection_criteria.user_verification_requirement() !=
UserVerificationRequirement::kRequired || UserVerificationRequirement::kRequired ||
options.user_verification_availability() == opt_options->user_verification_availability() ==
UvAvailability::kSupportedAndConfigured; UvAvailability::kSupportedAndConfigured;
} }
...@@ -112,16 +108,12 @@ MakeCredentialRequestHandler::~MakeCredentialRequestHandler() = default; ...@@ -112,16 +108,12 @@ MakeCredentialRequestHandler::~MakeCredentialRequestHandler() = default;
void MakeCredentialRequestHandler::DispatchRequest( void MakeCredentialRequestHandler::DispatchRequest(
FidoAuthenticator* authenticator) { FidoAuthenticator* authenticator) {
// The user verification field of the request may be adjusted to the
// authenticator, so we need to make a copy.
CtapMakeCredentialRequest request_copy = request_parameter_;
if (!CheckIfAuthenticatorSelectionCriteriaAreSatisfied( if (!CheckIfAuthenticatorSelectionCriteriaAreSatisfied(
authenticator, authenticator_selection_criteria_, &request_copy)) { authenticator, authenticator_selection_criteria_))
return; return;
}
authenticator->MakeCredential( authenticator->MakeCredential(
std::move(request_copy), request_parameter_,
base::BindOnce(&MakeCredentialRequestHandler::HandleResponse, base::BindOnce(&MakeCredentialRequestHandler::HandleResponse,
weak_factory_.GetWeakPtr(), authenticator)); weak_factory_.GetWeakPtr(), authenticator));
} }
......
...@@ -35,25 +35,6 @@ base::string16 OptionalGURLToUTF16(const base::Optional<GURL>& in) { ...@@ -35,25 +35,6 @@ base::string16 OptionalGURLToUTF16(const base::Optional<GURL>& in) {
return in ? base::UTF8ToUTF16(in->spec()) : base::string16(); return in ? base::UTF8ToUTF16(in->spec()) : base::string16();
} }
AuthenticatorSupportedOptions WinNativeCrossPlatformAuthenticatorOptions() {
AuthenticatorSupportedOptions options;
// Both MakeCredential and GetAssertion force CROSS_PLATFORM (in CTAP- and in
// U2F mode).
options.SetIsPlatformDevice(false);
// We don't know whether any of the connected USB devices support certain
// features such as resident keys, client PINs or UV/UP; but they might, and
// the platform supports them, so we set the "maximum" feature set here.
options.SetSupportsResidentKey(true);
options.SetClientPinAvailability(
AuthenticatorSupportedOptions::ClientPinAvailability::
kSupportedButPinNotSet);
options.SetUserVerificationAvailability(
AuthenticatorSupportedOptions::UserVerificationAvailability::
kSupportedAndConfigured);
options.SetUserPresenceRequired(true);
return options;
}
} // namespace } // namespace
WinNativeCrossPlatformAuthenticator::WinNativeCrossPlatformAuthenticator( WinNativeCrossPlatformAuthenticator::WinNativeCrossPlatformAuthenticator(
...@@ -389,11 +370,14 @@ WinNativeCrossPlatformAuthenticator::AuthenticatorTransport() const { ...@@ -389,11 +370,14 @@ WinNativeCrossPlatformAuthenticator::AuthenticatorTransport() const {
return FidoTransportProtocol::kUsbHumanInterfaceDevice; return FidoTransportProtocol::kUsbHumanInterfaceDevice;
} }
const AuthenticatorSupportedOptions& const base::Optional<AuthenticatorSupportedOptions>&
WinNativeCrossPlatformAuthenticator::Options() const { WinNativeCrossPlatformAuthenticator::Options() const {
static const AuthenticatorSupportedOptions options = // The request can potentially be fulfilled by any device that Windows
WinNativeCrossPlatformAuthenticatorOptions(); // communicates with, so returning AuthenticatorSupportedOptions really
return options; // doesn't make much sense.
static const base::Optional<AuthenticatorSupportedOptions> no_options =
base::nullopt;
return no_options;
} }
base::WeakPtr<FidoAuthenticator> base::WeakPtr<FidoAuthenticator>
......
...@@ -53,7 +53,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) WinNativeCrossPlatformAuthenticator ...@@ -53,7 +53,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) WinNativeCrossPlatformAuthenticator
std::string GetId() const override; std::string GetId() const override;
base::string16 GetDisplayName() const override; base::string16 GetDisplayName() const override;
bool IsInPairingMode() const override; bool IsInPairingMode() const override;
const AuthenticatorSupportedOptions& Options() const override; const base::Optional<AuthenticatorSupportedOptions>& Options() const override;
FidoTransportProtocol AuthenticatorTransport() const override; FidoTransportProtocol AuthenticatorTransport() const override;
base::WeakPtr<FidoAuthenticator> GetWeakPtr() override; base::WeakPtr<FidoAuthenticator> GetWeakPtr() override;
......
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