diff --git a/index.bs b/index.bs
index b78eade17..7f7bd35f6 100644
--- a/index.bs
+++ b/index.bs
@@ -870,88 +870,91 @@ When this method is invoked, the user agent MUST execute the following algorithm
[=AbortSignal/aborted flag=] is set to true, return a {{DOMException}} whose name is "{{AbortError}}"
and terminate this algorithm.
-1. Start |lifetimeTimer|.
-
1. Let |issuedRequests| be a new [=ordered set=].
-1. [=set/For each=] |authenticator| that becomes available on this platform until |lifetimeTimer| expires, perform the following
- steps:
+1. Let |authenticators| represent a [=set=] of platform-specific handles, where each value identifies an [=authenticator=]
+ presently available on this platform at a given instant.
- Issue: The definition of "becomes available" is intended to represent how
- devices are hot-plugged into (USB) or discovered by (NFC) browsers, and is underspecified.
- Resolving this with good definitions or some other means will be addressed by resolving
- [Issue #613](https://github.com/w3c/webauthn/issues/613).
+ Note: What qualifies an [=authenticator=] as "available" is intentionally unspecified; this is meant to represent how
+ [=authenticators=] can be hot-plugged into (e.g., via USB) or discovered (e.g., via NFC or Bluetooth) by the [=client=] by
+ various mechanisms.
- 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}
is [=present=]:
+1. Start |lifetimeTimer|.
- 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{authenticatorAttachment}}
is
- [=present|present=] and its value is not equal to |authenticator|'s attachment modality, [=iteration/continue=].
- 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}}
is set to
- `true` and the |authenticator| is not capable of storing a [=Client-Side-Resident Credential Private Key=],
- [=iteration/continue=].
- 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}
is
- set to {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user
- verification=], [=iteration/continue=].
+1. [=While=] |lifetimeTimer| has not expired, perform the following actions depending upon |lifetimeTimer|
+ and the state and response [=set/for each=] |authenticator| in |authenticators|:
+
|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}
+ : If the |options|.{{CredentialCreationOptions/signal}}
is [=present=] and its
+ [=AbortSignal/aborted flag=] is set to true,
+ :: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=]
+ operation on |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|. Then return a {{DOMException}}
+ whose name is "{{AbortError}}" and terminate this algorithm.
- |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}
is [=present=]:
- : is set to {{UserVerificationRequirement/required}}
- :: Let |userVerification| be `true`.
+ 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{authenticatorAttachment}}
is
+ [=present|present=] and its value is not equal to |authenticator|'s attachment modality, [=iteration/continue=].
+ 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}}
is set to
+ `true` and the |authenticator| is not capable of storing a [=Client-Side-Resident Credential Private Key=],
+ [=iteration/continue=].
+ 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}
is
+ set to {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user
+ verification=], [=iteration/continue=].
- : is set to {{UserVerificationRequirement/preferred}}
- :: If the |authenticator|
+ 1. Let |userVerification| be the effective user verification requirement for credential creation, a Boolean value,
+ as follows. If
+ |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}
|options|.{{PublicKeyCredentialCreationOptions/excludeCredentials}}
:
- 1. If |C|.{{transports}}
[=list/is not empty=], and |authenticator| is connected over a transport not
- mentioned in |C|.{{transports}}
, the client MAY [=continue=].
- 1. Otherwise, [=list/Append=] |C| to |excludeCredentialDescriptorList|.
+ 1. Let |userPresence| be a Boolean value set to the inverse of |userVerification|.
-
- 1. Invoke the [=authenticatorMakeCredential=] operation on |authenticator| with
- |clientDataHash|,
- |options|.{{PublicKeyCredentialCreationOptions/rp}}
, |options|.{{PublicKeyCredentialCreationOptions/user}}
,
- |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/requireResidentKey}}
,
- |userPresence|,
- |userVerification|,
- |credTypesAndPubKeyAlgs|,
- |excludeCredentialDescriptorList|,
- and |authenticatorExtensions| as parameters.
+ 1. Let |excludeCredentialDescriptorList| be a new [=list=].
- 1. [=set/Append=] |authenticator| to |issuedRequests|.
+ 1. [=list/For each=] credential descriptor |C| in |options|.{{PublicKeyCredentialCreationOptions/excludeCredentials}}
:
+ 1. If |C|.{{transports}}
[=list/is not empty=], and |authenticator| is connected over a transport not
+ mentioned in |C|.{{transports}}
, the client MAY [=continue=].
+ 1. Otherwise, [=list/Append=] |C| to |excludeCredentialDescriptorList|.
-1. [=While=] |lifetimeTimer| has not expired, perform the following actions depending upon |lifetimeTimer| and responses from the
- authenticators:
- |options|.{{PublicKeyCredentialCreationOptions/rp}}
, |options|.{{PublicKeyCredentialCreationOptions/user}}
,
+ |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/requireResidentKey}}
,
+ |userPresence|,
+ |userVerification|,
+ |credTypesAndPubKeyAlgs|,
+ |excludeCredentialDescriptorList|,
+ and |authenticatorExtensions| as parameters.
- : If the |options|.{{CredentialCreationOptions/signal}}
is [=present=] and its
- [=AbortSignal/aborted flag=] is set to true,
- :: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=]
- operation on |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|. Then return a {{DOMException}}
- whose name is "{{AbortError}}" and terminate this algorithm.
+ 1. [=set/Append=] |authenticator| to |issuedRequests|.
+
+ : If an |authenticator| ceases to be available on this platform,
+ :: [=set/Remove=] |authenticator| from |issuedRequests|.
: If any |authenticator| returns a status indicating that the user cancelled the operation,
:: 1. [=set/Remove=] |authenticator| from |issuedRequests|.
@@ -1200,122 +1203,123 @@ When this method is invoked, the user agent MUST execute the following algorithm
1. Let |issuedRequests| be a new [=ordered set=].
-1. Let |authenticator| be a platform-specific handle whose value identifies an [=authenticator=].
-
1. Let |savedCredentialIds| be a new [=map=].
-1. Start |lifetimeTimer|.
+1. Let |authenticators| represent a [=set=] of platform-specific handles, where each value identifies an [=authenticator=]
+ presently available on this platform at a given instant.
+
+ Note: What qualifies an [=authenticator=] as "available" is intentionally unspecified; this is meant to represent how
+ [=authenticators=] can be hot-plugged into (e.g., via USB) or discovered (e.g., via NFC or Bluetooth) by the [=client=] by
+ various mechanisms.
-1. [=set/For each=] |authenticator| that becomes available on this platform until |lifetimeTimer| expires, perform the following
- steps:
+1. Start |lifetimeTimer|.
- Issue: The definition of "becomes available" is intended to represent how
- devices are hot-plugged into (USB) or discovered by (NFC) browsers, and is underspecified.
- Resolving this with good definitions or some other means will be addressed by resolving
- [Issue #613](https://github.com/w3c/webauthn/issues/613).
+1. [=While=] |lifetimeTimer| has not expired, perform the following actions depending upon |lifetimeTimer|
+ and the state and response [=set/for each=] |authenticator| in |authenticators|:
- 1. If |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
is set to
- {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user verification=],
- [=iteration/continue=].
+ |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
+ : If |lifetimeTimer| expires,
+ :: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
+ |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|.
- |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
is set to
+ {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user verification=],
+ [=iteration/continue=].
- : is set to {{UserVerificationRequirement/preferred}}
- :: If the |authenticator|
+ 1. Let |userVerification| be the effective user verification requirement for assertion, a Boolean value, as
+ follows. If |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
- |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
are bound to this
- |authenticator|, by matching with |rpId|,
- |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/id}}
,
- and
- |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/type}}
.
- Set |allowCredentialDescriptorList| to this filtered list.
+ 1. Let |userPresence| be a Boolean value set to the inverse of |userVerification|.
- 1. If |allowCredentialDescriptorList| [=list/is empty=], [=continue=].
+ 1.
+ If |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
+ |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
are bound to this
+ |authenticator|, by matching with |rpId|,
+ |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/id}}
,
+ and
+ |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/type}}
.
+ Set |allowCredentialDescriptorList| to this filtered list.
- 1. If |allowCredentialDescriptorList| has exactly one value, set
- |savedCredentialIds|[|authenticator|]
to |allowCredentialDescriptorList|[0].id
's
- value (see [here](#authenticatorGetAssertion-return-values) in [[#op-get-assertion]] for more information).
+ 1. If |allowCredentialDescriptorList| [=list/is empty=], [=continue=].
- 1. [=list/For each=] credential descriptor |C| in |allowCredentialDescriptorList|,
- [=set/append=] each value, if any, of |C|.{{transports}}
to |distinctTransports|.
+ 1. Let |distinctTransports| be a new [=ordered set=].
- Note: This will aggregate only distinct values of {{transports}} (for this [=authenticator=]) in
- |distinctTransports| due to the properties of [=ordered sets=].
+ 1. If |allowCredentialDescriptorList| has exactly one value, set
+ |savedCredentialIds|[|authenticator|]
to |allowCredentialDescriptorList|[0].id
's
+ value (see [here](#authenticatorGetAssertion-return-values) in [[#op-get-assertion]] for more information).
- 1. If |distinctTransports|
- |C|.{{transports}}
to |distinctTransports|.
- : [=list/is empty=]
- :: Using local configuration knowledge of the appropriate transport to use with |authenticator|, invoke the
- [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|, |clientDataHash|, |userPresence|,
- |userVerification| and |clientExtensions| as parameters.
+ Note: This will aggregate only distinct values of {{transports}} (for this [=authenticator=]) in
+ |distinctTransports| due to the properties of [=ordered sets=].
- Note: In this case, the [=[RP]=] did not supply a list of acceptable credential descriptors. Thus, the
- authenticator is being asked to exercise any credential it may possess that is bound to
- the [=[RP]=], as identified by |rpId|.
-