diff --git a/index.bs b/index.bs index cfe670483..013929f4f 100644 --- a/index.bs +++ b/index.bs @@ -4,7 +4,7 @@ Status: ED Prepare for TR: true TR: https://www.w3.org/TR/webauthn/ ED: https://w3c.github.io/webauthn/ -Previous Version: http://www.w3.org/TR/2017/WD-webauthn-20170505/ +Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20170505/ Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20170216/ Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20161207/ Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20160928/ @@ -57,6 +57,7 @@ spec: HTML52; urlPrefix: https://w3c.github.io/html/ text: origin; url: concept-cross-origin text: opaque origin; url: opaque-origin text: tuple origin + text: document.domain; url:dom-document-domain spec: TokenBinding; urlPrefix: https://tools.ietf.org/html/draft-ietf-tokbind-protocol# type: dfn @@ -83,10 +84,12 @@ spec: CREDENTIAL-MANAGEMENT-1; urlPrefix: https://w3c.github.io/webappsec-creden @@ -247,9 +250,9 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S : Authentication :: The [=ceremony=] where a user, and the user's computing device(s) (containing at least one [=authenticator=]) work in - concert to cryptographically prove to an [=[RP]=] that the user controls the private key associated with a - previously-registered [=public key credential=] (see [=Registration=]). Note that this includes employing [=user - verification=]. + concert to cryptographically prove to an [=[RP]=] that the user controls the [=credential private key=] associated with a + previously-registered [=public key credential=] (see [=Registration=]). Note that this typically includes employing a [=test + of user presence=] or [=user verification=]. : Authentication Assertion :: The cryptographically signed {{AuthenticatorAssertionResponse}} object returned by an [=authenticator=] as the result of a @@ -280,6 +283,19 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S : Client :: See [=Conforming User Agent=]. +: Client-Side +:: This refers in general to the combination of the user's platform device, user agent, authenticators, and everything gluing + it all together. + +: Client-side-resident Credential Private Key +:: A [=Client-side-resident Credential Private Key=] is stored either on the client platform, or in some cases on the + authenticator itself, e.g., in the case of a discrete first-factor roaming authenticator. Such client-side credential + private key storage has the property that the authenticator is able to select the [=credential private key=] given + only an [=RP ID=], possibly with user assistance (e.g., by providing the user a pick list of credentials associated with the RP + ID). By definition, the private key is always exclusively controlled by the Authenticator. In the case of a + [=Client-side-resident Credential Private Key=], the Authenticator might offload storage of wrapped key material to the + client platform, but the client platform is not expected to offload the key storage to remote entities (e.g. RP Server). + : Conforming User Agent :: A user agent implementing, in conjunction with the underlying platform, the [=Web Authentication API=] and algorithms given in this specification, and handling communication between [=authenticators=] and [=[RPS]=]. @@ -293,23 +309,38 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S : Registration :: The [=ceremony=] where a user, a [=[RP]=], and the user's computing device(s) (containing at least one - [=authenticator=]) work in concert to create a [=public key credential=] and associate it with the user's [=[RP]=] - account. Note that this includes employing [=user verification=]. + [=authenticator=]) work in concert to create a [=public key credential=] and associate it with the user's [=[RP]=] account. + Note that this typically includes employing a [=test of user presence=] or [=user verification=]. : [RP] :: The entity whose web application utilizes the [=Web Authentication API=] to register and authenticate users. See [=Registration=] and [=Authentication=], respectively. - Note: While the term [=[RP]=] is used in other contexts (e.g., X.509 and OAuth), an entity acting as a [=[RP]=] in one context is - not necessarily a [=[RP]=] in other contexts. + Note: While the term [=[RP]=] is used in other contexts (e.g., X.509 and OAuth), an entity acting as a [=[RP]=] in one + context is not necessarily a [=[RP]=] in other contexts. : Relying Party Identifier : RP ID -:: An identifier for the [=[RP]=] on whose behalf a given registration or authentication ceremony is being performed. Public Key - credentials can only be used for authentication by the same entity (as identified by RP ID) that created and registered - them. By default, the RP ID for a WebAuthn operation is set to the [=environment settings object/origin=] specified by the - [=relevant settings object=] of the {{CredentialsContainer}} object. This default can be overridden by the caller subject - to certain restrictions, as specified in [[#createCredential]] and [[#getAssertion]]. +:: A [=valid domain string=] that identifies the [=[RP]=] on whose behalf a given [=registration=] or + [=authentication|authentication ceremony=] is being performed. A [=public key credential=] can only be used for + [=authentication=] with the same entity (as identified by [=RP ID=]) it was registered with. By default, the [=RP ID=] for a + WebAuthn operation is set to the caller's [=environment settings object/origin=]'s [=effective domain=]. This default MAY be + overridden by the caller, as long as the caller-specified [=RP ID=] value [=is a registrable domain suffix of or is equal + to=] the caller's [=environment settings object/origin=]'s [=effective domain=]. See also [[#createCredential]] and + [[#getAssertion]]. + +
+ Note: A [=Public key credential=]'s scope is for a [=[RP]=]'s [=origin=], with the following restrictions and + relaxations: + - The scheme is always `https` (i.e., a restriction), and, + - the host may be equal to the [=[RP]=]'s [=origin=]'s [=effective domain=], or it may be equal to a registrable + domain suffix of the [=[RP]=]'s [=origin=]'s [=effective domain=] (i.e., an available relaxation), and, + - all (TCP) ports on that host (i.e., a relaxation). + + This is done in order to match the behavior of pervasively deployed ambient credentials (e.g., cookies, [[RFC6265]]). + Please note that this is a greater relaxation of "same-origin" restrictions than what + [=document.domain=]'s setter provides. +
: Public Key Credential :: Generically, a credential is data one entity presents to another in order to authenticate the former to the @@ -329,19 +360,6 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S that this does not constitute [=user verification=] because [=TUP=], by definition, is not capable of [=biometric recognition=], nor does it involve the presentation of a shared secret such as a password or PIN. -: Client-side-resident Credential Private Key -:: A [=Client-side-resident Credential Private Key=] is stored either on the client platform, or in some cases on the authenticator - itself, e.g., in the case of a discrete first-factor roaming authenticator. Such client-side credential private key - storage has the property that the authenticator is able to select the [=credential private key=] given only an RP ID, - possibly with user assistance (e.g., by providing the user a pick list of credentials associated with the RP ID). By definition, - the private key is always exclusively controlled by the Authenticator. In the case of a [=Client-side-resident Credential Private - Key=], the Authenticator might offload storage of wrapped key material to the client platform, but the client platform is not - expected to offload the key storage to remote entities (e.g. RP Server). - -: Client-Side -:: This refers in general to the combination of the user's platform device, user agent, authenticators, and everything gluing - it all together. - : User Consent :: User consent means the user agrees with what they are being asked, i.e., it encompasses reading and understanding prompts. An [=authorization gesture=] is a [=ceremony=] component often employed to indicate [=user consent=]. @@ -386,14 +404,15 @@ a different [=origin=], by incorporating the [=origin=] in its responses. Specif the full [=origin=] of the requester is included, and signed over, in the [=attestation object=] produced when a new credential is created as well as in all assertions produced by WebAuthn credentials. -Additionally, to maintain user privacy and prevent malicious [=[RPS]=] from probing for the presence of credentials belonging to -other [RPS], each credential is also associated with a Relying Party Identifier, or RP ID. This RP ID is provided by the client -to the authenticator for all operations, and the authenticator ensures that credentials created by a [=[RP]=] can only be used -in operations requested by the same RP ID. Separating the [=origin=] from the RP ID in this way allows the API to be used in -cases where a single [=[RP]=] maintains multiple [=origins=]. +Additionally, to maintain user privacy and prevent malicious [=[RPS]=] from probing for the presence of [=public key +credentials=] belonging to other [=[RPS]=], each [=public key credential|credential=] is also associated with a [=Relying Party +Identifier=], or [=RP ID=]. This [=RP ID=] is provided by the client to the [=authenticator=] for all operations, and the +[=authenticator=] ensures that [=public key credential|credentials=] created by a [=[RP]=] can only be used in operations +requested by the same [=RP ID=]. Separating the [=origin=] from the [=RP ID=] in this way allows the API to be used in cases +where a single [=[RP]=] maintains multiple [=origins=]. -The client facilitates these security measures by providing correct [=origins=] and RP IDs to the authenticator for each -operation. Since this is an integral part of the WebAuthn security model, user agents MUST only expose this API to callers in +The client facilitates these security measures by providing the [=[RP]=]'s [=origin=] and [=RP ID=] to the [=authenticator=] for +each operation. Since this is an integral part of the WebAuthn security model, user agents only expose this API to callers in [=secure contexts=]. The Web Authentication API is defined by the union of the Web IDL fragments presented in the following sections. A combined IDL @@ -456,54 +475,56 @@ that are returned to the caller when a new credential is created, or a new asser implementation of {{PublicKeyCredential/[[DiscoverFromExternalSource]](options)}} and {{PublicKeyCredential/[[Create]](options)}}. -### `CredentialRequestOptions` Extension ### {#credentialrequestoptions-extension} +### `CredentialCreationOptions` Extension ### {#credentialcreationoptions-extension} -To support obtaining assertions via {{CredentialsContainer/get()|navigator.credentials.get()}}, this document extends the -{{CredentialRequestOptions}} dictionary as follows: +To support registration via {{CredentialsContainer/create()|navigator.credentials.create()}}, this document extends +the {{CredentialCreationOptions}} dictionary as follows:
-    partial dictionary CredentialRequestOptions {
-        PublicKeyCredentialRequestOptions? publicKey;
+    partial dictionary CredentialCreationOptions {
+        MakeCredentialOptions? publicKey;
     };
 
-### `CredentialCreationOptions` Extension ### {#credentialcreationoptions-extension} +### `CredentialRequestOptions` Extension ### {#credentialrequestoptions-extension} -To support registration via {{CredentialsContainer/create()|navigator.credentials.create()}}, this document extends -the {{CredentialCreationOptions}} dictionary as follows: +To support obtaining assertions via {{CredentialsContainer/get()|navigator.credentials.get()}}, this document extends the +{{CredentialRequestOptions}} dictionary as follows:
-    partial dictionary CredentialCreationOptions {
-        MakeCredentialOptions? publicKey;
+    partial dictionary CredentialRequestOptions {
+        PublicKeyCredentialRequestOptions? publicKey;
     };
 
-### Create a new credential - PublicKeyCredential's `\[[Create]](options)` method ### {#createCredential} +### Create a new credential - PublicKeyCredential's `[[Create]](options)` method ### {#createCredential} +
{{PublicKeyCredential}}'s [=interface object=]'s implementation of the \[[Create]](options) method allows scripts to call {{CredentialsContainer/create()|navigator.credentials.create()}} to request the creation of a new [=credential key pair=] -and {{PublicKeyCredential}}, managed by an authenticator. The user agent will prompt the user for [=user consent|consent=]. -On success, the returned promise will be resolved with a {{PublicKeyCredential}} containing an +and {{PublicKeyCredential}}, managed by an [=authenticator=]. The user agent will prompt the user for [=user consent|consent=]. +On success, the returned {{promise}} will be resolved with a {{PublicKeyCredential}} containing an {{AuthenticatorAttestationResponse}} object. -Note: This algorithm is synchronous; the {{Promise}} resolution/rejection is taken care of by +Note: This algorithm is synchronous; the {{Promise}} resolution/rejection is handled by {{CredentialsContainer/create()|navigator.credentials.create()}}. This method accepts a single argument:
: options - :: This argument is a {{CredentialCreationOptions}} object whose |options|["{{CredentialCreationOptions/publicKey}}"] - member contains a {{MakeCredentialOptions}} object specifying how the credential is to be made. + :: This argument is a {{CredentialCreationOptions}} object whose + |options|.{{CredentialCreationOptions/publicKey}} member contains a {{MakeCredentialOptions}} object + specifying the desired attributes of the to-be-created [=public key credential=].
When this method is invoked, the user agent MUST execute the following algorithm: -1. Assert: |options|["{{CredentialRequestOptions/publicKey}}"] is [=present=]. +1. Assert: |options|.{{CredentialCreationOptions/publicKey}} is [=present=]. -1. Let |options| be the value of |options|["{{CredentialRequestOptions/publicKey}}"]. +1. Let |options| be the value of |options|.{{CredentialCreationOptions/publicKey}}. 1. If any of the {{PublicKeyCredentialEntity/name}} member of |options|.{{MakeCredentialOptions/rp}}, the {{PublicKeyCredentialEntity/name}} member of |options|.{{MakeCredentialOptions/user}}, @@ -516,25 +537,35 @@ When this method is invoked, the user agent MUST execute the following algorithm |adjustedTimeout| to this adjusted value. If the {{MakeCredentialOptions/timeout}} member of |options| is [=present|not present=], then set |adjustedTimeout| to a platform-specific default. -1. Let |global| be the {{PublicKeyCredential}} [=interface object=]'s [=global object|environment settings object's global object=]. +1. Let |global| be the {{PublicKeyCredential}}'s [=interface object=]'s [=global object|environment settings object's global + object=]. -1. Let |callerOrigin| be the [=environment settings object/origin=] specified by this {{PublicKeyCredential}} [=interface object=]'s - [=relevant settings object=]. If |callerOrigin| is an [=opaque origin=], return a {{DOMException}} whose name is +1. Let |callerOrigin| be the [=environment settings object/origin=] specified by this {{PublicKeyCredential}} [=interface + object=]'s [=relevant settings object=]. If |callerOrigin| is an [=opaque origin=], return a {{DOMException}} whose name is "{{NotAllowedError}}", and terminate this algorithm. -1. If the {{PublicKeyCredentialEntity/id}} member of |options|.{{MakeCredentialOptions/rp}} is [=present|not present=], then set - |rpId| to |callerOrigin|. - - Otherwise: - - 1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=]. - 1. If |effectiveDomain| is null, then return a {{DOMException}} whose name is "{{SecurityError}}" and terminate this - algorithm. - 1. If |options|.{{MakeCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}} [=is not a registrable domain suffix of and is - not equal to=] |effectiveDomain|, return a {{DOMException}} whose name is "{{SecurityError}}", and terminate this - algorithm. - 1. Set |rpId| to |options|.{{MakeCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}}. - +1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=]. If |effectiveDomain| is null, + then return a {{DOMException}} whose name is "{{SecurityError}}" and terminate this algorithm. + + + +1. Let |rpId| be |effectiveDomain|. +
  • + If |options|.{{MakeCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}} is [=present=]: + + 1. If |options|.{{MakeCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}} [=is not a registrable domain suffix of and is + not equal to=] |effectiveDomain|, return a {{DOMException}} whose name is "{{SecurityError}}", and terminate this + algorithm. + 1. Set |rpId| to |options|.{{MakeCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}}. + + Note: |rpId| represents the caller's [=RP ID=]. The [=RP ID=] defaults to being the caller's [=environment settings + object/origin=]'s [=effective domain=] unless the caller has explicitly set + |options|.{{MakeCredentialOptions/rp}}.{{PublicKeyCredentialEntity/id}} when calling {{CredentialsContainer/create()}}. +
  • 1. Let |normalizedParameters| be a new [=list=] whose [=list/items=] are pairs of {{PublicKeyCredentialType}} and a [=dictionary=] type (as returned by [=normalizing an algorithm=]). @@ -568,13 +599,13 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. Let |collectedClientData| be a new {{CollectedClientData}} instance whose fields are: : {{CollectedClientData/challenge}} - :: The [=base64url encoding=] of |options|.{{MakeCredentialOptions/challenge}} - : {{origin}} - :: The [=unicode serialization of an origin|unicode serialization=] of |rpId| - : {{hashAlg}} + :: The [=base64url encoding=] of |options|.{{MakeCredentialOptions/challenge}}. + : {{CollectedClientData/origin}} + :: The [=ascii serialization of an origin|serialization of=] |callerOrigin|. + : {{CollectedClientData/hashAlg}} :: The [=recognized algorithm name=] of the hash algorithm selected by the client for generating the - [=hash of the serialized client data=] - : {{tokenBinding}} + [=hash of the serialized client data=]. + : {{CollectedClientData/tokenBindingId}} :: The [=Token Binding ID=] associated with |callerOrigin|, if one is available. : {{CollectedClientData/clientExtensions}} :: |clientExtensions| @@ -585,7 +616,7 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|. -1. Let |currentlyAvailableAuthenticators| be a new [=ordered set=] consisting of all [=authenticators=] +1. Let |currentlyAvailableAuthenticators| be a new [=ordered set=] consisting of all [=authenticators=] available on this platform. 1. Let |selectedAuthenticators| be a new [=ordered set=]. @@ -593,15 +624,15 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. If |currentlyAvailableAuthenticators| [=list/is empty=], return a {{DOMException}} whose name is "{{NotFoundError}}", and terminate this algorithm. -1. If |options|.{{MakeCredentialOptions/authenticatorSelection}} is [=present|present=], iterate through +1. If |options|.{{MakeCredentialOptions/authenticatorSelection}} is [=present|present=], iterate through |currentlyAvailableAuthenticators| and do the following [=set/for each=] |authenticator|: - 1. If {{AuthenticatorSelectionCriteria/attachment}} is [=present|present=] and its value is not equal + 1. If {{AuthenticatorSelectionCriteria/attachment}} is [=present|present=] and its value is not equal to |authenticator|'s attachment modality, [=iteration/continue=]. - 1. If {{AuthenticatorSelectionCriteria/requireResidentKey}} is set to |true| and the |authenticator| + 1. If {{AuthenticatorSelectionCriteria/requireResidentKey}} is set to |true| and the |authenticator| is not capable of storing a [=Client-Side-Resident Credential Private Key=], [=iteration/continue=]. - 1. [=set/Append=] |authenticator| to |selectedAuthenticators|. + 1. [=set/Append=] |authenticator| to |selectedAuthenticators|. -1. If |selectedAuthenticators| [=list/is empty=], return a {{DOMException}} whose name is +1. If |selectedAuthenticators| [=list/is empty=], return a {{DOMException}} whose name is "{{ConstraintError}}", and terminate this algoritm. 1. Let |issuedRequests| be a new [=ordered set=]. @@ -673,7 +704,7 @@ authorizing an authenticator.
    -### Use an existing credential - PublicKeyCredential::\[[DiscoverFromExternalSource]](options) method ### {#getAssertion} +### Use an existing credential to make an assertion - PublicKeyCredential's `[[DiscoverFromExternalSource]](options)` method ### {#getAssertion}
    The \[[DiscoverFromExternalSource]](options) method is used to discover and use an @@ -682,47 +713,61 @@ credentials are acceptable to it. The user agent and/or platform locates credent the user to pick one that the script will be allowed to use. The user may choose not to provide a credential even if one is present, for example to maintain privacy. -Note: This algorithm is synchronous; the {{Promise}} resolution/rejection is taken care of by +Note: This algorithm is synchronous; the {{Promise}} resolution/rejection is handled by {{CredentialsContainer/get()|navigator.credentials.get()}}. -
    - This method takes the following parameters: +This method accepts a single argument: - : |options| - :: A {{CredentialRequestOptions}} object, containing a challenge that the selected authenticator is expected to - sign to produce the assertion, and additional options as described in [[#assertion-options]] -
    +
    + : options + :: This argument is a {{CredentialRequestOptions}} object whose + |options|.{{CredentialRequestOptions/publicKey}} member contains a challenge and additional options as + described in [[#assertion-options]]. The selected authenticator signs the challenge along with other collected data in + order to produce an assertion. See [[#op-get-assertion]]. +
    When this method is invoked, the user agent MUST execute the following algorithm: -1. Let |publicKeyOptions| be the value of |options| {{CredentialRequestOptions/publicKey}} member. +1. Assert: |options|.{{CredentialRequestOptions/publicKey}} is [=present=]. + +1. Let |options| be the value of |options|.{{CredentialRequestOptions/publicKey}}. -1. If the {{PublicKeyCredentialRequestOptions/timeout}} member of |publicKeyOptions| is [=present=], check if its value lies +1. If the {{PublicKeyCredentialRequestOptions/timeout}} member of |options| is [=present=], check if its value lies within a reasonable range as defined by the platform and if not, correct it to the closest value lying within that range. Set |adjustedTimeout| to this adjusted value. If the {{PublicKeyCredentialRequestOptions/timeout}} member of - |publicKeyOptions| is [=present|not present=], then set |adjustedTimeout| to a platform-specific default. + |options| is [=present|not present=], then set |adjustedTimeout| to a platform-specific default. -1. Let |global| be the {{PublicKeyCredential}}'s [=relevant settings object=]'s - [=global object|environment settings object's global object=]. +1. Let |global| be the {{PublicKeyCredential}}'s [=interface object=]'s [=global object|environment settings object's global + object=]. -1. Let |callerOrigin| be the [=environment settings object/origin=] of this {{CredentialsContainer}} object's [=relevant - settings object=]. If |callerOrigin| is an [=opaque origin=], return {{DOMException}} whose name is +1. Let |callerOrigin| be the [=environment settings object/origin=] specified by this {{PublicKeyCredential}} [=interface + object=]'s [=relevant settings object=]. If |callerOrigin| is an [=opaque origin=], return a {{DOMException}} whose name is "{{NotAllowedError}}", and terminate this algorithm. -1. If the {{PublicKeyCredentialRequestOptions/rpId}} member of |publicKeyOptions| is [=present|not present=], then set |rpId| to - |callerOrigin|. - Otherwise: - 1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=]. - 1. If |effectiveDomain| is null, then return a {{DOMException}} whose name is "{{SecurityError}}" and terminate this - algorithm. - 1. If {{PublicKeyCredentialRequestOptions/rpId}} [=is not a registrable domain suffix of and is not equal to=] - |effectiveDomain|, return a {{DOMException}} whose name is "{{SecurityError}}", and terminate this algorithm. - 1. Set |rpId| to the {{PublicKeyCredentialRequestOptions/rpId}}. +1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=]. If |effectiveDomain| is null, then return a + {{DOMException}} whose name is "{{SecurityError}}" and terminate this algorithm. + + +
  • + If |options|.{{PublicKeyCredentialRequestOptions/rpId}} is [=present|not present=], then set |rpId| to |effectiveDomain|. + + Otherwise: + + 1. If |options|.{{PublicKeyCredentialRequestOptions/rpId}} [=is not a registrable domain suffix of and is not equal to=] + |effectiveDomain|, return a {{DOMException}} whose name is "{{SecurityError}}", and terminate this algorithm. + 1. Set |rpId| to |options|.{{PublicKeyCredentialRequestOptions/rpId}}. + Note: |rpId| represents the caller's [=RP ID=]. The [=RP ID=] defaults to being the caller's [=environment settings + object/origin=]'s [=effective domain=] unless the caller has explicitly set + |options|.{{PublicKeyCredentialRequestOptions/rpId}} when calling {{CredentialsContainer/get()}}. +
  • 1. Let |clientExtensions| be a new [=map=] and let |authenticatorExtensions| be a new [=map=]. -1. If the {{PublicKeyCredentialRequestOptions/extensions}} member of |publicKeyOptions| is [=present=], then [=map/for each=] - |extensionId| → |clientExtensionInput| of |publicKeyOptions|.{{PublicKeyCredentialRequestOptions/extensions}}: +1. If the {{PublicKeyCredentialRequestOptions/extensions}} member of |options| is [=present=], then [=map/for each=] + |extensionId| → |clientExtensionInput| of |options|.{{PublicKeyCredentialRequestOptions/extensions}}: 1. If |extensionId| is not supported by this client platform or is not an [=authentication extension=], then [=continue=]. 1. [=map/Set=] |clientExtensions|[|extensionId|] to |clientExtensionInput|. @@ -730,20 +775,19 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. If |extensionId| is not an [=authenticator extension=], then [=continue=]. 1. Let |authenticatorExtensionInput| be the ([=CBOR=]) result of running |extensionId|'s [=client extension processing=] - algorithm on |clientExtensionInput|. - If the algorithm returned an error, [=continue=]. + algorithm on |clientExtensionInput|. If the algorithm returned an error, [=continue=]. 1. [=map/Set=] |authenticatorExtensions|[|extensionId|] to the [=base64url encoding=] of |authenticatorExtensionInput|. 1. Let |collectedClientData| be a new {{CollectedClientData}} instance whose fields are: : {{CollectedClientData/challenge}} - :: The [=base64url encoding=] of |publicKeyOptions|.{{PublicKeyCredentialRequestOptions/challenge}} - : {{origin}} - :: The [=unicode serialization of an origin|unicode serialization=] of |rpId| - : {{hashAlg}} + :: The [=base64url encoding=] of |options|.{{PublicKeyCredentialRequestOptions/challenge}} + : {{CollectedClientData/origin}} + :: The [=ascii serialization of an origin|serialization of=] |callerOrigin|. + : {{CollectedClientData/hashAlg}} :: The [=recognized algorithm name=] of the hash algorithm selected by the client for generating the [=hash of the serialized client data=] - : {{tokenBinding}} + : {{CollectedClientData/tokenBindingId}} :: The [=Token Binding ID=] associated with |callerOrigin|, if one is available. : {{CollectedClientData/clientExtensions}} :: |clientExtensions| @@ -934,8 +978,8 @@ during registration. contents of the [=attestation statement=] are determined by the [=attestation statement format=] used by the [=authenticator=]. It also contains any additional information that the [=[RP]=]'s server requires to validate the [=attestation statement=], as well as to decode and validate the [=authenticator data=] along with the - [=JSON-serialized client data=]. For more details, see [[#sctn-attestation]] as well as - [Figure 3](#fig-attStructs). + [=JSON-serialized client data=]. For more details, see [[#sctn-attestation]], [[#generating-an-attestation-object]], + and [Figure 3](#fig-attStructs).
    ### Web Authentication Assertion (interface AuthenticatorAssertionResponse) ### {#iface-authenticatorassertionresponse} @@ -984,21 +1028,6 @@ optionally evidence of [=user consent=] to a specific transaction. will be used, and thus also the type of asymmetric key pair to be generated, e.g., RSA or Elliptic Curve. -## User Account Parameters for Credential Generation (dictionary PublicKeyCredentialUserEntity) ## {#sctn-user-credential-params} - -
    -    dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
    -        DOMString displayName;
    -    };
    -
    - -
    - This dictionary is used to supply additional parameters about the user account when creating a new credential. - - The displayName member contains a friendly name for the user account (e.g., "John P. Smith"). -
    - - ## Options for Credential Creation (dictionary MakeCredentialOptions) ## {#dictionary-makecredentialoptions} @@ -1023,9 +1052,8 @@ optionally evidence of [=user consent=] to a specific transaction. (e.g. "Acme Corporation", "Widgets, Inc.", or "Awesome Site". Its value's {{PublicKeyCredentialEntity/id}} member specifies the [=relying party identifier=] with which the credential - should be associated. If this identifier is not explicitly set, it will default to the [=ASCII serialization of an - origin|ASCII serialization=] of the {{CredentialsContainer}} object's [=relevant settings object=]'s [=environment - settings object/origin=]. + should be associated. If omitted, its value will be the {{CredentialsContainer}} object's [=relevant + settings object=]'s [=environment settings object/origin=]'s [=effective domain=]. : <dfn>user</dfn> :: This member contains data about the user account for which the [=[RP]=] is requesting attestation. @@ -1060,20 +1088,20 @@ optionally evidence of [=user consent=] to a specific transaction. on an authenticator that also contains one of the credentials enumerated in this parameter. : <dfn>authenticatorSelection</dfn> - :: This member is intended for use by [=[RPS]=] that wish to select the appropriate authenticators to participate in - the {{CredentialsContainer/create()}} or {{CredentialsContainer/get()}} operation. + :: This member is intended for use by [=[RPS]=] that wish to select the appropriate authenticators to participate in + the {{CredentialsContainer/create()}} or {{CredentialsContainer/get()}} operation. : <dfn>extensions</dfn> - :: This member contains additional parameters requesting additional processing by the client and authenticator. For example, - the caller may request that only authenticators with certain capabilies be used to create the credential, or that - particular information be returned in the [=attestation object=]. Some extensions are defined in [[#extensions]]; + :: This member contains additional parameters requesting additional processing by the client and authenticator. For + example, the caller may request that only authenticators with certain capabilies be used to create the credential, or + that particular information be returned in the [=attestation object=]. Some extensions are defined in [[#extensions]]; consult the IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]] for an up-to-date list of registered WebAuthn Extensions. </div> -### Entity Description ### {#dictionary-pkcredentialentity} +### Public Key Entity Description (dictionary <dfn dictionary>PublicKeyCredentialEntity</dfn>) ### {#dictionary-pkcredentialentity} -The {{PublicKeyCredentialEntity}} dictionary describes a user account or a [=[RP]=] with which a credential is +The {{PublicKeyCredentialEntity}} dictionary describes a user account, or a [=[RP]=], with which a [=public key credential=] is associated. <xmp class="idl"> @@ -1085,8 +1113,8 @@ associated.
    : id - :: A unique identifier for the entity. This will be the [=ASCII serialization of an origin=] for a [=[RP]=], - and an arbitrary string specified by the [=[RP]=] for user accounts. + :: A unique identifier for the entity. For a [=relying party=] entity, sets the [=RP ID=]. For a user account + entity, this will be an arbitrary string specified by the [=relying party=]. : name :: A human-friendly identifier for the entity. For example, this could be a company name for a [=[RP]=], or a @@ -1098,9 +1126,27 @@ associated.
    -### Authenticator Selection Criteria ### {#authenticatorSelection} +### User Account Parameters for Credential Generation (dictionary PublicKeyCredentialUserEntity) ### {#sctn-user-credential-params} -[=[RPS]=] may use the {{AuthenticatorSelectionCriteria}} dictionary to specify their requirements regarding authenticator attributes. +The {{PublicKeyCredentialUserEntity}} dictionary is used to supply additional user account attributes when creating a new +credential. + +
    +    dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
    +        DOMString displayName;
    +    };
    +
    + +
    + : displayName + :: A friendly name for the user account (e.g., "John P. Smith"). +
    + + +### Authenticator Selection Criteria (dictionary AuthenticatorSelectionCriteria) ### {#authenticatorSelection} + +[=[RPS]=] may use the {{AuthenticatorSelectionCriteria}} dictionary to specify their requirements regarding authenticator +attributes. dictionary AuthenticatorSelectionCriteria { @@ -1111,12 +1157,12 @@ associated. <div dfn-type="dict-member" dfn-for="AuthenticatorSelectionCriteria"> : <dfn>attachment</dfn> - :: If this memeber is [=present|present=], eligible authenticators are filtered to only authenticators attached with the + :: If this member is [=present|present=], eligible authenticators are filtered to only authenticators attached with the specified [[#attachment]]. : <dfn>requireResidentKey</dfn> - :: This member describes the [=[RPS]=]' requirements regarding availability of the [=Client-side-resident Credential - Private Key=]. If the parameter is set to true, the authenticator MUST create a + :: This member describes the [=[RPS]=]' requirements regarding availability of the [=Client-side-resident Credential + Private Key=]. If the parameter is set to true, the authenticator MUST create a [=Client-side-resident Credential Private Key=] when creating a [=public key credential=]. </div> @@ -1182,8 +1228,8 @@ an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member must be : <dfn>rpId</dfn> :: This optional member specifies the [=relying party identifier=] claimed by the caller. If omitted, its value will - be the [=ASCII serialization of an origin|ASCII serialization=] of the {{CredentialsContainer}} object's [=relevant - settings object=]'s [=environment settings object/origin=]. + be the {{CredentialsContainer}} object's [=relevant settings object=]'s [=environment settings object/origin=]'s + [=effective domain=]. : <dfn>allowList</dfn> :: This optional member contains a list of {{PublicKeyCredentialDescriptor}} object representing [=public key credentials=] @@ -1225,7 +1271,7 @@ following Web IDL. required DOMString challenge; required DOMString origin; required DOMString hashAlg; - DOMString tokenBinding; + DOMString tokenBindingId; AuthenticationExtensions clientExtensions; AuthenticationExtensions authenticatorExtensions; }; @@ -1241,9 +1287,9 @@ following Web IDL. algorithm used to compute the [=hash of the serialized client data=]. This algorithm is chosen by the client at its sole discretion. - The <dfn>tokenBinding</dfn> member contains the base64url encoding of the [=Token Binding ID=] that this client uses for the - [=Token Binding=] protocol when communicating with the [=[RP]=]. This can be omitted if no [=Token Binding=] has been negotiated - between the client and the [=[RP]=]. + The <dfn>tokenBindingId</dfn> member contains the base64url encoding of the [=Token Binding ID=] that this client uses for + the [=Token Binding=] protocol when communicating with the [=[RP]=]. This can be omitted if no [=Token Binding=] has been + negotiated between the client and the [=[RP]=]. The optional <dfn>clientExtensions</dfn> and <dfn>authenticatorExtensions</dfn> members contain additional parameters generated by processing the extensions passed in @@ -1424,7 +1470,7 @@ The [=authenticator data=] structure is a byte array of 37 bytes or more, as fol <tr> <td>32</td> <td> - SHA-256 hash of the RP ID associated with the credential. + SHA-256 hash of the [=RP ID=] associated with the credential. </td> </tr> <tr> @@ -1457,19 +1503,20 @@ The [=authenticator data=] structure is a byte array of 37 bytes or more, as fol </tr> </table> -The RP ID is originally received from the client when the credential is created, and again when an assertion is generated. -However, it differs from other [=client data=] in some important ways. First, unlike the client data, the RP ID of a credential -does not change between operations but instead remains the same for the lifetime of that credential. Secondly, it is validated -by the authenticator during the [=authenticatorGetAssertion=] operation, by verifying that the RP ID associated with the -requested credential exactly matches the RP ID supplied by the client. +The [=RP ID=] is originally received from the client when the credential is created, and again when an assertion is generated. +However, it differs from other [=client data=] in some important ways. First, unlike the client data, the [=RP ID=] of a +credential does not change between operations but instead remains the same for the lifetime of that credential. Secondly, it is +validated by the authenticator during the [=authenticatorGetAssertion=] operation, by verifying that the [=RP ID=] associated +with the requested credential exactly matches the [=RP ID=] supplied by the client, and that the [=RP ID=] [=is a registrable +domain suffix of or is equal to=] the [=effective domain=] of the RP's [=origin=]'s [=effective domain=]. -The `TUP` flag SHALL be set if and only if the authenticator detected a user through an authenticator specific gesture. The `RFU` bits -SHALL be set to zero. +The `TUP` flag SHALL be set if and only if the authenticator detected a user through an authenticator specific gesture. The +`RFU` bits SHALL be set to zero. For attestation signatures, the authenticator MUST set the AT flag and include the [=attestation data=]. For authentication signatures, the AT flag MUST NOT be set and the [=attestation data=] MUST NOT be included. -If the authenticator does not include any extension data, it MUST set the `ED` flag in the first byte to zero, and to one if +If the authenticator does not include any extension data, it MUST set the `ED` flag to zero, and to one if extension data is included. The [figure below](#fig-authData) shows a visual representation of the [=authenticator data=] structure. @@ -1498,16 +1545,18 @@ The following operations can be invoked by the client in an authenticator sessio This operation must be invoked in an authenticator session which has no other operations in progress. It takes the following input parameters: -- The caller's RP ID, as determined by the user agent and the client. +- The caller's [=RP ID=], as <a href='#CreateCred-DetermineRpId'>determined</a> by the user agent and the client. - The [=hash of the serialized client data=], provided by the client. - The [=[RP]=]'s {{PublicKeyCredentialEntity}}. -- The user account's {{PublicKeyCredentialEntity}}. -- The {{PublicKeyCredentialType}} and cryptographic parameters requested by the [=[RP]=], with the cryptographic algorithms - normalized as per the procedure in [[WebCryptoAPI#algorithm-normalization-normalize-an-algorithm]]. -- A list of {{PublicKeyCredential}} objects provided by the [=[RP]=] with the intention that, if any of these are known to the - authenticator, it should not create a new credential. -- Extension data created by the client based on the extensions requested by the [=[RP]=]. -- The |requireResidentKey| parameter of the |options|.{{MakeCredentialOptions/authenticatorSelection}} dictionary. +- The user account's {{PublicKeyCredentialUserEntity}}. +- A sequence of pairs of {{PublicKeyCredentialType}} and cryptographic algorithms (a dictionary type) requested by the [=[RP]=], + where the cryptographic algorithms are normalized as per the procedure in + [[WebCryptoAPI#algorithm-normalization-normalize-an-algorithm]]. This sequence is is ordered from most preferred to least + preferred. The platform makes a best-effort to create the most preferred credential that it can. +- An optional list of {{PublicKeyCredentialDescriptor}} objects provided by the [=[RP]=] with the intention that, if any of + these are known to the authenticator, it should not create a new credential. +- Extension data created by the client based on the extensions requested by the [=[RP]=], if any. +- The |requireResidentKey| parameter of the |options|.{{MakeCredentialOptions/authenticatorSelection}} dictionary. When this operation is invoked, the authenticator must perform the following procedure: - Check if all the supplied parameters are syntactically well-formed and of the correct length. If not, return an error code @@ -1516,7 +1565,7 @@ When this operation is invoked, the authenticator must perform the following pro If not, return an error code equivalent to "{{NotSupportedError}}" and terminate the operation. - Check if a credential matching any of the supplied {{PublicKeyCredential}} identifiers is present on this authenticator. If so, return an error code equivalent to "{{NotAllowedError}}" and terminate the operation. -- If the |requireResidentKey| flag is set to |true| and the authenticator cannot store a [=Client-side-resident Credential +- If the |requireResidentKey| flag is set to |true| and the authenticator cannot store a [=Client-side-resident Credential Private Key=], return an error code equivalent to "{{ConstraintError}}" and terminate the operation. - Prompt the user for consent to create a new credential. The prompt for obtaining this consent is shown by the authenticator if it has its own output capability, or by the user agent otherwise. If the user denies consent, return an error code @@ -1526,11 +1575,11 @@ When this operation is invoked, the authenticator must perform the following pro parameters supported by this authenticator. - Generate an identifier for this credential, such that this identifier is globally unique with high probability across all credentials with the same type across all authenticators. - - Associate the credential with the specified RP ID and the user's account identifier + - Associate the credential with the specified [=RP ID=] and the user's account identifier {{MakeCredentialOptions/user}}.{{PublicKeyCredentialEntity/id}}. - - Delete any older credentials with the same RP ID and {{MakeCredentialOptions/user}}.{{PublicKeyCredentialEntity/id}} that - are stored locally in the authenticator. -- If any error occurred while creating the new credential object, return an error code equivalent to "{{UnknownError}}" and + - Delete any older credentials with the same [=RP ID=] and {{MakeCredentialOptions/user}}.{{PublicKeyCredentialEntity/id}} + that are stored locally by the [=authenticator=]. +- If any error occurred while creating the new credential object, return an error code equivalent to "{{UnknownError}}" and terminate the operation. - Process all the supported extensions requested by the client, and generate the [=authenticator data=] with [=attestation data=] as specified in [[#sec-authenticator-data]]. Use this [=authenticator data=] and the @@ -1545,23 +1594,23 @@ On successful completion of this operation, the authenticator returns the [=atte This operation must be invoked in an authenticator session which has no other operations in progress. It takes the following input parameters: -- The caller's RP ID, as determined by the user agent and the client. +- The caller's [=RP ID=], as <a href='#GetAssn-DetermineRpId'>determined</a> by the user agent and the client. - The [=hash of the serialized client data=], provided by the client. -- A list of credentials acceptable to the [=[RP]=] (possibly filtered by the client). -- Extension data created by the client based on the extensions requested by the [=[RP]=]. +- A list of credentials acceptable to the [=[RP]=] (possibly filtered by the client), if any. +- Extension data created by the client based on the extensions requested by the [=[RP]=], if any. When this method is invoked, the [=authenticator=] must perform the following procedure: - Check if all the supplied parameters are syntactically well-formed and of the correct length. If not, return an error code equivalent to "{{UnknownError}}" and terminate the operation. - If a list of credentials was supplied by the client, filter it by removing those credentials that are not present on this - [=authenticator=]. If no list was supplied, create a list with all credentials stored for the caller's RP ID (as determined by - an exact match of the RP ID). + [=authenticator=]. If no list was supplied, create a list with all credentials stored for the caller's [=RP ID=] (as + determined by an exact match of the [=RP ID=]). - If the previous step resulted in an empty list, return an error code equivalent to "{{NotAllowedError}}" and terminate the operation. - Prompt the user to select a [=public key credential|credential=] from among the above list. Obtain [=user consent=] for using this [=public key credential|credential=]. The prompt for obtaining this [=user consent|consent=] may be shown by the [=authenticator=] if it has its own output capability, or by the user agent otherwise. -- Process all the supported extensions requested by the client, and generate the [=authenticator data=] as specified in +- Process all the supported extensions requested by the client, and generate the [=authenticator data=] as specified in [[#sec-authenticator-data]], though without [=attestation data=]. Concatenate this [=authenticator data=] with the [=hash of the serialized client data=] to generate an [=assertion signature=] using the [=credential private key|private key=] of the selected [=public key credential|credential=] as shown in [Figure 2](#fig-signature), below. A simple, undelimited @@ -1613,9 +1662,11 @@ information is returned by [=authenticators=] any time a new [=public key creden <figure id="fig-attStructs"> <img src="images/fido-attestation-structures.svg"/> - <figcaption>[=Attestation object=] layout illustrating the included [=authenticator data=] (containing [=attestation data=]) and the [=attestation statement=].</figcaption> + <figcaption>[=Attestation object=] layout illustrating the included [=authenticator data=] (containing [=attestation data=]) + and the [=attestation statement=].</figcaption> <div class="note"> - This figure illustrates only the `packed` [=attestation statement format=]. Several additional [=attestation statement formats=] are defined in [[#defined-attestation-formats]]. + This figure illustrates only the `packed` [=attestation statement format=]. Several additional [=attestation statement + formats=] are defined in [[#defined-attestation-formats]]. </div> </figure> @@ -1631,7 +1682,7 @@ statement=], a [=[RP]=] needs to understand these two aspects of [=attestation=] [=attestation statement formats=]. This specification supports a variety of such formats in an extensible way, as defined in [[#attestation-formats]]. -2. The <dfn>attestation type</dfn> defines the semantics of [=attestation statements=] and their underlying trust models. +2. The <dfn>attestation type</dfn> defines the semantics of [=attestation statements=] and their underlying trust models. Specifically, it defines how a [=[RP]=] establishes trust in a particular [=attestation statement=], after verifying that it is cryptographically valid. This specification supports a number of [=attestation types=], as described in [[#sctn-attestation-types]]. @@ -1642,7 +1693,7 @@ types=], while other formats and types have more limited applicability. The privacy, security and operational characteristics of [=attestation=] depend on: - The [=attestation type=], which determines the trust model, -- The [=attestation statement format=], which may constrain the strength of the [=attestation=] by limiting what can be +- The [=attestation statement format=], which may constrain the strength of the [=attestation=] by limiting what can be expressed in an [=attestation statement=], and - The characteristics of the individual [=authenticator=], such as its construction, whether part or all of it runs in a secure operating environment, and so on. @@ -1710,7 +1761,8 @@ credential. It has the following format: ### Attestation Statement Formats ### {#attestation-formats} As described above, an [=attestation statement format=] is a data format which represents a cryptographic signature by an -[=authenticator=] over a set of contextual bindings. Each [=attestation statement format=] MUST be defined using the following template: +[=authenticator=] over a set of contextual bindings. Each [=attestation statement format=] MUST be defined using the following +template: - <strong>[=Attestation statement format identifier=]:</strong> @@ -1720,15 +1772,15 @@ As described above, an [=attestation statement format=] is a data format which r The syntax of an [=attestation statement=] produced in this format, defined using [[!CDDL]] for the extension point `$attStmtFormat` defined in [[#generating-an-attestation-object]]. -- <dfn>Signing procedure</dfn>: - The [=signing procedure=] for computing an [=attestation statement=] in this [=attestation statement format|format=] given the [=public key credential=] to be attested, - the [=authenticator data=] structure containing the <dfn>authenticator data for the attestation</dfn>, and the [=hash of the - serialized client data=]. +- <dfn>Signing procedure</dfn>: + The [=signing procedure=] for computing an [=attestation statement=] in this [=attestation statement format|format=] given + the [=public key credential=] to be attested, the [=authenticator data=] structure containing the <dfn>authenticator data + for the attestation</dfn>, and the [=hash of the serialized client data=]. - <dfn>Verification procedurs</dfn>: - The procedure for verifying an [=attestation statement=], which takes as inputs the [=authenticator data=] structure containing - the <dfn>authenticator data claimed to have been used for the attestation</dfn> and the - [=hash of the serialized client data=], and returns either: + The procedure for verifying an [=attestation statement=], which takes as inputs the [=authenticator data=] structure + containing the <dfn>authenticator data claimed to have been used for the attestation</dfn> and the [=hash of the serialized + client data=], and returns either: - An error indicating that the attestation is invalid, or - The attestation type, and the trust path of the attestation. This trust path is either empty (in case of self-attestation), an identifier of a [=ECDAA-Issuer public key=] (in the case of [=ECDAA=]), or a set of X.509 @@ -1773,7 +1825,8 @@ WebAuthn supports multiple attestation types: ### Generating an Attestation Object ### {#generating-an-attestation-object} -This section specifies the algorithm for generating an [=attestation object=] for any [=attestation statement format=]. +This section specifies the algorithm for generating an [=attestation object=] (see: [Figure 3](#fig-attStructs)) for any +[=attestation statement format=]. In order to construct an [=attestation object=] for a given [=public key credential=] using a particular [=attestation statement format=], the [=authenticator=] MUST first generate the [=authenticator data=]. @@ -1830,8 +1883,8 @@ in several ways, including: [=origin=] attestation keys and attestation certificates. - A WebAuthn Authenticator can implement [=Elliptic Curve based direct anonymous attestation=] (see [[FIDOEcdaaAlgorithm]]). - Using this scheme, the authenticator generates a blinded attestation signature. This allows the [=[RP]=] to verify the signature - using the [=ECDAA-Issuer public key=], but the attestation signature doesn't serve as a global correlation handle. + Using this scheme, the authenticator generates a blinded attestation signature. This allows the [=[RP]=] to verify the + signature using the [=ECDAA-Issuer public key=], but the attestation signature doesn't serve as a global correlation handle. #### Attestation Certificate and Attestation Certificate CA Compromise #### {#ca-compromise} @@ -1873,17 +1926,17 @@ should be specified in the attestation certificate itself, so that it can be ver # [=[RP]=] Operations # {#rp-operations} -Upon successful execution of {{CredentialsContainer/create()}} or {{CredentialsContainer/get()}}, the [=[RP]=]'s script receives a -{{PublicKeyCredential}} containing an {{AuthenticatorAttestationResponse}} or {{AuthenticatorAssertionResponse}} structure, -respectively, from the client. It must then deliver the contents of this structure to the [=[RP]=] server, using methods -outside the scope of this specification. This section describes the operations that the [=[RP]=] must perform upon receipt of -these structures. +Upon successful execution of {{CredentialsContainer/create()}} or {{CredentialsContainer/get()}}, the [=[RP]=]'s script receives +a {{PublicKeyCredential}} containing an {{AuthenticatorAttestationResponse}} or {{AuthenticatorAssertionResponse}} structure, +respectively, from the client. It must then deliver the contents of this structure to the [=[RP]=] server, using methods outside +the scope of this specification. This section describes the operations that the [=[RP]=] must perform upon receipt of these +structures. ## Registering a new credential ## {#registering-a-new-credential} -When registering a new credential, represented by a {{AuthenticatorAttestationResponse}} structure, as part of a [=registration=] -[=ceremony=], a [=[RP]=] MUST proceed as follows: +When registering a new credential, represented by a {{AuthenticatorAttestationResponse}} structure, as part of a +[=registration=] [=ceremony=], a [=[RP]=] MUST proceed as follows: 1. Perform JSON deserialization on the {{AuthenticatorResponse/clientDataJSON}} field of the {{AuthenticatorAttestationResponse}} object to extract the [=client data=] |C| claimed as collected during the credential @@ -1894,7 +1947,7 @@ When registering a new credential, represented by a {{AuthenticatorAttestationRe 3. Verify that the {{CollectedClientData/origin}} in |C| matches the [=[RP]=]'s [=origin=]. -4. Verify that the {{CollectedClientData/tokenBinding}} in |C| matches the [=Token Binding ID=] for the TLS connection over +4. Verify that the {{CollectedClientData/tokenBindingId}} in |C| matches the [=Token Binding ID=] for the TLS connection over which the attestation was obtained. 5. Verify that the {{CollectedClientData/clientExtensions}} in |C| is a proper subset of the extensions requested by the RP @@ -1908,7 +1961,7 @@ When registering a new credential, represented by a {{AuthenticatorAttestationRe {{AuthenticatorAttestationResponse}} structure to obtain the attestation statement format |fmt|, the [=authenticator data=] |authData|, and the attestation statement |attStmt|. -8. Verify that the RP ID hash in |authData| is indeed the SHA-256 hash of the RP ID expected by the RP. +8. Verify that the [=RP ID=] hash in |authData| is indeed the SHA-256 hash of the [=RP ID=] expected by the RP. 9. Determine the attestation statement format by performing an USASCII case-sensitive match on |fmt| against the set of supported WebAuthn Attestation Statement Format Identifier values. @@ -1941,8 +1994,8 @@ When registering a new credential, represented by a {{AuthenticatorAttestationRe the registration ceremony. NOTE: However, if permitted by policy, the [=[RP]=] MAY register the credential ID and credential public key but treat the - credential as one with self-attestation (see [[#sctn-attestation-types]]). If doing so, the [=[RP]=] is asserting there is - no cryptographic proof that the [=public key credential=] has been generated by a particular [=authenticator=] model. + credential as one with self-attestation (see [[#sctn-attestation-types]]). If doing so, the [=[RP]=] is asserting there + is no cryptographic proof that the [=public key credential=] has been generated by a particular [=authenticator=] model. See [[FIDOSecRef]] and [[UAFProtocol]] for a more detailed discussion. 15. If verification of the attestation statement failed, the [=[RP]=] MUST fail the registration ceremony. @@ -1952,9 +2005,9 @@ in step 11 above. Also, if certificates are being used, the [=[RP]=] must have a intermediate CA certificates. The [=[RP]=] must also be able to build the attestation certificate chain if the client did not provide this chain in the attestation information. -To avoid ambiguity during authentication, the [=[RP]=] SHOULD check that each credential is registered to no more than one user. If -registration is requested for a credential that is already registered to a different user, the [=[RP]=] SHOULD fail this ceremony, -or it MAY decide to accept the registration, e.g. while deleting the older registration. +To avoid ambiguity during authentication, the [=[RP]=] SHOULD check that each credential is registered to no more than one user. +If registration is requested for a credential that is already registered to a different user, the [=[RP]=] SHOULD fail this +ceremony, or it MAY decide to accept the registration, e.g. while deleting the older registration. ## Verifying an authentication assertion ## {#verifying-assertion} @@ -1976,14 +2029,14 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) as part 5. Verify that the {{CollectedClientData/origin}} member of |C| matches the [=[RP]=]'s [=origin=]. -6. Verify that the {{CollectedClientData/tokenBinding}} member of |C| (if present) matches the [=Token Binding ID=] for the TLS - connection over which the signature was obtained. +6. Verify that the {{CollectedClientData/tokenBindingId}} member of |C| (if present) matches the [=Token Binding ID=] for the + TLS connection over which the signature was obtained. 7. Verify that the {{CollectedClientData/clientExtensions}} member of |C| is a proper subset of the extensions requested by the [=[RP]=] and that the {{CollectedClientData/authenticatorExtensions}} in |C| is also a proper subset of the extensions requested by the [=[RP]=]. -8. Verify that the RP ID hash in |aData| is the SHA-256 hash of the RP ID expected by the [=[RP]=]. +8. Verify that the [=RP ID=] hash in |aData| is the SHA-256 hash of the [=RP ID=] expected by the [=[RP]=]. 9. Let |hash| be the result of computing a hash over the |cData| using the algorithm represented by the {{CollectedClientData/hashAlg}} member of |C|. @@ -2010,9 +2063,11 @@ Attestation statement format identifiers SHOULD be registered per [[!WebAuthn-Re Unregistered attestation statement format identifiers SHOULD use lowercase reverse domain-name naming, using a domain name registered by the developer, in order to assure uniqueness of the identifier. All attestation statement format identifiers MUST be a maximum of 32 octets in length and MUST consist only of printable USASCII characters, excluding backslash and doublequote, -i.e., VCHAR as defined in [[!RFC5234]] but without %x22 and %x5c. (Note: This means attestation statement format identifiers -based on domain names MUST incorporate only LDH Labels [[!RFC5890]].) Implementations MUST match WebAuthn attestation statement -format identifiers in a case-sensitive fashion. +i.e., VCHAR as defined in [[!RFC5234]] but without %x22 and %x5c. + +Note: This means attestation statement format identifiers based on domain names MUST incorporate only LDH Labels [[!RFC5890]]. + +Implementations MUST match WebAuthn attestation statement format identifiers in a case-sensitive fashion. Attestation statement formats that may exist in multiple versions SHOULD include a version in their identifier. In effect, different versions are thus treated as different formats, e.g., `packed2` as a new version of the `packed` attestation statement @@ -2275,11 +2330,11 @@ TPM [=attestation certificate=] MUST have the following fields/extensions: ## Android Key Attestation Statement Format ## {#android-key-attestation} When the [=authenticator=] in question is a platform-provided Authenticator on the Android "N" or later platform, the -attestation statement is based on the -[Android key attestation](https://developer.android.com/preview/api-overview.html#key_attestation). In these cases, the -attestation statement is produced by a component running in a secure operating environment, but the [=authenticator data for the -attestation=] is produced outside this environment. The [=[RP]=] is expected to check that the [=authenticator data claimed to have -been used for the attestation=] is consistent with the fields of the attestation certificate's extension data. +attestation statement is based on the [Android key +attestation](https://developer.android.com/preview/api-overview.html#key_attestation). In these cases, the attestation statement +is produced by a component running in a secure operating environment, but the [=authenticator data for the attestation=] is +produced outside this environment. The [=[RP]=] is expected to check that the [=authenticator data claimed to have been used for +the attestation=] is consistent with the fields of the attestation certificate's extension data. : Attestation statement format identifier @@ -2310,10 +2365,9 @@ been used for the attestation=] is consistent with the fields of the attestation Concatenate |authenticatorData| and |clientDataHash| to form |attToBeSigned|. Request an Android Key Attestation by calling "keyStore.getCertificateChain(myKeyUUID)") providing |attToBeSigned| as the - challenge value (e.g., by using - <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setAttestationChallenge(byte%5B%5D)"> - setAttestationChallenge</a>), - and set the attestation statement to the returned value. + challenge value (e.g., by using <a + href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setAttestationChallenge(byte%5B%5D)"> + setAttestationChallenge</a>), and set the attestation statement to the returned value. : Verification procedure :: Verification is performed as follows: @@ -2325,7 +2379,7 @@ been used for the attestation=] is consistent with the fields of the attestation - The value of the `attestationChallenge` field is identical to the concatenation of |authenticatorData| and |clientDataHash|. - The `AuthorizationList.allApplications` field is <em>not</em> present, since PublicKeyCredentials must be bound to the - RP ID. + [=RP ID=]. - The value in the `AuthorizationList.origin` field is equal to `KM_TAG_GENERATED`. - The value in the `AuthorizationList.purpose` field is equal to `KM_PURPOSE_SIGN`. - If successful, return attestation type Basic with the trust path set to the entire attestation statement. @@ -2435,7 +2489,7 @@ This attestation statement format is used with FIDO U2F authenticators using the |clientDataHash|. Generate a signature as specified in [[FIDO-U2F-Message-Formats]] section 4.3, with the application parameter set to the - SHA-256 hash of the RP ID associated with the given credential, the challenge parameter set to |tbsHash|, and the key handle + SHA-256 hash of the [=RP ID=] associated with the given credential, the challenge parameter set to |tbsHash|, and the key handle parameter set to the credential ID of the given credential. Set this as |sig| and set the attestation certificate of the attestation public key as |x5c|. @@ -2447,9 +2501,9 @@ This attestation statement format is used with FIDO U2F authenticators using the |clientDataHash| denote the [=hash of the serialized client data=]. - If |clientDataHash| is 256 bits long, set |tbsHash| to this value. Otherwise set |tbsHash| to the SHA-256 hash of |clientDataHash|. - - From |authenticatorData|, extract the claimed RP ID hash, the claimed credential ID and the claimed credential public key. + - From |authenticatorData|, extract the claimed [=RP ID=] hash, the claimed credential ID and the claimed credential public key. - Generate the claimed to-be-signed data as specified in [[FIDO-U2F-Message-Formats]] section 4.3, with the application - parameter set to the claimed RP ID hash, the challenge parameter set to |tbsHash|, the key handle parameter set to the + parameter set to the claimed [=RP ID=] hash, the challenge parameter set to |tbsHash|, the key handle parameter set to the claimed credential ID of the given credential, and the user public key parameter set to the claimed credential public key. - Verify that the |sig| is a valid ECDSA P-256 signature over the to-be-signed data constructed above. @@ -2472,10 +2526,10 @@ client. - [=Client extension processing=] for [=registration extensions=] and [=authentication extensions=]. -When creating a [=public key credential=] or requesting an [=authentication assertion=], a [=[RP]=] can request the use of a set of -extensions. These extensions will be invoked during the requested operation if they are supported by the client and/or the -authenticator. The [=[RP]=] sends the [=client extension input=] for each extension in the {{CredentialsContainer/get()}} call (for -[=authentication extensions=]) or {{CredentialsContainer/create()}} call (for [=registration extensions=]) to the client +When creating a [=public key credential=] or requesting an [=authentication assertion=], a [=[RP]=] can request the use of a set +of extensions. These extensions will be invoked during the requested operation if they are supported by the client and/or the +authenticator. The [=[RP]=] sends the [=client extension input=] for each extension in the {{CredentialsContainer/get()}} call +(for [=authentication extensions=]) or {{CredentialsContainer/create()}} call (for [=registration extensions=]) to the client platform. The client platform performs [=client extension processing=] for each extension that it supports, and augments the [=client data=] as specified by each extension, by including the [=extension identifier=] and [=client extension output=] values. @@ -2550,15 +2604,13 @@ it must also specify the [=CBOR=] [=authenticator extension input=] argument sent via the [=authenticatorGetAssertion=] or [=authenticatorMakeCredential=] call, the [=authenticator extension processing=] rules, and the [=CBOR=] [=authenticator extension output=] value. -Any [=client extension=] that is processed by the client MUST return a [=client extension output=] value so that -the [=[RP]=] knows that the extension was honored by the client. Similarly, any extension that requires authenticator processing MUST -return an [=authenticator extension output=] to let the [=[RP]=] know that the extension was honored by the authenticator. -If an extension does not otherwise require any result values, it SHOULD be defined as returning a JSON Boolean [=client extension output=] result, -set to `true` to signify that the extension was understood and processed. -Likewise, any [=authenticator extension=] that does not otherwise require any result values -MUST return a value and -SHOULD return a CBOR Boolean [=authenticator extension output=] result, -set to `true` to signify that the extension was understood and processed. +Any [=client extension=] that is processed by the client MUST return a [=client extension output=] value so that the [=[RP]=] +knows that the extension was honored by the client. Similarly, any extension that requires authenticator processing MUST return +an [=authenticator extension output=] to let the [=[RP]=] know that the extension was honored by the authenticator. If an +extension does not otherwise require any result values, it SHOULD be defined as returning a JSON Boolean [=client extension +output=] result, set to `true` to signify that the extension was understood and processed. Likewise, any [=authenticator +extension=] that does not otherwise require any result values MUST return a value and SHOULD return a CBOR Boolean +[=authenticator extension output=] result, set to `true` to signify that the extension was understood and processed. ## Extending request parameters ## {#sctn-extension-request-parameters} @@ -2584,8 +2636,8 @@ The entry key is the [=extension identifier=] and the value is the [=client exte </pre> Extension definitions MUST specify the valid values for their [=client extension input=]. Clients SHOULD ignore extensions with -an invalid [=client extension input=]. If an extension does not require any parameters from the [=[RP]=], it SHOULD be defined as -taking a Boolean client argument, set to `true` to signify that the extension is requested by the [=[RP]=]. +an invalid [=client extension input=]. If an extension does not require any parameters from the [=[RP]=], it SHOULD be defined +as taking a Boolean client argument, set to `true` to signify that the extension is requested by the [=[RP]=]. Extensions that only affect client processing need not specify [=authenticator extension input=]. Extensions that have authenticator processing MUST specify the method of computing the [=authenticator extension input=] from the [=client extension @@ -2729,8 +2781,8 @@ error. ## Simple Transaction Authorization Extension (txAuthSimple) ## {#sctn-simple-txauth-extension} -This [=registration extension=] and [=authentication extension=] allows for a simple form of transaction authorization. A [=[RP]=] -can specify a prompt string, intended for display on a trusted device on the authenticator. +This [=registration extension=] and [=authentication extension=] allows for a simple form of transaction authorization. A +[=[RP]=] can specify a prompt string, intended for display on a trusted device on the authenticator. : Extension identifier :: `txAuthSimple` @@ -2792,8 +2844,9 @@ as well. This allows authenticators without a font rendering engine to be used a ## Authenticator Selection Extension (authnSel) ## {#sctn-authenticator-selection-extension} -This [=registration extension=] allows a [=[RP]=] to guide the selection of the authenticator that will be leveraged when creating -the credential. It is intended primarily for [=[RPS]=] that wish to tightly control the experience around credential creation. +This [=registration extension=] allows a [=[RP]=] to guide the selection of the authenticator that will be leveraged when +creating the credential. It is intended primarily for [=[RPS]=] that wish to tightly control the experience around credential +creation. : Extension identifier :: `authnSel` @@ -2899,7 +2952,7 @@ This [=registration extension=] and [=authentication extension=] enables use of Example for [=authenticator data=] containing one UVI extension <pre> - ... -- RP ID hash (32 bytes) + ... -- [=RP ID=] hash (32 bytes) 81 -- TUP and ED set 00 00 00 01 -- (initial) signature counter ... -- all public key alg etc. @@ -2949,7 +3002,7 @@ WebAuthn [=[RP]=]. Specification](https://dev.w3.org/geo/api/spec-source.html#coordinates_interface). <pre> - ... -- RP ID hash (32 bytes) + ... -- [=RP ID=] hash (32 bytes) 81 -- TUP and ED set 00 00 00 01 -- (initial) signature counter ... -- all public key alg etc. @@ -3023,7 +3076,7 @@ This [=registration extension=] and [=authentication extension=] enables use of Example for [=authenticator data=] containing one UVM extension for a multi-factor authentication instance where 2 factors were used: <pre> - ... -- RP ID hash (32 bytes) + ... -- [=RP ID=] hash (32 bytes) 81 -- TUP and ED set 00 00 00 01 -- (initial) signature counter ... -- all public key alg etc. @@ -3080,7 +3133,7 @@ This section registers the [=extension identifier=] values defined in Section [[ IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]]. - WebAuthn Extension Identifier: appid -- Description: This [=authentication extension=] allows [=[RPS]=] that have previously registered a credential using the legacy +- Description: This [=authentication extension=] allows [=[RPS]=] that have previously registered a credential using the legacy FIDO JavaScript APIs to request an assertion. - Specification Document: Section [[#sctn-appid-extension]] of this specification <br/><br/> @@ -3256,8 +3309,8 @@ credential. - The server now does whatever it would otherwise do upon successful authentication -- return a success page, set authentication cookies, etc. -If the [=[RP]=] script does not have any hints available (e.g., from locally stored data) to help it narrow the list of credentials, -then the sample code for performing such an authentication might look like this: +If the [=[RP]=] script does not have any hints available (e.g., from locally stored data) to help it narrow the list of +credentials, then the sample code for performing such an authentication might look like this: <pre class="example" highlight="js"> if (!PublicKeyCredential) { /* Platform not capable. Handle error. */ }