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|: +
+ : If |lifetimeTimer| expires, + :: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator| + and [=set/remove=] |authenticator| from |issuedRequests|. - 1. Let |userVerification| be the effective user verification requirement for credential creation, a Boolean value, - as follows. If - |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. -
+ : If an |authenticator| becomes available on this platform, + :: 1. If |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}}
- : is capable of [=user verification=] + + : is set to {{UserVerificationRequirement/required}} :: Let |userVerification| be `true`. - : is not capable of [=user verification=] - :: Let |userVerification| be `false`. -
+ : is set to {{UserVerificationRequirement/preferred}} + :: If the |authenticator| - : is set to {{UserVerificationRequirement/discouraged}} - :: Let |userVerification| be `false`. +
+ : is capable of [=user verification=] + :: Let |userVerification| be `true`. -
+ : is not capable of [=user verification=] + :: Let |userVerification| be `false`. +
- 1. Let |userPresence| be a Boolean value set to the inverse of |userVerification|. + : is set to {{UserVerificationRequirement/discouraged}} + :: Let |userVerification| be `false`. - 1. Let |excludeCredentialDescriptorList| be a new [=list=]. +
- 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. 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: -
- : If |lifetimeTimer| expires, - :: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator| - and [=set/remove=] |authenticator| from |issuedRequests|. + + 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. - : 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=]. +
- 1. Let |userVerification| be the effective user verification requirement for assertion, a Boolean value, as - follows. If |options|.{{PublicKeyCredentialRequestOptions/userVerification}} + : If |lifetimeTimer| expires, + :: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on + |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|. -
+ : If the {{CredentialRequestOptions/signal}} member is [=present=] and the [=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. - : is set to {{UserVerificationRequirement/required}} - :: Let |userVerification| be `true`. + : If an |authenticator| becomes available on this platform, + :: 1. If |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}}
- : is capable of [=user verification=] + + : is set to {{UserVerificationRequirement/required}} :: Let |userVerification| be `true`. - : is not capable of [=user verification=] - :: Let |userVerification| be `false`. -
+ : is set to {{UserVerificationRequirement/preferred}} + :: If the |authenticator| - : is set to {{UserVerificationRequirement/discouraged}} - :: Let |userVerification| be `false`. +
+ : is capable of [=user verification=] + :: Let |userVerification| be `true`. -
+ : is not capable of [=user verification=] + :: Let |userVerification| be `false`. +
- 1. Let |userPresence| be a Boolean value set to the inverse of |userVerification|. + : is set to {{UserVerificationRequirement/discouraged}} + :: Let |userVerification| be `false`. - 1. - If |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}} -
- : [=list/is not empty=] - :: 1. Let |allowCredentialDescriptorList| be a new [=list=]. +
- 1. Execute a platform-specific procedure to determine which, if any, [=public key credentials=] described by - |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}} +
+ : [=list/is not empty=] + :: 1. Let |allowCredentialDescriptorList| be a new [=list=]. - 1. Let |distinctTransports| be a new [=ordered set=]. + 1. Execute a platform-specific procedure to determine which, if any, [=public key credentials=] described by + |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| -
- : [=list/is not empty=] - :: The client selects one |transport| value from |distinctTransports|, possibly incorporating local - configuration knowledge of the appropriate transport to use with |authenticator| in making its - selection. - - Then, using |transport|, invoke the [=authenticatorGetAssertion=] operation on - |authenticator|, with |rpId|, |clientDataHash|, |allowCredentialDescriptorList|, |userPresence|, - |userVerification|, and |authenticatorExtensions| as parameters. - - : [=list/is empty=] - :: Using local configuration knowledge of the appropriate transport to use with |authenticator|, - invoke the [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|, - |clientDataHash|, |allowCredentialDescriptorList|, |userPresence|, |userVerification|, and - |clientExtensions| as parameters. -
+ 1. [=list/For each=] credential descriptor |C| in |allowCredentialDescriptorList|, + [=set/append=] each value, if any, of |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|. -
+ 1. If |distinctTransports| +
+ : [=list/is not empty=] + :: The client selects one |transport| value from |distinctTransports|, possibly incorporating local + configuration knowledge of the appropriate transport to use with |authenticator| in making its + selection. - 1. [=set/Append=] |authenticator| to |issuedRequests|. + Then, using |transport|, invoke the [=authenticatorGetAssertion=] operation on + |authenticator|, with |rpId|, |clientDataHash|, |allowCredentialDescriptorList|, |userPresence|, + |userVerification|, and |authenticatorExtensions| as parameters. -1. [=While=] |lifetimeTimer| has not expired, perform the following actions depending upon |lifetimeTimer| - and responses from the authenticators: + : [=list/is empty=] + :: Using local configuration knowledge of the appropriate transport to use with |authenticator|, + invoke the [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|, + |clientDataHash|, |allowCredentialDescriptorList|, |userPresence|, |userVerification|, and + |clientExtensions| as parameters. +
-
+ : [=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. - : If |lifetimeTimer| expires, - :: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on - |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|. + 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|. +
- : If the {{CredentialRequestOptions/signal}} member is [=present=] and the [=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|.