Commit a2694d17 authored by Nina Satragno's avatar Nina Satragno Committed by Commit Bot

[webauthn] Default to ES256 and RS256 algorithms

When a relying party sends an empty pubKeyCredParams, default to a list
containing ES256 and RS256 instead of returning an error.

See https://w3c.github.io/webauthn/#sctn-createCredential step 8.

This also touches up WPTs exercising this behaviour.

Fixed: 1064689
Change-Id: I599fd57f9eccea5aa26144e10e41009980fda79c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2132644
Auto-Submit: Nina Satragno <nsatragno@chromium.org>
Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Commit-Queue: Nina Satragno <nsatragno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#755836}
parent b53cba99
......@@ -54,6 +54,20 @@ using blink::mojom::blink::PublicKeyCredentialRequestOptionsPtr;
using blink::mojom::blink::PublicKeyCredentialType;
using blink::mojom::blink::UserVerificationRequirement;
namespace {
static constexpr int kCoseEs256 = -7;
static constexpr int kCoseRs256 = -257;
PublicKeyCredentialParametersPtr CreatePublicKeyCredentialParameter(int alg) {
auto mojo_parameter = PublicKeyCredentialParameters::New();
mojo_parameter->type = PublicKeyCredentialType::PUBLIC_KEY;
mojo_parameter->algorithm_identifier = alg;
return mojo_parameter;
}
} // namespace
// static
CredentialInfoPtr TypeConverter<CredentialInfoPtr, blink::Credential*>::Convert(
blink::Credential* credential) {
......@@ -391,25 +405,27 @@ TypeConverter<PublicKeyCredentialCreationOptionsPtr,
}
mojo_options->challenge = ConvertTo<Vector<uint8_t>>(options->challenge());
// Step 4 of https://w3c.github.io/webauthn/#createCredential
if (options->hasTimeout()) {
mojo_options->timeout =
base::TimeDelta::FromMilliseconds(options->timeout());
}
// Steps 8 and 9 of
// https://www.w3.org/TR/2017/WD-webauthn-20170505/#createCredential
// Steps 7 and 8 of https://w3c.github.io/webauthn/#sctn-createCredential
Vector<PublicKeyCredentialParametersPtr> parameters;
for (auto& parameter : options->pubKeyCredParams()) {
PublicKeyCredentialParametersPtr normalized_parameter =
PublicKeyCredentialParameters::From(parameter.Get());
if (normalized_parameter) {
parameters.push_back(std::move(normalized_parameter));
if (options->pubKeyCredParams().size() == 0) {
parameters.push_back(CreatePublicKeyCredentialParameter(kCoseEs256));
parameters.push_back(CreatePublicKeyCredentialParameter(kCoseRs256));
} else {
for (auto& parameter : options->pubKeyCredParams()) {
PublicKeyCredentialParametersPtr normalized_parameter =
PublicKeyCredentialParameters::From(parameter.Get());
if (normalized_parameter) {
parameters.push_back(std::move(normalized_parameter));
}
}
if (parameters.IsEmpty()) {
return nullptr;
}
}
if (parameters.IsEmpty() && options->hasPubKeyCredParams()) {
return nullptr;
}
mojo_options->public_key_parameters = std::move(parameters);
......
This is a testharness.js-based test.
PASS passing credentials.create() with default arguments
PASS passing credentials.create() with rpId (hostname)
PASS passing credentials.create() without rp.icon
PASS very short user id
PASS max length user id
PASS Uint8Array user id
PASS Int8Array user id
PASS Int16Array user id
PASS Int32Array user id
PASS Float32Array user id
PASS DataView user id
PASS passing credentials.create() without user.icon
PASS Int16Array challenge
PASS Int32Array challenge
PASS Float32Array challenge
PASS Float64Array challenge
PASS DataView challenge
PASS Absurdly large challenge
FAIL Bad pubKeyCredParams: pubKeyCredParams is empty Array promise_test: Unhandled rejection with value: object "NotSupportedError: Required parameters missing in `options.publicKey`."
PASS EC256 pubKeyCredParams
PASS SelectEC256 pubKeyCredParams from a list
PASS passing credentials.create() with no timeout
PASS authenticatorSelection is undefined
PASS authenticatorSelection is empty object
PASS authenticatorSelection default values
PASS authenticatorSelection attachment undefined
PASS authenticatorSelection residentKey undefined
PASS authenticatorSelection residentKey false
PASS authenticatorSelection userVerification undefined
PASS authenticatorSelection userVerification discouraged
PASS attestation parameter: attestation is "none"
PASS attestation parameter: attestation is "indirect"
PASS attestation parameter: attestation is "direct"
PASS attestation parameter: attestation is undefined
PASS extensions undefined
PASS extensions are empty object
PASS extensions are dict of empty strings
PASS Clean up the test environment
Harness: the test ran to completion.
......@@ -46,7 +46,8 @@ standardSetup(function() {
new CreateCredentialsTest("options.publicKey.challenge", new ArrayBuffer(8192)).runTest("Absurdly large challenge");
// good pubKeyCredParams values
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", []).runTest("Bad pubKeyCredParams: pubKeyCredParams is empty Array");
// empty pubKeyCredParams should default to EC256 and RS256
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", []).runTest("pubKeyCredParams is empty Array");
const pkParamEC256 = {
type: "public-key",
alg: cose_alg_ECDSA_w_SHA256
......@@ -55,14 +56,9 @@ standardSetup(function() {
type: "public-key",
alg: cose_alg_ECDSA_w_SHA512
};
// XXX: presumes all mock authenticators support EC256
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC256]).runTest("EC256 pubKeyCredParams");
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512, pkParamEC256])
.runTest("SelectEC256 pubKeyCredParams from a list");
// TODO: currently most browsers are mocking FIDO U2F, which is EC256 only
// new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512]).runTest("EC512 pubKeyCredParams");
// NOTE: excludeCredentials parameter -- see also: createcredential-excludecredentials.https.html
// timeout
new CreateCredentialsTest({path: "options.publicKey.timeout", value: undefined}).runTest("passing credentials.create() with no timeout");
......
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