diff --git a/index.bs b/index.bs index 2d7344966..421f96b7f 100644 --- a/index.bs +++ b/index.bs @@ -1097,6 +1097,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S : Credential Private Key : Credential Public Key : User Public Key +: User Credential :: A [=credential key pair=] is a pair of asymmetric cryptographic keys generated by an [=authenticator=] and [=scoped=] to a specific [=[WRP]=]. It is the central part of a [=public key credential=]. @@ -1187,6 +1188,14 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S : {{PublicKeyCredentialDescriptor/transports}} :: The [$credential record/transports$] of the [=credential record=]. +: Hardware-bound Device Key Pair +: Device-bound Key +: Device Private Key +: Device Public Key +:: A [=hardware-bound device key pair=], also known as a [=device-bound key=], is an [=authenticator=]-, [=[RP]=]-, and [=user credential=]-specific public key pair created upon a [=[RP]=]'s request via the [=devicePubKey=] [=WebAuthn extension=]. + The [=authenticator=] that a [=hardware-bound device key pair=] is created upon guarantees that the [=device private key=] is securely stored in hardware, i.e., it is unextractable. See also [[#sctn-device-publickey-extension]]. + + Note: All guarantees about the operation of an [=authenticator=] operation rely on [=attestation=]. In particular, [=[RPS]=] MUST NOT rely on the above guarantee of unextractability unless supported by a valid, trusted [=attestation statement=]. : Generating Authenticator :: The Generating Authenticator is the authenticator involved in the [=authenticatorMakeCredential=] operation resulting @@ -1958,6 +1967,17 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o + 1. Let |attestationFormats| be a list of strings, initialized to the value of |options|.{{PublicKeyCredentialCreationOptions/attestationFormats}}. + + 1. If |options|.{{PublicKeyCredentialCreationOptions/attestation}} + +
+ + : is set to {{AttestationConveyancePreference/none}} + :: Set |attestationFormats| be the single-element list containing the string “none” + +
+ 1. Let |excludeCredentialDescriptorList| be a new [=list=]. 1. [=list/For each=] credential descriptor |C| in |pkOptions|.{{PublicKeyCredentialCreationOptions/excludeCredentials}}: @@ -1977,7 +1997,7 @@ a numbered step. If outdented, it (today) is rendered either as a bullet in the -->
  • - + Invoke the [=authenticatorMakeCredential=] operation on |authenticator| with |clientDataHash|, |pkOptions|.{{PublicKeyCredentialCreationOptions/rp}}, @@ -1987,6 +2007,7 @@ a numbered step. If outdented, it (today) is rendered either as a bullet in the |credTypesAndPubKeyAlgs|, |excludeCredentialDescriptorList|, |enterpriseAttestationPossible|, + |attestationFormats|, and |authenticatorExtensions| as parameters.
  • @@ -2430,6 +2451,10 @@ When this method is invoked, the user agent MUST execute the following algorithm :: If the [=authenticator=] returned a [=user handle=], set the value of [=userHandleResult=] to be the bytes of the returned [=user handle=]. Otherwise, set the value of [=userHandleResult=] to null. + : assertionAttestation + :: If the [=authenticator=] returned an [=attestation=], set the value of [=assertionAttestation=] to be the bytes of + the [=attestation statement=]. Otherwise set it to null. + : clientExtensionResults :: whose value is an {{AuthenticationExtensionsClientOutputs}} object containing [=extension identifier=] → [=client extension output=] entries. The entries are created by running each extension's @@ -2472,6 +2497,12 @@ When this method is invoked, the user agent MUST execute the following algorithm [=%ArrayBuffer%=], containing the bytes of |assertionCreationData|.[=assertionCreationData/userHandleResult=]. + : {{AuthenticatorAssertionResponse/attestationObject}} + :: If |assertionCreationData|.[=assertionCreationData/assertionAttestation=] is null, set this + field to null. Otherwise, set this field to a new {{ArrayBuffer}}, created using |global|'s + [=%ArrayBuffer%=], containing the bytes of + |assertionCreationData|.[=assertionCreationData/assertionAttestation=]. + : {{PublicKeyCredential/[[clientExtensionsResults]]}} :: A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of |assertionCreationData|.[=assertionCreationData/clientExtensionResults=]. @@ -2554,6 +2585,30 @@ The steps for [=issuing a credential request to an authenticator=] are as follow + 1. Let |enterpriseAttestationPossible| be a Boolean value, as follows. If + |options|.{{PublicKeyCredentialRequestOptions/attestation}} + +
    + + : is set to {{AttestationConveyancePreference/enterprise}} + :: Let |enterpriseAttestationPossible| be [TRUE] if the user agent wishes to support enterprise attestation for |rpId| (see [Step 7](#GetAssn-DetermineRpId) of [[#sctn-discover-from-external-source]]). Otherwise [FALSE]. + + : otherwise + :: Let |enterpriseAttestationPossible| be [FALSE]. + +
    + + 1. Let |attestationFormats| be a list of strings, initialized to the value of |options|.{{PublicKeyCredentialRequestOptions/attestationFormats}}. + + 1. If |options|.{{PublicKeyCredentialRequestOptions/attestation}} + +
    + + : is set to {{AttestationConveyancePreference/none}} + :: Set |attestationFormats| be the single-element list containing the string “none” + +
    + 1. If |pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
    @@ -2590,19 +2645,25 @@ The steps for [=issuing a credential request to an authenticator=] are as follow Then, using |transport|, invoke the [=authenticatorGetAssertion=] operation on |authenticator|, with |rpId|, |clientDataHash|, |allowCredentialDescriptorList|, - |userVerification|, and |authenticatorExtensions| as parameters. + |userVerification|, + |enterpriseAttestationPossible|, + |attestationFormats|, + and |authenticatorExtensions| as parameters. : [=list/is empty=] :: Using local configuration knowledge of the appropriate transport to use with |authenticator|, invoke the [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|, - |clientDataHash|, |allowCredentialDescriptorList|, |userVerification|, and - |authenticatorExtensions| as parameters. + |clientDataHash|, |allowCredentialDescriptorList|, |userVerification|, + |enterpriseAttestationPossible|, |attestationFormats|, and |authenticatorExtensions| as parameters.
    : [=list/is empty=] :: Using local configuration knowledge of the appropriate transport to use with |authenticator|, invoke the [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|, |clientDataHash|, - |userVerification| and |authenticatorExtensions| as parameters. + |userVerification|, + |enterpriseAttestationPossible|, + |attestationFormats|, + and |authenticatorExtensions| as parameters. Note: In this case, the [=[RP]=] did not supply a list of acceptable credential descriptors. Thus, the authenticator is being asked to exercise any credential it may possess that is [=scoped=] to @@ -2871,6 +2932,7 @@ optionally evidence of [=user consent=] to a specific transaction. [SameObject] readonly attribute ArrayBuffer authenticatorData; [SameObject] readonly attribute ArrayBuffer signature; [SameObject] readonly attribute ArrayBuffer? userHandle; + [SameObject] readonly attribute ArrayBuffer? attestationObject; };
    @@ -2889,6 +2951,9 @@ optionally evidence of [=user consent=] to a specific transaction. : userHandle :: This attribute contains the [=user handle=] returned from the authenticator, or null if the authenticator did not return a [=user handle=]. See [[#sctn-op-get-assertion]]. + + : attestationObject + :: This OPTIONAL attribute contains an [=attestation object=], if the [=authenticator=] supports attestation in assertions. The [=attestation object=], if present, includes an [=attestation statement=]. Unlike the {{AuthenticatorAttestationResponse/attestationObject}} in an {{AuthenticatorAttestationResponse}}, it does not contain an `authData` key because the [=authenticator data=] is provided directly in an {{AuthenticatorAssertionResponse}} structure. For more details on attestation, see [[#sctn-attestation]], [[#sctn-attestation-in-assertions]], [[#sctn-generating-an-attestation-object]], and [Figure 6](#fig-attStructs).
    ## Parameters for Credential Generation (dictionary PublicKeyCredentialParameters) ## {#dictionary-credential-params} @@ -2928,6 +2993,7 @@ optionally evidence of [=user consent=] to a specific transaction. sequence excludeCredentials = []; AuthenticatorSelectionCriteria authenticatorSelection; DOMString attestation = "none"; + sequence attestationFormats = []; AuthenticationExtensionsClientInputs extensions; }; @@ -2994,6 +3060,14 @@ optionally evidence of [=user consent=] to a specific transaction. The default value is {{AttestationConveyancePreference/none}}. + : attestationFormats + :: The [=[RP]=] MAY use this OPTIONAL member to specify a preference regarding the [=attestation=] statement format used by the [=authenticator=]. + Values SHOULD be taken from the IANA "WebAuthn Attestation Statement Format Identifiers" registry [[!IANA-WebAuthn-Registries]] established by [[!RFC8809]]. + Values are ordered from most preferable to least preferable. + This parameter is advisory and the [=authenticator=] MAY use an attestation statement not enumerated in this parameter. + + The default value is the empty list, which indicates no preference. + : extensions :: The [=[RP]=] MAY use this OPTIONAL member to provide [=client extension inputs=] requesting additional processing by the [=client=] and [=authenticator=]. @@ -3299,6 +3373,8 @@ an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member MUST be USVString rpId; sequence allowCredentials = []; DOMString userVerification = "preferred"; + DOMString attestation = "none"; + sequence attestationFormats = []; AuthenticationExtensionsClientInputs extensions; }; @@ -3359,6 +3435,21 @@ an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member MUST be See {{UserVerificationRequirement}} for the description of {{AuthenticatorSelectionCriteria/userVerification}}'s values and semantics. + : attestation + :: The [=[RP]=] MAY use this OPTIONAL member to specify a preference regarding [=attestation conveyance=]. + Its value SHOULD be a member of {{AttestationConveyancePreference}}. + [=Client platforms=] MUST ignore unknown values, treating an unknown value as if the [=map/exist|member does not exist=]. + + The default value is {{AttestationConveyancePreference/none}}. + + : attestationFormats + :: The [=[RP]=] MAY use this OPTIONAL member to specify a preference regarding the [=attestation=] statement format used by the [=authenticator=]. + Values SHOULD be taken from the IANA "WebAuthn Attestation Statement Format Identifiers" registry [[!IANA-WebAuthn-Registries]] established by [[!RFC8809]]. + Values are ordered from most preferable to least preferable. + This parameter is advisory and the [=authenticator=] MAY use an attestation statement not enumerated in this parameter. + + The default value is the empty list, which indicates no preference. + : extensions :: The [=[RP]=] MAY use this OPTIONAL member to provide [=client extension inputs=] requesting additional processing by the [=client=] and [=authenticator=]. @@ -3402,7 +3493,7 @@ SHOULD be aborted. The subsections below define the data types used for conveying [=WebAuthn extension=] inputs and outputs. -Note: [=Authenticator extension outputs=] are conveyed as a part of [=Authenticator data=] (see [Table 1](#table-authData)). +Note: [=Authenticator extension outputs=] are conveyed as a part of [=authenticator data=] (see [Table 1](#table-authData)). Note: The types defined below — {{AuthenticationExtensionsClientInputs}} and {{AuthenticationExtensionsClientOutputs}} — are applicable to both [=registration extensions=] and [=authentication extensions=]. The "Authentication..." portion of their names should be regarded as meaning "WebAuthentication..." @@ -4360,7 +4451,7 @@ The result of looking up a [=credential id=] |cre It takes the following input parameters: - + : |hash| :: The [=hash of the serialized client data=], provided by the client. : |rpEntity| @@ -4385,6 +4476,8 @@ It takes the following input parameters: list of known credentials. : |enterpriseAttestationPossible| :: A Boolean value that indicates that individually-identifying attestation MAY be returned by the authenticator. +: |attestationFormats| +:: A sequence of strings that expresses the [=[RP]=]'s preference for attestation statement formats, from most to least preferable. If the [=authenticator=] returns [=attestation=], then it makes a best-effort attempt to use the most preferable format that it supports. : |extensions| :: 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. @@ -4496,11 +4589,13 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o 1. Let |attestedCredentialData| be the [=attested credential data=] byte array including the |credentialId| and |publicKey|. +1. Let |attestationFormat| be the first supported [=attestation statement format identifier=] from |attestationFormats|, taking into account |enterpriseAttestationPossible|. + If |attestationFormats| contains no supported value, then let |attestationFormat| be the [=attestation statement format identifier=] most preferred by this authenticator. 1. Let |authenticatorData| [=perform the following steps to generate an authenticator data structure|be the byte array=] specified in [[#sctn-authenticator-data]], including |attestedCredentialData| as the [=attestedCredentialData=] and |processedExtensions|, if any, as the [=authData/extensions=]. 1. Create an [=attestation object=] for the new credential using the procedure specified in - [[#sctn-generating-an-attestation-object]], using an authenticator-chosen [=attestation statement format=], |authenticatorData|, + [[#sctn-generating-an-attestation-object]], the [=attestation statement format=] |attestationFormat|, and the values |authenticatorData| and |hash|, as well as {{enterprise|taking into account}} the value of |enterpriseAttestationPossible|. For more details on attestation, see [[#sctn-attestation]]. On successful completion of this operation, the authenticator returns the [=attestation object=] to the client. @@ -4523,6 +4618,10 @@ It takes the following input parameters: wish to make a [=test of user presence=] optional although WebAuthn does not. : |requireUserVerification| :: The [=effective user verification requirement for assertion=], a Boolean value provided by the client. +: |enterpriseAttestationPossible| +:: A Boolean value that indicates that individually-identifying attestation MAY be returned by the authenticator. +: |attestationFormats| +:: A sequence of strings that expresses the [=[RP]=]'s preference for attestation statement formats, from most to least preferable. If the [=authenticator=] returns [=attestation=], then it makes a best-effort attempt to use the most preferable format that it supports. : |extensions| :: 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. @@ -4564,9 +4663,17 @@ When this method is invoked, the [=authenticator=] MUST perform the following pr which approach is implemented by the [=authenticator=], by some positive value. If the [=authenticator=] does not implement a [=signature counter=], let the [=signature counter=] value remain constant at zero. +1. If |attestationFormats|: +
    + : is [=list/is not empty|not empty=] + :: let |attestationFormat| be the first supported [=attestation statement format=] from |attestationFormats|, taking into account |enterpriseAttestationPossible|. If none are supported, fallthrough to: + + : is [=list/is empty|empty=] + :: let |attestationFormat| be the [=attestation statement format=] most preferred by this authenticator. If it does not support attestation during assertion then let this be `none`. +
    1. Let |authenticatorData| [=perform the following steps to generate an authenticator data structure|be the byte array=] specified in [[#sctn-authenticator-data]] including |processedExtensions|, if any, as - the [=authData/extensions=] and excluding [=attestedCredentialData=]. + the [=authData/extensions=] and excluding [=attestedCredentialData=]. This |authenticatorData| MUST include [=attested credential data=] if, and only if, |attestationFormat| is not `none`. 1. Let |signature| be the [=assertion signature=] of the concatenation |authenticatorData| || |hash| using the [=public key credential source/privateKey=] of |selectedCredential| as shown in Figure , below. A simple, undelimited @@ -4578,8 +4685,11 @@ When this method is invoked, the [=authenticator=] MUST perform the following pr
    Generating an [=assertion signature=].
    -1. If any error occurred while generating the [=assertion signature=], return an error code equivalent to "{{UnknownError}}" and - terminate the operation. +1. The |attestationFormat| is not `none` then create an [=attestation object=] for the new credential using the procedure specified in + [[#sctn-generating-an-attestation-object]], the [=attestation statement format=] |attestationFormat|, and the values |authenticatorData| + and |hash|, as well as {{enterprise|taking into account}} the value of |enterpriseAttestationPossible|. For more details on attestation, see [[#sctn-attestation]]. + +1. If any error occurred then return an error code equivalent to "{{UnknownError}}" and terminate the operation.