Allow each browsing context to have a in-flight conditional get request. A "conditionally mediated" WebAuthn request is a site's intention to submit a request in response to user interaction with browser-presented autofill UI. The WebAuthn spec only allows one active request at a time, but a conditional request can stay pending while another request is active. Prior to this patch we incorrectly applied the uniqueness requirement to conditional requests. The previous design had some other deficiencies as well. We held pending requests at the level of the platform nsIWebAuthnService, which meant we had duplicate logic for dispatching a pending request at each service. This patch hoists the pending request management up to the top level WebAuthnService, adds a new GetAutoFillEntriesForRpId method which allows WebAuthnService to request autofill entries from the platform-specific service, and simplifies the state management at the platform level. As part of this refactor it was natural to also remove some unnecessary synchronization mechanisms from the platform-specific nsIWebAuthnServices. Back when WebAuthnTransactionParent ran on the IPDL Background Thread we needed these synchronization mechanisms to allow prompts / main thread UI to cancel WebAuthn operations. This has not been necessary since Bug 1945969, which moved WebAuthnTransactionParent to the main thread. Differential Revision: https://phabricator.services.mozilla.com/D301134
150 lines
6.4 KiB
Plaintext
150 lines
6.4 KiB
Plaintext
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsISupports.idl"
|
|
#include "nsIWebAuthnArgs.idl"
|
|
#include "nsIWebAuthnPromise.idl"
|
|
|
|
[scriptable, uuid(6c4ecd9f-57c0-4d7d-8080-bf6e4d499f8f)]
|
|
interface nsICredentialParameters : nsISupports
|
|
{
|
|
readonly attribute ACString credentialId;
|
|
readonly attribute boolean isResidentCredential;
|
|
readonly attribute ACString rpId;
|
|
readonly attribute ACString privateKey;
|
|
readonly attribute ACString userHandle;
|
|
readonly attribute uint32_t signCount;
|
|
};
|
|
|
|
[scriptable, uuid(686d552e-a39d-4ba2-8127-faca54274039)]
|
|
interface nsIWebAuthnAutoFillEntry: nsISupports
|
|
{
|
|
const octet PROVIDER_UNKNOWN = 0;
|
|
const octet PROVIDER_TEST_TOKEN = 1;
|
|
const octet PROVIDER_PLATFORM_WINDOWS = 2;
|
|
const octet PROVIDER_PLATFORM_MACOS = 3;
|
|
const octet PROVIDER_PLATFORM_ANDROID = 4;
|
|
|
|
readonly attribute octet provider;
|
|
readonly attribute AString userName;
|
|
readonly attribute AString rpId;
|
|
readonly attribute Array<uint8_t> credentialId;
|
|
};
|
|
|
|
[scriptable, uuid(e236a9b4-a26f-11ed-b6cc-07a9834e19b1)]
|
|
interface nsIWebAuthnService : nsISupports
|
|
{
|
|
// IsUserVerifyingPlatformAuthenticatorAvailable
|
|
readonly attribute boolean isUVPAA;
|
|
|
|
[noscript]
|
|
void makeCredential(
|
|
in uint64_t aTransactionId,
|
|
in uint64_t browsingContextId,
|
|
in nsIWebAuthnRegisterArgs args,
|
|
in nsIWebAuthnRegisterPromise promise);
|
|
|
|
[noscript]
|
|
void getAssertion(
|
|
in uint64_t aTransactionId,
|
|
in uint64_t browsingContextId,
|
|
in nsIWebAuthnSignArgs args,
|
|
in nsIWebAuthnSignPromise promise);
|
|
|
|
// Cancel the ongoing transaction and any prompts that are shown, but do not reject
|
|
// its promise. This is used by the IPC parent when it receives an abort signal.
|
|
// The IPC child has already rejected the promises at this point.
|
|
[noscript] void reset();
|
|
|
|
// Cancel the ongoing transaction. Reject its promise, but do not cancel
|
|
// prompts. This is used by WebAuthnPromptHelper when the user hits the
|
|
// "cancel" button.
|
|
void cancel(in uint64_t aTransactionId);
|
|
|
|
// `hasPendingConditionalGet` returns the transaction ID of a pending
|
|
// conditionally-mediated getAssertion promise. The browsing context and
|
|
// origin arguments must match those of the pending promise. If there is no
|
|
// pending getAssertion promise, or the browsing context and origin do not
|
|
// match, then `hasPendingConditionalGet` returns 0.
|
|
uint64_t hasPendingConditionalGet(in uint64_t aBrowsingContextId, in AString aOrigin);
|
|
|
|
// If there is a pending conditionally-mediated getAssertion promise with
|
|
// transaction ID equal to `aTransactionId`, `getAutoFillEntries` invokes
|
|
// `aCallback` with an nsIWebAuthnAutoFillEntry for each silently
|
|
// discoverable credential that can be used to fulfill the request.
|
|
void getAutoFillEntries(
|
|
in uint64_t aTransactionId,
|
|
in nsIWebAuthnAutoFillEntriesCallback aCallback);
|
|
|
|
// Asynchronously lists silently discoverable credentials for the given
|
|
// relying party id, optionally restricted by an allow list. WebAuthnService
|
|
// uses this to populate the result of `getAutoFillEntries`. Platform
|
|
// service implementations of this method should perform the platform
|
|
// credential query and invoke aCallback when the result is available.
|
|
// Top-level callers should use `getAutoFillEntries` instead.
|
|
[noscript] void getAutoFillEntriesForRpId(
|
|
in AString aRpId,
|
|
in Array<Array<uint8_t> > aAllowList,
|
|
in nsIWebAuthnAutoFillEntriesCallback aCallback);
|
|
|
|
// A pending conditionally-mediated getAssertion promise is resolved by
|
|
// calling `selectAutoFillEntry` or `resumeConditionalGet`.
|
|
// `selectAutoFillEntry` specifies the credential ID that should be used to
|
|
// fulfill the request, whereas `resumeConditionalGet` indicates that any
|
|
// allowed credential can be used.
|
|
void selectAutoFillEntry(in uint64_t aTransactionId, in Array<uint8_t> aCredentialId);
|
|
void resumeConditionalGet(in uint64_t aTransactionId);
|
|
|
|
void pinCallback(in uint64_t aTransactionId, in AUTF8String aPin);
|
|
void setHasAttestationConsent(in uint64_t aTransactionId, in boolean aHasConsent);
|
|
void selectionCallback(in uint64_t aTransactionId, in uint64_t aIndex);
|
|
|
|
// Adds a virtual (software) authenticator for use in tests (particularly
|
|
// tests run via WebDriver). See
|
|
// https://w3c.github.io/webauthn/#sctn-automation-add-virtual-authenticator.
|
|
ACString addVirtualAuthenticator(
|
|
in ACString protocol,
|
|
in ACString transport,
|
|
in boolean hasResidentKey,
|
|
in boolean hasUserVerification,
|
|
in boolean isUserConsenting,
|
|
in boolean isUserVerified);
|
|
|
|
// Removes a previously-added virtual authenticator, as identified by its
|
|
// id. See
|
|
// https://w3c.github.io/webauthn/#sctn-automation-remove-virtual-authenticator
|
|
void removeVirtualAuthenticator(in ACString authenticatorId);
|
|
|
|
// Adds a credential to a previously-added authenticator. See
|
|
// https://w3c.github.io/webauthn/#sctn-automation-add-credential
|
|
void addCredential(
|
|
in ACString authenticatorId,
|
|
in ACString credentialId,
|
|
in boolean isResidentCredential,
|
|
in ACString rpId,
|
|
in ACString privateKey,
|
|
in ACString userHandle,
|
|
in uint32_t signCount);
|
|
|
|
// Gets all credentials that have been added to a virtual authenticator.
|
|
// See https://w3c.github.io/webauthn/#sctn-automation-get-credentials
|
|
Array<nsICredentialParameters> getCredentials(in ACString authenticatorId);
|
|
|
|
// Removes a credential from a virtual authenticator. See
|
|
// https://w3c.github.io/webauthn/#sctn-automation-remove-credential
|
|
void removeCredential(in ACString authenticatorId, in ACString credentialId);
|
|
|
|
// Removes all credentials from a virtual authenticator. See
|
|
// https://w3c.github.io/webauthn/#sctn-automation-remove-all-credentials
|
|
void removeAllCredentials(in ACString authenticatorId);
|
|
|
|
// Sets the "isUserVerified" bit on a virtual authenticator. See
|
|
// https://w3c.github.io/webauthn/#sctn-automation-set-user-verified
|
|
void setUserVerified(in ACString authenticatorId, in boolean isUserVerified);
|
|
|
|
// about:webauthn-specific functions
|
|
void listen();
|
|
void runCommand(in ACString aCommand);
|
|
};
|