diff --git a/images/fido-attestation-structures.svg b/images/fido-attestation-structures.svg index 45ad6dfa4..9cd0439d8 100644 --- a/images/fido-attestation-structures.svg +++ b/images/fido-attestation-structures.svg @@ -18,50 +18,53 @@ version="1.1" id="svg4696" sodipodi:docname="fido-attestation-structures.svg" - inkscape:version="0.91 r13725" + inkscape:version="0.92.3 (2405546, 2018-03-11)" style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-rule:evenodd;stroke-linecap:square;stroke-miterlimit:3">image/svg+xmlTabelle.4ATTESTATION OBJECTTabelle.4ATTESTATION OBJECTATTESTATION OBJECT + + + + + +authData“: ... +“fmt“: “packed“ +ATTESTATION OBJECT + v:langID="1031" + id="text4575" + style="font-size:9.59929752px;line-height:0%;font-family:Calibri;fill:#000000" + transform="scale(1.0417463,0.95992662)">attStmt“: ... + +Rechteck.3“sig“: ...“sig“: ... + Rechteck.5“alg“: ...“alg: ... + +Rechteck.6“x5c“: ...“x5c“: ... + +text150.64If Basic or Privacy CAIf Basic or Privacy CA: + +“ecdaaKeyId“: ... +text150.66If DAAIf ECDAA: + +   + + +  <title id="title4232">rect40<title id="title4237">line42<title id="title4242">line44<title id="title4247">line46<title id="title4252">line48<title id="title4257">line50<title id="title4262">line52<title id="title4267">line54<title id="title4272">line56<title id="title4277">line58<title id="title4282">line60<title id="title4287">line62<title id="title4292">line64<title id="title4297">line66<title id="title4302">line68text72RP ID hashRP ID hash -text72RP ID hashRP ID hash + +<title id="title4321">rect76text78FLAGSFLAGS -text8200 + transform="matrix(1,0,0,0.92145913,135.84915,-397.06996)">text78FLAGSFLAGS + text8600 + transform="matrix(1,0,0,0.92145913,121.58719,-352.57086)">text8200 + text8600 + +text9000 + v:groupContext="shape" + transform="matrix(1,0,0,0.92145913,155.60319,-352.57086)">text9000 + UV + id="tspan4132" + sodipodi:role="line">UV text9800 -text102ATAT + transform="matrix(1,0,0,0.92145913,189.61919,-352.57086)">text9800 + text102ATAT + +text106EDED + v:groupContext="shape" + transform="matrix(1,0,0,0.92145913,84.156191,-352.39118)">text106EDED + UP + x="194.89264" + y="200.72075">UP <title id="title4407">rect114text116COUNTERCOUNTER -text116COUNTERCOUNTER + +<title id="title4421">rect120text122ATTESTATION DATAATTESTED CRED. DATA + v:groupContext="shape" + transform="matrix(1,0,0,0.92145913,290.18015,-397.06996)">text122ATTESTATION DATAATTESTED CRED. DATA + text128EXTENSIONSEXTENSIONS -text128EXTENSIONSEXTENSIONS + +<title id="title4449">path132<title id="title4454">path134<title id="title4461">path136text13832 bytes32 bytes -text1421 byte1 byte + transform="matrix(1,0,0,0.92145913,43.313954,-415.03209)">text13832 bytes32 bytes + text1464 bytes (big-endian uint32)4 bytes (big-endian uint32) + transform="matrix(1,0,0,0.92145913,139.20682,-414.47593)">text1421 byte1 byte + text150variable length (if present)variable length + transform="matrix(1,0,0,0.92145913,174.58115,-414.47593)">text1464 bytes (big-endian uint32)4 bytes (big-endian uint32) + text154variable length (CBOR)variable length if present (CBOR) + transform="matrix(0.94538871,0,0,0.92145913,287.05365,-413.91976)">text150variable length (if present)variable length + text154variable length (CBOR)variable length if present (CBOR) + +text16677 -authData“: ... -text16677 + +“fmt“: “packed“ -attStmt“: ... -Tabelle.57AUTHENTICATOR DATAAUTHENTICATOR DATA -Rechteck.3“sig“: ...“sig“: ... -Rechteck.5“alg“: ...“alg: ... -Rechteck.6“x5c“: ...“x5c“: ... -text150.64If Basic or Privacy CAIf Basic or Privacy CA: -Rechteck.65“daaKey“: ...“ecdaaKeyId“: ... + y="110.54917" + x="183.11613">AUTHENTICATOR DATA text150.66If DAAIf ECDAA: - <title id="title4421-4">rect120text128EXTENSIONSAAGUID -text128EXTENSIONSAAGUID + +<title id="title4421-4-1">rect120 + x="278.23788" + y="99.178825" + style="font-size:30.00004578px;line-height:19.53277206;stroke-width:0.78131092">  text128EXTENSIONSL -text128EXTENSIONSL + +<title id="title4421-1">rect120CREDENTIAL ID -CREDENTIAL ID +CREDENTIAL PUBLIC KEY + v:langID="1031" + class="st2" + y="282.89581" + x="356.25369">CREDENTIAL PUBLIC KEY <title id="title4421-5">rect120text154variable length (CBOR)variable length (COSE_Key) + v:groupContext="shape" + transform="matrix(1,0,0,0.92145913,306.4357,-257.27537)">text154variable length (CBOR)variable length (COSE_Key) + LENGTH L + x="-1.9327474" + y="591.29724" + class="st7" + v:langID="1031" + id="text4510-3-9" + style="font-size:7.99996758px;line-height:0%;font-family:Calibri;fill:#000000;stroke-width:0.99999994">LENGTH L + (variable length) + x="-11.054238" + y="599.9588" + class="st7" + v:langID="1031" + id="text4510-3-5" + style="font-size:7.99996758px;line-height:0%;font-family:Calibri;fill:#000000;stroke-width:0.99999994">(variable length) + text1421 byte2 bytes + v:groupContext="shape" + transform="matrix(1,0,0,0.92145913,222.92083,-246.40181)">text1421 byte2 bytes + 16 bytes -16 bytes + +text16670 + v:mID="51" + id="g4007">text16670 + Tabelle.58ATTESTATION STATEMENTATTESTATION STATEMENT + id="path10873" + d="m 554.07676,322.68543 c -64.8064,46.09955 -368.04963,-13.76687 -366.40593,22.9448" + style="fill:none;stroke:#8c8c8c;stroke-width:0.80218744px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />Tabelle.58ATTESTATION STATEMENTATTESTATION STATEMENT + (in "packed" attestsion statement format) + transform="scale(1.0417463,0.95992663)" + x="352.17941" + y="376.21729" + class="st2" + v:langID="1031" + id="text10915" + style="font-size:9.59929752px;line-height:0%;font-family:Calibri;fill:#000000">(in "packed" attestation statement format) + Rechteck.3“sig“: ...“sig“: ... + id="g10930" + transform="translate(-84.363492,19.691765)">Rechteck.3“sig“: ...“sig“: ... + Rechteck.5“alg“: ...“algRechteck.5“alg“: ...“alg: ... -text150.64If Basic or Privacy CA + +  [Other attestation statement formats are as defined in their respective sections below] \ No newline at end of file + transform="matrix(0.8,0,0,0.8,3.5107972,15.798593)" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0.01%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;image-rendering:auto" + id="flowRoot10992" + xml:space="preserve">[Other attestation statement formats are as defined in their respective sections below] \ No newline at end of file diff --git a/index.bs b/index.bs index dcc72f3d9..3d5620cd6 100644 --- a/index.bs +++ b/index.bs @@ -11,7 +11,7 @@ Notes: Title: Web Authentication: An API for accessing Public Key Credentials - Level Status: ED Prepare for TR: true -TR: https://www.w3.org/TR/webauthn/ +TR: https://www.w3.org/TR/webauthn-2/ ED: https://w3c.github.io/webauthn/ Previous Version: https://www.w3.org/TR/2019/PR-webauthn-20190117/ Previous Version: https://www.w3.org/TR/2018/CR-webauthn-20180807/ @@ -45,6 +45,7 @@ Former Editor: Angelo Liao, w3cid 94342, Microsoft, huliao@microsoft.com !Contributors: Giridhar Mandyam (Qualcomm) !Contributors: Mike West (Google) !Contributors: Jeffrey Yasskin (Google) +!Contributors: Shane Weeden (IBM) group: webauthn Issue Tracking: GitHub https://github.com/w3c/webauthn/issues !Tests: web-platform-tests webauthn/ (ongoing work) @@ -92,6 +93,15 @@ figure.table .overlarge { + + + +
 
@@ -107,16 +117,31 @@ spec: ECMAScript; urlPrefix: https://tc39.github.io/ecma262/#
 spec: RFC8152; urlPrefix: https://tools.ietf.org/html/rfc8152
     type: dfn
         text: Section 7; url: section-7
+        text: Section 13.1; url: section-13.1
+        text: Section 8.1; url: section-8.1
 
-spec: HTML53; urlPrefix: https://w3c.github.io/html/
+spec: RFC8230; urlPrefix: https://tools.ietf.org/html/rfc8230
     type: dfn
+        text: Section 4; url: section-4
+        text: Section 2; url: section-2
+
+spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
+    type: dfn
+        urlPrefix: dom.html
+            for: Document; url: concept-document-feature-policy; text: feature policy
         urlPrefix: browsers.html
-            text: origin; url: concept-cross-origin
-            text: opaque origin; url: opaque-origin
-            text: tuple origin
+            text: browsing context; url: browsing-context
+        urlPrefix: origin.html
+            text: origin; url: concept-origin
+            text: opaque origin; url: concept-origin-opaque
+            text: tuple origin; url: concept-origin-tuple
             text: document.domain; url:dom-document-domain
-            text: scheme; url: origin-scheme
-            text: port; url: origin-port
+
+spec: url; urlPrefix: https://url.spec.whatwg.org
+    type: dfn
+        text: scheme; url: concept-url-scheme
+        text: port; url: concept-url-port
+
 
 spec: TokenBinding; urlPrefix: https://tools.ietf.org/html/rfc8471#
     type: dfn
@@ -154,7 +179,7 @@ spec: page-visibility; urlPrefix: https://www.w3.org/TR/page-visibility/
         text: visibility states
 
 spec: WHATWG HTML; urlPrefix: https://html.spec.whatwg.org/
-    type: dfn 
+    type: dfn
         text: focus
         text: username; url: attr-fe-autocomplete-username
 
@@ -198,10 +223,15 @@ spec: SP800-800-63r3; urlPrefix: https://pages.nist.gov/800-63-3/sp800-63-3.html
         text: something you know; url: af
         text: something you have; url: af
         text: something you are; url: af
+
 spec: webidl; urlPrefix: https://heycam.github.io/webidl
     type: dfn;
         text: get a copy of the bytes held by the buffer source; url: dfn-get-buffer-source-reference
 
+spec: UTR29
+    urlPrefix: https://unicode.org/reports/tr29/
+        type: dfn; for:/; url: Grapheme_Cluster_Boundaries; text: grapheme cluster
+
 
@@ -212,38 +242,16 @@ spec:html; type:dfn; for:environment settings object; text:global object spec:infra; type:dfn; for:/; text:set spec:infra; type:dfn; text:list spec:infra; type:dfn; for:struct; text:item +spec:infra; type:dfn; for:map-exists; text:exists spec:url; type:dfn; text:domain spec:url; type:dfn; for:url; text:host spec:url; type:dfn; text:valid domain; +spec:webidl; type:dfn; text:DOMString spec:webidl; type:interface; text:Promise -
-{
-    "IANA-COSE-ALGS-REG": {
-        "href": "https://www.iana.org/assignments/cose/cose.xhtml#algorithms",
-        "title": "IANA CBOR Object Signing and Encryption (COSE) Algorithms Registry",
-        "publisher": "IANA"
-    },
-
-    "Feature-Policy": {
-        "href": "https://wicg.github.io/feature-policy/",
-        "title": "Feature Policy",
-        "publisher": "WICG: Web Incubator Community Group",
-        "status": "Draft Community Group Report"
-    },
-
-    "WebAuthnAPIGuide": {
-        "href": "https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API",
-        "title": "Web Authentication API Guide",
-        "publisher": "MDN: Mozilla Developer Network",
-        "status": "Experimental"
-    }
-}
-
- -# Introduction # {#intro} +# Introduction # {#sctn-intro} [INFORMATIVE] @@ -275,45 +283,45 @@ Authenticators being implemented on device are called [=platform authenticators= Authenticators being implemented off device ([=roaming authenticators=]) can be accessed over a transport such as Universal Serial Bus (USB), Bluetooth Low Energy (BLE), or Near Field Communications (NFC). -## Specification Roadmap ## {#spec-roadmap} +## Specification Roadmap ## {#sctn-spec-roadmap} While many W3C specifications are directed primarily to user agent developers and also to web application developers (i.e., "Web authors"), the nature of Web Authentication requires that this specification be correctly used by multiple audiences, as described below. -All audiences ought to begin with [[#use-cases]], [[#sample-scenarios]], and [[#terminology]], and should also +All audiences ought to begin with [[#sctn-use-cases]], [[#sctn-sample-scenarios]], and [[#sctn-terminology]], and should also refer to [[WebAuthnAPIGuide]] for an overall tutorial.

- [=[RP]=] web application developers, expecially those responsible for [=[RP]=] [=web application=] login flows, account recovery flows, user account database content, etc. - Web framework developers - - The above two audiences should in particular refer to [[#rp-operations]]. - The introduction to [[#api]] may be helpful, though readers should realize that the [[#api]] section is targeted specifically + - The above two audiences should in particular refer to [[#sctn-rp-operations]]. + The introduction to [[#sctn-api]] may be helpful, though readers should realize that the [[#sctn-api]] section is targeted specifically at user agent developers, not web application developers. Additionally, if they intend to verify [=authenticator=] [=attestations=], then - [[#sctn-attestation]] and [[#defined-attestation-formats]] will also be relevant. - [[#extensions]], and [[#sctn-defined-extensions]] will be of interest if they wish to make use of extensions. + [[#sctn-attestation]] and [[#sctn-defined-attestation-formats]] will also be relevant. + [[#sctn-extensions]], and [[#sctn-defined-extensions]] will be of interest if they wish to make use of extensions.

- User agent developers - OS platform developers, responsible for OS platform API design and implementation in regards to platform-specific [=authenticator=] APIs, platform [=WebAuthn Client=] instantiation, etc. - - The above two audiences should read [[#api]] very carefully, along with [[#extensions]] if they intend to support extensions. + - The above two audiences should read [[#sctn-api]] very carefully, along with [[#sctn-extensions]] if they intend to support extensions.

- [=Authenticator=] developers. These readers will want to pay particular attention to [[#sctn-authenticator-model]], - [[#defined-attestation-formats]], [[#extensions]], and [[#sctn-defined-extensions]]. + [[#sctn-defined-attestation-formats]], [[#sctn-extensions]], and [[#sctn-defined-extensions]].

- Note: Along with the [[#api|Web Authentication API]] itself, this specification defines a + Note: Along with the [[#sctn-api|Web Authentication API]] itself, this specification defines a request-response cryptographic protocol between a [=[WRP]=] server and an [=authenticator=], where the [=[RP]=]'s request consists of a - [[#cryptographic-challenges|challenge]] and other + [[#sctn-cryptographic-challenges|challenge]] and other input data supplied by the [=[RP]=] and sent to the [=authenticator=]. The request is conveyed via the - combination of HTTPS, the [=[RP]=] [=web application=], the [[#api|WebAuthn API]], and the platform-specific communications channel + combination of HTTPS, the [=[RP]=] [=web application=], the [[#sctn-api|WebAuthn API]], and the platform-specific communications channel between the user agent and the [=authenticator=]. The [=authenticator=] replies with a digitally signed [=authenticator data=] message and other output data, which is conveyed back to the [=[RP]=] server via the same path in reverse. Protocol details vary according to whether an [=authentication=] or @@ -322,15 +330,15 @@ refer to [[WebAuthnAPIGuide]] for an overall tutorial. It is important for Web Authentication deployments' end-to-end security that the role of each component—the [=[RP]=] server, the [=client=], and the [=authenticator=]— - as well as [[#security-considerations]] and [[#sctn-privacy-considerations]], are understood by all audiences. + as well as [[#sctn-security-considerations]] and [[#sctn-privacy-considerations]], are understood by all audiences.
-## Use Cases ## {#use-cases} +## Use Cases ## {#sctn-use-cases} The below use case scenarios illustrate use of two very different types of [=authenticators=], as well as outline further -scenarios. Additional scenarios, including sample code, are given later in [[#sample-scenarios]]. +scenarios. Additional scenarios, including sample code, are given later in [[#sctn-sample-scenarios]]. -### Registration ### {#usecase-registration} +### Registration ### {#sctn-usecase-registration} - On a phone: * User navigates to example.com in a browser and signs in to an existing account using whatever method they have been using @@ -342,7 +350,7 @@ scenarios. Additional scenarios, including sample code, are given later in [[#sa * Website shows message, "Registration complete." -### Authentication ### {#usecase-authentication} +### Authentication ### {#sctn-usecase-authentication} - On a laptop or desktop: * User pairs their phone with the laptop or desktop via Bluetooth. @@ -359,7 +367,7 @@ scenarios. Additional scenarios, including sample code, are given later in [[#sa * Web page shows that the selected user is signed in, and navigates to the signed-in page. -### New Device Registration ### {#usecase-new-device-registration} +### New Device Registration ### {#sctn-usecase-new-device-registration} This use case scenario illustrates how a [=[RP]=] can leverage a combination of a [=roaming authenticator=] (e.g., a USB security key fob) and a [=platform authenticator=] (e.g., a built-in fingerprint sensor) such that the user has: @@ -399,7 +407,7 @@ Note: This approach of registering multiple [=authenticators=] for an account is * Website shows that the user is signed in, and navigates to the signed-in page. -### Other Use Cases and Configurations ### {#other-configurations} +### Other Use Cases and Configurations ### {#sctn-other-configurations} A variety of additional use cases and configurations are also possible, including (but not limited to): @@ -412,47 +420,345 @@ A variety of additional use cases and configurations are also possible, includin - A [=[RP]=] prompts the user for their [=authorization gesture=] in order to authorize a single transaction, such as a payment or other financial transaction. -## Platform-Specific Implementation Guidance ## {#platform-impl-guidance} + + + +## Sample API Usage Scenarios ## {#sctn-sample-scenarios} + +[INFORMATIVE] + +In this section, we walk through some events in the lifecycle of a [=public key credential=], along with the corresponding +sample code for using this API. Note that this is an example flow and does not limit the scope of how the API can be used. + +As was the case in earlier sections, this flow focuses on a use case involving a [=first-factor roaming authenticator=] +with its own display. One example of such an authenticator would be a smart phone. Other authenticator types are also supported +by this API, subject to implementation by the [=client platform=]. For instance, this flow also works without modification for the case of +an authenticator that is embedded in the [=client device=]. The flow also works for the case of an authenticator without +its own display (similar to a smart card) subject to specific implementation considerations. Specifically, the [=client platform=] +needs to display any prompts that would otherwise be shown by the authenticator, and the authenticator needs to allow the [=client +platform=] to enumerate all the authenticator's credentials so that the client can have information to show appropriate prompts. + + +### Registration ### {#sctn-sample-registration} + +This is the first-time flow, in which a new credential is created and registered with the server. +In this flow, the [=[WRP]=] does not have a preference for [=platform authenticator=] or [=roaming authenticators=]. + +1. The user visits example.com, which serves up a script. At this point, the user may already be logged in using a legacy + username and password, or additional authenticator, or other means acceptable to the [=[RP]=]. + Or the user may be in the process of creating a new account. + +1. The [=[RP]=] script runs the code snippet below. + +1. The [=client platform=] searches for and locates the authenticator. + +1. The [=client=] connects to the authenticator, performing any pairing actions if necessary. + +1. The authenticator shows appropriate UI for the user to provide a biometric or other authorization gesture. + +1. The authenticator returns a response to the [=client=], which in turn returns a response to the [=[RP]=] script. If + the user declined to select an authenticator or provide authorization, an appropriate error is returned. + +1. If a new credential was created, + - The [=[RP]=] script sends the newly generated [=credential public key=] to the server, along with additional information + such as attestation regarding the provenance and characteristics of the authenticator. + - The server stores the [=credential public key=] in its database and associates it with the user as well as with the + characteristics of authentication indicated by attestation, also storing a friendly name for later use. + - The script may store data such as the [=credential ID=] in local storage, to improve future UX by narrowing the choice of + credential for the user. + +The sample code for generating and registering a new key follows: + +
+    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
+
+    var publicKey = {
+      // The challenge is produced by the server; see the Security Considerations
+      challenge: new Uint8Array([21,31,105 /* 29 more random bytes generated by the server */]),
+
+      // Relying Party:
+      rp: {
+        name: "ACME Corporation"
+      },
+
+      // User:
+      user: {
+        id: Uint8Array.from(window.atob("MIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGTMII="), c=>c.charCodeAt(0)),
+        name: "alex.p.mueller@example.com",
+        displayName: "Alex P. Müller",
+        icon: "https://pics.example.com/00/p/aBjjjpqPb.png"
+      },
+
+      // This Relying Party will accept either an ES256 or RS256 credential, but
+      // prefers an ES256 credential.
+      pubKeyCredParams: [
+        {
+          type: "public-key",
+          alg: -7 // "ES256" as registered in the IANA COSE Algorithms registry
+        },
+        {
+          type: "public-key",
+          alg: -257 // Value registered by this specification for "RS256"
+        }
+      ],
+
+      timeout: 60000,  // 1 minute
+      excludeCredentials: [], // No exclude list of PKCredDescriptors
+      extensions: {"loc": true}  // Include location information
+                                               // in attestation
+    };
+
+    // Note: The following call will cause the authenticator to display UI.
+    navigator.credentials.create({ publicKey })
+      .then(function (newCredentialInfo) {
+        // Send new credential info to server for verification and registration.
+      }).catch(function (err) {
+        // No acceptable authenticator or user refused consent. Handle appropriately.
+      });
+
+ +### Registration Specifically with User-Verifying Platform Authenticator ### {#sctn-sample-registration-with-platform-authenticator} + +This is an example flow for when the [=[WRP]=] is specifically interested in creating a [=public key credential=] with +a [=user-verifying platform authenticator=]. + +1. The user visits example.com and clicks on the login button, which redirects the user to login.example.com. + +1. The user enters a username and password to log in. After successful login, the user is redirected back to example.com. + +1. The [=[RP]=] script runs the code snippet below. + + 1. The user agent checks if a [=user-verifying platform authenticator=] is available. If not, terminate this flow. + + 1. The [=[RP]=] asks the user if they want to create a credential with it. If not, terminate this flow. + + 1. The user agent and/or operating system shows appropriate UI and guides the user in creating a credential + using one of the available platform authenticators. + + 1. Upon successful credential creation, the [=[RP]=] script conveys the new credential to the server. + +
+    if (!window.PublicKeyCredential) { /* Client not capable of the API. Handle error. */ }
+
+    PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
+        .then(function (uvpaaAvailable) {
+            // If there is a user-verifying platform authenticator
+            if (uvpaaAvailable) {
+                // Render some RP-specific UI and get a Promise for a Boolean value
+                return askIfUserWantsToCreateCredential();
+            }
+        }).then(function (userSaidYes) {
+            // If there is a user-verifying platform authenticator
+            // AND the user wants to create a credential
+            if (userSaidYes) {
+                var publicKeyOptions = { /* Public key credential creation options. */};
+                return navigator.credentials.create({ "publicKey": publicKeyOptions });
+            }
+        }).then(function (newCredentialInfo) {
+            if (newCredentialInfo) {
+                // Send new credential info to server for verification and registration.
+            }
+        }).catch(function (err) {
+            // Something went wrong. Handle appropriately.
+        });
+
+ +### Authentication ### {#sctn-sample-authentication} + +This is the flow when a user with an already registered credential visits a website and wants to authenticate using the +credential. + +1. The user visits example.com, which serves up a script. + +1. The script asks the [=client=] for an Authentication Assertion, providing as much information as possible to narrow + the choice of acceptable credentials for the user. This can be obtained from the data that was stored locally after + registration, or by other means such as prompting the user for a username. + +1. The [=[RP]=] script runs one of the code snippets below. + +1. The [=client platform=] searches for and locates the authenticator. + +1. The [=client=] connects to the authenticator, performing any pairing actions if necessary. + +1. The authenticator presents the user with a notification that their attention is needed. On opening the + notification, the user is shown a friendly selection menu of acceptable credentials using the account information provided + when creating the credentials, along with some information on the [=origin=] that is requesting these keys. + +1. The authenticator obtains a biometric or other authorization gesture from the user. + +1. The authenticator returns a response to the [=client=], which in turn returns a response to the [=[RP]=] script. + If the user declined to select a credential or provide an authorization, an appropriate error is returned. + +1. If an assertion was successfully generated and returned, + - The script sends the assertion to the server. + - The server examines the assertion, extracts the [=credential ID=], looks up the registered + credential public key in its database, and verifies the assertion's authentication signature. + If valid, it looks up the identity associated with the assertion's [=credential ID=]; that + identity is now authenticated. If the [=credential ID=] is not recognized by the server (e.g., + it has been deregistered due to inactivity) then the authentication has failed; each [=[RP]=] + will handle this in its own way. + - The server now does whatever it would otherwise do upon successful authentication -- return a success page, set + authentication cookies, etc. + +If the [=[RP]=] script does not have any hints available (e.g., from locally stored data) to help it narrow the list of +credentials, then the sample code for performing such an authentication might look like this: + +
+    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
+
+    // credentialId is generated by the authenticator and is an opaque random byte array
+    var credentialId = new Uint8Array([183, 148, 245 /* more random bytes previously generated by the authenticator */]);
+    var options = {
+      // The challenge is produced by the server; see the Security Considerations
+      challenge: new Uint8Array([4,101,15 /* 29 more random bytes generated by the server */]),
+      timeout: 60000,  // 1 minute
+      allowCredentials: [{ type: "public-key", id: credentialId }]
+    };
+
+    navigator.credentials.get({ "publicKey": options })
+        .then(function (assertion) {
+        // Send assertion to server for verification
+    }).catch(function (err) {
+        // No acceptable credential or user refused consent. Handle appropriately.
+    });
+
+ +On the other hand, if the [=[RP]=] script has some hints to help it narrow the list of credentials, then the sample code for +performing such an authentication might look like the following. Note that this sample also demonstrates how to use the +extension for transaction authorization. + +
+    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
+
+    var encoder = new TextEncoder();
+    var acceptableCredential1 = {
+        type: "public-key",
+        id: encoder.encode("BA44712732CE")
+    };
+    var acceptableCredential2 = {
+        type: "public-key",
+        id: encoder.encode("BG35122345NF")
+    };
+
+    var options = {
+      // The challenge is produced by the server; see the Security Considerations
+      challenge: new Uint8Array([8,18,33 /* 29 more random bytes generated by the server */]),
+      timeout: 60000,  // 1 minute
+      allowCredentials: [acceptableCredential1, acceptableCredential2],
+      extensions: { 'txAuthSimple':
+         "Wave your hands in the air like you just don't care" }
+    };
+
+    navigator.credentials.get({ "publicKey": options })
+        .then(function (assertion) {
+        // Send assertion to server for verification
+    }).catch(function (err) {
+        // No acceptable credential or user refused consent. Handle appropriately.
+    });
+
+ +### Aborting Authentication Operations ### {#sctn-sample-aborting} + +The below example shows how a developer may use the AbortSignal parameter to abort a +credential registration operation. A similar procedure applies to an authentication operation. + +
+    const authAbortController = new AbortController();
+    const authAbortSignal = authAbortController.signal;
+
+    authAbortSignal.onabort = function () {
+        // Once the page knows the abort started, inform user it is attempting to abort.
+    }
+
+    var options = {
+        // A list of options.
+    }
+
+    navigator.credentials.create({
+        publicKey: options,
+        signal: authAbortSignal})
+        .then(function (attestation) {
+            // Register the user.
+        }).catch(function (error) {
+            if (error == "AbortError") {
+                // Inform user the credential hasn't been created.
+                // Let the server know a key hasn't been created.
+            }
+        });
+
+    // Assume widget shows up whenever authentication occurs.
+    if (widget == "disappear") {
+        authAbortController.abort();
+    }
+
+ + +### Decommissioning ### {#sctn-sample-decommissioning} + +The following are possible situations in which decommissioning a credential might be desired. Note that all of these are +handled on the server side and do not need support from the API specified here. + +- Possibility #1 -- user reports the credential as lost. + * User goes to server.example.net, authenticates and follows a link to report a lost/stolen [=authenticator=]. + * Server returns a page showing the list of registered credentials with friendly names as configured during registration. + * User selects a credential and the server deletes it from its database. + * In the future, the [=[RP]=] script does not specify this credential in any list of acceptable credentials, and assertions + signed by this credential are rejected. + +- Possibility #2 -- server deregisters the credential due to inactivity. + * Server deletes credential from its database during maintenance activity. + * In the future, the [=[RP]=] script does not specify this credential in any list of acceptable credentials, and assertions + signed by this credential are rejected. + +- Possibility #3 -- user deletes the credential from the [=authenticator=]. + * User employs a [=authenticator=]-specific method (e.g., device settings UI) to delete a credential from their [=authenticator=]. + * From this point on, this credential will not appear in any selection prompts, and no assertions can be generated with it. + * Sometime later, the server deregisters this credential due to inactivity. + + +## Platform-Specific Implementation Guidance ## {#sctn-platform-impl-guidance} This specification defines how to use Web Authentication in the general case. When using Web Authentication in connection with specific platform support (e.g. apps), it is recommended to see platform-specific documentation and guides for additional guidance and limitations. -# Conformance # {#conformance} + + +# Conformance # {#sctn-conformance} This specification defines three conformance classes. Each of these classes is specified so that conforming members of the class are secure against non-conforming or hostile members of the other classes. -## User Agents ## {#conforming-user-agents} +## User Agents ## {#sctn-conforming-user-agents} -A User Agent MUST behave as described by [[#api]] in order to be considered conformant. [=Conforming User Agents=] MAY implement +A User Agent MUST behave as described by [[#sctn-api]] in order to be considered conformant. [=Conforming User Agents=] MAY implement algorithms given in this specification in any way desired, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms. A conforming User Agent MUST also be a conforming implementation of the IDL fragments of this specification, as described in the -“Web IDL” specification. [[!WebIDL-1]] +“Web IDL” specification. [[!WebIDL]] -## Authenticators ## {#conforming-authenticators} +## Authenticators ## {#sctn-conforming-authenticators} A [=[WAA]=] MUST provide the operations defined by [[#sctn-authenticator-model]], and those operations MUST behave as described there. This is a set of functional and security requirements for an authenticator to be usable by a [=Conforming User Agent=]. -As described in [[#use-cases]], an authenticator may be implemented in the operating system underlying the User Agent, or in +As described in [[#sctn-use-cases]], an authenticator may be implemented in the operating system underlying the User Agent, or in external hardware, or a combination of both. -### Backwards Compatibility with FIDO U2F ### {#conforming-authenticators-u2f} +### Backwards Compatibility with FIDO U2F ### {#sctn-conforming-authenticators-u2f} -[=Authenticators=] that only support the [[#fido-u2f-attestation]] have no mechanism to store a +[=Authenticators=] that only support the [[#sctn-fido-u2f-attestation]] have no mechanism to store a [=user handle=], so the returned {{AuthenticatorAssertionResponse/userHandle}} will always be null. -## [WRPS] ## {#conforming-relying-parties} +## [WRPS] ## {#sctn-conforming-relying-parties} -A [=[WRP]=] MUST behave as described in [[#rp-operations]] to obtain all the security benefits offered by this specification. See +A [=[WRP]=] MUST behave as described in [[#sctn-rp-operations]] to obtain all the security benefits offered by this specification. See [[#sctn-rp-benefits]] for further discussion of this. -## All Conformance Classes ## {#conforming-all-classes} +## All Conformance Classes ## {#sctn-conforming-all-classes} All [=CBOR=] encoding performed by the members of the above conformance classes MUST be done using the [=CTAP2 canonical CBOR encoding form=]. @@ -460,7 +766,7 @@ All decoders of the above conformance classes SHOULD reject CBOR that is not val in the [=CTAP2 canonical CBOR encoding form=] and SHOULD reject messages with duplicate map keys. -# Dependencies # {#dependencies} +# Dependencies # {#sctn-dependencies} This specification relies on several other underlying specifications, listed below and in [[#index-defined-elsewhere]]. @@ -491,14 +797,14 @@ below and in [[#index-defined-elsewhere]]. :: [=%ArrayBuffer%=] is defined in [[!ECMAScript]]. : HTML -:: The concepts of [=relevant settings object=], [=origin=], - [=opaque origin=], and [=is a registrable domain suffix of or is equal to=] are defined in [[!HTML52]]. +:: The concepts of [=browsing context=], [=origin=], [=opaque origin=], [=tuple origin=], [=relevant settings object=], + and [=is a registrable domain suffix of or is equal to=] are defined in [[!HTML]]. : URL :: The concept of [=same site=] is defined in [[!URL]]. : Web IDL -:: Many of the interface definitions and all of the IDL in this specification depend on [[!WebIDL-1]]. This updated version of +:: Many of the interface definitions and all of the IDL in this specification depend on [[!WebIDL]]. This updated version of the Web IDL standard adds support for {{Promise}}s, which are now the preferred mechanism for asynchronous interaction in all new web APIs. @@ -511,7 +817,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S "OPTIONAL" in this document are to be interpreted as described in [[!RFC2119]]. -# Terminology # {#terminology} +# Terminology # {#sctn-terminology} : Assertion :: See [=Authentication Assertion=]. @@ -544,20 +850,18 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S :: The cryptographically signed {{AuthenticatorAssertionResponse}} object returned by an [=authenticator=] as the result of an [=authenticatorGetAssertion=] operation. - This corresponds to the [[CREDENTIAL-MANAGEMENT-1]] specification's single-use credentials. : Authenticator : [WAA] -:: A cryptographic entity used by a [=[WAC]=] to (i) generate a [=public key credential=] and register it with a [=[RP]=], - and (ii) [=authentication|authenticate=] by potentially [=user verification|verifying the user=], and then - cryptographically signing and returning, in the form of an [=Authentication Assertion=], - a challenge and other data presented by a [=[WRP]=] (in concert with the [=[WAC]=]). +:: A cryptographic entity, existing in hardware or software, that can [=registration|register=] a user with a given [=[RP]=] + and later [=Authentication Assertion|assert possession=] of the registered [=public key credential=], and optionally + [=user verification|verify the user=], when requested by the [=[RP]=]. [=Authenticators=] can report information + regarding their [=authenticator types|type=] and security characteristics via [=attestation=] during [=registration=]. - A [=[WAA]=] could be, for example, a dedicated USB or wireless device separate from the [=client device=], - a dedicated hardware subsystem integrated into the [=client device=], - or a software component of the [=client=]. - [=Authenticators=] can report their type and security characteristics via [=attestation=]. + A [=[WAA]=] could be a [=roaming authenticator=], a dedicated hardware subsystem integrated into the [=client device=], + or a software component of the [=client=] or [=client device=]. : Authorization Gesture :: An [=authorization gesture=] is a physical interaction performed by a user with an authenticator as part of a [=ceremony=], @@ -583,6 +887,24 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S [=Registration=] and [=Authentication=] are ceremonies, and an [=authorization gesture=] is often a component of those [=ceremonies=]. +: Client +: [WAC] +:: Also referred to herein as simply a [=client=]. See also [=Conforming User Agent=]. A [=[WAC]=] is an intermediary entity typically implemented in the user agent (in whole, or in part). Conceptually, it underlies the [=Web Authentication API=] and embodies the implementation of the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} [=internal methods=]. It is responsible for both marshalling the inputs for the underlying [=authenticator operations=], and for returning the results of the latter operations to the [=Web Authentication API=]'s callers. + + The [=[WAC]=] runs on, and is distinct from, a [=[WAC] Device=]. + +: Client Device +: [WAC] Device +:: The hardware device on which the [=[WAC]=] runs, for example a smartphone, a laptop computer or a desktop computer, and the + operating system running on that hardware. + + The distinctions between a [=[WAC] device=] and a [=client=] are: + * a single [=client device=] MAY support running multiple [=clients=], i.e., browser implementations, + which all have access to the same [=authenticators=] available on that [=client device=], and + * [=platform authenticators=] are bound to a [=client device=] rather than a [=[WAC]=]. + + A [=client device=] and a [=client=] together constitute a [=client platform=]. + : Client Platform :: A [=client device=] and a [=client=] together make up a [=client platform=]. A single hardware device MAY be part of multiple distinct [=client platforms=] at different times by running different operating systems and/or [=clients=]. @@ -591,16 +913,27 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S :: This refers in general to the combination of the user's [=client platform=], [=authenticators=], and everything gluing it all together. -: Resident Credential : Client-side-resident Public Key Credential Source -:: A [=Client-side-resident Public Key Credential Source=], or [=Resident Credential=] for short, is a [=public key credential - source=] whose [=credential private key=] is stored in the [=authenticator=], [=client=] or [=client device=]. Such - [=client-side=] storage requires a [=resident credential capable=] [=authenticator=] and has the property that the [=authenticator=] - is able to select the [=credential private key=] given - only an [=RP ID=], possibly with user assistance (e.g., by providing the user a pick list of [=public key credential|credentials=] [=scoped=] to the [=RP ID=]). - By definition, the [=credential private key=] is always exclusively controlled by the [=authenticator=]. In the case of a - [=resident credential=], the [=authenticator=] might offload storage of wrapped key material to the - [=client device=], but the [=client device=] is not expected to offload the key storage to remote entities (e.g., [=[WRP]=] Server). +: Resident Credential +:: A [=Client-side-resident Public Key Credential Source=], or [=Resident Credential=] for short, + is a [=public key credential source=] that is discoverable and usable in [=authentication ceremonies=] + without providing [=credential ID=]s, + i.e., calling {{CredentialsContainer/get()|navigator.credentials.get()}} + with an [=list/is empty|empty=] {{PublicKeyCredentialRequestOptions/allowCredentials}} argument. + + As a consequence, a [=resident credential capable=] [=authenticator=] can generate an [=assertion signature=] + for a [=resident credential=] given only an [=RP ID=], + which in turn means that the [=public key credential source=] + is stored in the [=authenticator=] or [=client platform=]. + This is in contrast to a [=server-side-resident public key credential source=], + which requires that the [=authenticator=] is given both the [=RP ID=] and the [=credential ID=] + but does not require [=client-side=] storage of the [=public key credential source=]. + + See also: [=client-side credential storage modality=]. + + Note: [=Resident credentials=] are also usable in [=authentication ceremonies=] where [=credential ID=]s are given, + i.e., when calling {{CredentialsContainer/get()|navigator.credentials.get()}} + with a non-[=list/is empty|empty=] {{PublicKeyCredentialRequestOptions/allowCredentials}} argument. : Conforming User Agent :: A user agent implementing, in cooperation with the underlying [=client device=], the [=Web Authentication API=] and algorithms @@ -619,17 +952,31 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S [=[RPS]=] do not need to distinguish these two [=Credential ID=] forms. +: Credential Key Pair +: Credential Private Key : Credential Public Key : User Public Key -:: The public key portion of a [=[RP]=]-specific credential key pair, generated by an [=authenticator=] and - returned to a [=[RP]=] at [=registration=] time (see also [=public key credential=]). The private key portion of the - [=credential key pair=] is known as the credential private key. Note that in the case of [=self +:: 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=]. + + A [=credential public key=] is the public key portion of a [=credential key pair=]. + The [=credential public key=] is returned to the [=[RP]=] during a [=registration ceremony=]. + + A [=credential private key=] is the private key portion of a [=credential key pair=]. + The [=credential private key=] is bound to a particular [=authenticator=] - its [=managing authenticator=] - + and is expected to never be exposed to any other party, not even to the owner of the [=authenticator=]. + + Note that in the case of [=self attestation=], the [=credential key pair=] is also used as the [=attestation key pair=], see [=self attestation=] for details. Note: The [=credential public key=] is referred to as the [=user public key=] in FIDO UAF [[UAFProtocol]], and in FIDO U2F [[FIDO-U2F-Message-Formats]] and some parts of this specification that relate to it. +: Credential Properties +:: A [=credential property=] is some characteristic property of a [=public key credential source=], such as whether it is a + [=resident credential=] or a [=non-resident credential=]. + : Human Palatability :: An identifier that is [=human palatability|human-palatable=] is intended to be rememberable and reproducible by typical human users, in contrast to identifiers that are, for example, randomly generated sequences of bits [[EduPersonObjectClassSpec]]. @@ -717,8 +1064,8 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S By default, the [=RP ID=] for a WebAuthn operation is set to the caller's [=environment settings object/origin=]'s [=effective domain=]. This default MAY be overridden by the caller, as long as the caller-specified [=RP ID=] value [=is a registrable domain suffix of or is equal - to=] the caller's [=environment settings object/origin=]'s [=effective domain=]. See also [[#createCredential]] and - [[#getAssertion]]. + to=] the caller's [=environment settings object/origin=]'s [=effective domain=]. See also [[#sctn-createCredential]] and + [[#sctn-getAssertion]].
Note: An [=RP ID=] is based on a [=host=]'s [=domain=] name. It does not itself include a [=scheme=] or [=port=], as an [=origin=] does. The [=RP ID=] of a [=public key credential=] determines its scope. I.e., it determines the set of origins on which the public key credential may be exercised, as follows: @@ -734,6 +1081,21 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S [=document.domain=]'s setter provides.
+: Server-side-resident Public Key Credential Source +: Non-Resident Credential +:: A [=Server-side-resident Public Key Credential Source=], or [=Non-Resident Credential=] for short, + is a [=public key credential source=] that cannot be used in an [=authentication ceremony=] + without providing the [=authenticator=] with the [=credential ID=], e.g., + the credential is only usable when its [=credential ID=] is specified in the {{PublicKeyCredentialRequestOptions/allowCredentials}} argument. + + As a consequence, [=client-side=] storage of the [=public key credential source=] + is not required for a [=non-resident credential=]. + This is in contrast to a [=client-side-resident public key credential source=], + which does not require the [=credential ID=] to be provided + but instead requires [=client-side=] storage of the [=public key credential source=]. + + See also: [=server-side credential storage modality=]. + : Test of User Presence :: A [=test of user presence=] is a simple form of [=authorization gesture=] and technical process where a user interacts with an [=authenticator=] by (typically) simply touching it (other modalities may also exist), yielding a Boolean result. Note @@ -751,18 +1113,29 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S to a specific user account with the [=[RP]=]. Authenticators in turn [=credentials map|map=] [=RP ID=]s and user handle pairs to [=public key credential sources=]. - A user handle is an opaque [=byte sequence=] with a maximum size of 64 bytes. User handles are not meant to be displayed to users. - The user handle MUST NOT contain [PII] about the user, such as a username or e-mail address; see - [[#sctn-user-handle-privacy]] for details. + 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. : User Verification :: The technical process by which an [=authenticator=] locally authorizes the invocation of the [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] operations. [=User verification=] MAY be instigated through various [=authorization gesture=] modalities; for example, through a touch plus pin code, password entry, or - [=biometric recognition=] (e.g., presenting a fingerprint) [[ISOBiometricVocabulary]]. The intent is to be able to - distinguish individual users. Note that invocation of the [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] - operations implies use of key material managed by the authenticator. Note that for security, [=user verification=] and use - of [=credential private keys=] must occur within a single logical security boundary defining the [=authenticator=]. + [=biometric recognition=] (e.g., presenting a fingerprint) [[ISOBiometricVocabulary]]. The intent is to + distinguish individual users. + + Note: Distinguishing natural persons depends in significant part upon the [=client platform=]'s + and [=authenticator=]'s capabilities. + For example, some devices are intended to be used by a single individual, + yet they may allow multiple natural persons to enroll fingerprints + and thus access the same [=[RP]=] account(s) using that device. + See also [[#sctn-uvi-extension]]. + +
+ Note: Invocation of the [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] operations + implies use of key material managed by the authenticator. + + Also, for security, [=user verification=] and use of [=credential private keys=] + must all occur within the logical security boundary defining the [=authenticator=]. +
[=User verification=] procedures MAY implement [=rate limiting=] as a protection against brute force attacks. @@ -775,33 +1148,17 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S : UV :: Upon successful completion of a [=user verification=] process, the user is said to be "[=user verified|verified=]". -: Client -: [WAC] -:: Also referred to herein as simply a [=client=]. See also [=Conforming User Agent=]. A [=[WAC]=] is an intermediary entity typically implemented in the user agent (in whole, or in part). Conceptually, it underlies the [=Web Authentication API=] and embodies the implementation of the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} [=internal methods=]. It is responsible for both marshalling the inputs for the underlying [=authenticator operations=], and for returning the results of the latter operations to the [=Web Authentication API=]'s callers. - - The [=[WAC]=] runs on, and is distinct from, a [=[WAC] Device=]. - -: Client Device -: [WAC] Device -:: The hardware device on which the [=[WAC]=] runs, for example a smartphone, a laptop computer or a desktop computer, and the - operating system running on that hardware. - - The distinction between this and the [=client=] is that one [=client device=] MAY support running multiple [=clients=], i.e., browser - implementations, which all have access to the same [=authenticators=] available on that [=client device=]; and that [=platform - authenticators=] are bound to a [=[WAC] Device=] rather than a [=[WAC]=]. A [=client device=] and a [=client=] together make - up a [=client platform=]. - : [WRP] -:: The entity whose web application utilizes the [[#api|Web Authentication API]] to [=registration|register=] and +:: The entity whose web application utilizes the [[#sctn-api|Web Authentication API]] to [=registration|register=] and [=authentication|authenticate=] users. Note: While the term [=[RP]=] is also often used in other contexts (e.g., X.509 and OAuth), an entity acting as a [=[RP]=] in one - context is not necessarily a [=[RP]=] in other contexts. In this specification, the term [=[WRP]=] is often shortened + context is not necessarily a [=[RP]=] in other contexts. In this specification, the term [=[WRP]=] is often shortened to be just [=[RP]=], and explicitly refers to a [=[RP]=] in the WebAuthn context. Note that in any concrete instantiation a WebAuthn context may be embedded in a broader overall context, e.g., one based on OAuth. -# Web Authentication API # {#api} +# Web Authentication API # {#sctn-api} This section normatively specifies the API for creating and using [=public key credentials=]. The basic idea is that the credentials belong to the user and are [=managing authenticator|managed=] by a [=[WAA]=], with which the [=[WRP]=] interacts through the [=client platform=]. [=[RP]=] scripts can (with the [=user consent|user's consent=]) request the @@ -837,7 +1194,7 @@ scripts. The security properties of this API are provided by the client and the authenticator working together. The authenticator, which holds and [=managing authenticator|manages=] credentials, ensures that all operations are [=scoped=] to a particular [=origin=], and cannot be replayed against -a different [=origin=], by incorporating the [=origin=] in its responses. Specifically, as defined in [[#authenticator-ops]], +a different [=origin=], by incorporating the [=origin=] in its responses. Specifically, as defined in [[#sctn-authenticator-ops]], the full [=origin=] of the requester is included, and signed over, in the [=attestation object=] produced when a new credential is created as well as in all assertions produced by WebAuthn credentials. @@ -921,7 +1278,7 @@ implementation of {{PublicKeyCredential/[[Create]](origin, options, sameOriginWi {{Credential/[[Store]](credential, sameOriginWithAncestors)}}. -### `CredentialCreationOptions` Dictionary Extension ### {#credentialcreationoptions-extension} +### `CredentialCreationOptions` Dictionary Extension ### {#sctn-credentialcreationoptions-extension} To support registration via {{CredentialsContainer/create()|navigator.credentials.create()}}, this document extends the {{CredentialCreationOptions}} dictionary as follows: @@ -932,7 +1289,7 @@ the {{CredentialCreationOptions}} dictionary as follows: }; -### `CredentialRequestOptions` Dictionary Extension ### {#credentialrequestoptions-extension} +### `CredentialRequestOptions` Dictionary Extension ### {#sctn-credentialrequestoptions-extension} To support obtaining assertions via {{CredentialsContainer/get()|navigator.credentials.get()}}, this document extends the {{CredentialRequestOptions}} dictionary as follows: @@ -944,11 +1301,11 @@ To support obtaining assertions via {{CredentialsContainer/get()|navigator.crede -### Create a New Credential - PublicKeyCredential's `[[Create]](origin, options, sameOriginWithAncestors)` Method ### {#createCredential} +### Create a New Credential - PublicKeyCredential's `[[Create]](origin, options, sameOriginWithAncestors)` Method ### {#sctn-createCredential}
{{PublicKeyCredential}}'s [=interface object=]'s implementation of the \[[Create]](origin, -options, sameOriginWithAncestors) [=internal method=] [[CREDENTIAL-MANAGEMENT-1]] allows +options, sameOriginWithAncestors) [=internal method=] [[!CREDENTIAL-MANAGEMENT-1]] allows [=[WRP]=] scripts to call {{CredentialsContainer/create()|navigator.credentials.create()}} to request the creation of a new [=public key credential source=], [=bound credential|bound=] to an [=authenticator=]. This {{CredentialsContainer/create()|navigator.credentials.create()}} operation can be aborted by leveraging the {{AbortController}}; @@ -988,14 +1345,14 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. If sameOriginWithAncestors is [FALSE], return a "{{NotAllowedError}}" {{DOMException}}. Note: This "sameOriginWithAncestors" restriction aims to address the concern raised in the - [[CREDENTIAL-MANAGEMENT-1#security-origin-confusion|Origin Confusion]] section of [[CREDENTIAL-MANAGEMENT-1]], + [[CREDENTIAL-MANAGEMENT-1#security-origin-confusion|Origin Confusion]] section of [[!CREDENTIAL-MANAGEMENT-1]], while allowing [=[RP]=] script access to Web Authentication functionality, e.g., when running in a [=secure context=] framed document that is [=same-origin with its ancestors=]. - However, in the future, this specification (in conjunction with - [[CREDENTIAL-MANAGEMENT-1]]) may provide [=[RPS]=] with more fine-grained control--e.g., ranging + However, in the future, this specification (in conjunction with + [[!CREDENTIAL-MANAGEMENT-1]]) may provide [=[RPS]=] with more fine-grained control--e.g., ranging from allowing only top-level access to Web Authentication functionality, to allowing cross-origin embedded cases--by leveraging - [[Feature-Policy]] once the latter specification becomes stably implemented in user agents. + [[!Feature-Policy]] once the latter specification becomes stably implemented in user agents. 1. Let |options| be the value of |options|.{{CredentialCreationOptions/publicKey}}. @@ -1090,7 +1447,7 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o 1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|. -1. If the |options|.{{CredentialCreationOptions/signal}} is [=present=] and its +1. If the |options|.{{CredentialCreationOptions/signal}} is [=present=] and its [=AbortSignal/aborted flag=] is set to [TRUE], return a {{DOMException}} whose name is "{{AbortError}}" and terminate this algorithm. @@ -1129,13 +1486,55 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{authenticatorAttachment}} is [=present|present=] and its value is not equal to |authenticator|'s [=authenticator attachment modality=], [=iteration/continue=]. - 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}} is set to - [TRUE] and the |authenticator| is not capable of storing a [=client-side-resident public key credential source=], - [=iteration/continue=]. + + 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{residentKey}} + +
+ : is present and set to {{ResidentKeyRequirement/required}} + :: If the |authenticator| is not capable of storing a [=client-side-resident public key credential + source=], [=iteration/continue=]. + + : is present and set to {{ResidentKeyRequirement/preferred}} or {{ResidentKeyRequirement/discouraged}} + :: No effect. + + : is [=not present=] + :: if |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}} + is set to [TRUE] and the |authenticator| is not capable of storing a [=client-side-resident public + key credential source=], [=iteration/continue=]. +
+ 1. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}} is set to {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user verification=], [=iteration/continue=]. + 1. Let |requireResidentKey| be the effective resident key requirement for credential creation, a Boolean value, as follows: + + If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{residentKey}} + +
+ + : is present and set to {{ResidentKeyRequirement/required}} + :: Let |requireResidentKey| be [TRUE]. + + : is present and set to {{ResidentKeyRequirement/preferred}} + :: If the |authenticator| + +
+ : is capable of [=client-side credential storage modality=] + :: Let |requireResidentKey| be [TRUE]. + + : is not capable of [=client-side credential storage modality=], or if the [=client=] cannot determine authenticator capability, + :: Let |requireResidentKey| be [FALSE]. +
+ + : is present and set to {{ResidentKeyRequirement/discouraged}} + :: Let |requireResidentKey| be [FALSE]. + + : is [=not present=] + :: Let |requireResidentKey| be the value of |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}}. + +
+ 1. Let |userVerification| be the effective user verification requirement for credential creation, a Boolean value, as follows. If |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}} @@ -1168,15 +1567,22 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o mentioned in |C|.{{transports}}, the client MAY [=continue=]. 1. Otherwise, [=list/Append=] |C| to |excludeCredentialDescriptorList|. - - 1. Invoke the [=authenticatorMakeCredential=] operation on |authenticator| with - |clientDataHash|, - |options|.{{PublicKeyCredentialCreationOptions/rp}}, |options|.{{PublicKeyCredentialCreationOptions/user}}, - |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/requireResidentKey}}, - |userVerification|, - |credTypesAndPubKeyAlgs|, - |excludeCredentialDescriptorList|, - and |authenticatorExtensions| as parameters. + +
  • + + + Invoke the [=authenticatorMakeCredential=] operation on |authenticator| with + |clientDataHash|, + |options|.{{PublicKeyCredentialCreationOptions/rp}}, |options|.{{PublicKeyCredentialCreationOptions/user}}, + |requireResidentKey|, + |userVerification|, + |credTypesAndPubKeyAlgs|, + |excludeCredentialDescriptorList|, + and |authenticatorExtensions| as parameters. + +
  • 1. [=set/Append=] |authenticator| to |issuedRequests|. @@ -1206,7 +1612,7 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o :: [=set/Remove=] |authenticator| from |issuedRequests|. Note: This case does not imply [=user consent=] for the operation, so details about the error are hidden from the - [=[RP]=] in order to prevent leak of potentially identifying information. See [[#sec-make-credential-privacy]] for + [=[RP]=] in order to prevent leak of potentially identifying information. See [[#sctn-make-credential-privacy]] for details. : If any |authenticator| indicates success, @@ -1217,7 +1623,7 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o : attestationObjectResult :: whose value is the bytes returned from the successful [=authenticatorMakeCredential=] operation. - Note: this value is attObj, as defined in [[#generating-an-attestation-object]]. + Note: this value is attObj, as defined in [[#sctn-generating-an-attestation-object]]. : clientDataJSONResult :: whose value is the bytes of |clientDataJSON|. @@ -1231,6 +1637,7 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o [=client extension processing=] algorithm to create the [=client extension outputs=], for each [=client extension=] in {{AuthenticatorResponse/clientDataJSON}}.clientExtensions. + 1. Let |constructCredentialAlg| be an algorithm that takes a [=global object=] |global|, and whose steps are: @@ -1242,7 +1649,7 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o 1. If the [=AAGUID=] in the [=attested credential data=] is 16 zero bytes, |credentialCreationData|.[=attestationObjectResult=].fmt is "packed", and "x5c" & "ecdaaKeyId" are both absent from |credentialCreationData|.[=attestationObjectResult=], then [=self attestation=] is being used and no further action is needed. 1. Otherwise 1. Replace the [=AAGUID=] in the [=attested credential data=] with 16 zero bytes. - 1. Set the value of |credentialCreationData|.[=attestationObjectResult=].fmt to "none", and set the value of |credentialCreationData|.[=attestationObjectResult=].attStmt to be an empty [=CBOR=] map. (See [[#none-attestation]] and [[#generating-an-attestation-object]]). + 1. Set the value of |credentialCreationData|.[=attestationObjectResult=].fmt to "none", and set the value of |credentialCreationData|.[=attestationObjectResult=].attStmt to be an empty [=CBOR=] map. (See [[#sctn-none-attestation]] and [[#sctn-generating-an-attestation-object]]). : "indirect" :: The client MAY replace the [=AAGUID=] and [=attestation statement=] with a more privacy-friendly @@ -1273,7 +1680,7 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o :: |attestationObject| : {{AuthenticatorAttestationResponse/[[transports]]}} - :: A sequence of zero or more unique {{AuthenticatorTransport}} values, in lexicographical order, that the |authenticator| is believed to support. + :: A sequence of zero or more unique {{DOMString}}s, in lexicographical order, that the |authenticator| is believed to support. The values SHOULD be members of {{AuthenticatorTransport}}. If a user agent does not wish to divulge this information it MAY substitute an arbitrary sequence designed to preserve privacy. This sequence MUST still be valid, i.e. lexicographically sorted and free of duplicates. For example, it may use the empty sequence. Either way, in this case the user agent takes the risk that [=[RP]=] behavior may be suboptimal. @@ -1296,14 +1703,14 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o 1. Return a {{DOMException}} whose name is "{{NotAllowedError}}". In order to prevent information leak that could identify the user without [=user consent|consent=], this step MUST NOT be executed before |lifetimeTimer| has expired. See - [[#sec-make-credential-privacy]] for details. + [[#sctn-make-credential-privacy]] for details. 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.
    -### Use an Existing Credential to Make an Assertion - PublicKeyCredential's `[[Get]](options)` Method ### {#getAssertion} +### Use an Existing Credential to Make an Assertion - PublicKeyCredential's `[[Get]](options)` Method ### {#sctn-getAssertion} [=[WRPS]=] call navigator.credentials.get({publicKey:..., ...}) to discover and use an existing [=public key credential=], with the [=user consent|user's consent=]. [=[RP]=] script optionally specifies some criteria @@ -1311,10 +1718,10 @@ to indicate what [=credential sources=] are acceptable to it. The [=client platf matching the specified criteria, and guides the user to pick one that the script will be allowed to use. The user may choose to decline the entire interaction even if a [=credential source=] is present, for example to maintain privacy. If the user picks a [=credential source=], the user agent then uses -[[#op-get-assertion]] to sign a [=[RP]=]-provided challenge and other collected data into an assertion, which is used as a +[[#sctn-op-get-assertion]] to sign a [=[RP]=]-provided challenge and other collected data into an assertion, which is used as a [=credential=]. -The {{CredentialsContainer/get()}} implementation [[CREDENTIAL-MANAGEMENT-1]] calls +The {{CredentialsContainer/get()}} implementation [[!CREDENTIAL-MANAGEMENT-1]] calls PublicKeyCredential.{{PublicKeyCredential/[[CollectFromCredentialStore]]()}} to collect any [=credentials=] that should be available without [=user mediation=] (roughly, this specification's [=authorization gesture=]), and if it does not find exactly one of those, it then calls PublicKeyCredential.{{PublicKeyCredential/[[DiscoverFromExternalSource]]()}} to have @@ -1328,7 +1735,7 @@ This {{CredentialsContainer/get()|navigator.credentials.get()}} operation can be aborted by leveraging the {{AbortController}}; see [[dom#abortcontroller-api-integration]] for detailed instructions. -#### PublicKeyCredential's \[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) Method #### {#discover-from-external-source} +#### PublicKeyCredential's \[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) Method #### {#sctn-discover-from-external-source}
    @@ -1364,14 +1771,14 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. If sameOriginWithAncestors is [FALSE], return a "{{NotAllowedError}}" {{DOMException}}. Note: This "sameOriginWithAncestors" restriction aims to address the concern raised in the - [[CREDENTIAL-MANAGEMENT-1#security-origin-confusion|Origin Confusion]] section of [[CREDENTIAL-MANAGEMENT-1]], + [[CREDENTIAL-MANAGEMENT-1#security-origin-confusion|Origin Confusion]] section of [[!CREDENTIAL-MANAGEMENT-1]], while allowing [=[RP]=] script access to Web Authentication functionality, e.g., when running in a [=secure context=] framed document that is [=same-origin with its ancestors=]. - However, in the future, this specification (in conjunction with - [[CREDENTIAL-MANAGEMENT-1]]) may provide [=[RPS]=] with more fine-grained control--e.g., ranging + However, in the future, this specification (in conjunction with + [[!CREDENTIAL-MANAGEMENT-1]]) may provide [=[RPS]=] with more fine-grained control--e.g., ranging from allowing only top-level access to Web Authentication functionality, to allowing cross-origin embedded cases--by leveraging - [[Feature-Policy]] once the latter specification becomes stably implemented in user agents. + [[!Feature-Policy]] once the latter specification becomes stably implemented in user agents. 1. Let |options| be the value of |options|.{{CredentialRequestOptions/publicKey}}. @@ -1385,7 +1792,7 @@ When this method is invoked, the user agent MUST execute the following algorithm Note: The user agent should take cognitive guidelines into considerations regarding timeout for users with special needs. -1. Let |callerOrigin| be {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)/origin}}. If |callerOrigin| is +1. Let |callerOrigin| be {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)/origin}}. If |callerOrigin| is an [=opaque origin=], return a {{DOMException}} whose name is "{{NotAllowedError}}", and terminate this algorithm. 1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=]. @@ -1444,7 +1851,7 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|. -1. If the |options|.{{CredentialRequestOptions/signal}} is [=present=] and its +1. If the |options|.{{CredentialRequestOptions/signal}} is [=present=] and its [=AbortSignal/aborted flag=] is set to [TRUE], return a {{DOMException}} whose name is "{{AbortError}}" and terminate this algorithm. @@ -1536,7 +1943,7 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. If |allowCredentialDescriptorList| has exactly one value, set |savedCredentialIds|[|authenticator|] to |allowCredentialDescriptorList|[0].id's - value (see [here](#authenticatorGetAssertion-return-values) in [[#op-get-assertion]] for more information). + value (see [here](#authenticatorGetAssertion-return-values) in [[#sctn-op-get-assertion]] for more information). 1. [=list/For each=] credential descriptor |C| in |allowCredentialDescriptorList|, [=set/append=] each value, if any, of |C|.{{transports}} to |distinctTransports|. @@ -1598,7 +2005,7 @@ When this method is invoked, the user agent MUST execute the following algorithm :: If |savedCredentialIds|[|authenticator|] exists, set the value of [=credentialIdResult=] to be the bytes of |savedCredentialIds|[|authenticator|]. Otherwise, set the value of [=credentialIdResult=] to be the bytes of the [=credential ID=] returned from the successful - [=authenticatorGetAssertion=] operation, as defined in [[#op-get-assertion]]. + [=authenticatorGetAssertion=] operation, as defined in [[#sctn-op-get-assertion]]. : clientDataJSONResult :: whose value is the bytes of |clientDataJSON|. @@ -1664,14 +2071,14 @@ When this method is invoked, the user agent MUST execute the following algorithm 1. Return a {{DOMException}} whose name is "{{NotAllowedError}}". In order to prevent information leak that could identify the user without [=user consent|consent=], this step MUST NOT be executed before |lifetimeTimer| has expired. See - [[#sec-assertion-privacy]] for details. + [[#sctn-assertion-privacy]] for details. 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.
    -### Store an Existing Credential - PublicKeyCredential's `[[Store]](credential, sameOriginWithAncestors)` Method ### {#storeCredential} +### Store an Existing Credential - PublicKeyCredential's `[[Store]](credential, sameOriginWithAncestors)` Method ### {#sctn-storeCredential}
    @@ -1698,7 +2105,7 @@ When this method is invoked, the user agent MUST execute the following algorithm
    -### Preventing Silent Access to an Existing Credential - PublicKeyCredential's `[[preventSilentAccess]](credential, sameOriginWithAncestors)` Method ### {#preventSilentAccessCredential} +### Preventing Silent Access to an Existing Credential - PublicKeyCredential's `[[preventSilentAccess]](credential, sameOriginWithAncestors)` Method ### {#sctn-preventSilentAccessCredential}
    @@ -1710,7 +2117,7 @@ This [=internal method=] accepts no arguments.
    -### Availability of [=User-Verifying Platform Authenticator=] - PublicKeyCredential's `isUserVerifyingPlatformAuthenticatorAvailable()` Method ### {#isUserVerifyingPlatformAuthenticatorAvailable} +### Availability of [=User-Verifying Platform Authenticator=] - PublicKeyCredential's `isUserVerifyingPlatformAuthenticatorAvailable()` Method ### {#sctn-isUserVerifyingPlatformAuthenticatorAvailable}
    @@ -1728,6 +2135,8 @@ This method has no arguments and returns a Boolean value. }; +Note: Invoking this method from a [=browsing context=] where the [=Web Authentication API=] is "disabled" according to the [=allowed to use=] algorithm—i.e., by a [=feature policy=]—will result in the promise being rejected with a {{DOMException}} whose name is "{{NotAllowedError}}". +
    ## Authenticator Responses (interface AuthenticatorResponse) ## {#iface-authenticatorresponse} @@ -1758,7 +2167,7 @@ during registration. [SecureContext, Exposed=Window] interface AuthenticatorAttestationResponse : AuthenticatorResponse { [SameObject] readonly attribute ArrayBuffer attestationObject; - sequence getTransports(); + sequence getTransports(); };
    @@ -1775,14 +2184,14 @@ during registration. contents of the [=attestation statement=] are determined by the [=attestation statement format=] used by the [=authenticator=]. It also contains any additional information that the [=[RP]=]'s server requires to validate the [=attestation statement=], as well as to decode and validate the [=authenticator data=] along with the - [=JSON-serialized client data=]. For more details, see [[#sctn-attestation]], [[#generating-an-attestation-object]], + [=JSON-serialized client data=]. For more details, see [[#sctn-attestation]], [[#sctn-generating-an-attestation-object]], and [Figure 5](#fig-attStructs). : {{AuthenticatorAttestationResponse/getTransports()}} :: This operation returns the value of {{AuthenticatorAttestationResponse/[[transports]]}}. : \[[transports]] - :: This [=internal slot=] contains a sequence of zero or more unique {{AuthenticatorTransport}} values in lexicographical order. These values are the transports that the [=authenticator=] is believed to support, or an empty sequence if the information is unavailable. + :: This [=internal slot=] contains a sequence of zero or more unique {{DOMString}}s in lexicographical order. These values are the transports that the [=authenticator=] is believed to support, or an empty sequence if the information is unavailable. The values SHOULD be members of {{AuthenticatorTransport}} but [=[RPS]=] MUST accept unknown values.
    ### Web Authentication Assertion (interface AuthenticatorAssertionResponse) ### {#iface-authenticatorassertionresponse} @@ -1803,22 +2212,22 @@ optionally evidence of [=user consent=] to a specific transaction.
    : {{AuthenticatorResponse/clientDataJSON}} :: This attribute, inherited from {{AuthenticatorResponse}}, contains the [=JSON-serialized client data=] (see - [[#sec-client-data]]) passed to the authenticator by the client in order to generate this assertion. The + [[#dictionary-client-data]]) passed to the authenticator by the client in order to generate this assertion. The exact JSON serialization MUST be preserved, as the [=hash of the serialized client data=] has been computed over it. : authenticatorData - :: This attribute contains the [=authenticator data=] returned by the authenticator. See [[#sec-authenticator-data]]. + :: This attribute contains the [=authenticator data=] returned by the authenticator. See [[#sctn-authenticator-data]]. : signature - :: This attribute contains the raw signature returned from the authenticator. See [[#op-get-assertion]]. + :: This attribute contains the raw signature returned from the authenticator. See [[#sctn-op-get-assertion]]. : userHandle :: This attribute contains the [=user handle=] returned from the authenticator, or null if the authenticator did not return a - [=user handle=]. See [[#op-get-assertion]]. + [=user handle=]. See [[#sctn-op-get-assertion]].
    -## Parameters for Credential Generation (dictionary PublicKeyCredentialParameters) ## {#credential-params} +## Parameters for Credential Generation (dictionary PublicKeyCredentialParameters) ## {#dictionary-credential-params} dictionary PublicKeyCredentialParameters { @@ -1867,7 +2276,7 @@ optionally evidence of [=user consent=] to a specific transaction. Its value's {{PublicKeyCredentialRpEntity/id}} member specifies the [=RP ID=] the credential should be [=scoped=] to. If omitted, its value will be the {{CredentialsContainer}} object's [=relevant - settings object=]'s [=environment settings object/origin=]'s [=effective domain=]. See [[#sctn-rp-credential-params]] + settings object=]'s [=environment settings object/origin=]'s [=effective domain=]. See [[#dictionary-rp-credential-params]] for further details. : <dfn>user</dfn> @@ -1875,11 +2284,11 @@ optionally evidence of [=user consent=] to a specific transaction. Its value's {{PublicKeyCredentialEntity/name}}, {{PublicKeyCredentialUserEntity/displayName}} and {{PublicKeyCredentialUserEntity/id}} members are REQUIRED. See [[#dictionary-pkcredentialentity]] and - [[#sctn-user-credential-params]] for further details. + [[#dictionary-user-credential-params]] for further details. : <dfn>challenge</dfn> :: This member contains a challenge intended to be used for generating the newly created credential's [=attestation - object=]. See the [[#cryptographic-challenges]] security consideration. + object=]. See the [[#sctn-cryptographic-challenges]] security consideration. : <dfn>pubKeyCredParams</dfn> :: This member contains information about the desired properties of the credential to be created. The sequence is ordered @@ -1906,9 +2315,9 @@ optionally evidence of [=user consent=] to a specific transaction. : <dfn>extensions</dfn> :: This member contains additional parameters requesting additional processing by the client and authenticator. For example, the caller may request that only authenticators with certain capabilities be used to create the credential, or - that particular information be returned in the [=attestation object=]. Some extensions are defined in [[#extensions]]; + that particular information be returned in the [=attestation object=]. Some extensions are defined in [[#sctn-extensions]]; consult the IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]] for an up-to-date list - of registered WebAuthn Extensions. + of registered [=WebAuthn Extensions=]. </div> ### Public Key Entity Description (dictionary <dfn dictionary>PublicKeyCredentialEntity</dfn>) ### {#dictionary-pkcredentialentity} @@ -1958,7 +2367,7 @@ associated with or [=scoped=] to, respectively. [=Authenticators=] MUST accept and store a 64-byte minimum length for a {{PublicKeyCredentialEntity/name}} member's value. Authenticators MAY truncate a {{PublicKeyCredentialEntity/name}} member's value to a length equal to or greater - than 64 bytes. + than 64 bytes. See also [[#sctn-strings]]. : <dfn>icon</dfn> :: A [=URL serializer|serialized=] URL which resolves to an image associated with the entity. For example, this could be @@ -1969,7 +2378,7 @@ associated with or [=scoped=] to, respectively. </div> -### Relying Party Parameters for Credential Generation (dictionary <dfn dictionary>PublicKeyCredentialRpEntity</dfn>) ### {#sctn-rp-credential-params} +### Relying Party Parameters for Credential Generation (dictionary <dfn dictionary>PublicKeyCredentialRpEntity</dfn>) ### {#dictionary-rp-credential-params} The {{PublicKeyCredentialRpEntity}} dictionary is used to supply additional [=[RP]=] attributes when creating a new credential. @@ -1985,7 +2394,7 @@ The {{PublicKeyCredentialRpEntity}} dictionary is used to supply additional [=[R </div> -### User Account Parameters for Credential Generation (dictionary <dfn dictionary>PublicKeyCredentialUserEntity</dfn>) ### {#sctn-user-credential-params} +### User Account Parameters for Credential Generation (dictionary <dfn dictionary>PublicKeyCredentialUserEntity</dfn>) ### {#dictionary-user-credential-params} The {{PublicKeyCredentialUserEntity}} dictionary is used to supply additional user account attributes when creating a new credential. @@ -1999,10 +2408,17 @@ credential. <div dfn-type="dict-member" dfn-for="PublicKeyCredentialUserEntity"> : <dfn>id</dfn> - :: The [=user handle=] of the user account entity. To ensure secure operation, authentication and authorization + :: The [=user handle=] of the user account entity. + 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. + + To ensure secure operation, authentication and authorization decisions MUST be made on the basis of this {{PublicKeyCredentialUserEntity/id}} member, not the {{PublicKeyCredentialUserEntity/displayName}} nor {{PublicKeyCredentialEntity/name}} members. See Section 6.1 of [[!RFC8266]]. + The [=user handle=] MUST NOT contain [PII] about the user, such as a username or e-mail address; + see [[#sctn-user-handle-privacy]] for details. + : <dfn>displayName</dfn> :: A [=human palatability|human-palatable=] name for the user account, intended only for display. For example, "Alex P. Müller" or "田中 倫". The [=[RP]=] SHOULD let the user choose this, and SHOULD NOT restrict the choice more than necessary. @@ -2020,11 +2436,11 @@ credential. [=Authenticators=] MUST accept and store a 64-byte minimum length for a {{PublicKeyCredentialUserEntity/displayName}} member's value. Authenticators MAY truncate a {{PublicKeyCredentialUserEntity/displayName}} member's value to a length - equal to or greater than 64 bytes. + equal to or greater than 64 bytes. See also [[#sctn-strings]]. </div> -### Authenticator Selection Criteria (dictionary <dfn dictionary>AuthenticatorSelectionCriteria</dfn>) ### {#authenticatorSelection} +### Authenticator Selection Criteria (dictionary <dfn dictionary>AuthenticatorSelectionCriteria</dfn>) ### {#dictionary-authenticatorSelection} [=[WRPS]=] may use the {{AuthenticatorSelectionCriteria}} dictionary to specify their requirements regarding authenticator attributes. @@ -2033,6 +2449,7 @@ attributes. dictionary AuthenticatorSelectionCriteria { AuthenticatorAttachment authenticatorAttachment; boolean requireResidentKey = false; + ResidentKeyRequirement residentKey; UserVerificationRequirement userVerification = "preferred"; }; @@ -2040,12 +2457,22 @@ attributes.
    : authenticatorAttachment :: If this member is [=present|present=], eligible authenticators are filtered to only authenticators attached with the - specified [[#attachment]]. + specified [[#enum-attachment]]. : requireResidentKey - :: This member describes the [=[RP]=]'s requirements regarding [=resident credentials=]. - If the parameter is set to [TRUE], the authenticator MUST create a - [=client-side-resident public key credential source=] when creating a [=public key credential=]. + :: Note: This member is retained for backwards compatibility with WebAuthn Level 1 but is deprecated in favour of {{residentKey}}. + {{requireResidentKey}} is ignored if the caller supplies {{residentKey}} and the latter is understood by the [=client=]. + Otherwise, {{requireResidentKey}}'s value is used. Note that {{requireResidentKey}}'s value defaults to [FALSE]. + + If used in absence of {{residentKey}}, it describes the [=[RP]=]'s requirements regarding [=resident credentials=]. + If {{requireResidentKey}} is set to [TRUE], the authenticator MUST create a [=client-side-resident public key credential source=] + when creating a [=public key credential=]. + + : residentKey + :: Note: This member supersedes {{requireResidentKey}}. If both are present and the [=client=] understands {{residentKey}}, then + {{residentKey}} is used and {{requireResidentKey}} is ignored. + + See {{ResidentKeyRequirement}} for the description of {{residentKey}}'s values and semantics. : userVerification :: This member describes the [=[RP]=]'s requirements regarding [=user verification=] for the @@ -2054,7 +2481,12 @@ attributes.
    -### Authenticator Attachment Enumeration (enum AuthenticatorAttachment) ### {#attachment} +### Authenticator Attachment Enumeration (enum AuthenticatorAttachment) ### {#enum-attachment} + +This enumeration's values describe [=authenticators=]' [=authenticator attachment modality|attachment modalities=]. +[=[RPS]=] use this to express a preferred [=authenticator attachment modality=] +when calling {{CredentialsContainer/create()|navigator.credentials.create()}} +to [[#sctn-createCredential|create a credential]]. enum AuthenticatorAttachment { @@ -2063,21 +2495,6 @@ attributes. }; -This enumeration's values describe [=authenticators=]' [=authenticator attachment modality|attachment modalities=]. [=[RPS]=] use this for two purposes: - -- to express a preferred [=authenticator attachment modality=] when calling - {{CredentialsContainer/create()|navigator.credentials.create()}} to [[#createCredential|create a credential]], and - -- to inform the [=client=] of the [=[RP]=]'s best belief about how to locate the [=managing authenticators=] of the - [=credentials=] listed in {{PublicKeyCredentialRequestOptions/allowCredentials}} when calling - {{CredentialsContainer/get()|navigator.credentials.get()}}. - - -
    : platform :: This value indicates [=platform attachment=]. @@ -2094,7 +2511,40 @@ operation has no [=authenticator attachment modality=] selection option, so the credential|credentials=]. The [=client=] and user will then use whichever is available and convenient at the time. -### Attestation Conveyance Preference Enumeration (enum AttestationConveyancePreference) ### {#attestation-convey} +### Resident Key Requirement Enumeration (enum ResidentKeyRequirement) ### {#enum-residentKeyRequirement} + + + enum ResidentKeyRequirement { + "discouraged", + "preferred", + "required" + }; + + +This enumeration's values describe the [=[RP]=]'s requirements for [=resident credentials=]: + +
    + : discouraged + :: This value indicates the [=[RP]=] prefers creating a [=non-resident credential=], but will accept a + [=resident credential=]. + + : preferred + :: This value indicates the [=[RP]=] prefers creating a [=resident credential=], but will accept a + [=non-resident credential=]. + + : required + :: This value indicates the [=[RP]=] requires a [=resident credential=], and is prepared to receive an error + if a [=resident credential=] cannot be created. +
    + +Note: The [=[RP]=] can use a combination of the value provided for |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{residentKey}} +and the [=credProps|Credential Properties Extension=]'s return value to determine whether or not the authenticator created a [=resident credential=]. +This is useful when values of {{ResidentKeyRequirement/discouraged}} or {{ResidentKeyRequirement/preferred}} are used for +|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{residentKey}}, because in those cases it is possible for an +[=authenticator=] to create either a [=resident credential=] or a [=non-resident credential=]. + + +### Attestation Conveyance Preference Enumeration (enum AttestationConveyancePreference) ### {#enum-attestation-convey} [=[WRPS]=] may use {{AttestationConveyancePreference}} to specify their preference regarding [=attestation conveyance=] during credential generation. @@ -2131,7 +2581,7 @@ during credential generation.
    -## Options for Assertion Generation (dictionary PublicKeyCredentialRequestOptions) ## {#assertion-options} +## Options for Assertion Generation (dictionary PublicKeyCredentialRequestOptions) ## {#dictionary-assertion-options} The {{PublicKeyCredentialRequestOptions}} dictionary supplies {{CredentialsContainer/get()}} with the data it needs to generate an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member MUST be present, while its other members are OPTIONAL. @@ -2150,7 +2600,7 @@ an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member MUST be
    : challenge :: This member represents a challenge that the selected [=authenticator=] signs, along with other data, when producing an - [=authentication assertion=]. See the [[#cryptographic-challenges]] security consideration. + [=authentication assertion=]. See the [[#sctn-cryptographic-challenges]] security consideration. : timeout :: This OPTIONAL member specifies a time, in milliseconds, that the caller is willing to wait for the call to complete. @@ -2178,70 +2628,79 @@ an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member MUST be
    -## Abort Operations with `AbortSignal` ## {#abortoperation} +## Abort Operations with `AbortSignal` ## {#sctn-abortoperation} -Developers are encouraged to leverage the {{AbortController}} to manage the +Developers are encouraged to leverage the {{AbortController}} to manage the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} operations. -See [[dom#abortcontroller-api-integration]] section for detailed instructions. +See [[dom#abortcontroller-api-integration]] section for detailed instructions. - Note: [[dom#abortcontroller-api-integration]] section specifies that web platform APIs integrating with the - {{AbortController}} must reject the promise immediately once the [=AbortSignal/aborted flag=] is set. + Note: [[dom#abortcontroller-api-integration]] section specifies that web platform APIs integrating with the + {{AbortController}} must reject the promise immediately once the [=AbortSignal/aborted flag=] is set. Given the complex inheritance and parallelization structure of the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} methods, the algorithms for the two APIs fulfills this - requirement by checking the [=AbortSignal/aborted flag=] in three places. In the case of + requirement by checking the [=AbortSignal/aborted flag=] in three places. In the case of {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}}, the aborted flag is checked first in [[credential-management-1#algorithm-create]] immediately before calling {{Credential/[[Create]](origin, options, sameOriginWithAncestors)}}, - then in [[#createCredential]] right before [=authenticator sessions=] start, and finally + then in [[#sctn-createCredential]] right before [=authenticator sessions=] start, and finally during [=authenticator sessions=]. The same goes for {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}}. -The [=visibility states|visibility=] and [=focus=] state of the [=Window=] object determines whether the +The [=visibility states|visibility=] and [=focus=] state of the [=Window=] object determines whether the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} operations -should continue. When the [=Window=] object associated with the [[=Document=] loses focus, +should continue. When the [=Window=] object associated with the [[=Document=] loses focus, {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} operations -SHOULD be aborted. +SHOULD be aborted. Issue: The WHATWG HTML WG is discussing whether to provide a hook when a browsing context gains or loses focuses. If a hook is provided, the above paragraph will be updated to include the hook. - See [WHATWG HTML WG Issue #2711](https://github.com/whatwg/html/issues/2711) for more details. + See [WHATWG HTML WG Issue #2711](https://github.com/whatwg/html/issues/2711) for more details. + + +## WebAuthn Extensions Inputs and Outputs ## {#sctn-extensions-inputs-outputs} + +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)). -## Authentication Extensions Client Inputs (typedef {{AuthenticationExtensionsClientInputs}}) ## {#iface-authentication-extensions-client-inputs} +Note: The types defined below—{{AuthenticationExtensionsClientInputs}}, {{AuthenticationExtensionsClientOutputs}}, and {{AuthenticationExtensionsAuthenticatorInputs}}—are applicable to both [=registration extensions=] and [=authentication extensions=]. The "Authentication..." portion of their names should be regarded as meaning "WebAuthentication..." + + +### Authentication Extensions Client Inputs (dictionary {{AuthenticationExtensionsClientInputs}}) ## {#iface-authentication-extensions-client-inputs} dictionary AuthenticationExtensionsClientInputs { }; -This is a dictionary containing the [=client extension input=] values for zero or more WebAuthn extensions, as defined in [[#extensions]]. +This is a dictionary containing the [=client extension input=] values for zero or more [=WebAuthn Extensions=]. -## Authentication Extensions Client Outputs (typedef {{AuthenticationExtensionsClientOutputs}}) ## {#iface-authentication-extensions-client-outputs} +### Authentication Extensions Client Outputs (dictionary {{AuthenticationExtensionsClientOutputs}}) ## {#iface-authentication-extensions-client-outputs} dictionary AuthenticationExtensionsClientOutputs { }; -This is a dictionary containing the [=client extension output=] values for zero or more WebAuthn extensions, as defined in [[#extensions]]. +This is a dictionary containing the [=client extension output=] values for zero or more [=WebAuthn Extensions=]. -## Authentication Extensions Authenticator Inputs (typedef {{AuthenticationExtensionsAuthenticatorInputs}}) ## {#iface-authentication-extensions-authenticator-inputs} +### Authentication Extensions Authenticator Inputs (typedef {{AuthenticationExtensionsAuthenticatorInputs}}) ## {#iface-authentication-extensions-authenticator-inputs} typedef record<DOMString, DOMString> AuthenticationExtensionsAuthenticatorInputs; -This is a dictionary containing the [=authenticator extension input=] values for zero or more WebAuthn extensions, as defined in [[#extensions]]. +This is a dictionary containing the [=authenticator extension input=] values for zero or more [=WebAuthn Extensions=]. -## Supporting Data Structures ## {#supporting-data-structures} +## Supporting Data Structures ## {#sctn-supporting-data-structures} The [=public key credential=] type uses certain data structures that are specified in supporting specifications. These are as follows. -### Client Data Used in WebAuthn Signatures (dictionary CollectedClientData) ### {#sec-client-data} +### Client Data Used in WebAuthn Signatures (dictionary CollectedClientData) ### {#dictionary-client-data} The client data represents the contextual bindings of both the [=[WRP]=] and the [=client=]. It is a key-value mapping whose keys are strings. Values can be any type that has a valid encoding in JSON. Its structure is defined by the @@ -2272,12 +2731,12 @@ Note: The {{CollectedClientData}} may be extended in the future. Therefore it's attacks (where an attacker substitutes one legitimate signature for another). : challenge - :: This member contains the base64url encoding of the challenge provided by the [=[RP]=]. See the [[#cryptographic-challenges]] + :: This member contains the base64url encoding of the challenge provided by the [=[RP]=]. See the [[#sctn-cryptographic-challenges]] security consideration. : origin :: This member contains the fully qualified [=origin=] of the requester, as provided to the authenticator by the client, in - the syntax defined by [[RFC6454]]. + the syntax defined by [[!RFC6454]]. : tokenBinding :: This OPTIONAL member contains information about the state of the [=Token Binding=] protocol [[!TokenBinding]] used when communicating @@ -2314,7 +2773,7 @@ Note: The {{CollectedClientData}} may be extended in the future. Therefore it's -### Credential Type Enumeration (enum PublicKeyCredentialType) ### {#credentialType} +### Credential Type Enumeration (enum PublicKeyCredentialType) ### {#enum-credentialType} enum PublicKeyCredentialType { @@ -2331,13 +2790,13 @@ Note: The {{CollectedClientData}} may be extended in the future. Therefore it's </div> -### Credential Descriptor (dictionary <dfn dictionary>PublicKeyCredentialDescriptor</dfn>) ### {#credential-dictionary} +### Credential Descriptor (dictionary <dfn dictionary>PublicKeyCredentialDescriptor</dfn>) ### {#dictionary-credential-descriptor} <xmp class="idl"> dictionary PublicKeyCredentialDescriptor { required PublicKeyCredentialType type; required BufferSource id; - sequence<AuthenticatorTransport> transports; + sequence<DOMString> transports; }; @@ -2354,30 +2813,36 @@ parameter to the {{CredentialsContainer/create()}} or {{CredentialsContainer/get : transports :: This OPTIONAL member contains a hint as to how the [=client=] might communicate with the [=managing authenticator=] of the - [=public key credential=] the caller is referring to. + [=public key credential=] the caller is referring to. The values SHOULD be members of {{AuthenticatorTransport}} but [=client platforms=] MUST ignore unknown values. -### Authenticator Transport Enumeration (enum AuthenticatorTransport) ### {#transport} +### Authenticator Transport Enumeration (enum AuthenticatorTransport) ### {#enum-transport} enum AuthenticatorTransport { "usb", "nfc", "ble", - "internal" + "internal", + "lightning" };
    - [=Authenticators=] may implement various [[#transport|transports]] for communicating with [=clients=]. This enumeration + [=Authenticators=] may implement various [[#enum-transport|transports]] for communicating with [=clients=]. This enumeration defines hints as to how clients might communicate with a particular authenticator in order to obtain an assertion for a specific credential. Note that these hints represent the [=[WRP]=]'s best belief as to how an authenticator may be reached. A - [=[RP]=] may obtain a list of transports hints from some [=attestation statement formats=] or via some out-of-band mechanism; - it is outside the scope of this specification to define that mechanism. + [=[RP]=] will typically learn of the supported transports for a [=public key credential=] via + {{AuthenticatorAttestationResponse/getTransports()}}. + + Note: The {{AuthenticatorTransport}} enumeration is not referenced by other parts of the Web IDL because that would preclude other values from being used without updating this specification and its implementations. It is important for backwards compatibility that [=client platforms=] and [=[RPS]=] handle unknown values. Therefore it exists here for documentation and as a registry. Where transports are represented elsewhere, they are typed as {{DOMString}}s, for example in {{PublicKeyCredentialDescriptor/transports}}. : usb :: Indicates the respective [=authenticator=] can be contacted over removable USB. + + : lightning + :: Indicates the respective [=authenticator=] can be contacted over removable Lightning. : nfc :: Indicates the respective [=authenticator=] can be contacted over Near Field Communication (NFC). @@ -2391,7 +2856,7 @@ parameter to the {{CredentialsContainer/create()}} or {{CredentialsContainer/get
    -### Cryptographic Algorithm Identifier (typedef {{COSEAlgorithmIdentifier}}) ### {#alg-identifier} +### Cryptographic Algorithm Identifier (typedef {{COSEAlgorithmIdentifier}}) ### {#sctn-alg-identifier} typedef long COSEAlgorithmIdentifier; @@ -2404,7 +2869,7 @@ parameter to the {{CredentialsContainer/create()}} or {{CredentialsContainer/get </div> -### User Verification Requirement Enumeration (enum <dfn enum>UserVerificationRequirement</dfn>) ### {#userVerificationRequirement} +### User Verification Requirement Enumeration (enum <dfn enum>UserVerificationRequirement</dfn>) ### {#enum-userVerificationRequirement} <xmp class="idl"> enum UserVerificationRequirement { @@ -2432,16 +2897,41 @@ needs. </div> +## Feature Policy integration ## {#sctn-feature-policy} + +This specification defines a [=policy-controlled feature=] identified by +the feature policy token "<code><dfn data-lt="webauthn-feature" export>webauthn</dfn></code>". +Its [=default allowlist=] is '<code>self</code>'. [[!Feature-Policy]] + +A {{Document}}'s [=Document/feature policy=] determines whether any content in that <a href="https://html.spec.whatwg.org/multipage/dom.html#documents">document</a> is allowed +to successfully invoke the [=Web Authentication API=], i.e., via +<code><a idl for="CredentialsContainer" lt="create()">navigator.credentials.create({publicKey:..., ...})</a></code> and +<code><a idl for="CredentialsContainer" lt="get()">navigator.credentials.get({publicKey:..., ...})</a></code>. +If disabled in any document, no content in the document will be [=allowed to use=] +the foregoing methods: attempting to do so will [return an error](https://www.w3.org/2001/tag/doc/promises-guide#errors). + +Note: Algorithms specified in [[!CREDENTIAL-MANAGEMENT-1]] perform the actual feature policy evaluation. This is because such policy evaluation needs to occur when there is access to the [=current settings object=]. The {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} [=internal methods=] do not have such access since they are invoked [=in parallel=] (by algorithms specified in [[!CREDENTIAL-MANAGEMENT-1]]). + + + +## Using Web Authentication within <code>iframe</code> elements ## {#sctn-iframe-guidance} + +The [=Web Authentication API=] is disabled by default in cross-origin <{iframe}>s. +To override this default policy and indicate that a cross-origin <{iframe}> is allowed to invoke the [=Web Authentication API=], specify the <{iframe/allow}> attribute on the <{iframe}> element and include the `webauthn` feature policy token in the <{iframe/allow}> attribute's value. + + + + # WebAuthn <dfn>Authenticator Model</dfn> # {#sctn-authenticator-model} -[[#api|The Web Authentication API]] implies a specific abstract functional model for a [=[WAA]=]. This section +[[#sctn-api|The Web Authentication API]] implies a specific abstract functional model for a [=[WAA]=]. This section describes that [=authenticator model=]. [=Client platforms=] MAY implement and expose this abstract model in any way desired. However, the behavior of the client's Web Authentication API implementation, when operating on the authenticators supported by that [=client platform=], MUST be indistinguishable -from the behavior specified in [[#api]]. +from the behavior specified in [[#sctn-api]]. -Note: [[FIDO-CTAP]] is an example of a concrete instantiation of this model, but it is one in which there are differences in the data it returns and those expected by the [[#api|WebAuthn API]]'s algorithms. The CTAP2 response messages are CBOR maps constructed using integer keys rather than the string keys defined in this specification for the same objects. The [=client=] is expected to perform any needed transformations on such data. The [[FIDO-CTAP]] specification details the mapping between CTAP2 integer keys and WebAuthn string keys, in section [=§6.2. Responses=]. +Note: [[!FIDO-CTAP]] is an example of a concrete instantiation of this model, but it is one in which there are differences in the data it returns and those expected by the [[#sctn-api|WebAuthn API]]'s algorithms. The CTAP2 response messages are CBOR maps constructed using integer keys rather than the string keys defined in this specification for the same objects. The [=client=] is expected to perform any needed transformations on such data. The [[!FIDO-CTAP]] specification details the mapping between CTAP2 integer keys and WebAuthn string keys, in section [=§6.2. Responses=]. For authenticators, this model defines the logical operations that they MUST support, and the data formats that they expose to the client and the [=[WRP]=]. However, it does not define the details of how authenticators communicate with the [=client device=], @@ -2452,10 +2942,10 @@ specific error codes are mentioned as a means of showing which error conditions in order to enable a compliant and secure client implementation. [=[RPS]=] may influence authenticator selection, if they deem necessary, by stipulating various authenticator characteristics -when [[#createCredential|creating credentials]] and/or when [[#getAssertion|generating assertions]], through use of -[[#dictionary-makecredentialoptions|credential creation options]] or [[#assertion-options|assertion generation options]], -respectively. The algorithms underlying the [[#api|WebAuthn API]] marshal these options and pass them to the applicable -[[#authenticator-ops|authenticator operations]] defined below. +when [[#sctn-createCredential|creating credentials]] and/or when [[#sctn-getAssertion|generating assertions]], through use of +[[#dictionary-makecredentialoptions|credential creation options]] or [[#dictionary-assertion-options|assertion generation options]], +respectively. The algorithms underlying the [[#sctn-api|WebAuthn API]] marshal these options and pass them to the applicable +[[#sctn-authenticator-ops|authenticator operations]] defined below. In this abstract model, the authenticator provides key management and cryptographic signatures. It can be embedded in the WebAuthn client or housed in a separate device entirely. The authenticator itself can contain a cryptographic module which @@ -2511,7 +3001,7 @@ Authenticators produce cryptographic signatures for two distinct purposes: The formats of these signatures, as well as the procedures for generating them, are specified below. -## Authenticator Data ## {#sec-authenticator-data} +## Authenticator Data ## {#sctn-authenticator-data} The <dfn>authenticator data</dfn> structure encodes contextual bindings made by the [=authenticator=]. These bindings are controlled by the authenticator itself, and derive their trust from the [=[WRP]=]'s assessment of the security properties of the @@ -2567,7 +3057,7 @@ The [=authenticator data=] structure is a byte array of 37 bytes or more, laid o <td><dfn>attestedCredentialData</dfn></td> <td>variable (if present)</td> <td> - [=attested credential data=] (if present). See [[#sec-attested-credential-data]] for details. Its length depends on + [=attested credential data=] (if present). See [[#sctn-attested-credential-data]] for details. Its length depends on the [=credentialIdLength|length=] of the [=credentialId|credential ID=] and [=credentialPublicKey|credential public key=] being attested. </td> @@ -2576,8 +3066,8 @@ The [=authenticator data=] structure is a byte array of 37 bytes or more, laid o <td><dfn lt="authDataExtensions">extensions</dfn></td> <td>variable (if present)</td> <td> - Extension-defined [=authenticator data=]. This is a [=CBOR=] [[RFC7049]] map with [=extension identifiers=] as keys, - and [=authenticator extension outputs=] as values. See [[#extensions]] for details. + Extension-defined [=authenticator data=]. This is a [=CBOR=] [[!RFC7049]] map with [=extension identifiers=] as keys, + and [=authenticator extension outputs=] as values. See [[#sctn-extensions]] for details. </td> </tr> </table> @@ -2605,7 +3095,7 @@ the requested [=public key credential|credential=] is [=scoped=] to exactly matc possibly combined in a single [=authorization gesture=], then the authenticator will set both the `UP` [=flag=] and the `UV` [=flag=]. -- For [=attestation signatures=], the authenticator MUST set the AT [=flag=] and include the <code>[=attestedCredentialData=]</code>. +- For [=attestation signatures=], the authenticator MUST set the AT [=flag=] and include the <code>[=attestedCredentialData=]</code>. For [=assertion signature|authentication signatures=], the AT [=flag=] MUST NOT be set and the <code>[=attestedCredentialData=]</code> MUST NOT be included. - If the authenticator does not include any [=authDataExtensions|extension data=], it MUST set the `ED` [=flag=] to zero, and to one if @@ -2623,10 +3113,10 @@ The [figure below](#fig-authData) shows a visual representation of the [=authent The [=attested credential data=] (which is only present if the AT [=flag=] is set) describes its own length. If the ED [=flag=] is set, then the total length is 37 bytes plus the length of the [=attested credential data=] (if the AT [=flag=] is set), plus the length of the [=authDataExtensions|extensions=] output (a [=CBOR=] map) that follows. - Determining [=attested credential data=]'s length, which is variable, involves determining <code>[=credentialPublicKey=]</code>'s beginning location given the preceding <code>[=credentialid|credentialId=]</code>'s [=credentialidlength|length=], and then determining the <code>[=credentialPublicKey=]</code>'s length (see also [=Section 7=] of [[RFC8152]]). + Determining [=attested credential data=]'s length, which is variable, involves determining <code>[=credentialPublicKey=]</code>'s beginning location given the preceding <code>[=credentialid|credentialId=]</code>'s [=credentialidlength|length=], and then determining the <code>[=credentialPublicKey=]</code>'s length (see also [=Section 7=] of [[!RFC8152]]). </div> -### <dfn>Signature Counter</dfn> Considerations ### {#sign-counter} +### <dfn>Signature Counter</dfn> Considerations ### {#sctn-sign-counter} Authenticators SHOULD implement a [=signature counter=] feature. The [=signature counter=] is incremented for each successful [=authenticatorGetAssertion=] operation by some positive value, and its value is returned to the [=[WRP]=] within the @@ -2637,15 +3127,15 @@ A [=[RP]=] stores the [=signature counter=] of the most recent [=authenticatorGe [=authenticatorGetAssertion=] operation, the [=[RP]=] compares the stored [=signature counter=] value with the new <code>[=signCount=]</code> value returned in the assertion's [=authenticator data=]. If this new <code>[=signCount=]</code> value is less than or equal to the stored value, a cloned authenticator may exist, or the authenticator may be malfunctioning. -Detecting a [=signature counter=] mismatch does not indicate whether the current operation was performed by a cloned authenticator or the original authenticator. [=[RPS]=] should address this situation appropriately relative to their individual situations, i.e., their risk tolerance. +Detecting a [=signature counter=] mismatch does not indicate whether the current operation was performed by a cloned authenticator or the original authenticator. [=[RPS]=] should address this situation appropriately relative to their individual situations, i.e., their risk tolerance. Authenticators: -- SHOULD implement per credential [=signature counters=]. This prevents the - [=signature counter=] value from being shared between [=[RPS]=] and being possibly employed - as a correlation handle for the user. Authenticators may implement a global [=signature counter=], - i.e., on a per-authenticator basis, but this is less privacy-friendly for users. +- SHOULD implement per credential [=signature counters=]. This prevents the + [=signature counter=] value from being shared between [=[RPS]=] and being possibly employed + as a correlation handle for the user. Authenticators may implement a global [=signature counter=], + i.e., on a per-authenticator basis, but this is less privacy-friendly for users. -- SHOULD ensure that the [=signature counter=] value does not +- SHOULD ensure that the [=signature counter=] value does not accidentally decrease (e.g., due to hardware failures). @@ -2665,7 +3155,7 @@ the same procedure as other [=assertion signatures=] generated by the [=authenti ## Authenticator Taxonomy ## {#sctn-authenticator-taxonomy} -[=Authenticator=] types vary along several different dimensions: [=authenticator attachment modality=], employed [[#transport|transport(s)]], +[=Authenticator=] types vary along several different dimensions: [=authenticator attachment modality=], employed [[#enum-transport|transport(s)]], [=credential storage modality=], and [=authentication factor capability=]. The combination of these dimensions defines an [=authenticator=]'s <dfn>authenticator type</dfn>, which in turn determines the broad use cases the [=authenticator=] supports. [Table 2](#table-authenticatorTypes) defines names for some [=authenticator types=]. @@ -2682,7 +3172,7 @@ the same procedure as other [=assertion signatures=] generated by the [=authenti </thead> <tbody> <tr> - <th> <dfn>Second-factor platform authenticator</dfn> </th> + <th> Second-factor platform authenticator </th> <td> [=platform attachment|platform=] </td> <td> [=server-side credential storage modality|Server-side storage=] </td> <td> [=single-factor capable|Single-factor=] </td> @@ -2694,19 +3184,19 @@ the same procedure as other [=assertion signatures=] generated by the [=authenti <td> [=multi-factor capable|Multi-factor=] </td> </tr> <tr> - <th> <dfn>First-factor platform authenticator</dfn> </th> + <th> First-factor platform authenticator </th> <td> [=platform attachment|platform=] </td> <td> [=client-side credential storage modality|Client-side storage=] </td> <td> [=multi-factor capable|Multi-factor=] </td> </tr> <tr> - <th> <dfn>Second-factor roaming authenticator</dfn> </th> + <th> Second-factor roaming authenticator </th> <td> [=cross-platform attachment|cross-platform=] </td> <td> [=server-side credential storage modality|Server-side storage=] </td> <td> [=single-factor capable|Single-factor=] </td> </tr> <tr> - <th> <dfn>User-verifying roaming authenticator</dfn> </th> + <th> User-verifying roaming authenticator </th> <td> [=cross-platform attachment|cross-platform=] </td> <td> [=server-side credential storage modality|Server-side storage=] </td> <td> [=multi-factor capable|Multi-factor=] </td> @@ -2724,7 +3214,7 @@ the same procedure as other [=assertion signatures=] generated by the [=authenti </figcaption> </figure> -These types can be further broken down into subtypes, such as which [[#transport|transport(s)]] a [=roaming authenticator=] +These types can be further broken down into subtypes, such as which [[#enum-transport|transport(s)]] a [=roaming authenticator=] supports. The following sections define the terms [=authenticator attachment modality=], [=credential storage modality=] and [=authentication factor capability=]. @@ -2733,7 +3223,7 @@ supports. The following sections define the terms [=authenticator attachment mod [=Clients=] can communicate with [=authenticators=] using a variety of mechanisms. For example, a [=client=] MAY use a [=client device=]-specific API to communicate with an [=authenticator=] which is physically bound to a [=client device=]. On the other hand, a -[=client=] can use a variety of standardized cross-platform transport protocols such as Bluetooth (see [[#transport]]) to discover +[=client=] can use a variety of standardized cross-platform transport protocols such as Bluetooth (see [[#enum-transport]]) to discover and communicate with [=cross-platform attachment|cross-platform attached=] [=authenticators=]. We refer to [=authenticators=] that are part of the [=client device=] as <dfn>platform authenticators</dfn>, while those that are reachable via cross-platform transport protocols are referred to as <dfn>roaming authenticators</dfn>. @@ -2765,8 +3255,8 @@ backup [=public key credential|credentials=] in case another [=authenticator=] i An [=authenticator=] can store a [=public key credential source=] in one of two ways: - 1. In persistent storage embedded in the [=authenticator=], [=client=] or [=client device=], e.g., in a secure element. A - [=public key credential source=] stored in this way is a [=resident credential=]. + 1. In persistent storage embedded in the [=authenticator=], [=client=] or [=client device=], e.g., in a secure element. + This is a technical requirement for a [=client-side-resident public key credential source=]. 1. By encrypting (i.e., wrapping) the [=credential private key=] such that only this [=authenticator=] can decrypt (i.e., unwrap) it and letting the resulting ciphertext be the [=credential ID=] for the [=public key credential source=]. The [=credential ID=] is stored by the [=[RP]=] @@ -2789,7 +3279,8 @@ modality</dfn> as follows: Note that a [=resident credential capable=] [=authenticator=] MAY support both storage strategies. In this case, the [=authenticator=] MAY at its discretion use different storage strategies for different [=public key credential|credentials=], though subject to the -{{AuthenticatorSelectionCriteria/requireResidentKey}} option of {{CredentialsContainer/create()}}. +{{AuthenticatorSelectionCriteria/residentKey}} or {{AuthenticatorSelectionCriteria/requireResidentKey}} options of +{{CredentialsContainer/create()}}. ### <dfn>Authentication Factor Capability</dfn> ### {#sctn-authentication-factor-capability} @@ -2812,7 +3303,7 @@ The [=[RP]=] can therefore use the [=UV=] flag to verify that additional [=authe [=authenticator=]'s [=attestation statement=]. -## <dfn>Authenticator Operations</dfn> ## {#authenticator-ops} +## <dfn>Authenticator Operations</dfn> ## {#sctn-authenticator-ops} A [=[WAC]=] MUST connect to an authenticator in order to invoke any of the operations of that authenticator. This connection defines an <dfn>authenticator session</dfn>. An authenticator must maintain isolation between sessions. It may do this by only allowing one @@ -2821,7 +3312,7 @@ session to exist at any particular time, or by providing more complicated sessio The following operations can be invoked by the client in an authenticator session. -### Lookup Credential Source by Credential ID Algorithm ### {#op-lookup-credsource-by-credid} +### Lookup Credential Source by Credential ID Algorithm ### {#sctn-op-lookup-credsource-by-credid} The result of <dfn for="credential id">looking up</dfn> a [=credential id=] |credentialId| in an [=authenticator=] |authenticator| is the result of the following algorithm: @@ -2833,7 +3324,7 @@ The result of <dfn for="credential id">looking up</dfn> a [=credential id=] |cre 1. Return `null`. -### The <dfn>authenticatorMakeCredential</dfn> Operation ### {#op-make-cred} +### The <dfn>authenticatorMakeCredential</dfn> Operation ### {#sctn-op-make-cred} It takes the following input parameters: @@ -2845,26 +3336,26 @@ It takes the following input parameters: : |userEntity| :: The user account's {{PublicKeyCredentialUserEntity}}, containing the [=user handle=] given by the [=[RP]=]. : |requireResidentKey| -:: The {{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}} value given by the [=[RP]=]. +:: The [=effective resident key requirement for credential creation=], a Boolean value determined by the [=client=]. : |requireUserPresence| :: The constant Boolean value [TRUE]. It is included here as a pseudo-parameter to simplify applying this abstract authenticator model to implementations that may wish to make a [=test of user presence=] optional although WebAuthn does not. : |requireUserVerification| -:: The [=effective user verification requirement for credential creation=], a Boolean value provided by the client. +:: The [=effective user verification requirement for credential creation=], a Boolean value determined by the [=client=]. : |credTypesAndPubKeyAlgs| :: A sequence of pairs of {{PublicKeyCredentialType}} and public key algorithms ({{COSEAlgorithmIdentifier}}) requested by the [=[RP]=]. This sequence is ordered from most preferred to least preferred. The [=authenticator=] makes a best-effort to create the most preferred credential that it can. : |excludeCredentialDescriptorList| :: An OPTIONAL list of {{PublicKeyCredentialDescriptor}} 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. |excludeCredentialDescriptorList| contains a + these are known to the authenticator, it SHOULD NOT create a new credential. |excludeCredentialDescriptorList| contains a list of known credentials. : |extensions| -:: A [=CBOR=] [=map=] from [=extension identifiers=] to their [=authenticator extension inputs=], created by the client based on +:: A [=CBOR=] [=map=] from [=extension identifiers=] to their [=authenticator extension inputs=], created by the [=client=] based on the extensions requested by the [=[RP]=], if any. -Note: Before performing this operation, all other operations in progress in the [=authenticator session=] MUST be aborted by +Note: Before performing this operation, all other operations in progress in the [=authenticator session=] MUST be aborted by running the [=authenticatorCancel=] operation. When this operation is invoked, the [=authenticator=] MUST perform the following procedure: @@ -2879,8 +3370,9 @@ When this operation is invoked, the [=authenticator=] MUST perform the following 1. If [=credential id/looking up=] <code>|descriptor|.{{PublicKeyCredentialDescriptor/id}}</code> in this authenticator returns non-null, and the returned [=list/item=]'s [=RP ID=] and [=type=] match <code>|rpEntity|.{{PublicKeyCredentialRpEntity/id}}</code> and - <code>|excludeCredentialDescriptorList|.{{PublicKeyCredentialDescriptor/type}}</code> respectively, then obtain [=user - consent=] for creating a new credential. The method of obtaining [=user consent=] MUST include a [=test + <code>|excludeCredentialDescriptorList|.{{PublicKeyCredentialDescriptor/type}}</code> respectively, + then collect an [=authorization gesture=] confirming [=user + consent=] for creating a new credential. The [=authorization gesture=] MUST include a [=test of user presence=]. If the user <dl class="switch"> : confirms consent to create a new credential @@ -2899,21 +3391,22 @@ When this operation is invoked, the [=authenticator=] MUST perform the following a numbered step. If outdented, it (today) is rendered as a bullet in the midst of a numbered list :-/ --> <li id='op-makecred-step-user-consent'> - Obtain [=user consent=] for creating a new credential. The prompt for obtaining this [=user consent|consent=] is shown by the + Collect an [=authorization gesture=] confirming [=user consent=] for creating a new credential. + The prompt for the [=authorization gesture=] is shown by the authenticator if it has its own output capability, or by the user agent otherwise. The prompt SHOULD display <code>|rpEntity|.{{PublicKeyCredentialRpEntity/id}}</code>, <code>|rpEntity|.{{PublicKeyCredentialEntity/name}}</code>, <code>|userEntity|.{{PublicKeyCredentialEntity/name}}</code> and <code>|userEntity|.{{PublicKeyCredentialUserEntity/displayName}}</code>, if possible. - If |requireUserVerification| is [TRUE], the method of obtaining [=user consent=] MUST include [=user verification=]. + If |requireUserVerification| is [TRUE], the [=authorization gesture=] MUST include [=user verification=]. - If |requireUserPresence| is [TRUE], the method of obtaining [=user consent=] MUST include a [=test of user presence=]. + If |requireUserPresence| is [TRUE], the [=authorization gesture=] MUST include a [=test of user presence=]. If the user does not [=user consent|consent=] or if [=user verification=] fails, return an error code equivalent to "{{NotAllowedError}}" and terminate the operation. </li> -1. Once [=user consent=] has been obtained, generate a new credential object: +1. Once the [=authorization gesture=] has been completed and [=user consent=] has been obtained, generate a new credential object: 1. Let (|publicKey|, |privateKey|) be a new pair of cryptographic keys using the combination of {{PublicKeyCredentialType}} and cryptographic parameters represented by the first [=list/item=] in |credTypesAndPubKeyAlgs| that is supported by this authenticator. @@ -2946,7 +3439,7 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o 1. If the [=authenticator=] supports: <dl class="switch"> : a global [=signature counter=] - :: Use the global [=signature counter=]'s actual value when generating + :: Use the global [=signature counter=]'s actual value when generating [=authenticator data=]. : a per credential [=signature counter=] :: allocate the counter, associate it with the new credential, and initialize the counter value as zero. @@ -2956,17 +3449,17 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o </dl> 1. Let |attestedCredentialData| be the [=attested credential data=] byte array including the |credentialId| and |publicKey|. -1. Let |authenticatorData| [=perform the following steps to generate an authenticator data structure|be the byte array=] specified in [[#sec-authenticator-data]], including |attestedCredentialData| as the +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 <code>[=attestedCredentialData=]</code> and |processedExtensions|, if any, as the <code>[=authDataExtensions|extensions=]</code>. 1. Return the [=attestation object=] for the new credential created by the procedure specified in - [[#generating-an-attestation-object]] using an authenticator-chosen [=attestation statement format=], |authenticatorData|, + [[#sctn-generating-an-attestation-object]] using an authenticator-chosen [=attestation statement format=], |authenticatorData|, and |hash|. For more details on attestation, see [[#sctn-attestation]]. On successful completion of this operation, the authenticator returns the [=attestation object=] to the client. -### The <dfn>authenticatorGetAssertion</dfn> Operation ### {#op-get-assertion} +### The <dfn>authenticatorGetAssertion</dfn> Operation ### {#sctn-op-get-assertion} It takes the following input parameters: @@ -3005,16 +3498,17 @@ When this method is invoked, the [=authenticator=] MUST perform the following pr 1. If |credentialOptions| is now empty, return an error code equivalent to "{{NotAllowedError}}" and terminate the operation. 1. Prompt the user to select a [=public key credential source=] |selectedCredential| from |credentialOptions|. - Obtain [=user consent=] for using |selectedCredential|. The prompt for obtaining this [=user consent|consent=] may be shown + Collect an [=authorization gesture=] confirming [=user consent=] for using |selectedCredential|. + The prompt for the [=authorization gesture=] may be shown by the [=authenticator=] if it has its own output capability, or by the user agent otherwise. - If |requireUserVerification| is [TRUE], the method of obtaining [=user consent=] MUST include [=user verification=]. + If |requireUserVerification| is [TRUE], the [=authorization gesture=] MUST include [=user verification=]. Note: For the overall WebAuthn security properties to hold, the user verified here must be the same user that was verified when this [=authenticator=] created this [=public key credential=] in - <a href='#op-makecred-step-user-consent'>Step 6</a> of [[#op-make-cred]]. + <a href='#op-makecred-step-user-consent'>Step 6</a> of [[#sctn-op-make-cred]]. - If |requireUserPresence| is [TRUE], the method of obtaining [=user consent=] MUST include a + If |requireUserPresence| is [TRUE], the [=authorization gesture=] MUST include a [=test of user presence=]. If the user does not [=user consent|consent=], return an error code equivalent to @@ -3023,12 +3517,12 @@ When this method is invoked, the [=authenticator=] MUST perform the following pr 1. Let |processedExtensions| be the result of [=authenticator extension processing=] [=map/for each=] supported [=extension identifier=] → [=authenticator extension input=] in |extensions|. 1. Increment the credential associated - [=signature counter=] or the global [=signature counter=] value, depending on + [=signature counter=] or the global [=signature counter=] value, depending on 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. Let |authenticatorData| [=perform the following steps to generate an authenticator data structure|be the byte array=] - specified in [[#sec-authenticator-data]] including |processedExtensions|, if any, as + specified in [[#sctn-authenticator-data]] including |processedExtensions|, if any, as the <code>[=authDataExtensions|extensions=]</code> and excluding <code>[=attestedCredentialData=]</code>. 1. Let |signature| be the [=assertion signature=] of the concatenation <code>|authenticatorData| || |hash|</code> using the [=public key credential source/privateKey=] of |selectedCredential| as shown in [Figure 4](#fig-signature), below. A simple, @@ -3052,11 +3546,11 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o - |selectedCredential|.[=public key credential source/id=], if either a list of credentials (i.e., |allowCredentialDescriptorList|) of length 2 or greater was supplied by the client, or no such list was supplied. - + Note: If, within |allowCredentialDescriptorList|, the client supplied exactly one credential and it was successfully employed, then its [=credential ID=] is not returned since the client already knows it. This saves transmitting these bytes over what may be a constrained connection in what is likely a common case. - + - |authenticatorData| - |signature| - |selectedCredential|.[=public key credential source/userHandle=] @@ -3069,7 +3563,7 @@ If the [=authenticator=] cannot find any [=public key credential|credential=] co matches the specified criteria, it terminates the operation and returns an error. -### The <dfn>authenticatorCancel</dfn> Operation ### {#op-cancel} +### The <dfn>authenticatorCancel</dfn> Operation ### {#sctn-op-cancel} This operation takes no input parameters and returns no result. @@ -3082,25 +3576,44 @@ This operation is ignored if it is invoked in an [=authenticator session=] which or [=authenticatorGetAssertion=] operation currently in progress. +## String Handling ## {#sctn-strings} + +Authenticators may be required to store arbitrary strings chosen by a [=[RP]=], for example the {{PublicKeyCredentialEntity/name}}, {{PublicKeyCredentialUserEntity/displayName}}, and {{PublicKeyCredentialEntity/icon}} members in a {{PublicKeyCredentialUserEntity}}. Each will have some accommodation for the potentially limited resources available to an [=authenticator=]. + +If string value truncation is the chosen accommodation, the [=authenticator=] SHOULD take care to truncate on character boundaries, although the authenticator MAY truncate without reference to any character encoding. For example, an authenticator could truncate a {{PublicKeyCredentialEntity/name}} and leave a partial UTF-8 sequence at the end. If the authenticator is using [[!FIDO-CTAP]] then future messages from the authenticator may contain invalid CBOR since the value is typed as a CBOR string and thus is required to be valid UTF-8. + +Additionally, a [=grapheme cluster=] may be truncated [[UTR29]], <i>altering</i> the resulting character in the mind of the user. + +User agents are tasked with handling this to avoid burdening authenticators with understanding character encodings and Unicode character properties. Thus, when dealing with [=authenticators=], user agents SHOULD: + +1. Ensure that any strings sent to authenticators are validly encoded. +1. Handle the case where strings have been truncated resulting in an invalid encoding. For example, any partial code point at the end may be dropped or replaced with [U+FFFD](http://unicode.org/cldr/utility/character.jsp?a=FFFD). + ## Attestation ## {#sctn-attestation} -[=Authenticators=] MUST also provide some form of [=attestation=]. The basic requirement is that the [=authenticator=] can +[=Authenticators=] SHOULD also provide some form of [=attestation=], if possible. +If an authenticator does, the basic requirement is that the [=authenticator=] can produce, for each [=credential public key=], an [=attestation statement=] verifiable by the [=[WRP]=]. Typically, this [=attestation statement=] contains a signature by an [=attestation private key=] over the attested [=credential public key=] and a challenge, as well as a certificate or similar data providing provenance information for the [=attestation public key=], enabling the [=[RP]=] to make a trust decision. However, if an [=attestation key pair=] is not available, then the authenticator -MUST perform [=self attestation=] of the [=credential public key=] with the corresponding [=credential private key=]. All this +MAY either perform [=self attestation=] of the [=credential public key=] with the corresponding [=credential private key=], +or otherwise perform [=None|no attestation=]. All this information is returned by [=authenticators=] any time a new [=public key credential=] is generated, in the overall form of an <dfn>attestation object</dfn>. The relationship of the [=attestation object=] with [=authenticator data=] (containing [=attested credential data=]) and the [=attestation statement=] is illustrated in [figure 5](#fig-attStructs), below. +If an [=authenticator=] employs [=self attestation=] or [=None|no attestation=], then no provenance information is provided +for the [=[RP]=] to base a trust decision on. +In these cases, the [=authenticator=] provides no guarantees about its operation to the [=[RP]=]. + <figure id="fig-attStructs"> <img src="images/fido-attestation-structures.svg"/> <figcaption>[=Attestation object=] layout illustrating the included [=authenticator data=] (containing [=attested credential data=]) and the [=attestation statement=].</figcaption> <div class="note"> This figure illustrates only the `packed` [=attestation statement format=]. Several additional [=attestation statement - formats=] are defined in [[#defined-attestation-formats]]. + formats=] are defined in [[#sctn-defined-attestation-formats]]. </div> </figure> @@ -3114,7 +3627,7 @@ statement=], a [=[RP]=] needs to understand these two aspects of [=attestation=] bindings are incorporated into the attestation statement by the [=authenticator=]. In other words, this defines the syntax of the statement. Various existing components and OS platforms (such as TPMs and the Android OS) have previously defined [=attestation statement formats=]. This specification supports a variety of such formats in an extensible way, as defined in - [[#attestation-formats]]. + [[#sctn-attestation-formats]]. The formats themselves are identified by strings, as described in [[#sctn-attstn-fmt-ids]]. 2. The <dfn>attestation type</dfn> defines the semantics of [=attestation statements=] and their underlying trust models. Specifically, it defines how a [=[RP]=] establishes trust in a particular [=attestation statement=], after verifying that it @@ -3122,7 +3635,7 @@ statement=], a [=[RP]=] needs to understand these two aspects of [=attestation=] [[#sctn-attestation-types]]. In general, there is no simple mapping between [=attestation statement formats=] and [=attestation types=]. For example, the -"packed" [=attestation statement format=] defined in [[#packed-attestation]] can be used in conjunction with all [=attestation +"packed" [=attestation statement format=] defined in [[#sctn-packed-attestation]] can be used in conjunction with all [=attestation types=], while other formats and types have more limited applicability. The privacy, security and operational characteristics of [=attestation=] depend on: @@ -3138,7 +3651,7 @@ understand the characteristics of the [=authenticators=] that they trust, based [=authenticators=]. For example, the FIDO Metadata Service [[FIDOMetadataService]] provides one way to access such information. -### Attested Credential Data ### {#sec-attested-credential-data} +### Attested Credential Data ### {#sctn-attested-credential-data} <dfn>Attested credential data</dfn> is a variable-length byte array added to the [=authenticator data=] when generating an [=attestation object=] for a given credential. Its format is shown in [Table 3](#table-attestedCredentialData). @@ -3170,12 +3683,12 @@ object=] for a given credential. Its format is shown in [Table 3](#table-atteste <td>variable</td> <td> The [=credential public key=] encoded in COSE_Key format, - as defined in [=Section 7=] of [[RFC8152]], using the [=CTAP2 canonical CBOR encoding form=]. + as defined in [=Section 7=] of [[!RFC8152]], using the [=CTAP2 canonical CBOR encoding form=]. The COSE_Key-encoded [=credential public key=] MUST contain the "alg" parameter and MUST NOT contain any other OPTIONAL parameters. The "alg" parameter MUST contain a {{COSEAlgorithmIdentifier}} value. The encoded [=credential public key=] MUST also contain any additional REQUIRED parameters stipulated by the relevant key type specification, i.e., REQUIRED for the key type "kty" and algorithm "alg" (see Section 8 of - [[RFC8152]]). + [[!RFC8152]]). </td> </tr> </table> @@ -3188,15 +3701,15 @@ object=] for a given credential. Its format is shown in [Table 3](#table-atteste #### Examples of `credentialPublicKey` Values Encoded in COSE_Key Format #### {#sctn-encoded-credPubKey-examples} This section provides examples of COSE_Key-encoded Elliptic Curve and RSA public keys for the ES256, PS256, and RS256 -signature algorithms. These examples adhere to the rules defined above for the [=credentialPublicKey=] value, and are presented in [[CDDL]] for clarity. +signature algorithms. These examples adhere to the rules defined above for the [=credentialPublicKey=] value, and are presented in [[!CDDL]] for clarity. -[[RFC8152]] [=Section 7=] defines the general framework for all COSE_Key-encoded keys. -Specific key types for specific algorithms are defined in other sections of [[RFC8152]] as well as in other specifications, +[[!RFC8152]] [=Section 7=] defines the general framework for all COSE_Key-encoded keys. +Specific key types for specific algorithms are defined in other sections of [[!RFC8152]] as well as in other specifications, as noted below. -Below is an example of a COSE_Key-encoded Elliptic Curve public key in EC2 format (see [[RFC8152]] -[Section 13.1](https://tools.ietf.org/html/rfc8152#section-13.1)), on the P-256 curve, to be used with the ES256 signature -algorithm (ECDSA w/ SHA-256, see [[RFC8152]] [Section 8.1](https://tools.ietf.org/html/rfc8152#section-8.1)): +Below is an example of a COSE_Key-encoded Elliptic Curve public key in EC2 format (see [[!RFC8152]] +[=Section 13.1=]), on the P-256 curve, to be used with the ES256 signature +algorithm (ECDSA w/ SHA-256, see [[!RFC8152]] [=Section 8.1=]: <pre class="example" highlight="json"> { @@ -3211,7 +3724,7 @@ algorithm (ECDSA w/ SHA-256, see [[RFC8152]] [Section 8.1](https://tools.ietf.or </pre> Below is the above Elliptic Curve public key encoded in the [=CTAP2 canonical CBOR encoding form=], whitespace and line breaks -are included here for clarity and to match the [[CDDL]] presentation above: +are included here for clarity and to match the [[!CDDL]] presentation above: <pre class="example" highlight="json"> A5 @@ -3227,9 +3740,9 @@ are included here for clarity and to match the [[CDDL]] presentation above: </pre> -Below is an example of a COSE_Key-encoded 2048-bit RSA public key (see [[RFC8230]] [Section 4](https://tools.ietf.org/html/rfc8230#section-4)), +Below is an example of a COSE_Key-encoded 2048-bit RSA public key (see [[RFC8230]] [=Section 4=], to be used with the PS256 signature algorithm -(RSASSA-PSS with SHA-256, see [[RFC8230]] [Section 2](https://tools.ietf.org/html/rfc8230#section-2)): +(RSASSA-PSS with SHA-256, see [[RFC8230]] [=Section 2=]: <pre class="example" highlight="json"> { @@ -3242,7 +3755,7 @@ to be used with the PS256 signature algorithm } </pre> -Below is an example of the same COSE_Key-encoded RSA public key as above, +Below is an example of the same COSE_Key-encoded RSA public key as above, to be used with the RS256 signature algorithm (RSASSA-PKCS1-v1_5 with SHA-256, see [[#sctn-cose-alg-reg]]): <pre class="example" highlight="json"> @@ -3257,7 +3770,7 @@ to be used with the RS256 signature algorithm (RSASSA-PKCS1-v1_5 with SHA-256, s </pre> -### Attestation Statement Formats ### {#attestation-formats} +### Attestation Statement Formats ### {#sctn-attestation-formats} As described above, an [=attestation statement format=] is a data format which represents a cryptographic signature by an [=authenticator=] over a set of contextual bindings. Each [=attestation statement format=] MUST be defined using the following @@ -3269,7 +3782,7 @@ template: - <strong>Syntax:</strong> The syntax of an [=attestation statement=] produced in this format, defined using [[!CDDL]] for the extension point - `$attStmtFormat` defined in [[#generating-an-attestation-object]]. + `$attStmtFormat` defined in [[#sctn-generating-an-attestation-object]]. - <dfn>Signing procedure</dfn>: The [=signing procedure=] for computing an [=attestation statement=] in this [=attestation statement format|format=] given @@ -3288,7 +3801,7 @@ template: empty (in case of [=self attestation=]), an identifier of an [=ECDAA-Issuer public key=] (in the case of [=ECDAA=]), or a set of X.509 certificates. -The initial list of specified [=attestation statement formats=] is in [[#defined-attestation-formats]]. +The initial list of specified [=attestation statement formats=] is in [[#sctn-defined-attestation-formats]]. <!-- Editors Note: differentiating section IDs from non-section IDs is useful because at times we need to seperately reference @@ -3303,12 +3816,12 @@ Note: This specification does not define any data structures explicitly expressi calling {{CredentialsContainer/create()|navigator.credentials.create()}} they select an [=attestation conveyance=] other than {{AttestationConveyancePreference/none}} and verify the received [=attestation statement=] &mdash; will determine the employed [=attestation type=] as a part of [=verification procedure|verification=]. See the "Verification procedure" subsections of -[[#defined-attestation-formats]]. See also [[#sec-attestation-privacy]]. +[[#sctn-defined-attestation-formats]]. See also [[#sctn-attestation-privacy]]. : <dfn>Basic Attestation</dfn> (<dfn>Basic</dfn>) :: In the case of basic attestation [[UAFProtocol]], the authenticator's [=attestation key pair=] is specific to an authenticator model. Thus, authenticators of the same model often share the same attestation key pair. See - [[#sec-attestation-privacy]] for further information. + [[#sctn-attestation-privacy]] for further information. : <dfn>Self Attestation</dfn> (<dfn>Self</dfn>) :: In the case of [=self attestation=], also known as surrogate basic attestation [[UAFProtocol]], the Authenticator does not have @@ -3340,9 +3853,9 @@ calling {{CredentialsContainer/create()|navigator.credentials.create()}} they se as ECDAA-Issuer (see [[FIDOEcdaaAlgorithm]]). : No attestation statement (<dfn>None</dfn>) -:: In this case, no attestation information is available. See also [[#none-attestation]]. +:: In this case, no attestation information is available. See also [[#sctn-none-attestation]]. -### Generating an Attestation Object ### {#generating-an-attestation-object} +### Generating an Attestation Object ### {#sctn-generating-an-attestation-object} To generate an [=attestation object=] (see: [Figure 5](#fig-attStructs)) given: @@ -3376,7 +3889,7 @@ the [=authenticator=] MUST: attStmtTemplate .within $$attStmtType ``` -### Signature Formats for Packed Attestation, FIDO U2F Attestation, and Assertion Signatures ### {#signature-attestation-types} +### Signature Formats for Packed Attestation, FIDO U2F Attestation, and Assertion Signatures ### {#sctn-signature-attestation-types} - For COSEAlgorithmIdentifier -7 (ES256), and other ECDSA-based algorithms, a signature value is encoded as an ASN.1 DER Ecdsa-Sig-Value, as defined in [[RFC3279]] section 2.2.3. @@ -3405,7 +3918,7 @@ the [=authenticator=] MUST: RSASSA-PSS signature scheme defined in section 8.1.1 in [[RFC8017]] with SHA-256 as the hash function. The signature is not ASN.1 wrapped. -# [=[WRP]=] Operations # {#rp-operations} +# [=[WRP]=] Operations # {#sctn-rp-operations} A [=registration ceremony|registration=] or [=authentication ceremony=] begins with the [=[WRP]=] creating a {{PublicKeyCredentialCreationOptions}} or {{PublicKeyCredentialRequestOptions}} object, respectively, which encodes the parameters for the [=ceremony=]. The [=[RP]=] @@ -3418,12 +3931,15 @@ the scope of this specification. This section describes the operations that the structures. -## Registering a New Credential ## {#registering-a-new-credential} +## Registering a New Credential ## {#sctn-registering-a-new-credential} When registering a new credential, represented by an {{AuthenticatorAttestationResponse}} structure |response| and an {{AuthenticationExtensionsClientOutputs}} structure |clientExtensionResults|, as part of a [=registration ceremony=], a [=[RP]=] MUST proceed as follows: +1. Let |options| be the {{PublicKeyCredentialCreationOptions}} that was passed + as the <code>{{CredentialCreationOptions/publicKey}}</code> option in the {{CredentialsContainer/create()}} call. + 1. Let |JSONtext| be the result of running [=UTF-8 decode=] on the value of <code>|response|.{{AuthenticatorResponse/clientDataJSON}}</code>. @@ -3438,14 +3954,14 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR 1. Verify that the value of <code>|C|.{{CollectedClientData/type}}</code> is `webauthn.create`. -1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> matches the challenge that was sent to the - authenticator in the {{CredentialsContainer/create()}} call. +1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> equals + the base64url encoding of <code>|options|.{{PublicKeyCredentialCreationOptions/challenge}}</code>. 1. Verify that the value of <code>|C|.{{CollectedClientData/origin}}</code> matches the [=[RP]=]'s [=origin=]. 1. Verify that the value of <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/status}}</code> matches the state of [=Token Binding=] for the TLS connection over which the [=assertion=] was obtained. If [=Token Binding=] was used on that TLS connection, also verify that <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/id}}</code> matches the [=base64url encoding=] of the [=Token Binding ID=] for the connection. -1. Compute the hash of <code>|response|.{{AuthenticatorResponse/clientDataJSON}}</code> using SHA-256. +1. Let |hash| be the result of computing a hash over <code>|response|.{{AuthenticatorResponse/clientDataJSON}}</code> using SHA-256. 1. Perform CBOR decoding on the {{AuthenticatorAttestationResponse/attestationObject}} field of the {{AuthenticatorAttestationResponse}} structure to obtain the attestation statement format |fmt|, the [=authenticator data=] @@ -3458,14 +3974,17 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR 1. If [=user verification=] is required for this registration, verify that the [=User Verified=] bit of the <code>[=flags=]</code> in |authData| is set. +1. Verify that the "alg" parameter in the [=credentialPublicKey|credential public key=] in |authData| + matches the {{PublicKeyCredentialParameters/alg}} attribute of one of the [=list/items=] in + <code>|options|.{{PublicKeyCredentialCreationOptions/pubKeyCredParams}}</code>. + 1. Verify that the values of the [=client extension outputs=] in |clientExtensionResults| and the [=authenticator extension outputs=] in the <code>[=authdataextensions|extensions=]</code> in |authData| are as expected, considering the [=client - extension input=] values that were given as the {{PublicKeyCredentialCreationOptions/extensions}} option in the - {{CredentialsContainer/create()}} call. + extension input=] values that were given in <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>. In particular, any [=extension identifier=] values in the |clientExtensionResults| and the <code>[=authdataextensions|extensions=]</code> in |authData| - MUST be also be present as [=extension identifier=] values in - the {{PublicKeyCredentialCreationOptions/extensions}} member of |options|, + MUST also be present as [=extension identifier=] values in + <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>, i.e., no extensions are present that were not requested. In the general case, the meaning of "are as expected" is specific to the [=[RP]=] and which extensions are in use. @@ -3478,10 +3997,9 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR is maintained in the IANA registry of the same name [[!WebAuthn-Registries]]. 1. Verify that |attStmt| is a correct [=attestation statement=], conveying a valid [=attestation signature=], by using the - [=attestation statement format=] |fmt|'s [=verification procedure=] given |attStmt|, |authData| and the [=hash of the serialized - client data=] computed in step 7. + [=attestation statement format=] |fmt|'s [=verification procedure=] given |attStmt|, |authData| and |hash|. - Note: Each [=attestation statement format=] specifies its own [=verification procedure=]. See [[#defined-attestation-formats]] for + Note: Each [=attestation statement format=] specifies its own [=verification procedure=]. See [[#sctn-defined-attestation-formats]] for the initially-defined formats, and [[!WebAuthn-Registries]] for the up-to-date list. 1. If validation is successful, obtain a list of acceptable trust anchors (attestation root certificates or [=ECDAA-Issuer @@ -3489,27 +4007,26 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR example, the FIDO Metadata Service [[FIDOMetadataService]] provides one way to obtain such information, using the <code>[=aaguid=]</code> in the <code>[=attestedCredentialData=]</code> in |authData|. -1. Assess the attestation trustworthiness using the outputs of the [=verification procedure=] in step 14, as follows: +1. Assess the attestation trustworthiness using the outputs of the [=verification procedure=] in step 16, as follows: - If [=None|no attestation=] was provided, verify that [=None=] attestation is acceptable under [=[RP]=] policy. - If [=self attestation=] was used, verify that [=self attestation=] is acceptable under [=[RP]=] policy. - If [=ECDAA=] was used, verify that the [=identifier of the ECDAA-Issuer public key=], returned as the [=attestation trust path=] from the [=verification procedure=], - is included in the set of acceptable trust anchors obtained in step 15. + is included in the set of acceptable trust anchors obtained in step 17. - Otherwise, use the X.509 certificates returned as the [=attestation trust path=] from the [=verification procedure=] to verify that the attestation public key correctly chains up to an acceptable root certificate. -1. Check that the <code>[=credentialId=]</code> is not yet registered to any other user. If registration - is requested for a credential that is already registered to a different user, the [=[RP]=] SHOULD +1. Check that the <code>[=credentialId=]</code> is not yet registered to any other user. If registration + is requested for a credential that is already registered to a different user, the [=[RP]=] SHOULD fail this [=registration ceremony=], or it MAY decide to accept the registration, e.g. while deleting the older registration. 1. If the attestation statement |attStmt| verified successfully and is found to be trustworthy, then register the new - credential with the account that was denoted in the - {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)/options}}.{{PublicKeyCredentialCreationOptions/user}} passed to - {{CredentialsContainer/create()}}, by associating it with the <code>[=credentialId=]</code> and + credential with the account that was denoted in <code>|options|.{{PublicKeyCredentialCreationOptions/user}}</code>, + by associating it with the <code>[=credentialId=]</code> and <code>[=credentialPublicKey=]</code> in the <code>[=attestedCredentialData=]</code> in |authData|, as appropriate for the [=[RP]=]'s system. -1. If the attestation statement |attStmt| successfully verified but is not trustworthy per step 16 above, the [=[RP]=] SHOULD fail +1. If the attestation statement |attStmt| successfully verified but is not trustworthy per step 18 above, the [=[RP]=] SHOULD fail the [=registration ceremony=]. NOTE: However, if permitted by policy, the [=[RP]=] MAY register the [=credential ID=] and credential public key but treat the @@ -3518,19 +4035,22 @@ When registering a new credential, represented by an {{AuthenticatorAttestationR See [[FIDOSecRef]] and [[UAFProtocol]] for a more detailed discussion. Verification of [=attestation objects=] requires that the [=[RP]=] has a trusted method of determining acceptable trust anchors -in step 15 above. Also, if certificates are being used, the [=[RP]=] MUST have access to certificate status information for the +in step 17 above. Also, if certificates are being used, the [=[RP]=] MUST have access to certificate status information for the intermediate CA certificates. The [=[RP]=] MUST also be able to build the attestation certificate chain if the client did not provide this chain in the attestation information. -## Verifying an Authentication Assertion ## {#verifying-assertion} +## Verifying an Authentication Assertion ## {#sctn-verifying-assertion} When verifying a given {{PublicKeyCredential}} structure (|credential|) and an {{AuthenticationExtensionsClientOutputs}} structure |clientExtensionResults|, as part of an [=authentication ceremony=], the [=[RP]=] MUST proceed as follows: -1. If the {{PublicKeyCredentialRequestOptions/allowCredentials}} option was given when this [=authentication ceremony=] was - initiated, verify that <code>|credential|.{{Credential/id}}</code> identifies one of the [=public key credentials=] that were - listed in {{PublicKeyCredentialRequestOptions/allowCredentials}}. +1. Let |options| be the {{PublicKeyCredentialRequestOptions}} that was passed + as the <code>{{CredentialCreationOptions/publicKey}}</code> option in the {{CredentialsContainer/get()}} call. + +1. If <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> [=list/is not empty=], + verify that <code>|credential|.{{Credential/id}}</code> identifies one of the [=public key credentials=] + listed in <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code>. 1. Identify the user being authenticated and verify that this user is the owner of the [=public key credential source=] |credentialSource| identified by <code>|credential|.{{Credential/id}}</code>: @@ -3546,8 +4066,9 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an { present, and that the user identified by this value is the owner of |credentialSource|. </dl> -1. Using |credential|'s {{Credential/id}} attribute (or the corresponding {{PublicKeyCredential/rawId}}, if - [=base64url encoding=] is inappropriate for your use case), look up the corresponding credential public key. +1. Using <code>|credential|.{{Credential/id}}</code> (or <code>|credential|.{{PublicKeyCredential/rawId}}</code>, if + [=base64url encoding=] is inappropriate for your use case), look up the corresponding [=credential public key=] + and let |credentialPublicKey| be that [=credential public key=]. 1. Let |cData|, |authData| and |sig| denote the value of |credential|'s {{PublicKeyCredential/response}}'s {{AuthenticatorResponse/clientDataJSON}}, {{AuthenticatorAssertionResponse/authenticatorData}}, and @@ -3566,14 +4087,21 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an { 1. Verify that the value of <code>|C|.{{CollectedClientData/type}}</code> is the string `webauthn.get`. -1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> matches the challenge that was sent to the - authenticator in the {{PublicKeyCredentialRequestOptions}} passed to the {{CredentialsContainer/get()}} call. +1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> equals + the base64url encoding of <code>|options|.{{PublicKeyCredentialRequestOptions/challenge}}</code>. 1. Verify that the value of <code>|C|.{{CollectedClientData/origin}}</code> matches the [=[RP]=]'s [=origin=]. 1. Verify that the value of <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/status}}</code> matches the state of [=Token Binding=] for the TLS connection over which the attestation was obtained. If [=Token Binding=] was used on that TLS connection, also verify that <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/id}}</code> matches the [=base64url encoding=] of the [=Token Binding ID=] for the connection. -1. Verify that the <code>[=rpIdHash=]</code> in |authData| is the SHA-256 hash of the [=RP ID=] expected by the [=[RP]=]. +<!-- Note: this next step is actually a top-level step, but bikeshed wanted it indented this much in order to render it as +a numbered step. If outdented, it (today) is rendered as a bullet in the midst of a numbered list :-/ +--> + <li id='rp-op-verifying-assertion-step-rpid-hash'> + Verify that the <code>[=rpIdHash=]</code> in |authData| is the SHA-256 hash of the [=RP ID=] expected by the [=[RP]=]. + + Note: If using the [=appid=] extension, this step needs some special logic. See [[#sctn-appid-extension]] for details. + </li> 1. Verify that the [=User Present=] bit of the <code>[=flags=]</code> in |authData| is set. @@ -3582,12 +4110,11 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an { 1. Verify that the values of the [=client extension outputs=] in |clientExtensionResults| and the [=authenticator extension outputs=] in the <code>[=authdataextensions|extensions=]</code> in |authData| are as expected, considering the [=client - extension input=] values that were given as the {{PublicKeyCredentialRequestOptions/extensions}} option in the - {{CredentialsContainer/get()}} call. + extension input=] values that were given in <code>|options|.{{PublicKeyCredentialRequestOptions/extensions}}</code>. In particular, any [=extension identifier=] values in the |clientExtensionResults| and the <code>[=authdataextensions|extensions=]</code> in |authData| - MUST be also be present as [=extension identifier=] values in - the {{PublicKeyCredentialCreationOptions/extensions}} member of |options|, + MUST also be present as [=extension identifier=] values in + the <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>, i.e., no extensions are present that were not requested. In the general case, the meaning of "are as expected" is specific to the [=[RP]=] and which extensions are in use. @@ -3596,30 +4123,30 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an { 1. Let |hash| be the result of computing a hash over the |cData| using SHA-256. -1. Using the credential public key looked up in step 3, verify that |sig| is a valid signature over the binary concatenation of +1. Using |credentialPublicKey|, verify that |sig| is a valid signature over the binary concatenation of |authData| and |hash|. Note: This verification step is compatible with signatures generated by FIDO U2F authenticators. See [[#sctn-fido-u2f-sig-format-compat]]. 1. If the [=signature counter=] value |authData|.<code>[=signCount=]</code> is nonzero or the value stored - in conjunction with |credential|'s {{Credential/id}} attribute + in conjunction with <code>|credential|.{{Credential/id}}</code> is nonzero, then run the following sub-step: - If the [=signature counter=] value |authData|.<code>[=signCount=]</code> is <dl class="switch"> - <dt>greater than the [=signature counter=] value stored in conjunction - with |credential|'s {{Credential/id}} attribute.</dt> - <dd>Update the stored [=signature counter=] value, associated with - |credential|'s {{Credential/id}} attribute, to be the value of + <dt>greater than the [=signature counter=] value stored in conjunction + with <code>|credential|.{{Credential/id}}</code>.</dt> + <dd>Update the stored [=signature counter=] value, associated with + <code>|credential|.{{Credential/id}}</code>, to be the value of |authData|.<code>[=signCount=]</code>.</dd> <dt>less than or equal to the [=signature counter=] value stored in conjunction - with |credential|'s {{Credential/id}} attribute.</dt> + with <code>|credential|.{{Credential/id}}</code>.</dt> <dd>This is a signal that - the authenticator may be cloned, i.e. at least - two copies of the [=credential private key=] may exist and are - being used in parallel. [=[RPS]=] should incorporate this information - into their risk scoring. Whether the [=[RP]=] updates the - stored [=signature counter=] value in this case, or not, or fails the + the authenticator may be cloned, i.e. at least + two copies of the [=credential private key=] may exist and are + being used in parallel. [=[RPS]=] should incorporate this information + into their risk scoring. Whether the [=[RP]=] updates the + stored [=signature counter=] value in this case, or not, or fails the [=authentication ceremony=] or not, is [=[RP]=]-specific. </dd> </dl> @@ -3628,14 +4155,14 @@ When verifying a given {{PublicKeyCredential}} structure (|credential|) and an { [=authentication ceremony=]. -# Defined Attestation Statement Formats # {#defined-attestation-formats} +# Defined Attestation Statement Formats # {#sctn-defined-attestation-formats} WebAuthn supports pluggable attestation statement formats. This section defines an initial set of such formats. ## Attestation Statement Format Identifiers ## {#sctn-attstn-fmt-ids} Attestation statement formats are identified by a string, called an <dfn>attestation statement format identifier</dfn>, chosen by -the author of the attestation statement format. +the author of the [=attestation statement format=]. Attestation statement format identifiers SHOULD be registered per [[!WebAuthn-Registries]] "Registries for Web Authentication (WebAuthn)". All registered attestation statement format identifiers are unique amongst themselves as a matter of course. @@ -3650,15 +4177,14 @@ Note: This means attestation statement format identifiers based on domain names Implementations MUST match WebAuthn attestation statement format identifiers in a case-sensitive fashion. Attestation statement formats that may exist in multiple versions SHOULD include a version in their identifier. In effect, -different versions are thus treated as different formats, e.g., `packed2` as a new version of the `packed` attestation statement -format. +different versions are thus treated as different formats, e.g., `packed2` as a new version of the [[#sctn-packed-attestation]]. The following sections present a set of currently-defined and registered attestation statement formats and their identifiers. -The up-to-date list of registered WebAuthn Extensions is maintained in the IANA "WebAuthn Attestation Statement Format +The up-to-date list of registered [=WebAuthn Extensions=] is maintained in the IANA "WebAuthn Attestation Statement Format Identifier" registry established by [[!WebAuthn-Registries]]. -## Packed Attestation Statement Format ## {#packed-attestation} +## Packed Attestation Statement Format ## {#sctn-packed-attestation} This is a WebAuthn optimized attestation statement format. It uses a very compact but still extensible encoding method. It is implementable by [=authenticators=] with limited resources (e.g., secure elements). @@ -3715,9 +4241,9 @@ implementable by [=authenticators=] with limited resources (e.g., secure element as defined section 3.3, step 3.5 in [[!FIDOEcdaaAlgorithm]]. : Signing procedure -:: The signing procedure for this attestation statement format is +:: The signing procedure for this attestation statement format is similar to [the procedure for generating assertion signatures](#fig-signature). - 1. Let |authenticatorData| denote the [=authenticator data for the attestation=], + 1. Let |authenticatorData| denote the [=authenticator data for the attestation=], and let |clientDataHash| denote the [=hash of the serialized client data=]. 1. If [=Basic=] or [=AttCA=] [=attestation=] is in use, the authenticator produces the |sig| by concatenating |authenticatorData| and @@ -3727,7 +4253,7 @@ implementable by [=authenticators=] with limited resources (e.g., secure element 1. If [=ECDAA=] is in use, the authenticator produces |sig| by concatenating |authenticatorData| and |clientDataHash|, and signing the result using ECDAA-Sign (see section 3.5 of [[!FIDOEcdaaAlgorithm]]) after selecting an - [=ECDAA-Issuer public key=] related to the ECDAA signature private key through an + [=ECDAA-Issuer public key=] related to the ECDAA signature private key through an authenticator-specific mechanism (see [[!FIDOEcdaaAlgorithm]]). It sets |alg| to the algorithm of the selected [=ECDAA-Issuer public key=] and |ecdaaKeyId| to the [=identifier of the ECDAA-Issuer public key=] (see above). @@ -3745,7 +4271,7 @@ implementable by [=authenticators=] with limited resources (e.g., secure element 1. If |x5c| is present, this indicates that the attestation type is not [=ECDAA=]. In this case: - Verify that |sig| is a valid signature over the concatenation of |authenticatorData| and |clientDataHash| using the attestation public key in |attestnCert| with the algorithm specified in |alg|. - - Verify that |attestnCert| meets the requirements in [[#packed-attestation-cert-requirements]]. + - Verify that |attestnCert| meets the requirements in [[#sctn-packed-attestation-cert-requirements]]. - If |attestnCert| contains an extension with OID 1.3.6.1.4.1.45724.1.1.4 (`id-fido-gen-ce-aaguid`) verify that the value of this extension matches the <code>[=aaguid=]</code> in |authenticatorData|. - Optionally, inspect |x5c| and consult externally provided knowledge to determine whether |attStmt| conveys a @@ -3767,7 +4293,7 @@ implementable by [=authenticators=] with limited resources (e.g., secure element [=attestation trust path=]. -### Packed Attestation Statement Certificate Requirements ### {#packed-attestation-cert-requirements} +### Packed Attestation Statement Certificate Requirements ### {#sctn-packed-attestation-cert-requirements} The attestation certificate MUST have the following fields/extensions: @@ -3805,7 +4331,7 @@ The attestation certificate MUST have the following fields/extensions: See, for example, the FIDO Metadata Service [[FIDOMetadataService]]. -## TPM Attestation Statement Format ## {#tpm-attestation} +## TPM Attestation Statement Format ## {#sctn-tpm-attestation} This attestation statement format is generally used by authenticators that use a Trusted Platform Module as their cryptographic engine. @@ -3861,13 +4387,13 @@ engine. step 3.5 in [[!FIDOEcdaaAlgorithm]]. : sig - :: The attestation signature, in the form of a TPMT_SIGNATURE structure as specified in [[TPMv2-Part2]] section 11.3.4. + :: The attestation signature, in the form of a TPMT_SIGNATURE structure as specified in [[!TPMv2-Part2]] section 11.3.4. : certInfo - :: The TPMS_ATTEST structure over which the above signature was computed, as specified in [[TPMv2-Part2]] section 10.12.8. + :: The TPMS_ATTEST structure over which the above signature was computed, as specified in [[!TPMv2-Part2]] section 10.12.8. : pubArea - :: The TPMT_PUBLIC structure (see [[TPMv2-Part2]] section 12.2.4) used by the TPM to represent the credential public key. + :: The TPMT_PUBLIC structure (see [[!TPMv2-Part2]] section 12.2.4) used by the TPM to represent the credential public key. : Signing procedure :: Let |authenticatorData| denote the [=authenticator data for the attestation=], and let |clientDataHash| denote the @@ -3875,7 +4401,7 @@ engine. Concatenate |authenticatorData| and |clientDataHash| to form |attToBeSigned|. - Generate a signature using the procedure specified in [[TPMv2-Part3]] Section 18.2, using the attestation private key and + Generate a signature using the procedure specified in [[!TPMv2-Part3]] Section 18.2, using the attestation private key and setting the `extraData` parameter to the digest of |attToBeSigned| using the hash algorithm corresponding to the "alg" signature algorithm. (For the "RS256" algorithm, this would be a SHA-256 digest.) @@ -3898,18 +4424,18 @@ engine. - Verify that `magic` is set to `TPM_GENERATED_VALUE`. - Verify that `type` is set to `TPM_ST_ATTEST_CERTIFY`. - Verify that `extraData` is set to the hash of |attToBeSigned| using the hash algorithm employed in "alg". - - Verify that `attested` contains a `TPMS_CERTIFY_INFO` structure as specified in [[TPMv2-Part2]] section 10.12.3, + - Verify that `attested` contains a `TPMS_CERTIFY_INFO` structure as specified in [[!TPMv2-Part2]] section 10.12.3, whose `name` field contains a valid Name for |pubArea|, - as computed using the algorithm in the `nameAlg` field of |pubArea| using the procedure specified in [[TPMv2-Part1]] + as computed using the algorithm in the `nameAlg` field of |pubArea| using the procedure specified in [[!TPMv2-Part1]] section 16. - - Note that the remaining fields in the "Standard Attestation Structure" [[TPMv2-Part1]] + - Note that the remaining fields in the "Standard Attestation Structure" [[!TPMv2-Part1]] section 31.2, i.e., `qualifiedSigner`, `clockInfo` and `firmwareVersion` are ignored. These fields MAY be used as an input to risk engines. If |x5c| is present, this indicates that the attestation type is not [=ECDAA=]. In this case: - Verify the |sig| is a valid signature over |certInfo| using the attestation public key in |aikCert| with the algorithm specified in |alg|. - - Verify that |aikCert| meets the requirements in [[#tpm-cert-requirements]]. + - Verify that |aikCert| meets the requirements in [[#sctn-tpm-cert-requirements]]. - If |aikCert| contains an extension with OID `1 3 6 1 4 1 45724 1 1 4` (id-fido-gen-ce-aaguid) verify that the value of this extension matches the <code>[=aaguid=]</code> in |authenticatorData|. - If successful, return implementation-specific values representing [=attestation type=] [=AttCA=] and [=attestation trust @@ -3921,7 +4447,7 @@ engine. path=] |ecdaaKeyId|. -### TPM Attestation Statement Certificate Requirements ### {#tpm-cert-requirements} +### TPM Attestation Statement Certificate Requirements ### {#sctn-tpm-cert-requirements} TPM [=attestation certificate=] MUST have the following fields/extensions: @@ -3929,7 +4455,7 @@ TPM [=attestation certificate=] MUST have the following fields/extensions: - Subject field MUST be set to empty. -- The Subject Alternative Name extension MUST be set as defined in [[TPMv2-EK-Profile]] section 3.2.9. +- The Subject Alternative Name extension MUST be set as defined in [[!TPMv2-EK-Profile]] section 3.2.9. - The Extended Key Usage extension MUST contain the "joint-iso-itu-t(2) internationalorganizations(23) 133 tcg-kp(8) tcg-kp-AIKCertificate(3)" OID. @@ -3941,7 +4467,7 @@ TPM [=attestation certificate=] MUST have the following fields/extensions: See, for example, the FIDO Metadata Service [[FIDOMetadataService]]. -## Android Key Attestation Statement Format ## {#android-key-attestation} +## Android Key Attestation Statement Format ## {#sctn-android-key-attestation} When the [=authenticator=] in question is a platform-provided Authenticator on the Android "N" or later platform, the attestation statement is based on the [Android key @@ -4012,15 +4538,15 @@ the attestation=] is consistent with the fields of the attestation certificate's - If successful, return implementation-specific values representing [=attestation type=] [=Basic=] and [=attestation trust path=] |x5c|. -### Android Key Attestation Statement Certificate Requirements ### {#key-attstn-cert-requirements} +### Android Key Attestation Statement Certificate Requirements ### {#sctn-key-attstn-cert-requirements} -Android Key Attestation [=attestation certificate=]'s <dfn>android key attestation certificate extension -data</dfn> is identified by the OID "1.3.6.1.4.1.11129.2.1.17". +Android Key Attestation [=attestation certificate=]'s <dfn>android key attestation certificate extension +data</dfn> is identified by the OID "1.3.6.1.4.1.11129.2.1.17", and its schema is defined in the [Android developer documentation](https://developer.android.com/training/articles/security-key-attestation#certificate_schema). -## Android SafetyNet Attestation Statement Format ## {#android-safetynet-attestation} +## Android SafetyNet Attestation Statement Format ## {#sctn-android-safetynet-attestation} When the [=authenticator=] is platform-provided by certain Android platforms, the attestation -statement may be based on the [SafetyNet API](https://developer.android.com/training/safetynet/attestation.html). In +statement may be based on the [SafetyNet API](https://developer.android.com/training/safetynet/attestation#compat-check-response). In this case the [=authenticator data=] is completely controlled by the caller of the SafetyNet API (typically an application running on the Android platform) and the attestation statement provides some statements about the health of the platform and the identity of the calling application @@ -4053,8 +4579,8 @@ and the identity of the calling application :: The version number of Google Play Services responsible for providing the SafetyNet API. : response - :: The [=UTF-8 encoded=] result of the getJwsResult() call of the SafetyNet API. This value is a JWS [[RFC7515]] object (see - [SafetyNet online documentation](https://developer.android.com/training/safetynet/attestation.html#compat-check-response)) + :: The [=UTF-8 encoded=] result of the getJwsResult() call of the SafetyNet API. This value is a JWS [[!RFC7515]] object (see + [SafetyNet online documentation](https://developer.android.com/training/safetynet/attestation#compat-check-response)) in Compact Serialization. : Signing procedure @@ -4072,17 +4598,17 @@ and the identity of the calling application as follows: - Verify that |attStmt| is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the contained fields. - - Verify that |response| is a valid SafetyNet response of version |ver| + - Verify that |response| is a valid SafetyNet response of version |ver| by following the steps indicated by the [SafetyNet online documentation](https://developer.android.com/training/safetynet/attestation.html#compat-check-response). As of this writing, there is only one format of the SafetyNet response and |ver| is reserved for future use. - Verify that the `nonce` attribute in the payload of |response| is identical to the Base64 encoding of the SHA-256 hash of the concatenation of |authenticatorData| and |clientDataHash|. - - Verify that the SafetyNet response actually came from the SafetyNet service by following the steps in the - [SafetyNet online documentation](https://developer.android.com/training/safetynet/attestation.html#compat-check-response). + - Verify that the SafetyNet response actually came from the SafetyNet service by following the steps in the + [SafetyNet online documentation](https://developer.android.com/training/safetynet/attestation#compat-check-response). - If successful, return implementation-specific values representing [=attestation type=] [=Basic=] and [=attestation trust path=] |x5c|. -## FIDO U2F Attestation Statement Format ## {#fido-u2f-attestation} +## FIDO U2F Attestation Statement Format ## {#sctn-fido-u2f-attestation} This attestation statement format is used with FIDO U2F authenticators using the formats defined in [[FIDO-U2F-Message-Formats]]. @@ -4114,7 +4640,7 @@ This attestation statement format is used with FIDO U2F authenticators using the :: A single element array containing the attestation certificate in X.509 format. : sig - :: The [=attestation signature=]. + :: The [=attestation signature=]. The signature was calculated over the (raw) U2F registration response message [[!FIDO-U2F-Message-Formats]] received by the [=client=] from the authenticator. @@ -4124,7 +4650,7 @@ This attestation statement format is used with FIDO U2F authenticators using the and let |clientDataHash| denote the [=hash of the serialized client data=]. (Since SHA-256 is used to hash the serialized client data, |clientDataHash| will be 32 bytes long.) - Generate a Registration Response Message as specified in [[FIDO-U2F-Message-Formats]] [=Section 4.3=], with the application parameter set to the + Generate a Registration Response Message as specified in [[!FIDO-U2F-Message-Formats]] [=Section 4.3=], with the application parameter set to the SHA-256 hash of the [=RP ID=] that the given [=public key credential|credential=] is [=scoped=] to, the challenge parameter set to |clientDataHash|, and the key handle parameter set to the [=credential ID=] of the given credential. Set the raw signature part of this Registration Response Message (i.e., without the [=user public key=], key handle, and attestation certificates) as |sig| and set the attestation certificates of @@ -4136,8 +4662,8 @@ This attestation statement format is used with FIDO U2F authenticators using the 1. Verify that |attStmt| is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the contained fields. 1. Check that |x5c| has exactly one element and let |attCert| be that element. Let |certificate public key| be the public key - conveyed by |attCert|. If |certificate public key| is not an Elliptic Curve (EC) public - key over the P-256 curve, terminate this algorithm and return an appropriate error. + conveyed by |attCert|. If |certificate public key| is not an Elliptic Curve (EC) public + key over the P-256 curve, terminate this algorithm and return an appropriate error. 1. Extract the claimed |rpIdHash| from |authenticatorData|, and the claimed |credentialId| and |credentialPublicKey| from |authenticatorData|.<code>[=attestedCredentialData=]</code>. 1. Convert the COSE_KEY formatted |credentialPublicKey| (see [=Section 7=] of [[!RFC8152]]) to Raw ANSI X9.62 public key @@ -4147,21 +4673,24 @@ This attestation statement format is used with FIDO U2F authenticators using the If size differs or "-2" key is not found, terminate this algorithm and return an appropriate error. - Let |y| be the value corresponding to the "-3" key (representing y coordinate) in |credentialPublicKey|, and confirm its size to be of 32 bytes. - If size differs or "-3" key is not found, terminate this algorithm and return an appropriate error. + If size differs or "-3" key is not found, terminate this algorithm and return an appropriate error. - Let |publicKeyU2F| be the concatenation <code>0x04 || |x| || |y|</code>. Note: This signifies uncompressed ECC key format. 1. Let |verificationData| be the concatenation of (0x00 || |rpIdHash| || |clientDataHash| || |credentialId| || |publicKeyU2F|) (see [=Section 4.3=] of [[!FIDO-U2F-Message-Formats]]). - 1. Verify the |sig| using |verificationData| and |certificate public key| per [[!SEC1]]. + 1. Verify the |sig| using |verificationData| and the |certificate public key| per section 4.1.4 of [[!SEC1]] with SHA-256 as the hash function used in step two. 1. Optionally, inspect |x5c| and consult externally provided knowledge to determine whether |attStmt| conveys a [=Basic=] or [=AttCA=] attestation. 1. If successful, return implementation-specific values representing [=attestation type=] [=Basic=], [=AttCA=] or uncertainty, and [=attestation trust path=] |x5c|. -## None Attestation Statement Format ## {#none-attestation} +## None Attestation Statement Format ## {#sctn-none-attestation} + +The none attestation statement format is used to replace any [=authenticator=]-provided [=attestation statement=] when a [=[WRP]=] indicates it does not wish to receive attestation information, see [[#enum-attestation-convey]]. -The none attestation statement format is used to replace any [=authenticator=]-provided [=attestation statement=] when a [=[WRP]=] indicates it does not wish to receive attestation information, see [[#attestation-convey]]. +The [=authenticator=] MAY also directly generate attestation statements of this format +if the [=authenticator=] does not support [=attestation=]. : Attestation statement format identifier :: none @@ -4187,10 +4716,10 @@ The none attestation statement format is used to replace any [=authenticator=]-p : Verification procedure :: Return implementation-specific values representing [=attestation type=] [=None=] and an empty [=attestation trust path=]. -# WebAuthn Extensions # {#extensions} +# <dfn>WebAuthn Extensions</dfn> # {#sctn-extensions} The mechanism for generating [=public key credentials=], as well as requesting and generating Authentication assertions, as -defined in [[#api]], can be extended to suit particular use cases. Each case is addressed by defining a <dfn>registration +defined in [[#sctn-api]], can be extended to suit particular use cases. Each case is addressed by defining a <dfn>registration extension</dfn> and/or an <dfn>authentication extension</dfn>. Every extension is a <dfn>client extension</dfn>, meaning that the extension involves communication with and processing by the @@ -4230,14 +4759,14 @@ that it supports, and returns the [=CBOR=] [=authenticator extension output=] fo the [=client extension processing=] for [=authenticator extensions=] is to use the [=authenticator extension output=] as an input to creating the [=client extension output=]. -All WebAuthn extensions are OPTIONAL for both clients and authenticators. Thus, any extensions requested by a [=[RP]=] MAY be +All [=WebAuthn Extensions=] are OPTIONAL for both clients and authenticators. Thus, any extensions requested by a [=[RP]=] MAY be ignored by the client browser or OS and not passed to the authenticator at all, or they MAY be ignored by the authenticator. Ignoring an extension is never considered a failure in WebAuthn API processing, so when [=[RPS]=] include extensions with any API calls, they MUST be prepared to handle cases where some or all of those extensions are ignored. Clients wishing to support the widest possible range of extensions MAY choose to pass through any extensions that they do not recognize to authenticators, generating the [=authenticator extension input=] by simply encoding the [=client extension input=] -in CBOR. All WebAuthn extensions MUST be defined in such a way that this implementation choice does not endanger the user's +in CBOR. All [=WebAuthn Extensions=] MUST be defined in such a way that this implementation choice does not endanger the user's security or privacy. For instance, if an extension requires client processing, it could be defined in a manner that ensures such a naïve pass-through will produce a semantically invalid [=authenticator extension input=] value, resulting in the extension being ignored by the authenticator. Since all extensions are OPTIONAL, this will not cause a functional failure in the API @@ -4251,7 +4780,7 @@ are converted to [=CBOR=] values in the [=authenticator extension inputs=]. When the JavaScript value is an [=%ArrayBuffer%=], it is converted to a [=CBOR=] byte array. When the JavaScript value is a non-integer number, it is converted to a 64-bit CBOR floating point number. Otherwise, when the JavaScript type corresponds to a JSON type, the conversion is done -using the rules defined in Section 4.2 of [[RFC7049]] (Converting from JSON to CBOR), +using the rules defined in Section 4.2 of [[!RFC7049]] (Converting from JSON to CBOR), but operating on inputs of JavaScript type values rather than inputs of JSON type values. Once these conversions are done, canonicalization of the resulting [=CBOR=] MUST be performed using the [=CTAP2 canonical CBOR encoding form=]. @@ -4262,7 +4791,7 @@ are converted to JavaScript values in the [=client extension outputs=]. When the CBOR value is a byte string, it is converted to a JavaScript [=%ArrayBuffer%=] (rather than a base64url-encoded string). Otherwise, when the CBOR type corresponds to a JSON type, the conversion is done -using the rules defined in Section 4.1 of [[RFC7049]] (Converting from CBOR to JSON), +using the rules defined in Section 4.1 of [[!RFC7049]] (Converting from CBOR to JSON), but producing outputs of JavaScript type values rather than outputs of JSON type values. Note that some clients may choose to implement this pass-through capability under a feature flag. @@ -4270,7 +4799,7 @@ Supporting this capability can facilitate innovation, allowing authenticators to and [=[RPS]=] to use them before there is explicit support for them in clients. The IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]] can be consulted -for an up-to-date list of registered WebAuthn Extensions. +for an up-to-date list of registered [=WebAuthn Extensions=]. ## Extension Identifiers ## {#sctn-extension-id} @@ -4394,19 +4923,40 @@ These MAY be implemented by user agents targeting broad interoperability. ## FIDO <dfn>AppID</dfn> Extension (appid) ## {#sctn-appid-extension} This extension allows [=[WRPS]=] that have previously registered a -credential using the legacy FIDO JavaScript APIs to request an [=assertion=]. The +credential using the legacy FIDO U2F JavaScript API [[FIDOU2FJavaScriptAPI]] to request an [=assertion=]. The FIDO APIs use an alternative identifier for [=[RPS]=] called an |AppID| -[[FIDO-APPID]], and any credentials created using those APIs will be [=scoped=] to +[[!FIDO-APPID]], and any credentials created using those APIs will be [=scoped=] to that identifier. Without this extension, they would need to be re-registered in order to be [=scoped=] to an [=RP ID=]. +In addition to setting the {{AuthenticationExtensionsClientInputs/appid}} extension input, +using this extension requires some additional processing by the [=[RP]=] +in order to allow users to [=authentication|authenticate=] using their registered U2F credentials: + + 1. List the desired U2F credentials in the {{PublicKeyCredentialRequestOptions/allowCredentials}} option + of the {{CredentialsContainer/get()}} method: + + - Set the {{PublicKeyCredentialDescriptor/type}} members to {{PublicKeyCredentialType/public-key}}. + - Set the {{PublicKeyCredentialDescriptor/id}} members to the respective U2F key handles of the desired credentials. Note that U2F key handles commonly use [=base64url encoding=] but must be decoded to their binary form when used in {{PublicKeyCredentialDescriptor/id}}. + + {{PublicKeyCredentialRequestOptions/allowCredentials}} MAY contain a mixture + of both WebAuthn [=credential IDs=] and U2F key handles; + stating the {{AuthenticationExtensionsClientInputs/appid}} via this extension + does not prevent the user from using a WebAuthn-registered credential + scoped to the [=RP ID=] stated in {{PublicKeyCredentialRequestOptions/rpId}}. + + 1. When [verifying the assertion](#rp-op-verifying-assertion-step-rpid-hash), expect that the <code>[=rpIdHash=]</code> + MAY be the hash of the |AppID| instead of the [=RP ID=]. + This extension does not allow FIDO-compatible credentials to be created. Thus, credentials created with WebAuthn are not backwards compatible with the FIDO JavaScript APIs. Note: {{AuthenticationExtensionsClientInputs/appid}} should be set to the AppID that the [=[RP]=] *previously* used in the legacy FIDO APIs. -This might not be the same as the result of translating the [=[RP]=]'s WebAuthn [=RP ID=] to the AppID format. +This might not be the same as the result of translating the [=[RP]=]'s WebAuthn [=RP ID=] to the AppID format, +e.g., the previously used AppID may have been "https://accounts.example.com" +but the currently used [=RP ID=] might be "example.com". : Extension identifier :: `appid` @@ -4441,19 +4991,100 @@ This might not be the same as the result of translating the [=[RP]=]'s WebAuthn if the [=assertion=] was created by a U2F authenticator with the U2F application parameter set to the SHA-256 hash of |appId| instead of the SHA-256 hash of the [=RP ID=], set |output| to [TRUE]. -Note: In practice, several implementations do not implement steps four and onward of the -algorithm for [=determining if a caller's FacetID is authorized for an AppID=]. -Instead, in step three, the comparison on the host is relaxed to accept hosts on the -[=same site=]. +Note: In practice, several implementations do not implement steps four and onward of the +algorithm for [=determining if a caller's FacetID is authorized for an AppID=]. +Instead, in step three, the comparison on the host is relaxed to accept hosts on the +[=same site=]. + +: Client extension output +:: Returns the value of |output|. If true, the |AppID| was used and thus, when [verifying the assertion](#rp-op-verifying-assertion-step-rpid-hash), the [=[RP]=] MUST expect the <code>[=rpIdHash=]</code> to be the hash of the |AppID|, not the [=RP ID=]. + + <xmp class="idl"> + partial dictionary AuthenticationExtensionsClientOutputs { + boolean appid; + }; + + +: Authenticator extension input +:: None. + +: Authenticator extension processing +:: None. + +: Authenticator extension output +:: None. + +## FIDO AppID Exclusion Extension (appidExclude) ## {#sctn-appid-exclude-extension} + +This registration extension allows [=[WRPS]=] to exclude authenticators which contain specified credentials that were created with the legacy FIDO U2F JavaScript API [[FIDOU2FJavaScriptAPI]]. + +During a transition from the FIDO U2F JavaScript API, a [=[RP]=] may have a population of users with legacy credentials already registered. The [appid](#sctn-appid-extension) extension allows the sign-in flow to be transitioned smoothly but, when transitioning the registration flow, the [excludeCredentials](#dom-publickeycredentialcreationoptions-excludecredentials) field will not be effective in excluding authenticators with legacy credentials because its contents are taken to be WebAuthn credentials. This extension directs [=client platforms=] to consider the contents of [excludeCredentials](#dom-publickeycredentialcreationoptions-excludecredentials) as both WebAuthn and legacy FIDO credentials. Note that U2F key handles commonly use [=base64url encoding=] but must be decoded to their binary form when used in [excludeCredentials](#dom-publickeycredentialcreationoptions-excludecredentials). + + +: Extension identifier +:: `appidExclude` + +: Operation applicability +:: [=registration extension|Registration=] + +: Client extension input +:: A single USVString specifying a FIDO |AppID|. + + partial dictionary AuthenticationExtensionsClientInputs { + USVString appidExclude; + }; + + +: Client extension processing +:: When [[#sctn-createCredential|creating a new credential]]: + 1. Just after [establishing the RP ID](#CreateCred-DetermineRpId) perform these steps: + 1. Let |facetId| be the result of passing the caller's [=origin=] to the FIDO algorithm + for [=determining the FacetID of a calling application=]. + 1. Let |appId| be the value of the extension input {{appidExclude}}. + 1. Pass |facetId| and |appId| to the FIDO algorithm for [=determining if a caller's + FacetID is authorized for an AppID=]. If the latter algorithm rejects |appId| then + return a "{{SecurityError}}" {{DOMException}} and terminate the + [creating a new credential](#sctn-createCredential) algorithm as well as these steps. + + Note: In practice, several implementations do not implement steps four and onward of the algorithm for [=determining if a caller's FacetID is authorized for an AppID=]. Instead, in step three, the comparison on the host is relaxed to accept hosts on the [=same site=]. + + 1. Otherwise, continue with normal processing. + + 1. Just prior to [invoking authenticatorMakeCredential](#CreateCred-InvokeAuthnrMakeCred) perform these steps: + 1. If |authenticator| supports the U2F protocol [[!FIDO-U2F-Message-Formats]], then [=list/for each=] + [credential descriptor](#dictdef-publickeycredentialdescriptor) |C| in |excludeCredentialDescriptorList|: + 1. Check whether |C| was created using U2F on |authenticator| by sending a + `U2F_AUTHENTICATE` message to |authenticator| + whose "five parts" are set to the following values: + + : |control byte| + :: `0x07` ("check-only") + + : challenge parameter + :: 32 random bytes + + : application parameter + :: SHA-256 hash of |appId| -: Client extension output -:: Returns the value of |output|. If true, the |AppID| was used and thus, when [verifying an assertion](#verifying-assertion), the [=[RP]=] MUST expect the [=rpIdHash=] to be the hash of the |AppID|, not the [=RP ID=]. + : key handle length + :: The length of |C|.{{PublicKeyCredentialDescriptor/id}} (in bytes) - - partial dictionary AuthenticationExtensionsClientOutputs { - boolean appid; - }; - + : key handle + :: The value of |C|.{{PublicKeyCredentialDescriptor/id}}, i.e., the [=credential id=]. + + 1. If |authenticator| responds with `message:error:test-of-user-presence-required` (i.e., success): + cease normal processing of this |authenticator| and indicate in a platform-specific manner + that the authenticator is inapplicable. For example, this could be in the form of UI, or + could involve requesting [=user consent=] from |authenticator| and, upon receipt, treating + it as if the authenticator had returned {{InvalidStateError}}. Requesting [=user consent=] + can be accomplished by sending another `U2F_AUTHENTICATE` message to |authenticator| as + above except for setting |control byte| to `0x03` ("enforce-user-presence-and-sign"), + and ignoring the response. + + 1. Continue with normal processing. + +: Client extension output +:: None. : Authenticator extension input :: None. @@ -4464,7 +5095,6 @@ Instead, in step three, the comparison on the host is relaxed to accept hosts on : Authenticator extension output :: None. - ## Simple Transaction Authorization Extension (txAuthSimple) ## {#sctn-simple-txauth-extension} This extension allows for a simple form of transaction authorization. A @@ -4749,7 +5379,7 @@ This extension provides the [=authenticator=]'s current location to the WebAuthn : Client extension output :: Returns a JavaScript object that encodes the location information in the authenticator extension output as a {{Coordinates}} value, - as defined by [[Geolocation-API]]. + as defined by [[!Geolocation-API]]. partial dictionary AuthenticationExtensionsClientOutputs { Coordinates loc; @@ -4763,8 +5393,8 @@ This extension provides the [=authenticator=]'s current location to the WebAuthn :: Determine the Geolocation value. : Authenticator extension output -:: A - [[Geolocation-API]] +:: A + [[!Geolocation-API]] {{Coordinates}} record encoded as a CBOR map. Values represented by the "double" type in JavaScript are represented as 64-bit CBOR floating point numbers. Per the Geolocation specification, the "latitude", "longitude", and "accuracy" values are REQUIRED @@ -4877,431 +5507,204 @@ as candidates to be employed in a [=registration ceremony=]. <xmp class="idl"> dictionary authenticatorBiometricPerfBounds{ float FAR; - float FRR; - }; - - - The FAR is the maximum false acceptance rate for a biometric authenticator allowed by the [=[RP]=]. - - The FRR is the maximum false rejection rate for a biometric authenticator allowed by the [=[RP]=]. - -: Client extension processing -:: If the client supports this extension, it MUST NOT use a biometric authenticator whose FAR or FRR does not match the - bounds as provided. The client can obtain information about the biometric authenticator's performance from authoritative - sources such as the FIDO Metadata Service [[FIDOMetadataService]] (see Sec. 3.2 of [[FIDOUAFAuthenticatorMetadataStatements]]). - -: Client extension output -:: Returns the JSON value [TRUE] to indicate to the [=[RP]=] that the extension was acted upon - -: Authenticator extension input -:: None. - -: Authenticator extension processing -:: None. - -: Authenticator extension output -:: None. - -# IANA Considerations # {#sctn-IANA} - -## WebAuthn Attestation Statement Format Identifier Registrations ## {#sctn-att-fmt-reg} - -This section registers the attestation statement formats defined in Section [[#defined-attestation-formats]] in the -IANA "WebAuthn Attestation Statement Format Identifier" registry established by [[!WebAuthn-Registries]]. - -- WebAuthn Attestation Statement Format Identifier: packed -- Description: The "packed" attestation statement format is a WebAuthn-optimized format for [=attestation=]. It uses a very - compact but still extensible encoding method. This format is implementable by authenticators with limited resources (e.g., - secure elements). -- Specification Document: Section [[#packed-attestation]] of this specification -

    -- WebAuthn Attestation Statement Format Identifier: tpm -- Description: The TPM attestation statement format returns an attestation statement in the same format as the packed - attestation statement format, although the rawData and signature fields are computed differently. -- Specification Document: Section [[#tpm-attestation]] of this specification -

    -- WebAuthn Attestation Statement Format Identifier: android-key -- Description: Platform-provided authenticators based on versions "N", and later, may provide this proprietary "hardware - attestation" statement. -- Specification Document: Section [[#android-key-attestation]] of this specification -

    -- WebAuthn Attestation Statement Format Identifier: android-safetynet -- Description: Android-based, platform-provided authenticators MAY produce an attestation statement based on the Android - SafetyNet API. -- Specification Document: Section [[#android-safetynet-attestation]] of this specification -

    -- WebAuthn Attestation Statement Format Identifier: fido-u2f -- Description: Used with FIDO U2F authenticators -- Specification Document: Section [[#fido-u2f-attestation]] of this specification - -## WebAuthn Extension Identifier Registrations ## {#sctn-extensions-reg} - -This section registers the [=extension identifier=] values defined in Section [[#extensions]] in the -IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]]. - -- WebAuthn Extension Identifier: appid -- Description: This [=authentication extension=] allows [=[WRPS]=] that have previously registered a credential using the legacy - FIDO JavaScript APIs to request an assertion. -- Specification Document: Section [[#sctn-appid-extension]] of this specification -

    -- WebAuthn Extension Identifier: txAuthSimple -- Description: This [=registration extension=] and [=authentication extension=] allows for a simple form of transaction - authorization. A WebAuthn Relying Party can specify a prompt string, intended for display on a trusted device on the - authenticator -- Specification Document: Section [[#sctn-simple-txauth-extension]] of this specification -

    -- WebAuthn Extension Identifier: txAuthGeneric -- Description: This [=registration extension=] and [=authentication extension=] allows images to be used as transaction - authorization prompts as well. This allows authenticators without a font rendering engine to be used and also supports a - richer visual appearance than accomplished with the webauthn.txauth.simple extension. -- Specification Document: Section [[#sctn-generic-txauth-extension]] of this specification -

    -- WebAuthn Extension Identifier: authnSel -- Description: This [=registration extension=] allows a WebAuthn Relying Party to guide the selection of the authenticator that - will be leveraged when creating the credential. It is intended primarily for [=[WRPS]=] that wish to tightly - control the experience around credential creation. -- Specification Document: Section [[#sctn-authenticator-selection-extension]] of this specification -

    -- WebAuthn Extension Identifier: exts -- Description: This [=registration extension=] enables the [=[WRP]=] to determine which extensions the authenticator supports. The - extension data is a list (CBOR array) of extension identifiers encoded as UTF-8 Strings. This extension is added - automatically by the authenticator. This extension can be added to attestation statements. -- Specification Document: Section [[#sctn-supported-extensions-extension]] of this specification -

    -- WebAuthn Extension Identifier: uvi -- Description: This [=registration extension=] and [=authentication extension=] enables use of a user verification index. The - user verification index is a value uniquely identifying a user verification data record. The UVI data can be used by servers - to understand whether an authentication was authorized by the exact same biometric data as the initial key generation. This - allows the detection and prevention of "friendly fraud". -- Specification Document: Section [[#sctn-uvi-extension]] of this specification -

    -- WebAuthn Extension Identifier: loc -- Description: The location [=registration extension=] and [=authentication extension=] provides the [=client device=]'s current - location to the [=[WRP]=], if supported by the [=client platform=] and subject to [=user consent=]. -- Specification Document: Section [[#sctn-location-extension]] of this specification -

    -- WebAuthn Extension Identifier: uvm -- Description: This [=registration extension=] and [=authentication extension=] enables use of a user verification method. - The user verification method extension returns to the [=[WRP]=] which user verification methods (factors) were - used for the WebAuthn operation. -- Specification Document: Section [[#sctn-uvm-extension]] of this specification - -## COSE Algorithm Registrations ## {#sctn-cose-alg-reg} - -This section registers identifiers for the following ECDAA algorithms in the -IANA COSE Algorithms registry [[!IANA-COSE-ALGS-REG]]. -Note that [[!WebAuthn-COSE-Algs]] also registers -RSASSA-PKCS1-v1_5 [[RFC8017]] algorithms using SHA-2 and SHA-1 hash functions in the -IANA COSE Algorithms registry [[!IANA-COSE-ALGS-REG]], -such as registering -257 for "RS256". - -- Name: ED256 -- Value: TBD (requested assignment -260) -- Description: TPM_ECC_BN_P256 curve w/ SHA-256 -- Reference: Section 4.2 of [[!FIDOEcdaaAlgorithm]] -- Recommended: Yes -

    -- Name: ED512 -- Value: TBD (requested assignment -261) -- Description: ECC_BN_ISOP512 curve w/ SHA-512 -- Reference: Section 4.2 of [[!FIDOEcdaaAlgorithm]] -- Recommended: Yes - -# Sample Scenarios # {#sample-scenarios} - -[INFORMATIVE] - -In this section, we walk through some events in the lifecycle of a [=public key credential=], along with the corresponding -sample code for using this API. Note that this is an example flow and does not limit the scope of how the API can be used. - -As was the case in earlier sections, this flow focuses on a use case involving a [=first-factor roaming authenticator=] -with its own display. One example of such an authenticator would be a smart phone. Other authenticator types are also supported -by this API, subject to implementation by the [=client platform=]. For instance, this flow also works without modification for the case of -an authenticator that is embedded in the [=client device=]. The flow also works for the case of an authenticator without -its own display (similar to a smart card) subject to specific implementation considerations. Specifically, the [=client platform=] -needs to display any prompts that would otherwise be shown by the authenticator, and the authenticator needs to allow the [=client -platform=] to enumerate all the authenticator's credentials so that the client can have information to show appropriate prompts. - - -## Registration ## {#sample-registration} - -This is the first-time flow, in which a new credential is created and registered with the server. -In this flow, the [=[WRP]=] does not have a preference for [=platform authenticator=] or [=roaming authenticators=]. - -1. The user visits example.com, which serves up a script. At this point, the user may already be logged in using a legacy - username and password, or additional authenticator, or other means acceptable to the [=[RP]=]. - Or the user may be in the process of creating a new account. - -1. The [=[RP]=] script runs the code snippet below. - -1. The [=client platform=] searches for and locates the authenticator. - -1. The [=client=] connects to the authenticator, performing any pairing actions if necessary. - -1. The authenticator shows appropriate UI for the user to select the authenticator on which the new credential will be - created, and obtains a biometric or other authorization gesture from the user. - -1. The authenticator returns a response to the [=client=], which in turn returns a response to the [=[RP]=] script. If - the user declined to select an authenticator or provide authorization, an appropriate error is returned. - -1. If a new credential was created, - - The [=[RP]=] script sends the newly generated [=credential public key=] to the server, along with additional information - such as attestation regarding the provenance and characteristics of the authenticator. - - The server stores the [=credential public key=] in its database and associates it with the user as well as with the - characteristics of authentication indicated by attestation, also storing a friendly name for later use. - - The script may store data such as the [=credential ID=] in local storage, to improve future UX by narrowing the choice of - credential for the user. - -The sample code for generating and registering a new key follows: - -
    -    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
    -
    -    var publicKey = {
    -      // The challenge is produced by the server; see the Security Considerations
    -      challenge: new Uint8Array([21,31,105 /* 29 more random bytes generated by the server */]),
    -
    -      // Relying Party:
    -      rp: {
    -        name: "ACME Corporation"
    -      },
    -
    -      // User:
    -      user: {
    -        id: Uint8Array.from(window.atob("MIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGTMII="), c=>c.charCodeAt(0)),
    -        name: "alex.p.mueller@example.com",
    -        displayName: "Alex P. Müller",
    -        icon: "https://pics.example.com/00/p/aBjjjpqPb.png"
    -      },
    -
    -      // This Relying Party will accept either an ES256 or RS256 credential, but
    -      // prefers an ES256 credential.
    -      pubKeyCredParams: [
    -        {
    -          type: "public-key",
    -          alg: -7 // "ES256" as registered in the IANA COSE Algorithms registry
    -        },
    -        {
    -          type: "public-key",
    -          alg: -257 // Value registered by this specification for "RS256"
    -        }
    -      ],
    -
    -      timeout: 60000,  // 1 minute
    -      excludeCredentials: [], // No exclude list of PKCredDescriptors
    -      extensions: {"loc": true}  // Include location information
    -                                               // in attestation
    -    };
    -
    -    // Note: The following call will cause the authenticator to display UI.
    -    navigator.credentials.create({ publicKey })
    -      .then(function (newCredentialInfo) {
    -        // Send new credential info to server for verification and registration.
    -      }).catch(function (err) {
    -        // No acceptable authenticator or user refused consent. Handle appropriately.
    -      });
    -
    - -## Registration Specifically with User-Verifying Platform Authenticator ## {#sample-registration-with-platform-authenticator} - -This is flow for when the [=[WRP]=] is specifically interested in creating a [=public key credential=] with -a [=user-verifying platform authenticator=]. - -1. The user visits example.com and clicks on the login button, which redirects the user to login.example.com. - -1. The user enters a username and password to log in. After successful login, the user is redirected back to example.com. - -1. The [=[RP]=] script runs the code snippet below. - -1. The user agent asks the user whether they are willing to register with the [=[RP]=] using an available [=platform authenticator=]. - -1. If the user is not willing, terminate this flow. - -1. The user is shown appropriate UI and guided in creating a credential using one of the available platform authenticators. - Upon successful credential creation, the [=[RP]=] script conveys the new credential to the server. - -
    -    if (!window.PublicKeyCredential) { /* Client not capable of the API. Handle error. */ }
    -
    -    PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
    -        .then(function (userIntent) {
    -
    -            // If the user has affirmed willingness to register with the 
    -            // relying party using an available platform authenticator
    -            if (userIntent) {
    -                var publicKeyOptions = { /* Public key credential creation options. */};
    -
    -                // Create and register credentials.
    -                return navigator.credentials.create({ "publicKey": publicKeyOptions });
    -            } else {
    -
    -                // Record that the user does not intend to use a platform authenticator
    -                // and default the user to a password-based flow in the future.
    -            }
    -
    -        }).then(function (newCredentialInfo) {
    -            // Send new credential info to server for verification and registration.
    -        }).catch( function(err) {
    -            // Something went wrong. Handle appropriately.
    -        });
    -
    + float FRR; + }; + -## Authentication ## {#sample-authentication} + The FAR is the maximum false acceptance rate for a biometric authenticator allowed by the [=[RP]=]. -This is the flow when a user with an already registered credential visits a website and wants to authenticate using the -credential. + The FRR is the maximum false rejection rate for a biometric authenticator allowed by the [=[RP]=]. -1. The user visits example.com, which serves up a script. +: Client extension processing +:: If the client supports this extension, it MUST NOT use a biometric authenticator whose FAR or FRR does not match the + bounds as provided. The client can obtain information about the biometric authenticator's performance from authoritative + sources such as the FIDO Metadata Service [[FIDOMetadataService]] (see Sec. 3.2 of [[FIDOUAFAuthenticatorMetadataStatements]]). -1. The script asks the [=client=] for an Authentication Assertion, providing as much information as possible to narrow - the choice of acceptable credentials for the user. This can be obtained from the data that was stored locally after - registration, or by other means such as prompting the user for a username. +: Client extension output +:: Returns the JSON value [TRUE] to indicate to the [=[RP]=] that the extension was acted upon -1. The [=[RP]=] script runs one of the code snippets below. +: Authenticator extension input +:: None. -1. The [=client platform=] searches for and locates the authenticator. +: Authenticator extension processing +:: None. -1. The [=client=] connects to the authenticator, performing any pairing actions if necessary. +: Authenticator extension output +:: None. -1. The authenticator presents the user with a notification that their attention is needed. On opening the - notification, the user is shown a friendly selection menu of acceptable credentials using the account information provided - when creating the credentials, along with some information on the [=origin=] that is requesting these keys. -1. The authenticator obtains a biometric or other authorization gesture from the user. +## Credential Properties Extension (credProps) ## {#sctn-authenticator-credential-properties-extension} -1. The authenticator returns a response to the [=client=], which in turn returns a response to the [=[RP]=] script. - If the user declined to select a credential or provide an authorization, an appropriate error is returned. +This [=client extension|client=] [=registration extension=] facilitates reporting certain [=credential properties=] known by the [=client=] to the requesting [=[WRP]=] upon creation of a [=public key credential source=] as a result of a [=registration ceremony=]. -1. If an assertion was successfully generated and returned, - - The script sends the assertion to the server. - - The server examines the assertion, extracts the [=credential ID=], looks up the registered - credential public key it is database, and verifies the assertion's authentication signature. - If valid, it looks up the identity associated with the assertion's [=credential ID=]; that - identity is now authenticated. If the [=credential ID=] is not recognized by the server (e.g., - it has been deregistered due to inactivity) then the authentication has failed; each [=[RP]=] - will handle this in its own way. - - The server now does whatever it would otherwise do upon successful authentication -- return a success page, set - authentication cookies, etc. +At this time, one [=credential property=] is defined: the [=resident key credential property=]. -If the [=[RP]=] script does not have any hints available (e.g., from locally stored data) to help it narrow the list of -credentials, then the sample code for performing such an authentication might look like this: +: Extension identifier +:: `credProps` -
    -    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
    +: Operation applicability
    +:: [=registration extension|Registration=]
     
    -    // credentialId is generated by the authenticator and is an opaque random byte array
    -    var credentialId = new Uint8Array([183, 148, 245 /* more random bytes previously generated by the authenticator */]);
    -    var options = {
    -      // The challenge is produced by the server; see the Security Considerations
    -      challenge: new Uint8Array([4,101,15 /* 29 more random bytes generated by the server */]),
    -      timeout: 60000,  // 1 minute
    -      allowCredentials: [{ type: "public-key", id: credentialId }]
    +: Client extension input
    +:: The Boolean value [TRUE] to indicate that this extension is requested by the [=[RP]=].
    +    
    +    partial dictionary AuthenticationExtensionsClientInputs {
    +        boolean credProps;
         };
    +    
     
    -    navigator.credentials.get({ "publicKey": options })
    -        .then(function (assertion) {
    -        // Send assertion to server for verification
    -    }).catch(function (err) {
    -        // No acceptable credential or user refused consent. Handle appropriately.
    -    });
    -
    - -On the other hand, if the [=[RP]=] script has some hints to help it narrow the list of credentials, then the sample code for -performing such an authentication might look like the following. Note that this sample also demonstrates how to use the -extension for transaction authorization. +: Client extension processing +:: None, other than to report on credential properties in the output. -
    -    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }
    +: Client extension output
    +:: [=map/Set=] [=credentialCreationData/clientExtensionResults=]["{{AuthenticationExtensionsClientOutputs/credProps}}"]["rk"] to the value of the |requireResidentKey| parameter that was used in the invocation of the [=authenticatorMakeCredential=] operation.
     
    -    var encoder = new TextEncoder();
    -    var acceptableCredential1 = {
    -        type: "public-key",
    -        id: encoder.encode("BA44712732CE")
    -    };
    -    var acceptableCredential2 = {
    -        type: "public-key",
    -        id: encoder.encode("BG35122345NF")
    +    
    +    dictionary CredentialPropertiesOutput {
    +        boolean rk;
         };
     
    -    var options = {
    -      // The challenge is produced by the server; see the Security Considerations
    -      challenge: new Uint8Array([8,18,33 /* 29 more random bytes generated by the server */]),
    -      timeout: 60000,  // 1 minute
    -      allowCredentials: [acceptableCredential1, acceptableCredential2],
    -      extensions: { 'txAuthSimple':
    -         "Wave your hands in the air like you just don't care" }
    +    partial dictionary AuthenticationExtensionsClientOutputs {
    +        CredentialPropertiesOutput credProps;
         };
    +    
     
    -    navigator.credentials.get({ "publicKey": options })
    -        .then(function (assertion) {
    -        // Send assertion to server for verification
    -    }).catch(function (err) {
    -        // No acceptable credential or user refused consent. Handle appropriately.
    -    });
    -
    +
    + : rk + :: This OPTIONAL property, known abstractly as the resident key credential property, + is a Boolean value indicating whether the {{PublicKeyCredential}} returned as a result of a [=registration ceremony=] + is a [=resident credential=]. + If {{rk}} is [TRUE], the credential is a [=resident credential=]; + if {{rk}} is [FALSE], the credential is a [=non-resident credential=]. + If {{rk}} is [=not present=], it is not known whether the credential is a [=resident credential=] or a [=non-resident credential=]. +
    -## Aborting Authentication Operations ## {#sample-aborting} -The below example shows how a developer may use the AbortSignal parameter to abort a -credential registration operation. A similar procedure applies to an authentication operation. +: Authenticator extension input +:: None. -
    -    const authAbortController = new AbortController(); 
    -    const authAbortSignal = authAbortController.signal;
    +: Authenticator extension processing
    +:: None.
     
    -    authAbortSignal.onabort = function () {
    -        // Once the page knows the abort started, inform user it is attempting to abort.  
    -    }
    +: Authenticator extension output
    +:: None.
     
    -    var options = {
    -        // A list of options. 
    -    }
     
    -    navigator.credentials.create({
    -        publicKey: options, 
    -        signal: authAbortSignal})
    -        .then(function (attestation) {
    -            // Register the user. 
    -        }).catch(function (error) {
    -            if (error == "AbortError") {
    -                // Inform user the credential hasn't been created. 
    -                // Let the server know a key hasn't been created. 
    -            }
    -        });
    +# IANA Considerations # {#sctn-IANA}
     
    -    // Assume widget shows up whenever authentication occurs.
    -    if (widget == "disappear") {
    -        authAbortController.abort(); 
    -    }
    -
    +## WebAuthn Attestation Statement Format Identifier Registrations ## {#sctn-att-fmt-reg} +This section registers the attestation statement formats defined in Section [[#sctn-defined-attestation-formats]] in the +IANA "WebAuthn Attestation Statement Format Identifier" registry established by [[!WebAuthn-Registries]]. -## Decommissioning ## {#sample-decommissioning} +- WebAuthn Attestation Statement Format Identifier: packed +- Description: The "packed" attestation statement format is a WebAuthn-optimized format for [=attestation=]. It uses a very + compact but still extensible encoding method. This format is implementable by authenticators with limited resources (e.g., + secure elements). +- Specification Document: Section [[#sctn-packed-attestation]] of this specification +

    +- WebAuthn Attestation Statement Format Identifier: tpm +- Description: The TPM attestation statement format returns an attestation statement in the same format as the packed + attestation statement format, although the rawData and signature fields are computed differently. +- Specification Document: Section [[#sctn-tpm-attestation]] of this specification +

    +- WebAuthn Attestation Statement Format Identifier: android-key +- Description: Platform-provided authenticators based on versions "N", and later, may provide this proprietary "hardware + attestation" statement. +- Specification Document: Section [[#sctn-android-key-attestation]] of this specification +

    +- WebAuthn Attestation Statement Format Identifier: android-safetynet +- Description: Android-based, platform-provided authenticators MAY produce an attestation statement based on the Android + SafetyNet API. +- Specification Document: Section [[#sctn-android-safetynet-attestation]] of this specification +

    +- WebAuthn Attestation Statement Format Identifier: fido-u2f +- Description: Used with FIDO U2F authenticators +- Specification Document: Section [[#sctn-fido-u2f-attestation]] of this specification -The following are possible situations in which decommissioning a credential might be desired. Note that all of these are -handled on the server side and do not need support from the API specified here. +## WebAuthn Extension Identifier Registrations ## {#sctn-extensions-reg} -- Possibility #1 -- user reports the credential as lost. - * User goes to server.example.net, authenticates and follows a link to report a lost/stolen [=authenticator=]. - * Server returns a page showing the list of registered credentials with friendly names as configured during registration. - * User selects a credential and the server deletes it from its database. - * In future, the [=[RP]=] script does not specify this credential in any list of acceptable credentials, and assertions - signed by this credential are rejected. +This section registers the [=extension identifier=] values defined in Section [[#sctn-extensions]] in the +IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]]. -- Possibility #2 -- server deregisters the credential due to inactivity. - * Server deletes credential from its database during maintenance activity. - * In the future, the [=[RP]=] script does not specify this credential in any list of acceptable credentials, and assertions - signed by this credential are rejected. +- WebAuthn Extension Identifier: appid +- Description: This [=authentication extension=] allows [=[WRPS]=] that have previously registered a credential using the legacy + FIDO U2F JavaScript API [[FIDOU2FJavaScriptAPI]] to request an assertion. +- Specification Document: Section [[#sctn-appid-extension]] of this specification +

    +- WebAuthn Extension Identifier: txAuthSimple +- Description: This [=registration extension=] and [=authentication extension=] allows for a simple form of transaction + authorization. A WebAuthn Relying Party can specify a prompt string, intended for display on a trusted device on the + authenticator +- Specification Document: Section [[#sctn-simple-txauth-extension]] of this specification +

    +- WebAuthn Extension Identifier: txAuthGeneric +- Description: This [=registration extension=] and [=authentication extension=] allows images to be used as transaction + authorization prompts as well. This allows authenticators without a font rendering engine to be used and also supports a + richer visual appearance than accomplished with the webauthn.txauth.simple extension. +- Specification Document: Section [[#sctn-generic-txauth-extension]] of this specification +

    +- WebAuthn Extension Identifier: authnSel +- Description: This [=registration extension=] allows a WebAuthn Relying Party to guide the selection of the authenticator that + will be leveraged when creating the credential. It is intended primarily for [=[WRPS]=] that wish to tightly + control the experience around credential creation. +- Specification Document: Section [[#sctn-authenticator-selection-extension]] of this specification +

    +- WebAuthn Extension Identifier: exts +- Description: This [=registration extension=] enables the [=[WRP]=] to determine which extensions the authenticator supports. The + extension data is a list (CBOR array) of extension identifiers encoded as UTF-8 Strings. This extension is added + automatically by the authenticator. This extension can be added to attestation statements. +- Specification Document: Section [[#sctn-supported-extensions-extension]] of this specification +

    +- WebAuthn Extension Identifier: uvi +- Description: This [=registration extension=] and [=authentication extension=] enables use of a user verification index. The + user verification index is a value uniquely identifying a user verification data record. The UVI data can be used by servers + to understand whether an authentication was authorized by the exact same biometric data as the initial key generation. This + allows the detection and prevention of "friendly fraud". +- Specification Document: Section [[#sctn-uvi-extension]] of this specification +

    +- WebAuthn Extension Identifier: loc +- Description: The location [=registration extension=] and [=authentication extension=] provides the [=client device=]'s current + location to the [=[WRP]=], if supported by the [=client platform=] and subject to [=user consent=]. +- Specification Document: Section [[#sctn-location-extension]] of this specification +

    +- WebAuthn Extension Identifier: uvm +- Description: This [=registration extension=] and [=authentication extension=] enables use of a user verification method. + The user verification method extension returns to the [=[WRP]=] which user verification methods (factors) were + used for the WebAuthn operation. +- Specification Document: Section [[#sctn-uvm-extension]] of this specification +

    +- WebAuthn Extension Identifier: credProps +- Description: This [=client extension|client=] [=registration extension=] enables reporting of a newly-created [=credential=]'s properties, + as determined by the [=client=], to the calling [=[WRP]=]'s [=web application=]. +- Specification Document: Section [[#sctn-authenticator-credential-properties-extension]] of this specification +

    -- Possibility #3 -- user deletes the credential from the [=authenticator=]. - * User employs a [=authenticator=]-specific method (e.g., device settings UI) to delete a credential from their [=authenticator=]. - * From this point on, this credential will not appear in any selection prompts, and no assertions can be generated with it. - * Sometime later, the server deregisters this credential due to inactivity. +## COSE Algorithm Registrations ## {#sctn-cose-alg-reg} + +This section registers identifiers for the following ECDAA algorithms in the +IANA COSE Algorithms registry [[!IANA-COSE-ALGS-REG]]. +Note that [[!WebAuthn-COSE-Algs]] also registers +RSASSA-PKCS1-v1_5 [[RFC8017]] algorithms using SHA-2 and SHA-1 hash functions in the +IANA COSE Algorithms registry [[!IANA-COSE-ALGS-REG]], +such as registering -257 for "RS256". + +- Name: ED256 +- Value: TBD (requested assignment -260) +- Description: TPM_ECC_BN_P256 curve w/ SHA-256 +- Reference: Section 4.2 of [[!FIDOEcdaaAlgorithm]] +- Recommended: Yes +

    +- Name: ED512 +- Value: TBD (requested assignment -261) +- Description: ECC_BN_ISOP512 curve w/ SHA-512 +- Reference: Section 4.2 of [[!FIDOEcdaaAlgorithm]] +- Recommended: Yes -# Security Considerations # {#security-considerations} +# Security Considerations # {#sctn-security-considerations} -This specification defines a [[#api|Web API]] and a cryptographic peer-entity authentication protocol. +This specification defines a [[#sctn-api|Web API]] and a cryptographic peer-entity authentication protocol. The [=Web Authentication API=] allows Web developers (i.e., "authors") to utilize the Web Authentication protocol in their [=registration=] and [=authentication=] [=ceremonies=]. The entities comprising the Web Authentication protocol endpoints are user-controlled [=[WAA]s=] and a [=[WRP]=]'s @@ -5315,7 +5718,7 @@ Also, the [[FIDOAuthnrSecReqs]] document suite provides useful information about The below subsections comprise the current Web Authentication-specific security considerations. -## Cryptographic Challenges ## {#cryptographic-challenges} +## Cryptographic Challenges ## {#sctn-cryptographic-challenges} As a cryptographic protocol, Web Authentication is dependent upon randomized challenges to avoid replay attacks. Therefore, the values of both {{PublicKeyCredentialCreationOptions}}.{{PublicKeyCredentialCreationOptions/challenge}} and {{PublicKeyCredentialRequestOptions}}.{{PublicKeyCredentialRequestOptions/challenge}} MUST be randomly generated @@ -5329,9 +5732,9 @@ of the protocol. In order to prevent replay attacks, the challenges MUST contain enough entropy to make guessing them infeasible. Challenges SHOULD therefore be at least 16 bytes long. -## Attestation Security Considerations ## {#sec-attestation-security-considerations} +## Attestation Security Considerations ## {#sctn-attestation-security-considerations} -### Attestation Certificate Hierarchy ### {#cert-hierarchy} +### Attestation Certificate Hierarchy ### {#sctn-cert-hierarchy} A 3-tier hierarchy for attestation certificates is RECOMMENDED (i.e., Attestation Root, Attestation Issuing CA, Attestation Certificate). It is also RECOMMENDED that for each [=[WAA]=] device line (i.e., model), a separate issuing CA is @@ -5341,7 +5744,7 @@ If the attestation root certificate is not dedicated to a single [=[WAA]=] devic SHOULD be specified in the attestation certificate itself, so that it can be verified against the [=authenticator data=]. -### Attestation Certificate and Attestation Certificate CA Compromise ### {#ca-compromise} +### Attestation Certificate and Attestation Certificate CA Compromise ### {#sctn-ca-compromise} When an intermediate CA or a root CA used for issuing attestation certificates is compromised, [=[WAA]=] attestation keys are still safe although their certificates can no longer be trusted. A [=[WAA]=] manufacturer that @@ -5377,41 +5780,55 @@ The main benefits offered to [=[WRPS]=] by this specification include: any conforming [=authenticator=] and use that same [=authenticator=] with any number of [=[RPS]=]. The [=[RP]=] can optionally enforce requirements on [=authenticators=]' security properties by inspecting the [=attestation statements=] returned from the [=authenticators=]. -1. [=Registration=] and [=authentication=] [=ceremonies=] are resistant to [=man-in-the-middle attacks=]. +1. [=Authentication ceremonies=] are resistant to [=man-in-the-middle attacks=]. + Regarding [=registration ceremonies=], see [[#sctn-attestation-limitations]], below. 1. The [=[RP]=] can automatically support multiple types of [=user verification=] - for example PIN, biometrics and/or future methods - with little or no code change, and can let each user decide which they prefer to use via their choice of [=authenticator=]. 1. The [=[RP]=] does not need to store additional secrets in order to gain the above benefits. -As stated in the [[#conforming-relying-parties|Conformance]] section, the [=[RP]=] MUST behave as described in [[#rp-operations]] +As stated in the [[#sctn-conforming-relying-parties|Conformance]] section, the [=[RP]=] MUST behave as described in [[#sctn-rp-operations]] to obtain all of the above security benefits. However, one notable use case that departs slightly from this is described in the next section. -### Considerations for Self and None Attestation Types and Ignoring Attestation ### {#sctn-no-attestation-security-attestation} +### Attestation Limitations ### {#sctn-attestation-limitations} -When [[#registering-a-new-credential|registering a new credential]], the [=[WRP]=] MAY choose to accept an [=attestation -statement=] of [[#sctn-attestation-types|type]] [=self attestation|Self=] or [=None=], or to not verify -the [=attestation statement=]. In all of these cases the [=[RP]=] loses much of benefit (3) listed above, but retains the other -benefits. +[INFORMATIVE] + +When [[#sctn-registering-a-new-credential|registering a new credential]], the [=attestation statement=], if present, +may allow the [=[WRP]=] to derive assurances about various [=authenticator=] qualities. +For example, the [=authenticator=] model, or how it stores and protects [=credential private keys=]. +However, it is important to note that an [=attestation statement=], on its own, +provides no means for a [=[RP]=] to verify that an [=attestation object=] was generated +by the [=authenticator=] the user intended, and not by a [=man-in-the-middle attack|man-in-the-middle attacker=]. +For example, such an attacker could use malicious code injected into [=[RP]=] script. +The [=[RP]=] must therefore rely on other means, e.g., TLS and related technologies, +to protect the [=attestation object=] from [=man-in-the-middle attacks=]. + +Under the assumption that a [=registration ceremony=] is completed securely, and that the [=authenticator=] maintains +confidentiality of the [=credential private key=], subsequent [=authentication ceremonies=] using that [=public key +credential=] are resistant to [=man-in-the-middle attacks=]. + +The discussion above holds for all [=attestation types=]. In all cases it is possible for a [=man-in-the-middle +attack|man-in-the-middle attacker=] to replace the {{PublicKeyCredential}} object, including the [=attestation statement=] and the +[=credential public key=] to be registered, and subsequently tamper with future [=authentication assertions=] [=scoped=] for the +same [=[RP]=] and passing through the same attacker. -In these cases it is possible for a [=man-in-the-middle attack|man-in-the-middle attacker=] - for example, a malicious [=client=] -or script - to replace the [=credential public key=] to be registered, and subsequently tamper with future [=authentication -assertions=] [=scoped=] for the same [=[RP]=] and passing through the same attacker. Accepting these [[#sctn-attestation-types|types]] -of [=attestation statements=] therefore constitutes a [=leap of faith=]. In cases where [=registration=] was accomplished -securely, subsequent [=authentication=] [=ceremonies=] remain resistant to [=man-in-the-middle attacks=], i.e., benefit (3) is -retained. Note, however, that such an attack would be easy to detect and very difficult to maintain, since any [=authentication=] -[=ceremony=] that the same attacker does not or cannot tamper with would always fail. +Such an attack would potentially be detectable; since the [=[RP]=] has registered the attacker's [=credential public key=] rather +than the user's, the attacker must tamper with all subsequent [=authentication ceremonies=] with that [=[RP]=]: unscathed +ceremonies will fail, potentially revealing the attack. -The [=[RP]=] SHOULD consider the above in its threat model when deciding its policy on what [[#sctn-attestation-types|attestation -types]] to accept or whether to ignore [=attestation=]. +[=Attestation types=] other than [=Self Attestation=] and [=None=] can increase the difficulty of such attacks, since [=[RPS]=] +can possibly display [=authenticator=] information, e.g., model designation, to the user. An attacker might therefore need to use +a genuine [=authenticator=] of the same model as the user's [=authenticator=], or the user might notice that the [=[RP]=] reports +a different [=authenticator=] model than the user expects. -Note: The default [[#sctn-attestation-types|attestation type]] is [=None=], since the above issues will likely not be a major -concern in most [=[RPS]=]' threat models. For example, the [=man-in-the-middle attack=] described above is more difficult than a -[=man-in-the-middle attack=] against a [=[RP]=] that only uses conventional password authentication. +Note: All variants of [=man-in-the-middle attacks=] described above are more difficult for an attacker to mount +than a [=man-in-the-middle attack=] against conventional password authentication. -## Credential ID Unsigned ## {#credentialIdSecurity} +## Credential ID Unsigned ## {#sctn-credentialIdSecurity} The [=credential ID=] is not signed. This is not a problem because all that would happen if an [=authenticator=] returns @@ -5420,14 +5837,14 @@ the wrong [=credential ID=], or if an attacker intercepts and manipulates the [= (a.k.a., [=assertion=]), and thus the interaction would end in an error. -## Browser Permissions Framework and Extensions ## {#browser-permissions-framework-extensions} +## Browser Permissions Framework and Extensions ## {#sctn-browser-permissions-framework-extensions} Web Authentication API implementations SHOULD leverage the browser permissions framework as much as possible when obtaining user permissions for certain extensions. An example is the location extension (see [[#sctn-location-extension]]), implementations of which SHOULD make use of the existing browser permissions framework for the Geolocation API. -## Credential Loss and Key Mobility ## {#credential-loss-key-mobility} +## Credential Loss and Key Mobility ## {#sctn-credential-loss-key-mobility} This specification defines no protocol for backing up [=credential private keys=], or for sharing them between [=authenticators=]. In general, it is expected that a [=credential private key=] never leaves the [=authenticator=] that created it. Losing an @@ -5488,7 +5905,7 @@ Some of the above information is necessarily shared with the [=[RP]=]. The follo prevent malicious [=[RPS]=] from using it to discover a user's personal identity. -## Anonymous, Scoped, Non-correlatable [=Public Key Credentials=] ## {#sec-non-correlatable-credentials} +## Anonymous, Scoped, Non-correlatable [=Public Key Credentials=] ## {#sctn-non-correlatable-credentials} [INFORMATIVE] @@ -5502,7 +5919,7 @@ authentication, they are designed to be minimally identifying and not shared bet revealed to other [=[RPS]=]. A malicious [=[RP]=] thus cannot ask the [=client=] to reveal a user's other identities. - The [=client=] also ensures that the existence of a [=public key credential=] is not revealed to the [=[RP]=] without [=user - consent=]. This is detailed further in [[#sec-make-credential-privacy]] and [[#sec-assertion-privacy]]. A malicious [=[RP]=] + consent=]. This is detailed further in [[#sctn-make-credential-privacy]] and [[#sctn-assertion-privacy]]. A malicious [=[RP]=] thus cannot silently identify a user, even if the user has a [=public key credential=] registered and available. - [=Authenticators=] ensure that the [=credential IDs=] and [=credential public keys=] of different [=public key credentials=] are @@ -5510,7 +5927,7 @@ authentication, they are designed to be minimally identifying and not shared bet systems without additional information, e.g., a willfully reused username or e-mail address. - [=Authenticators=] ensure that their [=attestation certificates=] are not unique enough to identify a single [=authenticator=] - or a small group of [=authenticators=]. This is detailed further in [[#sec-attestation-privacy]]. A pair of malicious + or a small group of [=authenticators=]. This is detailed further in [[#sctn-attestation-privacy]]. A pair of malicious [=[RPS]=] thus cannot correlate users between their systems by tracking individual [=authenticators=]. Additionally, a [=client-side-resident public key credential source=] can optionally include a [=user @@ -5519,7 +5936,7 @@ handle=] specified by the [=[RP]=]. The [=public key credential|credential=] can without a traditional username, further improving non-correlatability between [=[RPS]=]. -## Authenticator-local [=Biometric Recognition=] ## {#sec-biometric-privacy} +## Authenticator-local [=Biometric Recognition=] ## {#sctn-biometric-privacy} [=Biometric authenticators=] perform the [=biometric recognition=] internally in the [=authenticator=] - though for [=platform authenticators=] the biometric data might also be visible to the [=client=], depending on the implementation. Biometric data is @@ -5533,7 +5950,7 @@ perfoming [=user verification=] and then signaling the result by setting the [=U instead of revealing the biometric data itself to the [=[RP]=]. -## Attestation Privacy ## {#sec-attestation-privacy} +## Attestation Privacy ## {#sctn-attestation-privacy} Attestation keys can be used to track users or link various online identities of the same user together. This can be mitigated in several ways, including: @@ -5563,7 +5980,7 @@ in several ways, including: signature using the [=ECDAA-Issuer public key=], but the attestation signature does not serve as a global correlation handle. -## Registration Ceremony Privacy ## {#sec-make-credential-privacy} +## Registration Ceremony Privacy ## {#sctn-make-credential-privacy} In order to protect users from being identified without [=user consent|consent=], implementations of the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} method need to take care to not leak information that @@ -5586,7 +6003,7 @@ distinguishable error is returned, because in this case the user has confirmed i leaked. -## Authentication Ceremony Privacy ## {#sec-assertion-privacy} +## Authentication Ceremony Privacy ## {#sctn-assertion-privacy} In order to protect users from being identified without [=user consent|consent=], implementations of the {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} method need to take care to not @@ -5688,7 +6105,7 @@ leakage due to such an attack: verification failed because the signature is invalid or because no such user or credential is registered. -# Acknowledgements # {#acknowledgements} +# Acknowledgements # {#sctn-acknowledgements} We thank the following people for their reviews of, and contributions to, this specification: Yuriy Ackermann, James Barclay, @@ -5706,6 +6123,7 @@ Yoshikazu Nojima, Kimberly Paulhamus, Adam Powers, Yaron Sheffer, +Nick Steele, Anne van Kesteren, Johan Verrept, and @@ -5731,6 +6149,28 @@ for their contributions as our W3C Team Contacts.
     {
    +
    +  "UTR29": {
    +    "href": "http://www.unicode.org/reports/tr29/",
    +    "title": "UNICODE Text Segmentation",
    +    "publisher": "UNICODE Consortium"
    +  },
    +
    +
    +  "IANA-COSE-ALGS-REG": {
    +    "href": "https://www.iana.org/assignments/cose/cose.xhtml#algorithms",
    +    "title": "IANA CBOR Object Signing and Encryption (COSE) Algorithms Registry",
    +    "publisher": "IANA"
    +  },
    +
    +
    +  "WebAuthnAPIGuide": {
    +    "href": "https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API",
    +    "title": "Web Authentication API Guide",
    +    "publisher": "MDN: Mozilla Developer Network",
    +    "status": "Experimental"
    +  },
    +
       "Ceremony": {
         "title": "Ceremony Design and Analysis",
         "href": "https://eprint.iacr.org/2007/399.pdf",
    @@ -5764,18 +6204,6 @@ for their contributions as our W3C Team Contacts.
         "id": "WebAuthn-COSE-Algs"
       },
     
    -  "GeoJSON": {
    -    "title": "The GeoJSON Format Specification",
    -    "href": "http://geojson.org/geojson-spec.html"
    -  },
    -
    -  "SP800-107r1": {
    -    "title": "NIST Special Publication 800-107: Recommendation for Applications Using Approved Hash Algorithms",
    -    "href": "http://csrc.nist.gov/publications/nistpubs/800-107-rev1/sp800-107-rev1.pdf",
    -    "authors": ["Quynh Dang"],
    -    "date": "August 2012"
    -  },
    -
       "SP800-800-63r3": {
         "title": "NIST Special Publication 800-63: Digital Identity Guidelines",
         "href": "https://pages.nist.gov/800-63-3/sp800-63-3.html",
    @@ -5783,12 +6211,6 @@ for their contributions as our W3C Team Contacts.
         "date": "June 2017"
       },
     
    -  "OSCCA-SM3": {
    -    "title": "SM3 Cryptographic Hash Algorithm",
    -    "href": "http://www.oscca.gov.cn/UpFile/20101222141857786.pdf",
    -    "date": "December 2010"
    -  },
    -
       "UAFProtocol": {
         "authors": ["R. Lindemann", "D. Baghdasaryan", "E. Tiffany", "D. Balfanz", "B. Hill", "J. Hodges"],
         "title": "FIDO UAF Protocol Specification v1.0",
    @@ -5818,36 +6240,43 @@ for their contributions as our W3C Team Contacts.
         "status": "FIDO Alliance Implementation Draft",
         "date": "27 February 2018"
       },
    -  
    +
       "FIDOUAFAuthenticatorMetadataStatements": {
         "authors": ["B. Hill", "D. Baghdasaryan", "J. Kemp"],
         "title": "FIDO UAF Authenticator Metadata Statements v1.0",
         "href": "https://fidoalliance.org/specs/fido-uaf-v1.0-ps-20141208/fido-uaf-authnr-metadata-v1.0-ps-20141208.html",
         "status": "FIDO Alliance Proposed Standard"
       },
    -  
    +
    +  "FIDOU2FJavaScriptAPI": {
    +    "authors": ["D. Balfanz", "A. Birgisson", "J. Lang"],
    +    "title": "FIDO U2F JavaScript API",
    +    "href": "https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-javascript-api-v1.2-ps-20170411.html",
    +    "status": "FIDO Alliance Proposed Standard"
    +  },
    +
       "TPMv2-Part1": {
         "title": "Trusted Platform Module Library, Part 1: Architecture",
         "publisher": "Trusted Computing Group",
    -    "href": "http://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.38.pdf"
    +    "href": "https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.38.pdf"
       },
     
       "TPMv2-Part2": {
         "title": "Trusted Platform Module Library, Part 2: Structures",
         "publisher": "Trusted Computing Group",
    -    "href": "http://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf"
    +    "href": "https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf"
       },
     
       "TPMv2-Part3": {
         "title": "Trusted Platform Module Library, Part 3: Commands",
         "publisher": "Trusted Computing Group",
    -    "href": "http://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-3-Commands-01.38.pdf"
    +    "href": "https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-3-Commands-01.38.pdf"
       },
     
       "TPMv2-EK-Profile": {
         "title": "TCG EK Credential Profile for TPM Family 2.0",
         "publisher": "Trusted Computing Group",
    -    "href": "http://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf"
    +    "href": "https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf"
       },
     
       "FIDOAuthnrSecReqs": {