diff --git a/index.bs b/index.bs index 0e61497b8..fb55cfbf4 100644 --- a/index.bs +++ b/index.bs @@ -1424,7 +1424,7 @@ BCP 14 [[!RFC2119]] [[!RFC8174]] when, and only when, they appear in all capital A user handle is an opaque [=byte sequence=] with a maximum size of 64 bytes, and is not meant to be displayed to the user. It MUST NOT contain personally identifying information, see [[#sctn-user-handle-privacy]]. -: User Present +: User Present :: Upon successful completion of a [=test of user presence|user presence test=], the user is said to be "[=user present|present=]". @@ -7598,7 +7598,662 @@ However, [=authenticators=] that do not utilize [[!FIDO-CTAP]] do not necessaril This section defines extensions that are both [=client extensions=] and [=authenticator extensions=]. -This section is currently empty. + +### Signing extension (sign) ### {#sctn-sign-extension} + +This [=authenticator extension|authenticator=] [=registration extension=] and [=authentication extension=] +allows a [=[RP]=] to sign arbitrary data using an asymmetric key pair associated with a [=credential=] +but different from the [=credential key pair=]. +A [=registration ceremony=] creates the signing key pair and emits the signing public key, +and [=authentication ceremonies=] can use the signing private key to sign arbitrary data. +The signing private key is held exclusively by the [=authenticator=]. + +The high-level usage flow is as follows: + +1. To create a signing key pair, the [=[RP]=] initiates a [=registration ceremony=] and requests the extension. + The [=authenticator=] returns a signing public key and a signing key handle for the key pair. + +1. To sign some chosen data, the [=[RP]=] initiates an [=authentication ceremony=] and requests the extension + with one or more [=signing key handles=] for key pairs eligible to perform the signature. + The [=authenticator=] returns a signature over the given data. + Unlike an [=assertion signature=], the given data is signed unaltered; + the signed data does not include [=authenticator data=] or [=client data=]. + + This step can be repeated any number of times. + +As a motivating example use case, a [=[RP]=] could generate an asymmetric key pair +and use the generated public key as verification material for a [=verifiable credential=]. +Proofs for such a verifiable credential could then be generated only by getting an assertion from the associated WebAuthn credential. + +Each [=credential=] can be associated with at most one signing key pair, +and the [=user presence=] and [=user verification=] policy for the signing key pair is fixed at the time of creation. +If additional signing key pairs are required, +or signing key pairs with different [=user presence=] or [=user verification=] policies, +the [=[RP]=] MAY create a new [=credential=] for each. +In that case, the [=[RP]=] SHOULD use a different [=user handle=] for each such [=registration ceremony=], +to avoid overwriting existing credentials, +and SHOULD NOT specify the {{PublicKeyCredentialCreationOptions/excludeCredentials}} parameter, +to allow creating multiple credentials on the same [=authenticator=]. +Additional credentials created for this purpose SHOULD be stored and managed separately from ordinary authentication credentials, +and SHOULD NOT be used for other purposes than signing data with the associated signing key pair. + +[=Attestation=] is supported for signing key pairs. +This attestation signs over the same [=RP ID=], [=authenticator data=] [=flags=], +[=/AAGUID=] and [=hash of the serialized client data=] +as the attestation for the associated [=credential=], +but is not otherwise coupled to the associated [=credential=]. +The attestation also encodes the [=user presence=] and [=user verification=] policy of the signing key pair +since unlike the associated credential, +the signing key pair does not sign over an [=authenticator data=] structure. + +Although this extension can be used with [=discoverable credentials=], +it does not support use with an empty {{PublicKeyCredentialRequestOptions/allowCredentials}} +because the intended use is for signing data that is meaningful on its own. +This is unlike a random authentication challenge, which may be meaningless on its own +and is used only to guarantee that an authentication signature was generated recently. +In order to sign meaningful data, the [=[RP]=] must first know what is to be signed, +thus presumably must also first know which user is performing the signature, +and thus also which signing keys are eligible. +Thus, the signing use case is largely incompatible with the anonymous authentication challenge use case. +Therefore the restriction to non-empty {{PublicKeyCredentialRequestOptions/allowCredentials}} +is unlikely to impose any additional restriction in practice, +but does enable support for stateless [=authenticator=] implementations +where neither the signing key pair nor the associated [=credential=] need to consume storage space on the [=authenticator=]. + + +: Extension identifier +:: `sign` + +: Operation applicability +:: [=registration extension|Registration=] and [=authentication extension|authentication=] + +: Client extension input +::
{{AuthenticationExtensionsSignOutputs/generatedKey}}.{{AuthenticationExtensionsSignGeneratedKey/keyHandle}}
.
+ Alternatively, if the [=[RP]=] needs [=attestation=] for the signing key pair,
+ the [=[RP]=] MUST instead verify the [=attestation object=]
+ embedded as the [=authenticator extension output=]
+ [=authData/extensions=]["sign"][att-obj (7)]
+ and construct the [=signing key handle=] from
+ [=authData/extensions=]["sign"][att-obj (7)]["authData"].[=authData/attestedCredentialData=].[=authData/attestedCredentialData/credentialPublicKey=]
+ using the procedure to [=extension/sign/construct a key handle from a COSE_Key=]
+ defined in [[#sctn-sign-extension-key-handle-from-cose-key]].
+ |pkOptions|.{{PublicKeyCredentialCreationOptions/extensions}}.{{AuthenticationExtensionsClientInputs/sign}}
.
+
+ 1. If |extSign|.{{AuthenticationExtensionsSignInputs/generateKey}}
is not present,
+ return a {{DOMException}} whose name is “{{NotSupportedError}}”.
+
+ 1. If |extSign|.{{AuthenticationExtensionsSignInputs/sign}}
is present,
+ return a {{DOMException}} whose name is “{{NotSupportedError}}”.
+
+ 1. Set the `sign` [=authenticator extension input=] to a CBOR map with the entries:
+
+ - `phData`: |extSign|.{{AuthenticationExtensionsSignInputs/generateKey}}.{{AuthenticationExtensionsSignGenerateKeyInputs/phData}}
+ encoded as a CBOR byte string, if present.
+ Otherwise omit this entry.
+
+ - `alg`: |extSign|.{{AuthenticationExtensionsSignInputs/generateKey}}.{{AuthenticationExtensionsSignGenerateKeyInputs/algorithms}}
+ encoded as a CBOR array of integers, in order.
+
+ - `flags`: The CDDL value `0b101` if |pkOptions|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}
is set to {{UserVerificationRequirement/required}},
+ otherwise the CDDL value `0b001`.
+
+ 1. After the [=authenticatorMakeCredential=] operation is successful,
+ let |authData| denote |credentialCreationData|.[=credentialCreationData/attestationObjectResult=]["authData"]
.
+ Set the [=client extension output=] |credentialCreationData|.[=credentialCreationData/clientExtensionResults=].{{AuthenticationExtensionsClientOutputs/sign}}
+ to an {{AuthenticationExtensionsSignOutputs}} value with the members:
+
+ - {{AuthenticationExtensionsSignOutputs/generatedKey}}: An {{AuthenticationExtensionsSignGeneratedKey}} value with the members:
+ - {{AuthenticationExtensionsSignGeneratedKey/publicKey}}:
+ An {{ArrayBuffer}} containing
+ the [=authData/attestedCredentialData=].[=authData/attestedCredentialData/credentialPublicKey=]
part
+ of |authData|.[=authData/extensions=]["sign"][att-obj]["authData"]
.
+
+ - {{AuthenticationExtensionsSignGeneratedKey/keyHandle}}:
+ An {{ArrayBuffer}} constructed as follows:
+
+ 1. Let |pk| be the value of {{AuthenticationExtensionsSignGeneratedKey/publicKey}} parsed as a CBOR map.
+ 1. Let {{AuthenticationExtensionsSignGeneratedKey/keyHandle}} be an {{ArrayBuffer}}
+ containing the result of [=extension/sign/constructing a key handle from a COSE_Key=]
+ given the COSE_Key structure |pk|.
+
+ - {{AuthenticationExtensionsSignOutputs/signature}}:
+ The [=authenticator extension output=] |authData|.[=authData/extensions=]["sign"][sig]
+ parsed as an {{ArrayBuffer}}, if present.
+ Otherwise omit this member.
+
+ The CBOR map keys `phData`, `alg`, `flags`, `att-obj` and `sig` are aliases defined below
+ in the CDDL for the [=authenticator extension input=] and [=authenticator extension output=].
+
+
+: Client extension processing ([=authentication extension|authentication=])
+:: These extension processing steps use the variables |pkOptions| and |assertionCreationData|
+ defined in [[#sctn-getAssertion]].
+
+ 1. Let |extSign| denote |pkOptions|.{{PublicKeyCredentialRequestOptions/extensions}}.{{AuthenticationExtensionsClientInputs/sign}}
.
+
+ 1. If |extSign|.{{AuthenticationExtensionsSignInputs/sign}}
is not present,
+ return a {{DOMException}} whose name is “{{NotSupportedError}}”.
+
+ 1. If |extSign|.{{AuthenticationExtensionsSignInputs/generateKey}}
is present,
+ return a {{DOMException}} whose name is “{{NotSupportedError}}”.
+
+ 1. If |pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
[=list/is empty=],
+ return a {{DOMException}} whose name is “{{NotSupportedError}}”.
+
+ 1. If the [=map/size=] of |extSign|.{{AuthenticationExtensionsSignInputs/sign}}.{{AuthenticationExtensionsSignSignInputs/keyHandleByCredential}}
+ does not equal the [=list/size=] of |pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
,
+ return a {{DOMException}} whose name is “{{NotSupportedError}}”.
+
+ 1. Let |keyHandles| be a new CBOR array.
+
+ 1. [=list/For each=] |allowedCredential| in |pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
:
+
+ 1. Let |encodedCredentialId| be the base64url encoding of |allowedCredential|.{{PublicKeyCredentialDescriptor/id}}
.
+ 1. Let |keyHandle| be |extSign|.{{AuthenticationExtensionsSignInputs/sign}}.{{AuthenticationExtensionsSignSignInputs/keyHandleByCredential}}[|encodedCredentialId|]
.
+ 1. If |keyHandle| is undefined, return a {{DOMException}} whose name is “{{SyntaxError}}”.
+ 1. Append |keyHandle| to |keyHandles|, encoded as a CBOR byte string.
+
+ If the [=client=] divides {{PublicKeyCredentialRequestOptions/allowCredentials}} into smaller batches
+ to fit [=authenticator=] message length limits,
+ the client MUST also divide |keyHandles| into batches of the same size and in the same order.
+
+ 1. If the [=list/size=] of |keyHandles| does not equal the [=list/size=] of
+ |pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
,
+ return a {{DOMException}} whose name is “{{SyntaxError}}”.
+
+ 1. Set the `sign` authenticator extension input to a CBOR map with the entries:
+ - `phData`: |extSign|.{{AuthenticationExtensionsSignInputs/sign}}.{{AuthenticationExtensionsSignSignInputs/phData}}
encoded as a CBOR byte string.
+ - `key-refs`: |keyHandles|.
+
+ 1. After the [=authenticatorGetAssertion=] operation is successful,
+ let |authData| denote |assertionCreationData|.[=assertionCreationData/authenticatorDataResult=]
.
+ Set the [=client extension output=] |assertionCreationData|.[=assertionCreationData/clientExtensionResults=].{{AuthenticationExtensionsClientOutputs/sign}}
+ to an {{AuthenticationExtensionsSignOutputs}} value with the members:
+
+ - {{AuthenticationExtensionsSignOutputs/generatedKey}}: Omit this member.
+
+ - {{AuthenticationExtensionsSignOutputs/signature}}:
+ The [=authenticator extension output=] |authData|.[=authData/extensions=]["sign"][sig]
+ parsed as an {{ArrayBuffer}}.
+
+ The CBOR map keys `phData`, `key-refs` and `sig` are aliases defined below
+ in the CDDL for the [=authenticator extension input=] and [=authenticator extension output=].
+
+
+: Client extension output
+:: {{AuthenticationExtensionsSignInputs/generateKey}}.{{AuthenticationExtensionsSignGenerateKeyInputs/phData}}
+ input was present.
+ {{AuthenticationExtensionsSignInputs/sign}}.{{AuthenticationExtensionsSignSignInputs/keyHandleByCredential}}
+ input to request generation of a signature.
+
+ This member is intended for use by [=[RPS]=] that do not request [=attestation=].
+ [=[RPS]=] that request attestation SHOULD instead construct key handles
+ as described for the [=client extension input=] {{AuthenticationExtensionsSignSignInputs/keyHandleByCredential}}.
+ [=authData/extensions=]["sign"][att-obj]["authData"].[=authData/attestedCredentialData=].[=authData/attestedCredentialData/credentialPublicKey=]
+ using the procedure to [=extension/sign/construct a key handle from a COSE_Key=]
+ defined in [[#sctn-sign-extension-key-handle-from-cose-key]].
+
+ Note: The `key-refs` entry is defined as an array of byte strings containing CBOR-encoded data
+ instead of direct CBOR maps because the [=CTAP2 canonical CBOR encoding form=] allows at most 4 levels of nested CBOR structures.
+ If `key-refs` would contain CBOR maps as items, those maps would exceed this nesting limit
+ when the extension input is embedded in the CTAP2 message structure.
+
+
+: Authenticator extension processing ([=registration extension|registration=])
+:: These processing steps use the |hash|, |rpEntity|, and |extensions| parameters
+ and the |attestationFormat| variable in the [=authenticatorMakeCredential=] operation.
+ Let |extSign| denote |extensions|["sign"]
.
+ Let |authData| denote the [=authenticator data=] that will be returned from the [=authenticatorMakeCredential=] operation.
+
+ 1. Let |auxIkm| denote some, possibly empty, random entropy
+ and/or auxiliary data of the [=authenticator's=] choice to be used to generate a signing key pair.
+
+ 1. Let |chosenAlg| be null.
+
+ 1. [=list/For each=] |candidateAlg| in |extSign|[alg]
:
+
+ 1. If the [=authenticator=] supports |candidateAlg| for signing operations,
+ let |chosenAlg| be |candidateAlg| and [=break=].
+
+ 1. If |chosenAlg| is null,
+ return an error code equivalent to "{{NotSupportedError}}" and terminate the operation.
+ Implementations in [[FIDO-CTAP]] return the error code `CTAP2_ERR_INVALID_CREDENTIAL`.
+
+ 1. Let |signFlags| be the value of |extSign|[flags]
.
+
+ 1. If |signFlags| is not one of the values `unattended` (`0b000`), `require-up` (`0b001`) or `require-uv` (`0b101`),
+ return an error code equivalent to "{{SyntaxError}}" and terminate these processing steps.
+ Implementations in [[FIDO-CTAP]] return the error code `CTAP2_ERR_INVALID_OPTION`.
+
+ 1. Use |signFlags|, |auxIkm| and a per-credential authenticator secret
+ as the seeds to deterministically generate a new key pair for the algorithm |chosenAlg|.
+ Let |p| be the generated private key and |P| be the corresponding public key.
+
+ 1. Let |kid| be an authenticator-specific encoding of |chosenAlg|, |signFlags| and |auxIkm|,
+ which the authenticator can later use to re-generate the same key pair |p|, |P|.
+ The encoding SHOULD include integrity protection
+ to ensure that a given |kid| is valid for a particular authenticator.
+
+ An example implementation of this encoding is given in [[#sctn-sign-extension-example-key-handle-encoding]].
+
+ 1. Let |P_cose| be a CBOR map encoding |P| in COSE_Key format.
+
+ 1. Set |P_cose|[kid]
to |kid|.
+
+ 1. Set |authData|.[=authData/extensions=]["sign"]
to a new CBOR map with the entries:
+ - `att-obj`: a CBOR byte array
+ encoding an [=attestation object=] generated as described in [[#sctn-generating-an-attestation-object]]
+ using the inputs:
+
+ - |attestationFormat|: |attestationFormat|.
+ - |authData|: an [=authenticator data=] structure with the contents:
+
+ - [=authData/rpIdHash=]: |authData|.[=authData/rpIdHash=]
.
+ - [=authData/flags=]: |authData|.[=authData/flags=]
.
+ - [=authData/signCount=]: 0.
+ - [=authData/attestedCredentialData=]: An [=attested credential data=] structure with the contents:
+
+ - [=authData/attestedCredentialData/aaguid=]: |authData|.[=authData/attestedCredentialData=].[=authData/attestedCredentialData/aaguid=]
.
+ - [=authData/attestedCredentialData/credentialIdLength=]: 0.
+ - [=authData/attestedCredentialData/credentialId=]: An empty byte string.
+ - [=authData/attestedCredentialData/credentialPublicKey=]: |P_cose| encoded in CBOR.
+
+ - [=authData/extensions=]: A CBOR map with the entries:
+ - `"sign"`: A CBOR map with the entries:
+ - `flags`: |signFlags| encoded as a CBOR unsigned integer.
+
+ Note: The `"sign"` key here is a CDDL text string literal,
+ but `flags` is an alias of an integer value.
+
+ - |hash|: |hash|.
+
+ - `sig`: The result of signing |extensions|["sign"][phData]
, if present, using private key |p|,
+ if |chosenAlg| supports signing during registration.
+ Otherwise omit this entry.
+
+ The signing procedure MUST interpret |extensions|["sign"][phData]
as pre-hashed
+ as appropriate for the chosen signing algorithm.
+
+ ISSUE: Need to define pre-hashing more precisely.
+
+ The CBOR map keys `alg`, `flags`, `kid`, `sig`, `att-obj` and `phData` are aliases defined above and below
+ in the CDDL for the [=authenticator extension input=] and [=authenticator extension output=].
+
+
+: Authenticator extension processing ([=authentication extension|authentication=])
+:: Using the |extensions| argument to the [=authenticatorGetAssertion=] operation,
+ let |extSign| denote |extensions|["sign"]
.
+ Let |authData| denote the [=authenticator data=] that will be returned from the [=authenticatorGetAssertion=] operation.
+
+ 1. If |allowCredentialDescriptorList| is empty,
+ return an error code equivalent to "{{NotAllowedError}}" and terminate these processing steps.
+ Implementations in [[FIDO-CTAP]] return the error code `CTAP2_ERR_NO_CREDENTIALS`.
+
+ 1. If |extSign|[phData]
is not present or |extSign|[key-refs]
is not present,
+ or if the [=list/size=] of |extSign|[key-refs]
does not equal the [=list/size=] of |allowCredentialDescriptorList|,
+ return an error code equivalent to "{{UnknownError}}" and terminate these processing steps.
+ Implementations in [[FIDO-CTAP]] return the error code `CTAP2_ERR_INVALID_OPTION`.
+
+ 1. Let |credentialId| be the [=credential ID=] of the [=credential=] being used for this assertion.
+
+ 1. Let |credentialIdIndex| be the index of |credentialId| in |allowCredentialDescriptorList|.
+
+ 1. Let |keyRefCbor| be |extSign|[key-refs][|credentialIdIndex|]
.
+
+ 1. If |keyRefCbor| is null or undefined,
+ return an error code equivalent to "{{UnknownError}}" and terminate these processing steps.
+ Implementations in [[FIDO-CTAP]] return the error code `CTAP2_ERR_INVALID_OPTION`.
+
+ 1. Let |keyRef| be |keyRefCbor| decoded as a COSE_Key_Ref strucure.
+
+ 1. Decode the authenticator-specific encoding of |keyRef|[kid]
to extract the encoded |chosenAlg|, |signFlags| and |auxIkm|.
+ This procedure SHOULD verify integrity to ensure that |keyRef|[kid]
was generated by this authenticator.
+
+ An example implementation of this decoding is given in [[#sctn-sign-extension-example-key-handle-encoding]].
+
+ 1. If |keyRef|[alg]
is present and does not equal |chosenAlg|,
+ return an error code equivalent to "{{NotSupportedError}}" and terminate the operation.
+ Implementations in [[FIDO-CTAP]] return the error code `CTAP2_ERR_INVALID_CREDENTIAL`.
+
+ 1. If the [=authData/flags/UP=] bit is set in |signFlags| but not in |authData|.[=authData/flags=]
,
+ return an error code equivalent to "{{ConstraintError}}" and terminate the operation.
+ Implementations in [[FIDO-CTAP]] return the error code `CTAP2_ERR_UP_REQUIRED`.
+
+ 1. If the [=authData/flags/UV=] bit is set in |signFlags| but not in |authData|.[=authData/flags=]
,
+ return an error code equivalent to "{{ConstraintError}}" and terminate the operation.
+ Implementations in [[FIDO-CTAP]] return the error code`CTAP2_ERR_PUAT_REQUIRED`.
+
+ 1. Use |signFlags|, |auxIkm|, and a per-credential authenticator secret
+ as the seeds to deterministically re-generate the key pair with private key |p| and public key |P|
+ for the algorithm |chosenAlg|.
+
+ 1. Set |authData|.[=authData/extensions=]["sign"]
+ to a new CBOR map with the entries:
+ - `sig`: The result of signing |extSign|[phData]
using the private key referenced by |keyRef|.
+
+ The signing procedure MUST interpret |extSign|[phData]
as pre-hashed
+ as appropriate for the chosen signing algorithm.
+
+ ISSUE: Need to define pre-hashing more precisely.
+
+ The CBOR map keys `phData`, `key-refs`, `kid`, `alg` and `sig` are aliases defined above and below
+ in the CDDL for the [=authenticator extension input=] and [=authenticator extension output=].
+
+
+: Authenticator extension output
+:: A CBOR map with the structure of the following CDDL:
+
+ ```
+ ; The symbolic names on the left are represented in CBOR by the integers on the right
+ flags = 4
+ sig = 6
+ att-obj = 7
+
+ $$extensionOutput //= (
+ sign: {
+ ; Registration (key generation) outputs
+ att-obj => bstr .cbor attObj, ; Attestation object for signing key pair
+ ? sig => bstr, ; Signature over phData input, if present
+ //
+ ; Authentication (signing) outputs
+ sig => bstr, ; Signature over phData input
+ //
+ ; Attestation fields
+ flags => &(unattended: 0b000,
+ require-up: 0b001,
+ require-uv: 0b101)
+ },
+ )
+ ```
+
+ Note: The `att-obj` entry is defined as a byte string containing CBOR-encoded data
+ instead of a direct CBOR map because the [=CTAP2 canonical CBOR encoding form=] allows at most 4 levels of nested CBOR structures.
+
+ : att-obj
+ :: An [=attestation object=] for the signing key pair.
+ MUST be present in [=registration ceremonies=].
+ MUST NOT be present in [=authentication ceremonies=].
+
+ : sig
+ :: A signature over the extension input `phData`, if present, by the signing private key.
+ MAY be present in [=registration ceremonies=].
+ MUST be present in [=authentication ceremonies=].
+
+ : flags
+ :: A copy of the `flags` input.
+ Present only in the [=attestation object=] embedded within the `att-obj` output during [=registration ceremonies=].
+ This represents whether signing operations with this signing private key
+ require [=user presence=] and [=user verification=]:
+
+ - If `unattended` (`0b000`), signatures do not require [=user presence=] or [=user verification=].
+ - If `require-up` (`0b001`), signatures require [=user verification=] but do not require [=user presence=].
+ - If `require-uv` (`0b101`), signatures require [=user presence=] and [=user verification=].
+
+#### Constructing a key handle from a COSE_Key #### {#sctn-sign-extension-key-handle-from-cose-key}
+
+To construct a key handle from a COSE_Key
+given a COSE_Key structure |coseKey|,
+a [=[RP]=] or [=client=] proceeds as follows:
+
+1. Let |keyHandle| be a copy of |coseKey|.
+1. Remove all entries from |keyHandle| whose key is not one of `kty`, `kid` or `alg`.
+1. Return |keyHandle| encoded in CBOR.
+
+The CBOR map keys `kty`, `kid` and `alg` are aliases defined above
+in the CDDL for the [=authenticator extension input=].
+
+
+#### Example key handle encoding #### {#sctn-sign-extension-example-key-handle-encoding}
+
+This section defines one possible implementation of the encoding and decoding of the [=signing key handle=] |kid|
+in the [=authenticator extension processing=] steps defined above.
+[=Authenticator=] implementations MAY use these encoding and decoding procedures,
+or MAY use different encodings with the same inputs and outputs.
+
+To encode |chosenAlg|, |signFlags| and |auxIkm|, producing the output |kid|, perform the following steps:
+
+1. Let |macKey| be a per-credential authenticator secret.
+
+1. Let |kidParams| be a CBOR array with the items:
+ 1. |chosenAlg| encoded as a CBOR integer.
+ 1. |signFlags| encoded as a CBOR unsigned integer.
+ 1. |auxIkm| encoded as a CBOR byte string.
+
+1. Let |kidMac| be the output of HMAC-SHA-256 [[RFC2104]] with the inputs:
+
+ - Secret key `K`: |macKey|
+ - Input `text`: |kidParams| || UTF8Encode("sign") || |authData|.[=authData/rpIdHash=]
.
+
+1. Let |kid| be |kidMac| || |kidParams|
.
+
+To decode |kid|, producing the output |chosenAlg|, |signFlags| and |auxIkm|, perform the following steps:
+
+1. Let |macKey| be a per-credential authenticator secret.
+
+1. Let |mac| be the first 32 bytes of |kid| and let |kidParams| be the remaining bytes of |kid| after removing the first 32 bytes.
+
+1. Verify that |mac| equals the output of HMAC-SHA-256 [[RFC2104]] with the inputs:
+
+ - Secret key `K`: |macKey|
+ - Input `text`: |kidParams| || UTF8Encode("sign") || |authData|.[=authData/rpIdHash=]
.
+
+ If not, this |kid| was generated by a different authenticator.
+ Return an error code equivalent to "{{NotAllowedError}}" and terminate the extension processing steps.
+
+1. Parse |kidParams| as a CBOR array.
+
+1. Let |chosenAlg| be |kidParams|[0]
.
+
+1. Let |signFlags| be |kidParams|[1]
.
+
+1. Let |auxIkm| be |kidParams|[2]
.
# User Agent Automation # {#sctn-automation}
@@ -9221,6 +9876,14 @@ for their contributions as our W3C Team Contacts.
"title": "EduPerson",
"href": "https://refeds.org/eduperson",
"date": "ongoing"
+ },
+
+ "ARKG": {
+ "authors": ["E. Lundberg", "J. Bradley", "P. Altmann"],
+ "title": "The Asynchronous Remote Key Generation (ARKG) algorithm (Editor's copy)",
+ "href": "https://yubico.github.io/arkg-rfc/draft-bradleylundberg-cfrg-arkg.html",
+ "status": "IETF Internet-Draft",
+ "date": "17 May, 2024"
}
}