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.