diff --git a/index.bs b/index.bs index 7fff2d1e7..24402f33c 100644 --- a/index.bs +++ b/index.bs @@ -387,7 +387,8 @@ Beyond that, the intended audiences for this document are the following main gro They should also carefully read [[#sctn-security-considerations-authenticator]] and [[#sctn-privacy-considerations-authenticator]].
- Note: Along with the [[#sctn-api|Web Authentication API]] itself, this specification defines a + Note: + Along with the [[#sctn-api|Web Authentication API]] itself, this specification defines a request-response cryptographic protocol—the WebAuthn/FIDO2 protocol—between a [=[WRP]=] server and an [=authenticator=], where the [=[RP]=]'s request consists of a @@ -1225,7 +1226,8 @@ BCP 14 [[!RFC2119]] [[!RFC8174]] when, and only when, they appear in all capital [=authentication assertion=]. Which one is generally determined by context.
- Note: This is a [=willful violation=] of [[RFC4949]]. In English, a "credential" is both a) the thing presented to prove + Note: + This is a [=willful violation=] of [[RFC4949]]. In English, a "credential" is both a) the thing presented to prove a statement and b) intended to be used multiple times. It's impossible to achieve both criteria securely with a single piece of data in a public key system. [[RFC4949]] chooses to define a credential as the thing that can be used multiple times (the public key), while this specification gives "credential" the English term's flexibility. This specification @@ -1327,23 +1329,29 @@ BCP 14 [[!RFC2119]] [[!RFC8174]] when, and only when, they appear in all capital to=] the caller's [=environment settings object/origin=]'s [=effective domain=]. See also [[#sctn-createCredential]] and [[#sctn-getAssertion]]. -
- Note: An [=RP ID=] is based on a [=origin/host=]'s [=domain=] name. It does not itself include a [=origin/scheme=] or [=port=], as an [=origin=] does. The [=RP ID=] of a [=public key credential=] determines its scope. I.e., it determines the set of origins on which the public key credential may be exercised, as follows: + An [=RP ID=] is based on a [=origin/host=]'s [=domain=] name. + It does not itself include a [=origin/scheme=] or [=port=], as an [=origin=] does. + The [=RP ID=] of a [=public key credential=] determines its scope. + I.e., it determines the set of origins on which the public key credential may be exercised, as follows: - - The [=RP ID=] must be equal to the [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=effective domain=], or a [=is a registrable domain suffix of or is equal to|registrable domain suffix=] of the [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=effective domain=]. - - One of the following must be true: - - The [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=origin/scheme=] is `https`. - - The [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=origin/host=] is `localhost` and its [=origin/scheme=] is `http`. - - The [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=port=] is unrestricted. + - The [=RP ID=] must be equal to the [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=effective domain=], + or a [=is a registrable domain suffix of or is equal to|registrable domain suffix=] of the + [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=effective domain=]. + - One of the following must be true: + - The [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=origin/scheme=] is `https`. + - The [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=origin/host=] is `localhost` + and its [=origin/scheme=] is `http`. + - The [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=port=] is unrestricted. - For example, given a [=[RP]=] whose origin is `https://login.example.com:1337`, then the following [=RP ID=]s are valid: `login.example.com` (default) and `example.com`, but not `m.login.example.com` and not `com`. Another example of a valid origin is `http://localhost:8000`, due to the origin being `localhost`. + For example, given a [=[RP]=] whose origin is `https://login.example.com:1337`, then the following [=RP ID=]s are valid: + `login.example.com` (default) and `example.com`, but not `m.login.example.com` and not `com`. + Another example of a valid origin is `http://localhost:8000`, due to the origin being `localhost`. - 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. + 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. - These restrictions on origin values apply to [=WebAuthn Clients=]. -
+ These restrictions on origin values apply to [=WebAuthn Clients=]. Other specifications mimicking the [=web authentication api|WebAuthn API=] to enable WebAuthn [=public key credentials=] on non-Web platforms (e.g. native mobile applications), MAY define different rules for binding a caller to a [=Relying Party Identifier=]. Though, the [=RP ID=] syntaxes MUST conform to either [=valid domain strings=] or URIs [[!RFC3986]] [[!URL]]. @@ -1442,13 +1450,11 @@ BCP 14 [[!RFC2119]] [[!RFC8174]] when, and only when, they appear in all capital yet they may allow multiple natural persons to enroll fingerprints or know the same PIN and thus access the same [=user account=](s) using that device. -
- Note: Invocation of the [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] operations - implies use of key material managed by the authenticator. + NOTE: Invocation of the [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] operations + implies use of key material managed by the authenticator. - Also, for security, [=user verification=] and use of [=credential private keys=] - must all occur within the logical security boundary defining the [=authenticator=]. -
+ For security, [=user verification=] and use of [=credential private keys=] + MUST all occur within the logical security boundary defining the [=authenticator=]. [=User verification=] procedures MAY implement [=rate limiting=] as a protection against brute force attacks. @@ -1552,7 +1558,8 @@ that are returned to the caller when a new credential is created, or a new asser as if the value were null.
- Note: If, as the result of a [=registration ceremony|registration=] or [=authentication ceremony=], {{PublicKeyCredential/authenticatorAttachment}}'s value is "cross-platform" and + Note: + If, as the result of a [=registration ceremony|registration=] or [=authentication ceremony=], {{PublicKeyCredential/authenticatorAttachment}}'s value is "cross-platform" and concurrently {{isUserVerifyingPlatformAuthenticatorAvailable}} returns [TRUE], then the user employed a [=roaming authenticator=] for this [=ceremony=] while there is an available [=platform authenticator=]. Thus the [=[RP]=] has the opportunity to prompt the user to register the available [=platform authenticator=], which may enable more streamlined user experience flows. @@ -1584,7 +1591,7 @@ that are returned to the caller when a new credential is created, or a new asser Note: If this method is not present, {{CredentialMediationRequirement/conditional}} [=user mediation=] is not available for {{CredentialsContainer/get()|navigator.credentials.get()}}. - Note: This method does _not_ indicate + Note: This method does *not* indicate whether or not {{CredentialMediationRequirement/conditional}} [=user mediation=] is available in {{CredentialsContainer/create()|navigator.credentials.create()}}. For that, see the {{ClientCapability/conditionalCreate}} capability in {{PublicKeyCredential/getClientCapabilities()}}. @@ -1684,8 +1691,8 @@ that are returned to the caller when a new credential is created, or a new asser The [=credential ID=] is used to look up credentials for use, and is therefore expected to be globally unique with high probability across all credentials of the same type, across all authenticators. - Note: This API does not constrain - the format or length of this identifier, except that it MUST be sufficient for the [=authenticator=] to uniquely select a key. + This API does not constrain the format of this identifier, + except that it MUST NOT be longer than 1023 bytes and MUST be sufficient for the [=authenticator=] to uniquely select a key. For example, an authenticator without on-board storage may create identifiers containing a [=credential private key=] wrapped with a symmetric key that is burned into the authenticator. @@ -1771,8 +1778,8 @@ This [=internal method=] accepts three arguments: Note: This algorithm is synchronous: the {{Promise}} resolution/rejection is handled by {{CredentialsContainer/create()|navigator.credentials.create()}}. -Note: All {{BufferSource}} objects used in this algorithm must be snapshotted when the algorithm begins, to -avoid potential synchronization issues. The algorithm implementations should [=get a copy of the bytes held +All {{BufferSource}} objects used in this algorithm MUST be snapshotted when the algorithm begins, to +avoid potential synchronization issues. Implementations SHOULD [=get a copy of the bytes held by the buffer source=] and use that copy for relevant portions of the algorithm. When this method is invoked, the user agent MUST execute the following algorithm: @@ -1794,10 +1801,9 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. [=Consume user activation=] of the [=relevant global object=]. - NOTE: The [=client=] SHOULD make it clear to the user in the case where the - [=origin=] that is creating a credential is different from the - [=top-level origin=] of the [=relevant global object=] (i.e., is a - different origin than the user can see in the address bar). + 1. If the [=origin=] that is creating a credential is different from the [=top-level origin=] of the [=relevant global object=] + (i.e., is a different origin than the user can see in the address bar), + the [=client=] SHOULD make this fact clear to the user. 1. Let |pkOptions| be the value of |options|.{{CredentialCreationOptions/publicKey}}. @@ -1809,7 +1815,7 @@ When this method is invoked, the user agent MUST execute the following algorithm See the [=recommended range and default for a WebAuthn ceremony timeout=] for guidance on deciding a reasonable range and default for |pkOptions|.{{PublicKeyCredentialCreationOptions/timeout}}. - Note: The user agent should take cognitive guidelines into considerations regarding timeout for users with special needs. + The [=client=] SHOULD take cognitive guidelines into considerations regarding timeout for users with special needs. 1. If the length of |pkOptions|.{{PublicKeyCredentialCreationOptions/user}}.{{PublicKeyCredentialUserEntity/id}} is not between 1 and 64 bytes (inclusive) then throw a {{TypeError}}. @@ -2350,8 +2356,8 @@ This [=internal method=] accepts three arguments: Note: This algorithm is synchronous: the {{Promise}} resolution/rejection is handled by {{CredentialsContainer/get()|navigator.credentials.get()}}. -Note: All {{BufferSource}} objects used in this algorithm must be snapshotted when the algorithm begins, to -avoid potential synchronization issues. The algorithm implementations should [=get a copy of the bytes held +All {{BufferSource}} objects used in this algorithm MUST be snapshotted when the algorithm begins, to +avoid potential synchronization issues. Implementations SHOULD [=get a copy of the bytes held by the buffer source=] and use that copy for relevant portions of the algorithm. When this method is invoked, the user agent MUST execute the following algorithm: @@ -2386,7 +2392,7 @@ When this method is invoked, the user agent MUST execute the following algorithm See the [=recommended range and default for a WebAuthn ceremony timeout=] for guidance on deciding a reasonable range and default for |pkOptions|.{{PublicKeyCredentialRequestOptions/timeout}}. - Note: The user agent should take cognitive guidelines into considerations regarding timeout for users with special needs. + The user agent SHOULD take cognitive guidelines into considerations regarding timeout for users with special needs. 1. Let |callerOrigin| be {{PublicKeyCredential/[DISCOVER-METHOD]/origin}}. If |callerOrigin| is an [=opaque origin=], throw a "{{NotAllowedError}}" {{DOMException}}. @@ -2509,7 +2515,9 @@ When this method is invoked, the user agent MUST execute the following algorithm [=non-autofill credential type=] is `"webauthn"`, ::
- Note: The `"webauthn"` [=autofill detail token=] must appear immediately after the last [=autofill detail token=] + + Note: + The `"webauthn"` [=autofill detail token=] must appear immediately after the last [=autofill detail token=] of type "Normal" or "Contact". For example: - `"username webauthn"` @@ -2518,11 +2526,12 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. If |silentlyDiscoveredCredentials| is not [=list/empty=]: - 1. Prompt the user to optionally select a [=DiscoverableCredentialMetadata=] (|credentialMetadata|) from |silentlyDiscoveredCredentials|. - - Note: The prompt shown SHOULD include values from |credentialMetadata|'s [=DiscoverableCredentialMetadata/otherUI=] + 1. Prompt the user to optionally select a [=DiscoverableCredentialMetadata=] from |silentlyDiscoveredCredentials|. + The prompt SHOULD display values from the [=DiscoverableCredentialMetadata/otherUI=] of each [=DiscoverableCredentialMetadata=], such as {{PublicKeyCredentialEntity/name}} and {{PublicKeyCredentialUserEntity/displayName}}. + Let |credentialMetadata| be the [=DiscoverableCredentialMetadata=] chosen by the user, if any. + 1. If the user selects a |credentialMetadata|, 1. Let |publicKeyOptions| be a temporary copy of |pkOptions|. @@ -2919,7 +2928,8 @@ When a capability does not [=map/exist=] as a key, the availability of the clien The set of [=map/keys=] SHOULD also contain a key for each [extension](#sctn-extensions) implemented by the client, where the key is formed by prefixing the string `extension:` to the [=extension identifier=]. The associated value for each implemented extension SHOULD be [TRUE]. If `getClientCapabilities()` is supported by a client, but an extension is not mapped to the value [TRUE], then a [=[RP]=] MAY assume that client processing steps for that extension will not be carried out by this client and that the extension MAY not be forwarded to the authenticator. -Note: Even if an extension is mapped to [TRUE], the authenticator used for any given operation may not support that extension, so [=[RPS]=] MUST NOT assume that the authenticator processing steps for that extension will be performed on that basis. +Note that even if an extension is mapped to [TRUE], the authenticator used for any given operation may not support that extension, +so [=[RPS]=] MUST NOT assume that the authenticator processing steps for that extension will be performed on that basis. Note: Invoking this method from a [=browsing context=] where the [=Web Authentication API=] is "disabled" according to the [=allowed to use=] algorithm—i.e., by a [=permissions policy=]—will result in the promise being rejected with a {{DOMException}} whose name is "{{NotAllowedError}}". See also [[#sctn-permissions-policy]]. @@ -3235,7 +3245,7 @@ ceremonies=].
-Note: [=Authenticators=] may not be attached at the time +Note: [=Authenticators=] might not be attached at the time {{PublicKeyCredential/signalAllAcceptedCredentials(options)}} is executed. Therefore, [=[WRPS]=] may choose to run {{PublicKeyCredential/signalAllAcceptedCredentials(options)}} periodically, @@ -3249,8 +3259,8 @@ ID=] were accidentally omitted, the [=relying party=] should immediately include it in {{PublicKeyCredential/signalAllAcceptedCredentials(options)}} as soon as possible to "unhide" it, if supported by the [=authenticator=]. -Note: [=Authenticators=] should prefer hiding [=public key credentials=] for a period of time instead -of permanently removing them whenever possible to aid recovery if a [=[WRP]=] +[=Authenticators=] SHOULD, whenever possible, prefer hiding [=public key credentials=] for a period of time instead +of permanently removing them, to aid recovery if a [=[WRP]=] accidentally omits valid [=credential IDs=] from {{AllAcceptedCredentialsOptions/allAcceptedCredentialIds}}. @@ -3306,7 +3316,7 @@ of the matching credential.
-Note: [=Authenticators=] may not be attached at the time +Note: [=Authenticators=] might not be attached at the time {{PublicKeyCredential/signalCurrentUserDetails(options)}} is executed. Therefore, [=[WRPS]=] may choose to run {{PublicKeyCredential/signalCurrentUserDetails(options)}} periodically, e.g. on @@ -3397,7 +3407,12 @@ A [=SubjectPublicKeyInfo=] does not include information about the signing algori To remove the need to parse CBOR at all in many cases, {{AuthenticatorAttestationResponse/getAuthenticatorData()}} returns the [=authenticator data=] from {{AuthenticatorAttestationResponse/attestationObject}}. The [=authenticator data=] contains other fields that are encoded in a binary format. However, helper functions are not provided to access them because [=[RPS]=] already need to extract those fields when [getting an assertion](#sctn-getAssertion). In contrast to [credential creation](#sctn-createCredential), where signature verification is [optional](#enumdef-attestationconveyancepreference), [=[RPS]=] should always be verifying signatures from an assertion and thus must extract fields from the signed [=authenticator data=]. The same functions used there will also serve during credential creation. -Note: {{AuthenticatorAttestationResponse/getPublicKey()}} and {{AuthenticatorAttestationResponse/getAuthenticatorData()}} were only added in level two of this spec. [=[RPS]=] SHOULD use feature detection before using these functions by testing the value of `'getPublicKey' in AuthenticatorAttestationResponse.prototype`. [=[RPS]=] that require this function to exist may not interoperate with older user-agents. +[=[RPS]=] SHOULD use feature detection before using these functions by testing the value of +'getPublicKey' in AuthenticatorAttestationResponse.prototype. + +Note: {{AuthenticatorAttestationResponse/getPublicKey()}} and {{AuthenticatorAttestationResponse/getAuthenticatorData()}} +were only added in Level 2 of this specification. +[=[RPS]=] that require these functions to exist may not interoperate with older user-agents. ### Web Authentication Assertion (interface AuthenticatorAssertionResponse) ### {#iface-authenticatorassertionresponse} @@ -3674,7 +3689,7 @@ credential. The [=user handle=] MUST NOT contain [PII] about the user, such as a username or e-mail address; see [[#sctn-user-handle-privacy]] for details. The [=user handle=] MUST NOT be empty. - Note: the [=user handle=] ought not be a constant value across different [=user accounts=], + The [=user handle=] SHOULD NOT be a constant value across different [=user accounts=], even for [=non-discoverable credentials=], because some authenticators always create [=discoverable credentials=]. Thus a constant [=user handle=] would prevent a user from using such an authenticator with more than one [=user account=] at the [=[RP]=]. @@ -3778,8 +3793,9 @@ Note: The {{AuthenticatorAttachment}} enumeration is deliberately not referenced Note: An [=authenticator attachment modality=] selection option is available only in the {{PublicKeyCredential/[CREATE-METHOD]}} operation. The [=[RP]=] may use it to, for example, ensure the user has a [=roaming credential=] for authenticating on another [=client device=]; or to specifically register a [=platform credential=] for easier reauthentication using a particular [=client device=]. The {{PublicKeyCredential/[DISCOVER-METHOD]}} -operation has no [=authenticator attachment modality=] selection option, so the [=[RP]=] SHOULD accept any of the user's registered [=public key -credential|credentials=]. The [=client=] and user will then use whichever is available and convenient at the time. +operation has no [=authenticator attachment modality=] selection option. +The [=client=] and user will use whichever [=credential=] is available and convenient at the time, +subject to the {{PublicKeyCredentialRequestOptions/allowCredentials}} option. ### Resident Key Requirement Enumeration (enum ResidentKeyRequirement) ### {#enum-residentKeyRequirement} @@ -4280,13 +4296,13 @@ and mirrors some fields of the {{PublicKeyCredential}} object returned by
: type :: This member contains the type of the [=public key credential=] the caller is referring to. The value SHOULD be a member of {{PublicKeyCredentialType}} but [=client platforms=] MUST ignore any {{PublicKeyCredentialDescriptor}} with an unknown {{PublicKeyCredentialDescriptor/type}}. + However, if all elements are ignored due to unknown {{PublicKeyCredentialDescriptor/type}}, + then that MUST result in an error since an empty {{PublicKeyCredentialRequestOptions/allowCredentials}} is semantically distinct. This SHOULD be set to the value of the [$credential record/type$] item of the [=credential record=] representing the identified [=public key credential source=]. This mirrors the {{Credential/type}} field of {{PublicKeyCredential}}. - Note: If all {{PublicKeyCredentialDescriptor}} elements in {{PublicKeyCredentialRequestOptions/allowCredentials}} are ignored then that MUST result in an error since an empty {{PublicKeyCredentialRequestOptions/allowCredentials}} is semantically distinct. - : id :: This member contains the [=credential ID=] of the [=public key credential=] the caller is referring to. @@ -4508,7 +4524,7 @@ A {{Document}}'s [=Document/permissions policy=] determines whether any content If disabled in any document, no content in the document will be [=allowed to use=] the foregoing methods: attempting to do so will [return an error](https://www.w3.org/2001/tag/doc/promises-guide#errors). -Note: Algorithms specified in [[!CREDENTIAL-MANAGEMENT-1]] perform the actual permissions policy evaluation. This is because such policy evaluation needs to occur when there is access to the [=current settings object=]. The {{PublicKeyCredential/[CREATE-METHOD]}} and {{PublicKeyCredential/[DISCOVER-METHOD]}} [=internal methods=] does not have such access since they are invoked [=in parallel=] by {{CredentialsContainer}}'s Create a `Credential` and Request a `Credential` abstract operations [[!CREDENTIAL-MANAGEMENT-1]]. +Note: Algorithms specified in [[!CREDENTIAL-MANAGEMENT-1]] perform the actual permissions policy evaluation. This is because such policy evaluation needs to occur when there is access to the [=current settings object=]. The {{PublicKeyCredential/[CREATE-METHOD]}} and {{PublicKeyCredential/[DISCOVER-METHOD]}} [=internal methods=] do not have such access since they are invoked [=in parallel=] by {{CredentialsContainer}}'s Create a `Credential` and Request a `Credential` abstract operations [[!CREDENTIAL-MANAGEMENT-1]]. @@ -4784,7 +4800,8 @@ the requested [=public key credential|credential=] is [=scoped=] to exactly matc
- Note: [=authenticator data=] describes its own length: If the [=AT=] and [=authData/flags/ED=] [=flags=] are not set, it is always 37 bytes long. + Note: + The [=authenticator data=] describes its own length: If the [=AT=] and [=authData/flags/ED=] [=flags=] are not set, it is always 37 bytes long. The [=attested credential data=] (which is only present if the [=AT=] [=flag=] is set) describes its own length. If the [=authData/flags/ED=] [=flag=] is set, then the total length is 37 bytes plus the length of the [=attested credential data=] (if the [=AT=] [=flag=] is set), plus the length of the [=authData/extensions=] output (a [=CBOR=] map) that follows. @@ -5145,7 +5162,10 @@ The result of looking up a [=credential id=] |cre ### The authenticatorMakeCredential Operation ### {#sctn-op-make-cred} -It takes the following input parameters: +Before invoking this operation, the client MUST invoke the [=authenticatorCancel=] operation +in order to abort all other operations in progress in the [=authenticator session=]. + +This operation takes the following input parameters: : |hash| @@ -5176,9 +5196,6 @@ It takes the following input parameters: :: A [=CBOR=] [=map=] from [=extension identifiers=] to their [=authenticator extension inputs=], created by the [=client=] based on the extensions requested by the [=[RP]=], if any. -Note: Before performing this operation, all other operations in progress in the [=authenticator session=] MUST be aborted by -running the [=authenticatorCancel=] operation. - When this operation is invoked, the [=authenticator=] MUST perform the following procedure: 1. 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. @@ -5297,7 +5314,10 @@ On successful completion of this operation, the authenticator returns the [=atte ### The authenticatorGetAssertion Operation ### {#sctn-op-get-assertion} -It takes the following input parameters: +Before invoking this operation, the client MUST invoke the [=authenticatorCancel=] operation +in order to abort all other operations in progress in the [=authenticator session=]. + +This operation takes the following input parameters: : |rpId| :: The caller's [=RP ID=], as determined by the user agent and the client. @@ -5316,8 +5336,6 @@ It takes the following input parameters: :: A [=CBOR=] [=map=] from [=extension identifiers=] to their [=authenticator extension inputs=], created by the client based on the extensions requested by the [=[RP]=], if any. -Note: Before performing this operation, all other operations in progress in the [=authenticator session=] MUST be aborted by running the [=authenticatorCancel=] operation. - When this method is invoked, the [=authenticator=] MUST perform the following procedure: 1. Check if all the supplied parameters are syntactically well-formed and of the correct length. If not, return an error code @@ -5565,8 +5583,9 @@ In these cases, the [=authenticator=] provides no guarantees about its operation data=]) and the [=attestation statement=].
- This figure illustrates only the `packed` [=attestation statement format=]. Several additional [=attestation statement - formats=] are defined in [[#sctn-defined-attestation-formats]]. + Note: + This figure illustrates only the `packed` [=attestation statement format=]. Several additional [=attestation statement + formats=] are defined in [[#sctn-defined-attestation-formats]].
An important component of the [=attestation object=] is the attestation statement. This is a specific type of signed @@ -5914,7 +5933,7 @@ In order to perform a [=registration ceremony=], the [=[RP]=] MUST proceed as fo running [=UTF-8 decode=] on the value of |response|.{{AuthenticatorResponse/clientDataJSON}}. Note: Using any implementation of [=UTF-8 decode=] is acceptable as long as it yields the same result as that yielded by - the [=UTF-8 decode=] algorithm. In particular, any leading byte order mark (BOM) MUST be stripped. + the [=UTF-8 decode=] algorithm. In particular, any leading byte order mark (BOM) must be stripped. 1. Let |C|, the [=client data=] claimed as collected during the credential creation, be the result of running an implementation-specific JSON parser on |JSONtext|. @@ -6014,7 +6033,8 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o 1. Verify that the [=credentialId=] is not yet registered for any user. If the [=credentialId=] is already known then the [=[RP]=] SHOULD fail this [=registration ceremony=]. - NOTE: The rationale for [=[RPS]=] rejecting duplicate [=credential IDs=] is as follows: [=credential IDs=] contain sufficient entropy that accidental duplication is very unlikely. However, [=attestation types=] other than [=self attestation=] do not include a self-signature to explicitly prove possession of the [=credential private key=] at [=registration=] time. Thus an attacker who has managed to obtain a user's [=credential ID=] and [=credential public key=] for a site (this could be potentially accomplished in various ways), could attempt to register a victim's credential as their own at that site. If the [=[RP]=] accepts this new registration and replaces the victim's existing credential registration, and the [=discoverable credentials|credentials are discoverable=], then the victim could be forced to sign into the attacker's account at their next attempt. Data saved to the site by the victim in that state would then be available to the attacker. + Note: The rationale for [=[RPS]=] rejecting duplicate [=credential IDs=] is as follows: + [=credential IDs=] contain sufficient entropy that accidental duplication is very unlikely. However, [=attestation types=] other than [=self attestation=] do not include a self-signature to explicitly prove possession of the [=credential private key=] at [=registration=] time. Thus an attacker who has managed to obtain a user's [=credential ID=] and [=credential public key=] for a site (this could be potentially accomplished in various ways), could attempt to register a victim's credential as their own at that site. If the [=[RP]=] accepts this new registration and replaces the victim's existing credential registration, and the [=discoverable credentials|credentials are discoverable=], then the victim could be forced to sign into the attacker's account at their next attempt. Data saved to the site by the victim in that state would then be available to the attacker.
  • If the attestation statement |attStmt| verified successfully and is found to be trustworthy, @@ -6089,10 +6109,11 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o 1. If the attestation statement |attStmt| successfully verified but is not trustworthy per [step 23](#reg-ceremony-assess-trust) above, the [=[RP]=] SHOULD fail 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. - See [[FIDOSecRef]] and [[UAFProtocol]] for a more detailed discussion. + If the [=[RP]=] does not fail the [=registration ceremony=] in this case, + then the [=[RP]=] is accepting that there is no cryptographic proof + that the [=public key credential=] has been generated by any particular [=authenticator=] model. + The [=[RP]=] MAY consider the credential as equivalent to one with [=None|no attestation=] (see [[#sctn-attestation-types]]). + See [[FIDOSecRef]] and [[UAFProtocol]] for a more detailed discussion. Verification of [=attestation objects=] requires that the [=[RP]=] has a trusted method of determining acceptable trust anchors in [step 22](#reg-ceremony-attestation-trust-anchors) above. @@ -6148,7 +6169,7 @@ In order to perform an [=authentication ceremony=], the [=[RP]=] MUST proceed as 1. Let |JSONtext| be the result of running [=UTF-8 decode=] on the value of |cData|. Note: Using any implementation of [=UTF-8 decode=] is acceptable as long as it yields the same result as that yielded by - the [=UTF-8 decode=] algorithm. In particular, any leading byte order mark (BOM) MUST be stripped. + the [=UTF-8 decode=] algorithm. In particular, any leading byte order mark (BOM) must be stripped. 1. Let |C|, the [=client data=] claimed as used for the signature, be the result of running an implementation-specific JSON parser on |JSONtext|. @@ -6301,7 +6322,7 @@ registered by the developer, in order to assure uniqueness of the identifier. Al 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]]. +Note: This means attestation statement format identifiers based on domain names are restricted to incorporating only LDH Labels [[!RFC5890]]. Implementations MUST match WebAuthn attestation statement format identifiers in a case-sensitive fashion. @@ -7066,7 +7087,7 @@ The entry key is the [=extension identifier=] and the value is the [=client exte Note: Other documents have specified extensions where the extension input does not always use the [=extension identifier=] as the entry key. -New extensions SHOULD follow the above convention. +The above convention still applies to new extensions. var assertionPromise = navigator.credentials.get({ @@ -7114,8 +7135,8 @@ and returns an array of at least one byte string as [=authenticator extension ou ) -Note: Extensions should aim to define authenticator arguments that are as small as possible. Some authenticators communicate - over low-bandwidth links such as Bluetooth Low-Energy or NFC. +Because some authenticators communicate over low-bandwidth links such as Bluetooth Low-Energy or NFC, +extensions SHOULD aim to define authenticator arguments that are as small as possible. ## Client Extension Processing ## {#sctn-client-extension-processing} @@ -7401,7 +7422,7 @@ At this time, one [=credential property=] is defined: the [=client-side discover If {{rk}} is [FALSE], the credential is a [=server-side credential=]. If {{rk}} is not present, it is not known whether the credential is a [=discoverable credential=] or a [=server-side credential=]. - Note: some [=authenticators=] create [=discoverable credentials=] even when not requested by the [=client platform=]. Because of this, [=client platforms=] may be forced to omit the {{rk}} property because they lack the assurance to be able to set it to [FALSE]. [=[RPS]=] should assume that, if the `credProps` extension is supported, then [=client platforms=] will endeavour to populate the {{rk}} property. Therefore a missing {{rk}} indicates that the created credential is most likely a [=non-discoverable credential=]. + Note: Some [=authenticators=] create [=discoverable credentials=] even when not requested by the [=client platform=]. Because of this, [=client platforms=] may be forced to omit the {{rk}} property because they lack the assurance to be able to set it to [FALSE]. [=[RPS]=] should assume that, if the `credProps` extension is supported, then [=client platforms=] will endeavour to populate the {{rk}} property. Therefore a missing {{rk}} indicates that the created credential is most likely a [=non-discoverable credential=].
  • @@ -7424,7 +7445,7 @@ This extension is implemented on top of the [[FIDO-CTAP]] `hmac-secret` extensio The `hmac-secret` extension provides two PRFs per credential: one which is used for requests where [=user verification=] is performed and another for all other requests. This extension only exposes a single PRF per credential and, when implementing on top of `hmac-secret`, that PRF MUST be the one used for when [=user verification=] is performed. This overrides the {{UserVerificationRequirement}} if neccessary. -Note: this extension may be implemented for [=authenticators=] that do not use [[FIDO-CTAP]] so long as the behavior observed by a [=[RP]=] is identical. +Note: This extension may be implemented for [=authenticators=] that do not use [[FIDO-CTAP]] so long as the behavior observed by a [=[RP]=] is identical. : Extension identifier :: `prf` @@ -7806,7 +7827,7 @@ However, [=authenticators=] that do not utilize [[!FIDO-CTAP]] do not necessaril 1. If any authenticator indicates success (in {{PublicKeyCredential/[DISCOVER-METHOD]}}), attempt to read any largeBlob data associated with the asserted credential. 1. If successful, set {{AuthenticationExtensionsLargeBlobOutputs/blob}} to the result. - Note: if the read is not successful, {{AuthenticationExtensionsClientOutputs/largeBlob}} will be present in {{AuthenticationExtensionsClientOutputs}} but the {{AuthenticationExtensionsLargeBlobOutputs/blob}} member will not be present. + Note: If the read is not successful, {{AuthenticationExtensionsClientOutputs/largeBlob}} will be present in {{AuthenticationExtensionsClientOutputs}} but the {{AuthenticationExtensionsLargeBlobOutputs/blob}} member will not be present. 1. If {{AuthenticationExtensionsLargeBlobInputs/write}} is present: 1. If {{PublicKeyCredentialRequestOptions/allowCredentials}} does not contain exactly one element: @@ -8081,7 +8102,7 @@ The [=remote end steps=] are: 1. If |parameters| is not a JSON [=Object=], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=]. - Note: |parameters| is a [=Authenticator Configuration=] object. + Note: |parameters| is an [=Authenticator Configuration=] object. 1. Let |authenticator| be a new [=Virtual Authenticator=]. 1. For each enumerable [=own property=] in |parameters|: 1. Let |key| be the name of the property.