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