Commit 8cd3170a authored by Martin Kreichgauer's avatar Martin Kreichgauer Committed by Commit Bot

fido: plumb AuthenticatorAttachment into CtapMakeCredentialRequest

This adds an AuthenticatorAttachment field to
CtapMakeCredentialRequest. The field is initialized by
MakeCredentialRequestHandler from the equivalent field on its
AuthenticatorSelectionCriteria parameter, and is consumed by
WinNativeApiAuthenticator to initialize the equivalent parameter passed
to the Windows WebAuthn API.

Also moves the AuthenticatorAttachment enum out of
AuthenticatorSelectionCriteria and into fido_constants.h, and fixes a
common misspelling of attachment throughout the code.

Also migrates the allowList and excludeList parameters of the Windows
WebAuthn API to an updated version that respects the
PublicKeyCredentialDescriptor's transports field.

Bug: 898718
Change-Id: I4dbc80929fcb6c4ff534822acd4b80410c14ae7f
Reviewed-on: https://chromium-review.googlesource.com/c/1335785
Commit-Queue: Martin Kreichgauer <martinkr@chromium.org>
Reviewed-by: default avatarKim Paulhamus <kpaulhamus@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarAdam Langley <agl@chromium.org>
Cr-Commit-Position: refs/heads/master@{#608631}
parent aad98611
......@@ -116,10 +116,10 @@ TypeConverter<std::vector<::device::PublicKeyCredentialDescriptor>,
}
// static
::device::UserVerificationRequirement
TypeConverter<::device::UserVerificationRequirement,
UserVerificationRequirement>::
Convert(const UserVerificationRequirement& input) {
::device::UserVerificationRequirement TypeConverter<
::device::UserVerificationRequirement,
UserVerificationRequirement>::Convert(const UserVerificationRequirement&
input) {
switch (input) {
case UserVerificationRequirement::PREFERRED:
return ::device::UserVerificationRequirement::kPreferred;
......@@ -133,23 +133,19 @@ TypeConverter<::device::UserVerificationRequirement,
}
// static
::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment TypeConverter<
::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment,
::device::AuthenticatorAttachment TypeConverter<
::device::AuthenticatorAttachment,
AuthenticatorAttachment>::Convert(const AuthenticatorAttachment& input) {
switch (input) {
case AuthenticatorAttachment::NO_PREFERENCE:
return ::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kAny;
return ::device::AuthenticatorAttachment::kAny;
case AuthenticatorAttachment::PLATFORM:
return ::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kPlatform;
return ::device::AuthenticatorAttachment::kPlatform;
case AuthenticatorAttachment::CROSS_PLATFORM:
return ::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kCrossPlatform;
return ::device::AuthenticatorAttachment::kCrossPlatform;
}
NOTREACHED();
return ::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kAny;
return ::device::AuthenticatorAttachment::kAny;
}
// static
......@@ -158,8 +154,7 @@ TypeConverter<::device::AuthenticatorSelectionCriteria,
AuthenticatorSelectionCriteriaPtr>::
Convert(const AuthenticatorSelectionCriteriaPtr& input) {
return device::AuthenticatorSelectionCriteria(
ConvertTo<
::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment>(
ConvertTo<::device::AuthenticatorAttachment>(
input->authenticator_attachment),
input->require_resident_key,
ConvertTo<::device::UserVerificationRequirement>(
......
......@@ -9,6 +9,7 @@
#include "device/fido/authenticator_selection_criteria.h"
#include "device/fido/cable/cable_discovery_data.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_transport_protocol.h"
#include "device/fido/public_key_credential_descriptor.h"
#include "device/fido/public_key_credential_params.h"
......@@ -62,11 +63,10 @@ struct TypeConverter<
};
template <>
struct TypeConverter<
::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment,
struct TypeConverter<::device::AuthenticatorAttachment,
::blink::mojom::AuthenticatorAttachment> {
static ::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment
Convert(const ::blink::mojom::AuthenticatorAttachment& input);
static ::device::AuthenticatorAttachment Convert(
const ::blink::mojom::AuthenticatorAttachment& input);
};
template <>
......
......@@ -9,10 +9,10 @@ namespace device {
AuthenticatorSelectionCriteria::AuthenticatorSelectionCriteria() = default;
AuthenticatorSelectionCriteria::AuthenticatorSelectionCriteria(
AuthenticatorAttachment authenticator_attachement,
AuthenticatorAttachment authenticator_attachment,
bool require_resident_key,
UserVerificationRequirement user_verification_requirement)
: authenticator_attachement_(authenticator_attachement),
: authenticator_attachment_(authenticator_attachment),
require_resident_key_(require_resident_key),
user_verification_requirement_(user_verification_requirement) {}
......
......@@ -15,15 +15,9 @@ namespace device {
// https://w3c.github.io/webauthn/#authenticatorSelection
class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorSelectionCriteria {
public:
enum class AuthenticatorAttachment {
kAny,
kPlatform,
kCrossPlatform,
};
AuthenticatorSelectionCriteria();
AuthenticatorSelectionCriteria(
AuthenticatorAttachment authenticator_attachement,
AuthenticatorAttachment authenticator_attachment,
bool require_resident_key,
UserVerificationRequirement user_verification_requirement);
AuthenticatorSelectionCriteria(const AuthenticatorSelectionCriteria& other);
......@@ -34,8 +28,8 @@ class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorSelectionCriteria {
AuthenticatorSelectionCriteria&& other);
~AuthenticatorSelectionCriteria();
AuthenticatorAttachment authenticator_attachement() const {
return authenticator_attachement_;
AuthenticatorAttachment authenticator_attachment() const {
return authenticator_attachment_;
}
bool require_resident_key() const { return require_resident_key_; }
......@@ -45,7 +39,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorSelectionCriteria {
}
private:
AuthenticatorAttachment authenticator_attachement_ =
AuthenticatorAttachment authenticator_attachment_ =
AuthenticatorAttachment::kAny;
bool require_resident_key_ = false;
UserVerificationRequirement user_verification_requirement_ =
......
......@@ -96,6 +96,13 @@ std::vector<uint8_t> CtapMakeCredentialRequest::EncodeAsCBOR() const {
return cbor_request;
}
CtapMakeCredentialRequest&
CtapMakeCredentialRequest::SetAuthenticatorAttachment(
AuthenticatorAttachment authenticator_attachment) {
authenticator_attachment_ = authenticator_attachment;
return *this;
}
CtapMakeCredentialRequest& CtapMakeCredentialRequest::SetUserVerification(
UserVerificationRequirement user_verification) {
user_verification_ = user_verification;
......
......@@ -15,6 +15,7 @@
#include "base/containers/span.h"
#include "base/macros.h"
#include "base/optional.h"
#include "device/fido/fido_constants.h"
#include "device/fido/public_key_credential_descriptor.h"
#include "device/fido/public_key_credential_params.h"
#include "device/fido/public_key_credential_rp_entity.h"
......@@ -45,6 +46,8 @@ class COMPONENT_EXPORT(DEVICE_FIDO) CtapMakeCredentialRequest {
// https://drafts.fidoalliance.org/fido-2/latest/fido-client-to-authenticator-protocol-v2.0-wd-20180305.html#authenticatorMakeCredential
std::vector<uint8_t> EncodeAsCBOR() const;
CtapMakeCredentialRequest& SetAuthenticatorAttachment(
AuthenticatorAttachment authenticator_attachment);
CtapMakeCredentialRequest& SetUserVerification(
UserVerificationRequirement user_verification);
CtapMakeCredentialRequest& SetResidentKeyRequired(bool resident_key);
......@@ -68,6 +71,9 @@ class COMPONENT_EXPORT(DEVICE_FIDO) CtapMakeCredentialRequest {
UserVerificationRequirement user_verification() const {
return user_verification_;
}
AuthenticatorAttachment authenticator_attachment() const {
return authenticator_attachment_;
}
bool resident_key_required() const { return resident_key_required_; }
bool is_individual_attestation() const { return is_individual_attestation_; }
bool hmac_secret() const { return hmac_secret_; }
......@@ -87,6 +93,8 @@ class COMPONENT_EXPORT(DEVICE_FIDO) CtapMakeCredentialRequest {
PublicKeyCredentialParams public_key_credential_params_;
UserVerificationRequirement user_verification_ =
UserVerificationRequirement::kPreferred;
AuthenticatorAttachment authenticator_attachment_ =
AuthenticatorAttachment::kAny;
bool resident_key_required_ = false;
bool is_individual_attestation_ = false;
// hmac_secret_ indicates whether the "hmac-secret" extension should be
......
......@@ -255,6 +255,16 @@ enum class U2fApduInstruction : uint8_t {
enum class CredentialType { kPublicKey };
// Authenticator attachment constraint passed on from the relying party as a
// parameter for AuthenticatorSelectionCriteria. |kAny| is equivalent to the
// (optional) attachment field not being present.
// https://w3c.github.io/webauthn/#attachment
enum class AuthenticatorAttachment {
kAny,
kPlatform,
kCrossPlatform,
};
// User verification constraint passed on from the relying party as a parameter
// for AuthenticatorSelectionCriteria and for CtapGetAssertion request.
// https://w3c.github.io/webauthn/#enumdef-userverificationrequirement
......
......@@ -215,8 +215,7 @@ TEST_F(FidoMakeCredentialHandlerTest, U2fRegisterWithUserVerificationRequired) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
false /* require_resident_key */,
AuthenticatorAttachment::kAny, false /* require_resident_key */,
UserVerificationRequirement::kRequired));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -231,8 +230,7 @@ TEST_F(FidoMakeCredentialHandlerTest, U2fRegisterWithResidentKeyRequirement) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
true /* require_resident_key */,
AuthenticatorAttachment::kAny, true /* require_resident_key */,
UserVerificationRequirement::kPreferred));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -247,8 +245,7 @@ TEST_F(FidoMakeCredentialHandlerTest, UserVerificationRequirementNotMet) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
false /* require_resident_key */,
AuthenticatorAttachment::kAny, false /* require_resident_key */,
UserVerificationRequirement::kRequired));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -271,8 +268,7 @@ TEST_F(FidoMakeCredentialHandlerTest, AnyAttachment) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
false /* require_resident_key */,
AuthenticatorAttachment::kAny, false /* require_resident_key */,
UserVerificationRequirement::kPreferred));
// MakeCredentialHandler will not dispatch the kAny request to the platform
......@@ -294,8 +290,7 @@ TEST_F(FidoMakeCredentialHandlerTest, CrossPlatformAttachment) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kCrossPlatform,
AuthenticatorAttachment::kCrossPlatform,
false /* require_resident_key */,
UserVerificationRequirement::kPreferred));
......@@ -320,8 +315,7 @@ TEST_F(FidoMakeCredentialHandlerTest, PlatformAttachment) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kPlatform,
AuthenticatorAttachment::kPlatform,
false /* require_resident_key */,
UserVerificationRequirement::kRequired));
......@@ -333,8 +327,7 @@ TEST_F(FidoMakeCredentialHandlerTest, ResidentKeyRequirementNotMet) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
true /* require_resident_key */,
AuthenticatorAttachment::kAny, true /* require_resident_key */,
UserVerificationRequirement::kPreferred));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -352,8 +345,7 @@ TEST_F(FidoMakeCredentialHandlerTest,
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kCrossPlatform,
AuthenticatorAttachment::kCrossPlatform,
true /* require_resident_key */,
UserVerificationRequirement::kRequired));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -392,8 +384,7 @@ TEST_F(FidoMakeCredentialHandlerTest,
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kPlatform,
AuthenticatorAttachment::kPlatform,
true /* require_resident_key */,
UserVerificationRequirement::kRequired));
......@@ -412,8 +403,7 @@ TEST_F(FidoMakeCredentialHandlerTest,
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kCrossPlatform,
AuthenticatorAttachment::kCrossPlatform,
false /* require_resident_key */,
UserVerificationRequirement::kPreferred));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -443,8 +433,7 @@ TEST_F(FidoMakeCredentialHandlerTest,
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kPlatform,
AuthenticatorAttachment::kPlatform,
true /* require_resident_key */,
UserVerificationRequirement::kRequired));
......@@ -463,8 +452,7 @@ TEST_F(FidoMakeCredentialHandlerTest, SupportedTransportsAreOnlyBleAndNfc) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kCrossPlatform,
AuthenticatorAttachment::kCrossPlatform,
false /* require_resident_key */,
UserVerificationRequirement::kPreferred));
......@@ -475,8 +463,7 @@ TEST_F(FidoMakeCredentialHandlerTest, IncorrectRpIdHash) {
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
false /* require_resident_key */,
AuthenticatorAttachment::kAny, false /* require_resident_key */,
UserVerificationRequirement::kPreferred));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -503,8 +490,7 @@ TEST_F(FidoMakeCredentialHandlerTest,
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
true /* require_resident_key */,
AuthenticatorAttachment::kAny, true /* require_resident_key */,
UserVerificationRequirement::kPreferred));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -523,8 +509,7 @@ TEST_F(FidoMakeCredentialHandlerTest,
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
true /* require_resident_key */,
AuthenticatorAttachment::kAny, true /* require_resident_key */,
UserVerificationRequirement::kPreferred));
discovery()->WaitForCallToStartAndSimulateSuccess();
......@@ -550,8 +535,7 @@ TEST_F(FidoMakeCredentialHandlerTest,
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::
kPlatform,
AuthenticatorAttachment::kPlatform,
false /* require_resident_key */,
UserVerificationRequirement::kPreferred));
......@@ -572,8 +556,7 @@ TEST_F(FidoMakeCredentialHandlerTest,
auto request_handler =
CreateMakeCredentialHandlerWithAuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria(
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny,
false /* require_resident_key */,
AuthenticatorAttachment::kAny, false /* require_resident_key */,
UserVerificationRequirement::kPreferred));
discovery()->WaitForCallToStartAndSimulateSuccess();
......
......@@ -23,8 +23,6 @@ namespace {
bool CheckIfAuthenticatorSelectionCriteriaAreSatisfied(
FidoAuthenticator* authenticator,
const AuthenticatorSelectionCriteria& authenticator_selection_criteria) {
using AuthenticatorAttachment =
AuthenticatorSelectionCriteria::AuthenticatorAttachment;
using UvAvailability =
AuthenticatorSupportedOptions::UserVerificationAvailability;
......@@ -36,10 +34,10 @@ bool CheckIfAuthenticatorSelectionCriteriaAreSatisfied(
return true;
}
if ((authenticator_selection_criteria.authenticator_attachement() ==
if ((authenticator_selection_criteria.authenticator_attachment() ==
AuthenticatorAttachment::kPlatform &&
!opt_options->is_platform_device()) ||
(authenticator_selection_criteria.authenticator_attachement() ==
(authenticator_selection_criteria.authenticator_attachment() ==
AuthenticatorAttachment::kCrossPlatform &&
opt_options->is_platform_device()))
return false;
......@@ -56,19 +54,17 @@ bool CheckIfAuthenticatorSelectionCriteriaAreSatisfied(
base::flat_set<FidoTransportProtocol> GetTransportsAllowedByRP(
const AuthenticatorSelectionCriteria& authenticator_selection_criteria) {
using AttachmentType =
AuthenticatorSelectionCriteria::AuthenticatorAttachment;
const auto attachment_type =
authenticator_selection_criteria.authenticator_attachement();
authenticator_selection_criteria.authenticator_attachment();
switch (attachment_type) {
case AttachmentType::kPlatform:
case AuthenticatorAttachment::kPlatform:
return {FidoTransportProtocol::kInternal};
case AttachmentType::kCrossPlatform:
case AuthenticatorAttachment::kCrossPlatform:
// Cloud-assisted BLE is not yet supported for MakeCredential requests.
return {FidoTransportProtocol::kUsbHumanInterfaceDevice,
FidoTransportProtocol::kBluetoothLowEnergy,
FidoTransportProtocol::kNearFieldCommunication};
case AttachmentType::kAny:
case AuthenticatorAttachment::kAny:
// Cloud-assisted BLE is not yet supported for MakeCredential requests.
return {FidoTransportProtocol::kInternal,
FidoTransportProtocol::kNearFieldCommunication,
......@@ -112,12 +108,16 @@ void MakeCredentialRequestHandler::DispatchRequest(
authenticator, authenticator_selection_criteria_))
return;
// Set the rk and uv fields, which were only initialized to default values
// up to here.
// Set the rk, uv and attachment fields, which were only initialized to
// default values up to here. TODO(martinkr): Initialize these fields earlier
// (in AuthenticatorImpl) and get rid of the separate
// AuthenticatorSelectionCriteriaParameter.
request_parameter_.SetResidentKeyRequired(
authenticator_selection_criteria_.require_resident_key());
request_parameter_.SetUserVerification(
authenticator_selection_criteria_.user_verification_requirement());
request_parameter_.SetAuthenticatorAttachment(
authenticator_selection_criteria_.authenticator_attachment());
authenticator->MakeCredential(
request_parameter_,
......@@ -156,8 +156,8 @@ void MakeCredentialRequestHandler::SetPlatformAuthenticatorOrMarkUnavailable(
const bool has_transport_selection_ui =
observer() && observer()->EmbedderControlsAuthenticatorDispatch(
*platform_authenticator_info->authenticator);
if (authenticator_selection_criteria_.authenticator_attachement() ==
AuthenticatorSelectionCriteria::AuthenticatorAttachment::kAny &&
if (authenticator_selection_criteria_.authenticator_attachment() ==
AuthenticatorAttachment::kAny &&
!has_transport_selection_ui) {
platform_authenticator_info = base::nullopt;
}
......
......@@ -171,15 +171,6 @@ void WinWebAuthnApiAuthenticator::MakeCredentialBlocking(
request.client_data_json().data())),
WEBAUTHN_HASH_ALGORITHM_SHA_256};
std::vector<WEBAUTHN_CREDENTIAL> exclude_list;
if (request.exclude_list()) {
for (const PublicKeyCredentialDescriptor& desc : *request.exclude_list()) {
exclude_list.push_back(WEBAUTHN_CREDENTIAL{
WEBAUTHN_CREDENTIAL_CURRENT_VERSION, desc.id().size(),
const_cast<unsigned char*>(desc.id().data())});
}
}
std::vector<WEBAUTHN_EXTENSION> extensions;
if (request.hmac_secret()) {
static BOOL kHMACSecretTrue = TRUE;
......@@ -188,19 +179,28 @@ void WinWebAuthnApiAuthenticator::MakeCredentialBlocking(
sizeof(BOOL), static_cast<void*>(&kHMACSecretTrue)});
}
std::vector<_WEBAUTHN_CREDENTIAL_EX> exclude_list =
ToWinCredentialExVector(request.exclude_list());
auto* exclude_list_ptr = exclude_list.data();
_WEBAUTHN_CREDENTIAL_LIST exclude_credential_list{exclude_list.size(),
&exclude_list_ptr};
WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS make_credential_options{
WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION,
WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3,
kWinWebAuthnTimeoutMilliseconds,
WEBAUTHN_CREDENTIALS{exclude_list.size(), exclude_list.data()},
WEBAUTHN_CREDENTIALS{
0, nullptr}, // Ignored because pExcludeCredentialList is set.
WEBAUTHN_EXTENSIONS{extensions.size(), extensions.data()},
// TODO(martinkr): Plumb authenticator attachment into
// CtapMakeCredentialRequest and set here.
use_u2f_only_ ? WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM_U2F_V2
: WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY,
use_u2f_only_
? WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM_U2F_V2
: ToWinAuthenticatorAttachment(request.authenticator_attachment()),
request.resident_key_required(),
ToWinUserVerificationRequirement(request.user_verification()),
WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT, 0 /* flags */,
&cancellation_id_};
WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT,
0 /* flags */,
&cancellation_id_,
&exclude_credential_list,
};
// |credential_attestation| must not not outlive |win_api_|.
WinWebAuthnApi::ScopedCredentialAttestation credential_attestation;
......@@ -276,15 +276,7 @@ void WinWebAuthnApiAuthenticator::GetAssertionBlocking(
CtapGetAssertionRequest request,
GetAssertionCallback callback,
scoped_refptr<base::SequencedTaskRunner> callback_runner) {
std::vector<WEBAUTHN_CREDENTIAL> allow_list;
if (request.allow_list()) {
for (const PublicKeyCredentialDescriptor& desc : *request.allow_list()) {
allow_list.push_back(WEBAUTHN_CREDENTIAL{
WEBAUTHN_CREDENTIAL_CURRENT_VERSION, desc.id().size(),
const_cast<unsigned char*>(desc.id().data()),
WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY});
}
}
static BOOL kUseAppIdTrue = TRUE; // const
base::string16 rp_id16 = base::UTF8ToUTF16(request.rp_id());
......@@ -294,21 +286,26 @@ void WinWebAuthnApiAuthenticator::GetAssertionBlocking(
request.client_data_json().data())),
WEBAUTHN_HASH_ALGORITHM_SHA_256};
static BOOL kUseAppIdTrue = TRUE;
std::vector<_WEBAUTHN_CREDENTIAL_EX> allow_list =
ToWinCredentialExVector(request.allow_list());
auto* allow_list_ptr = allow_list.data();
_WEBAUTHN_CREDENTIAL_LIST allow_credential_list{allow_list.size(),
&allow_list_ptr};
WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS get_assertion_options{
WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION,
WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4,
kWinWebAuthnTimeoutMilliseconds,
WEBAUTHN_CREDENTIALS{allow_list.size(), allow_list.data()},
WEBAUTHN_CREDENTIALS{
0, nullptr}, // Ignored because pAllowCredentialList is set.
WEBAUTHN_EXTENSIONS{0, nullptr},
// TODO(martinkr): Plumb authenticator attachment into
// CtapMakeCredentialRequest and set here.
// Note that attachment is effectively restricted via |allow_list|.
use_u2f_only_ ? WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM_U2F_V2
: WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY,
ToWinUserVerificationRequirement(request.user_verification()),
0, // flags
use_u2f_only_ ? rp_id16.c_str() : nullptr, // pwszU2fAppId
use_u2f_only_ ? &kUseAppIdTrue : nullptr, // pbU2fAppId
&cancellation_id_,
&cancellation_id_, &allow_credential_list,
};
// |assertion| must not not outlive |win_api_|.
......
......@@ -94,6 +94,66 @@ uint32_t ToWinUserVerificationRequirement(
return WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED;
}
uint32_t ToWinAuthenticatorAttachment(
AuthenticatorAttachment authenticator_attachment) {
switch (authenticator_attachment) {
case AuthenticatorAttachment::kAny:
return WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY;
case AuthenticatorAttachment::kPlatform:
return WEBAUTHN_AUTHENTICATOR_ATTACHMENT_PLATFORM;
case AuthenticatorAttachment::kCrossPlatform:
return WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM;
}
NOTREACHED();
return WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY;
}
static uint32_t ToWinTransportsMask(
const base::flat_set<FidoTransportProtocol>& transports) {
uint32_t result = 0;
for (const FidoTransportProtocol transport : transports) {
switch (transport) {
case FidoTransportProtocol::kUsbHumanInterfaceDevice:
result |= WEBAUTHN_CTAP_TRANSPORT_USB;
break;
case FidoTransportProtocol::kNearFieldCommunication:
result |= WEBAUTHN_CTAP_TRANSPORT_NFC;
break;
case FidoTransportProtocol::kBluetoothLowEnergy:
result |= WEBAUTHN_CTAP_TRANSPORT_BLE;
break;
case FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy:
// caBLE is unsupported by the Windows API.
break;
case FidoTransportProtocol::kInternal:
result |= WEBAUTHN_CTAP_TRANSPORT_INTERNAL;
break;
}
}
return result;
}
std::vector<_WEBAUTHN_CREDENTIAL_EX> ToWinCredentialExVector(
const base::Optional<std::vector<PublicKeyCredentialDescriptor>>&
credentials) {
std::vector<_WEBAUTHN_CREDENTIAL_EX> result;
if (!credentials) {
return {};
}
for (const auto& credential : *credentials) {
if (credential.credential_type() != CredentialType::kPublicKey) {
continue;
}
result.push_back(_WEBAUTHN_CREDENTIAL_EX{
WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION, credential.id().size(),
const_cast<unsigned char*>(credential.id().data()),
WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY,
ToWinTransportsMask(credential.transports())});
}
return result;
}
CtapDeviceResponseCode WinErrorNameToCtapDeviceResponseCode(
const base::string16& error_name) {
// TODO(crbug/896522): Another mismatch of our authenticator models. Windows
......
......@@ -31,6 +31,15 @@ COMPONENT_EXPORT(DEVICE_FIDO)
uint32_t ToWinUserVerificationRequirement(
UserVerificationRequirement user_verification_requirement);
COMPONENT_EXPORT(DEVICE_FIDO)
uint32_t ToWinAuthenticatorAttachment(
AuthenticatorAttachment authenticator_attachment);
COMPONENT_EXPORT(DEVICE_FIDO)
std::vector<_WEBAUTHN_CREDENTIAL_EX> ToWinCredentialExVector(
const base::Optional<std::vector<PublicKeyCredentialDescriptor>>&
credentials);
COMPONENT_EXPORT(DEVICE_FIDO)
CtapDeviceResponseCode WinErrorNameToCtapDeviceResponseCode(
const base::string16& error_name);
......
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