From 62b67c02a37ab54ca8b3c1f7606bb7351298ddec Mon Sep 17 00:00:00 2001 From: Vijay Bharadwaj Date: Wed, 31 Aug 2016 10:10:01 -0700 Subject: [PATCH 1/7] Cleaned up exposition of processing rules (#154) * Replace facet with origin Facet was a holdover from the old FIDO specs and origin is the term used everywhere in this spec (as well as in recent FIDO specs) * Clean up explanation of computing clientDataHash and passing to authenticator Fixes #153 * Remove text from authnsel extension to avoid chicken-and-egg problem Fixes #152 * Address comments from @equalsJeffH --- index.bs | 259 +++++++++++++++++++++++++++---------------------------- 1 file changed, 128 insertions(+), 131 deletions(-) diff --git a/index.bs b/index.bs index e5f030649..05cc15006 100644 --- a/index.bs +++ b/index.bs @@ -127,7 +127,7 @@ or a combination of both. This specification relies on several other underlying specifications. : HTML5 -:: The concept of origin and the Navigator/dfn> interface are defined in [[!HTML5]]. +:: The concept of origin and the Navigator/dfn> interface are defined in [[!HTML5]]. : Web IDL :: Many of the interface definitions and all of the IDL in this specification depend on [[!WebIDL-1]]. This updated version of @@ -386,22 +386,19 @@ This method takes the following parameters: When this method is invoked, the user agent MUST execute the following algorithm: -1. If timeoutSeconds was specified, check if its value lies within a reasonable range as defined - by the platform and if not, correct it to the closest value lying within that range. Set |adjustedTimeout| to this adjusted - value. If timeoutSeconds was not specified then set |adjustedTimeout| to a platform-specific - default. +1. If {{CredentialOptions/timeoutSeconds}} was specified, check if its value lies within a reasonable range as defined by the + platform and if not, correct it to the closest value lying within that range. Set |adjustedTimeout| to this adjusted value. + If {{CredentialOptions/timeoutSeconds}} was not specified then set |adjustedTimeout| to a platform-specific default. 2. Let |promise| be a new Promise. Return |promise| and start a timer for |adjustedTimeout| seconds. Then asynchronously continue executing the following steps. -3. Set |callerOrigin| to the origin of the caller. Derive the RP ID from |callerOrigin| by computing the +3. Set |callerOrigin| to the origin of the caller. Derive the RP ID from |callerOrigin| by computing the "public suffix + 1" or "PS+1" (which is also referred to as the "Effective Top-Level Domain plus One" or "eTLD+1") - part of |callerOrigin| [[PSL]]. Set |rpIdHash| to the SHA-256 hash of the UTF-8 encoding of the lowercase form of this RP - ID. + part of |callerOrigin| [[PSL]]. Let |rpId| be the lowercase form of this RP ID. Set |rpIdHash| to the SHA-256 hash of the + UTF-8 encoding of |rpId|. -4. Initialize |issuedRequests| to an empty list. - -5. Process each element of cryptoParameters using the following steps, to produce a new sequence `normalizedParameters`: +4. Process each element of cryptoParameters using the following steps, to produce a new sequence `normalizedParameters`: - Let |current| be the currently selected element of cryptoParameters. - If `current.type` does not contain a {{CredentialType}} supported by this implementation, then stop processing |current| and move on to the next element in cryptoParameters. @@ -411,17 +408,22 @@ When this method is invoked, the user agent MUST execute the following algorithm - Add a new object of type {{ScopedCredentialParameters}} to `normalizedParameters`, with |type| set to `current.type` and |algorithm| set to `normalizedAlgorithm`. -6. If excludeList is undefined, set it to the empty list. +5. If excludeList is undefined, set it to the empty list. + +6. If {{CredentialOptions/extensions}} was specified, process any extensions supported by this client platform, to produce the + extension data that needs to be sent to the authenticator. Call this data |clientExtensions|. -7. If extensions was specified, process any extensions supported by this client platform, to - produce the extension data that needs to be sent to the authenticator. Call this data |clientExtensions|. +7. Use {{attestationChallenge}}, |callerOrigin| and |rpId|, along with the token binding key associated with |callerOrigin| (if + any), to create a {{ClientData}} structure representing this request. Choose a hash algorithm for {{ClientData/hashAlg}} and + compute the clientDataJSON and clientDataHash. + +8. Initialize |issuedRequests| to an empty list. -8. For each authenticator currently available on this platform: asynchronously invoke the - authenticatorMakeCredential operation on that authenticator with |callerOrigin|, |rpIdHash|, - accountInformation, `normalizedParameters`, excludeList, attestationChallenge and |clientExtensions| as - parameters. Add a corresponding entry to |issuedRequests|. +9. For each authenticator currently available on this platform: asynchronously invoke the authenticatorMakeCredential + operation on that authenticator with |rpIdHash|, clientDataHash, accountInformation, `normalizedParameters`, + excludeList and |clientExtensions| as parameters. Add a corresponding entry to |issuedRequests|. -9. While |issuedRequests| is not empty, perform the following actions depending upon the |adjustedTimeout| timer and responses +10. While |issuedRequests| is not empty, perform the following actions depending upon the |adjustedTimeout| timer and responses from the authenticators: - If the |adjustedTimeout| timer expires, then for each entry in |issuedRequests| invoke the authenticatorCancel operation on that authenticator and remove its entry from the list. @@ -432,7 +434,7 @@ When this method is invoked, the user agent MUST execute the following algorithm - If any authenticator indicates success: - Remove this authenticator's entry from |issuedRequests|. - Create a new {{ScopedCredentialInfo}} object named |value| and populate its fields with the values returned from the - authenticator. + authenticator as well as the clientDataJSON computed earlier. - For each remaining entry in |issuedRequests| invoke the authenticatorCancel operation on that authenticator and remove its entry from the list. - Resolve |promise| with |value| and terminate this algorithm. @@ -460,35 +462,39 @@ This method takes the following parameters: When this method is invoked, the user agent MUST execute the following algorithm: -1. If timeoutSeconds was specified, check if its value lies within a reasonable range as defined - by the platform and if not, correct it to the closest value lying within that range. Set |adjustedTimeout| to this adjusted - value. If timeoutSeconds was not specified then set |adjustedTimeout| to a platform-specific - default. +1. If {{AssertionOptions/timeoutSeconds}} was specified, check if its value lies within a reasonable range as defined by the + platform and if not, correct it to the closest value lying within that range. Set |adjustedTimeout| to this adjusted value. + If {{AssertionOptions/timeoutSeconds}} was not specified then set |adjustedTimeout| to a platform-specific default. 2. Let |promise| be a new Promise. Return |promise| and start a timer for |adjustedTimeout| seconds. Then asynchronously continue executing the following steps. -3. Set |callerOrigin| to the origin of the caller. Derive the RP ID from |callerOrigin| by computing the +3. Set |callerOrigin| to the origin of the caller. Derive the RP ID from |callerOrigin| by computing the "public suffix + 1" or "PS+1" (which is also referred to as the "Effective Top-Level Domain plus One" or "eTLD+1") - part of |callerOrigin| [[PSL]]. Set |rpIdHash| to the SHA-256 hash of the UTF-8 encoding of the lowercase form of this RP - ID. - -4. Initialize |issuedRequests| to an empty list. - -5. If extensions was specified, process any extensions supported by this client platform, to - produce the extension data that needs to be sent to the authenticator. Call this data |clientExtensions|. - -6. For each authenticator currently available on this platform, perform the following steps: - - If allowList is undefined or empty, let |credentialList| be a list containing a single wildcard entry. Otherwise, - execute a platform-specific procedure to determine which of these credentials might be present on this authenticator, - and set |credentialList| to this filtered list. - - - If |credentialList| is empty, ignore this authenticator and do not perform any of the following per-authenticator steps. - - Asynchronously invoke the authenticatorGetAssertion operation on this authenticator with |callerOrigin|, - |rpIdHash|, assertionChallenge, |credentialList|, and |clientExtensions| as parameters. + part of |callerOrigin| [[PSL]]. Let |rpId| be the lowercase form of this RP ID. Set |rpIdHash| to the SHA-256 hash of the + UTF-8 encoding of |rpId|. + +4. If {{AssertionOptions/extensions}} was specified, process any extensions supported by this client platform, to produce the + extension data that needs to be sent to the authenticator. Call this data |clientExtensions|. + +5. Use {{assertionChallenge}}, |callerOrigin| and |rpId|, along with the token binding key associated with |callerOrigin| (if + any), to create a {{ClientData}} structure representing this request. Choose a hash algorithm for {{ClientData/hashAlg}} and + compute the clientDataJSON and clientDataHash. + +6. Initialize |issuedRequests| to an empty list. + +7. For each authenticator currently available on this platform, perform the following steps: + - If allowList is undefined or empty, let |credentialList| be an empty list. Otherwise, execute a platform-specific + procedure to determine which, if any, credentials listed in allowList might be present on this authenticator, and + set |credentialList| to this filtered list. If no such filtering is possible, set |credentialList| to an empty list. + - If the above filtering process concludes that none of the credentials on allowList can possibly be on this + authenticator, do not perform any of the following steps for this authenticator, and proceed to the next authenticator + (if any). + - Asynchronously invoke the authenticatorGetAssertion operation on this authenticator with |rpIdHash|, + clientDataHash, |credentialList|, and |clientExtensions| as parameters. - Add an entry to |issuedRequests|, corresponding to this request. -7. While |issuedRequests| is not empty, perform the following actions depending upon the |adjustedTimeout| timer and responses +8. While |issuedRequests| is not empty, perform the following actions depending upon the |adjustedTimeout| timer and responses from the authenticators: - If the timer for |adjustedTimeout| expires, then for each entry in |issuedRequests| invoke the authenticatorCancel operation on that authenticator and remove its entry from the list. @@ -499,12 +505,12 @@ When this method is invoked, the user agent MUST execute the following algorithm - If any authenticator returns success: - Remove this authenticator's entry from |issuedRequests|. - Create a new {{WebAuthnAssertion}} object named |value| and populate its fields with the values returned from the - authenticator. + authenticator as well as the clientDataJSON computed earlier. - For each remaining entry in |issuedRequests| invoke the authenticatorCancel operation on that authenticator and remove its entry from the list. - Resolve |promise| with |value| and terminate this algorithm. -8. Resolve |promise| with a DOMException whose name is "NotFoundError", and terminate this algorithm. +9. Resolve |promise| with a DOMException whose name is "NotFoundError", and terminate this algorithm. During the above process, the user agent SHOULD show some UI to the user to guide them in the process of selecting and authorizing an authenticator with which to complete the operation. @@ -642,7 +648,7 @@ providing provenance information for the attesting key, enabling a trust decisio later versions of this specification. The clientData member contains the clientDataJSON (see [[#signature-format]]). The exact JSON encoding - must be preserved as the hash (clientDataHash) has been computed over it. + must be preserved as the hash (clientDataHash) has been computed over it. The statement element contains the actual attestation statement. The structure of this object depends on the attestation format. For more details, see [[#attestation]]. @@ -658,6 +664,51 @@ well as to decode and validate the bindings of both the client and authenticator The scoped credential type uses certain data structures that are specified in supporting specifications. These are as follows. +### Client data used in WebAuthn signatures (dictionary ClientData) ### {#sec-client-data} + +The client data represents the contextual bindings of both the [RP] and the client platform. It is a key-value mapping with +string-valued keys. Values may be any type that has a valid encoding in JSON. Its structure is defined by the following Web IDL. + +
+    dictionary ClientData {
+        required DOMString           challenge;
+        required DOMString           origin;
+        required DOMString           rpId;
+        required AlgorithmIdentifier hashAlg;
+        JsonWebKey                   tokenBinding;
+        WebAuthnExtensions           extensions;
+    };
+
+ +
+ The challenge member contains the base64url encoding of the challenge provided by the RP. + + The origin member contains the fully qualified web origin of the requester, as provided to the authenticator by + the client, in the syntax defined by [[RFC6454]]. + + The rpId member contains the RP ID of the requester, as computed by the client. + + The hashAlg member specifies the hash algorithm used to compute clientDataHash (see + [[#authenticator-signature]]). Use "S256" for SHA-256, "S384" for SHA384, "S512" for SHA512, and "SM3" for SM3 (see + [[#iana-considerations]]). This algorithm is chosen by the client at its sole discretion. + + The tokenBinding member contains a JsonWebKey object as defined by [[WebCryptoAPI#JsonWebKey-dictionary]] + describing the public key that this client uses for the Token Binding protocol when communicating with the [RP]. This can be + omitted if no Token Binding has been negotiated between the client and the [RP]. + + The optional extensions member contains additional parameters generated by processing the extensions passed in + by the [RP]. WebAuthn extensions are detailed in Section [[#extensions]]. +
+ +This structure is used by the client to compute the following quantities: + +: clientDataJSON +:: This is the UTF-8 encoded JSON serialization [[RFC7159]] of a {{ClientData}} dictionary. + +: clientDataHash +:: This is the hash (computed using hashAlg) of clientDataJSON. + + ### Credential Type enumeration (enum CredentialType) ### {#credentialType}
@@ -731,15 +782,13 @@ The following operations can be invoked by the client in an authenticator sessio This operation must be invoked in an authenticator session which has no other operations in progress. It takes the following input parameters: -- The web origin of the script on whose behalf the operation is being initiated, as determined by the user agent and the client. -- The SHA-256 hash of the RP ID corresponding to the above web origin, as determined by the user agent and the client. +- The SHA-256 hash of the caller's RP ID, as determined by the user agent and the client. +- The clientDataHash, which is the hash of the serialized {{ClientData}} and is provided by the client. - The {{Account}} information provided by the [RP]. -- The {{CredentialType}} requested by the [RP]. -- The cryptographic parameters requested by the [RP], with the cryptographic algorithms normalized as per the procedure in - [[WebCryptoAPI#algorithm-normalization-normalize-an-algorithm]]. +- The {{CredentialType}} and cryptographic parameters requested by the [RP], with the cryptographic algorithms normalized as per + the procedure in [[WebCryptoAPI#algorithm-normalization-normalize-an-algorithm]]. - A list of {{Credential}} objects provided by the [RP] with the intention that, if any of these are known to the authenticator, it should not create a new credential. -- A challenge provided by the [RP] to assure freshness of the attestation statement of the new credential. - Extension data created by the client based on the extensions requested by the [RP]. When this operation is invoked, the authenticator obtains user consent for creating a new credential. The prompt for obtaining @@ -765,9 +814,8 @@ If the user refuses consent, the authenticator returns an appropriate error stat This operation must be invoked in an authenticator session which has no other operations in progress. It takes the following input parameters: -- The web origin of the script on whose behalf the operation is being initiated, as determined by the user agent and the client. -- The RP ID hash corresponding to the above web origin, as determined by the user agent and the client. -- A challenge provided by the [RP] to assure freshness of the assertion produced. +- The SHA-256 hash of the caller's RP ID, as determined by the user agent and the client. +- The clientDataHash, which is the hash of the serialized {{ClientData}} and is provided by the client. - A list of credentials acceptable to the [RP] (possibly filtered by the client). - Extension data created by the client based on the extensions requested by the [RP]. @@ -837,45 +885,8 @@ The goals of this design can be summarized as follows. The contextual bindings are divided in two: Those added by the RP or the client platform, referred to as client data; and those added by the authenticator, referred to as the authenticator data. The client data must be signed over, but an authenticator is otherwise not interested in its contents. To save bandwidth and processing requirements on the authenticator, the client -platform hashes the client data and sends only the result to the authenticator. The authenticator signs over the combination of -this hash, and its own authenticator data. - - -### Client data used in WebAuthn signatures (dictionary ClientData) ### {#sec-client-data} - -The client data represents the contextual bindings of both the [RP] and the client platform. It is a key-value mapping with -string-valued keys. Values may be any type that has a valid encoding in JSON. Its structure is defined by the following Web IDL. - -
-    dictionary ClientData {
-        required DOMString           challenge;
-        required DOMString           facet;
-        required DOMString           rpId;
-        required AlgorithmIdentifier hashAlg;
-        JsonWebKey                   tokenBinding;
-        WebAuthnExtensions           extensions;
-    };
-
- -
- The challenge member contains the base64url encoding of the challenge provided by the RP. - - The facet member contains the fully qualified web origin of the requester, as provided to the authenticator by - the client, in the syntax defined by [[RFC6454]]. - - The rpId member contains the RP ID of the requester, as computed by the client. - - The hashAlg member specifies the hash algorithm used to compute clientDataHash (see - [[#authenticator-signature]]). Use "S256" for SHA-256, "S384" for SHA384, "S512" for SHA512, and "SM3" for SM3 (see - [[#iana-considerations]]). - - The tokenBinding member contains a JsonWebKey object as defined by [[WebCryptoAPI#JsonWebKey-dictionary]] - describing the public key that this client uses for the Token Binding protocol when communicating with the [RP]. This can be - omitted if no Token Binding has been negotiated between the client and the [RP]. - - The optional extensions member contains additional parameters generated by processing the extensions passed in - by the [RP]. WebAuthn extensions are detailed in Section [[#extensions]]. -
+platform hashes the {{ClientData}} and sends only the result to the authenticator. The authenticator signs over the combination of +this clientDataHash, and its own authenticator data. ### Authenticator data ### {#sec-authenticator-data} @@ -924,9 +935,9 @@ generated. However, it differs from other client data in some important ways. Fi credential does not change between operations but instead remains the same for the lifetime of that credential. Secondly, it is validated by the authenticator during the authenticatorGetAssertion operation, by making sure that the RP ID hash associated with the requested credential exactly matches the RP ID hash supplied by the client. These differences also explain -why the RP ID hash is always a SHA-256 hash instead of being crypto-agile like the |clientDataHash|; for a given RP ID, we need -the hash to be computed the same way by all clients for all operations so that authenticators can move between clients without -losing interoperability. +why the RP ID hash is always a SHA-256 hash instead of being crypto-agile like the clientDataHash; for a given RP ID, we +need the hash to be computed the same way by all clients for all operations so that authenticators can roam among clients +without losing interoperability. The `TUP` flag SHALL be set if and only if the authenticator detected a user through an authenticator specific gesture. The `RFU` bits in the flags byte SHALL be set to zero. @@ -947,22 +958,8 @@ it is 37 bytes plus the CBOR map that follows. ### Generating a signature ### {#authenticator-signature} -Before making a request to an authenticator, the client platform layer SHALL perform the following steps. - -1. Represent the parameters passed in by the RP in the form of a {{ClientData}} structure. - -2. Let clientDataJSON be the UTF-8 encoded JSON serialization [[RFC7159]] of this ClientData dictionary. - -3. Let clientDataHash be the hash (computed using hashAlg) of clientDataJSON, as an array. - -The |clientDataHash| value is delivered to the authenticator. - -The hash algorithm hashAlg used to compute clientDataHash is included in the {{ClientData}} object. This way it -is available to the [RP] and it is also hashed over when computing clientDataHash and hence anchored in the signature -itself. - A raw cryptographic signature must assert the integrity of both the client data and the authenticator data. Thus, an -authenticator SHALL compute a signature over the concatenation of the |authenticatorData| and the |clientDataHash|. +authenticator SHALL compute a signature over the concatenation of the |authenticatorData| and the clientDataHash.
@@ -970,7 +967,7 @@ A raw cryptographic signature must assert the integrity of both the client data
Note: A simple, undelimited concatenation is safe to use here because the |authenticatorData| describes its own length. The - |clientDataHash| (which potentially has a variable length) is always the last element. + clientDataHash (which potentially has a variable length) is always the last element. The authenticator MUST return both the authenticatorData and the raw signature back to the client. The client, in turn, MUST return clientDataJSON, authenticatorData and the signature to the RP. The clientDataJSON is returned @@ -1069,7 +1066,7 @@ Upon receiving an attestation statement, the [RP] shall: - Verify `rawData` syntax and that it doesn't contradict the signing algorithm specified in `alg`. - The DAA root key is dedicated to a single Authenticator model. -4. Verify the contextual bindings (e.g., channel binding) from the clientData (see [[#authenticator-signature]]). +4. Verify the contextual bindings (e.g., token binding) from the `clientData` (see [[#authenticator-signature]]). 5. Verify that user verification method and other authenticator characteristics related to this authenticator model, match the [RP] policy. The FIDO Metadata Service [[FIDOMetadataService]] provides an easy way to access the authenticator @@ -1189,8 +1186,8 @@ A Packed Attestation statement has the following format: The alg element contains the name of the algorithm used to generate the attestation signature according to [[!RFC7518]] section 3.1. - The rawData object contains the attested public key and the |clientDataHash|. See [[#sec-raw-data-packed]] for - details. + The rawData object contains the attested public key and the clientDataHash. See [[#sec-raw-data-packed]] + for details. The signature element contains the attestation signature. See [[#packed-attestation-signature]] for details.
@@ -1274,13 +1271,13 @@ arranged as given below: 2 - Byte length n of clientDataHash + Byte length n of clientDataHash n - clientDataHash (see [[#authenticator-signature]]). This is the hash of `clientDataJSON`. The hash algorithm itself - is stored in the `clientData` object [[#signature-format]]. + clientDataHash (see [[#authenticator-signature]]). This is the hash of clientDataJSON. The hash + algorithm itself is stored in the {{ClientData}} object [[#signature-format]]. @@ -1366,7 +1363,7 @@ if `version` equals 1. Else, if `version` equals 2, it MUST be a TPMS_ATTEST str 10.12.9. The field "extraData" (in the case of TPMS_ATTEST) or the field "data" (in the case of TPM_CERTIFY_INFO or TPM_CERTIFY_INFO2) -MUST contain the `clientDataHash` (see [[#signature-format]]). +MUST contain the clientDataHash (see [[#signature-format]]). ### Signature ### {#tpm-attestation-signature} @@ -1439,7 +1436,7 @@ This type of attestation statement is formatted as follows: ### Signature ### {#sec-android-attestation-signature} -For this attestation format, the ClientData dictionary is extended in the following way: +For this attestation format, the {{ClientData}} dictionary is extended in the following way:
     dictionary AndroidAttestationClientData : ClientData {
@@ -1470,24 +1467,25 @@ For this attestation format, the ClientData dictionary is extended in the follow
         this key is authorized to be used after the user is successfully authenticated.
 
 
-In order to generate an attestation statement, the client MUST create clientDataJSON by UTF8-encoding a structure of type
-AndroidAttestationClientData, and compute clientDataHash as the hash of clientDataJSON. It must then provide clientDataHash as
-the Nonce value when requesting the SafetyNet attestation.
+In order to generate an attestation statement, the client MUST create clientDataJSON by UTF8-encoding a structure of type
+{{AndroidAttestationClientData}}, and compute clientDataHash as the hash of clientDataJSON. It must then provide
+clientDataHash as the Nonce value when requesting the SafetyNet attestation.
 
 
 ### Verifying AndroidClientData specific contextual bindings ### {#verifying-android-contextual-bindings}
 
-A [RP] shall verify the clientData contextual bindings (see step 4 in [[#verifying-an-attestation-statement]]) as follows:
+A [RP] shall verify the {{ClientData}} contextual bindings (see step 4 in [[#verifying-an-attestation-statement]]) as follows:
 
 - Check that `AndroidAttestationClientData.challenge` equals the attestationChallenge that was passed into the
     {{makeCredential()}} call.
 
-- Check that the `facet` and `tokenBinding` parameters in the `AndroidAttestationClientData` match the [RP] App.
+- Check that the {{ClientData/origin}} and {{ClientData/tokenBinding}} parameters in the `AndroidAttestationClientData` match
+    the [RP] App.
 
 - Check that `AndroidAttestationClientData.publicKey` is the same key as the one returned in the `ScopedCredentialInfo` by the
     `makeCredential` call.
 
-- Check that the hash of the clientDataJSON matches the `nonce` attribute in the payload of the `safetynetResponse` JWS.
+- Check that the hash of the clientDataJSON matches the `nonce` attribute in the payload of the `safetynetResponse` JWS.
 
 - Check that the `ctsProfileMatch` attribute in the payload of the `safetynetResponse` is true.
 
@@ -1571,8 +1569,8 @@ in the {{getAssertion()}} or {{makeCredential()}} call, while the authentic
 to the authenticator during the processing of these calls.
 
 A [RP] simultaneously requests the use of an extension and sets its client argument by including an entry in the
-extensions option to the {{makeCredential()}} or {{getAssertion()}} call. The entry key MUST be
-the extension identifier, and the value MUST be the client argument.
+{{CredentialOptions/extensions}} option to the {{makeCredential()}} or {{getAssertion()}} call. The entry key MUST be the
+extension identifier, and the value MUST be the client argument.
 
 
     var assertionPromise = credentials.getAssertion(..., /* extensions */ {
@@ -1601,7 +1599,7 @@ value that the [RP] needs to be aware of, the extension should specify a client
 structure.
 
 The client data value may be any value that can be encoded using JSON. If any extension processed by a client defines such a
-value, the client SHOULD include a dictionary in {{ClientData}} with the key extensions. For each such
+value, the client SHOULD include a dictionary in {{ClientData}} with the key {{ClientData/extensions}}. For each such
 extension, the client SHOULD add an entry to this dictionary with the extension identifier as the key, and the extension's
 client data value.
 
@@ -1758,8 +1756,7 @@ credential. It is intended primarily for [RPS] that wish to tightly control the
 :: This extension can only be used during {{makeCredential()}}. If the client supports the Authenticator Selection Extension, it
     MUST use the first available authenticator whose AAGUID is present in the AuthenticatorSelectionList. If none of
     the available authenticators match a provided AAGUID, the client MUST select an authenticator from among the available
-    authenticators to generate the credential. If an authenticator was selected from {{AuthenticatorSelectionList}}, its
-    AAGUID MUST be added by the client to the ClientData as the client data value for this extension.
+    authenticators to generate the credential.
 
 : Authenticator argument
 :: There is no authenticator argument.

From a7817009bf82bd1ef3bca7d7c05ab3c88a3f2738 Mon Sep 17 00:00:00 2001
From: gmandyam 
Date: Wed, 31 Aug 2016 10:14:35 -0700
Subject: [PATCH 2/7] Update index.bs with proposed location extension (#157)

* Update index.bs

* Update index.bs

* Update index.bs

* Update index.bs
---
 index.bs | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/index.bs b/index.bs
index 05cc15006..ca6694b3f 100644
--- a/index.bs
+++ b/index.bs
@@ -1837,7 +1837,53 @@ credential. It is intended primarily for [RPS] that wish to tightly control the
                 82
     
+## Location Extension ## {#uvi-location} +: Extension identifier +:: `webauthn_loc` + +: Client argument +:: The Boolean value `true` to indicate that this extension is requested by the [RP]. + +: Client processing +:: None, except default forwarding of client argument to authenticator argument. + +: Authenticator argument +:: The Boolean value `true`, encoded in CBOR (major type 7, value 21). + +: Authenticator processing +:: If the authenticator does not support the extension, then the authenticator MUST ignore the extension request. + If the authenticator accepts the extension, then the authenticator SHOULD only add this extension data to a packed + attestation or assertion. + +: Authenticator data +:: If the authenticator accepts the extension request, then authenticator data SHOULD provide location data in the form of a + CBOR-encoded map, with the first value being the extension identifier and the second being an array of returned values. The array + elements SHOULD be derived from (key,value) pairings for each location attribute that the authenticator supports. The following is + an example of authenticator data where the returned array is comprised of a {longitude, latitude, altitude} triplet, following the + coordinate representation defined in The W3C Geolocation API + Specification. + +
+        F1 D0                                       -- This is a WebAuthn packed rawData object
+        81                                          -- TUP and ED set
+        00 00 00 01                                 -- (initial) signature counter
+        ...                                         -- all public key alg etc.
+        A1                                          -- extension: CBOR map of one element
+            6C                                      -- Value 1: CBOR text string of 11 bytes
+                77 65 62 61 75 74 68 6E 5F 6C 6F 63 -- "webauthn_loc" UTF-8 string
+            86                                      -- Value 2: array of 6 elements
+                68				    -- Element 1:  CBOR text string of 8 bytes
+                   6C 61 74 69 74 75 64 65          -- “latitude” UTF-8 string
+                FB ...				    -- Element 2:  Latitude as CBOR encoded double-precision float
+                69				    -- Element 3:  CBOR text string of 9 bytes
+                   6C 6F 6E 67 69 74 75 64 65       -- “longitude” UTF-8 string
+                FB ...				    -- Element 4:  Longitude as CBOR encoded double-precision float
+                68				    -- Element 5:  CBOR text string of 8 bytes
+                  61 6C 74 69 74 75 64 65           -- “altitude” UTF-8 string
+                FB ...				    -- Element 6:  Altitude as CBOR encoded double-precision float
+    
+ # IANA Considerations # {#iana-considerations} This specification registers the algorithm names "S256", "S384", "S512", and "SM3" with the IANA JSON Web Algorithms registry as From b6a2790a029263f3b5763e8d76771e57c1dadde3 Mon Sep 17 00:00:00 2001 From: Rahul Ghosh Date: Thu, 1 Sep 2016 08:39:20 -0700 Subject: [PATCH 3/7] =?UTF-8?q?Adding=20the=20User=20Verification=20Mode?= =?UTF-8?q?=20extension=20as=20per=20discussions=20in=20the=E2=80=A6=20(#1?= =?UTF-8?q?69)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adding the User Verification Mode extension as per discussions in the WG weekly metings. After a lot of thought I retained the sub-array instead of converting the sub-items in the extension to a map. This was primarily to avoid having to define string based keys that increases the size of the extension. Given that the array is well defined I think it keeps it easier to process in software and extendable for future additions as well. * Cleaned up exposition of processing rules (#154) * Replace facet with origin Facet was a holdover from the old FIDO specs and origin is the term used everywhere in this spec (as well as in recent FIDO specs) * Clean up explanation of computing clientDataHash and passing to authenticator Fixes #153 * Remove text from authnsel extension to avoid chicken-and-egg problem Fixes #152 * Address comments from @equalsJeffH * Update index.bs with proposed location extension (#157) * Update index.bs * Update index.bs * Update index.bs * Update index.bs * Adding the User Verification Mode extension as per discussions in the WG weekly metings. After a lot of thought I retained the sub-array instead of converting the sub-items in the extension to a map. This was primarily to avoid having to define string based keys that increases the size of the extension. Given that the array is well defined I think it keeps it easier to process in software and extendable for future additions as well. * fixing another merge issue with uvm extension being repeated following upstream merge --- index.bs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/index.bs b/index.bs index ca6694b3f..9b1c194f1 100644 --- a/index.bs +++ b/index.bs @@ -1,4 +1,4 @@ -