From 3361ef49c19daec3cd408d544802889279045aa0 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 19 Jan 2024 15:32:27 +0100 Subject: [PATCH 1/8] Explicitly specify binary encoding for string truncation --- index.bs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 08653a9b9..5757b2a1b 100644 --- a/index.bs +++ b/index.bs @@ -3194,7 +3194,7 @@ associated with or [=scoped=] to, respectively. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialEntity/name}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. - Authenticators MAY truncate a {{PublicKeyCredentialEntity/name}} member's value so that it fits within 64 bytes, if the authenticator stores the value. See [[#sctn-strings-truncation]] about truncation and other considerations. + Authenticators MAY truncate a {{PublicKeyCredentialEntity/name}} member's value so that its UTF-8 encoding fits within 64 bytes, if the authenticator stores the value. See [[#sctn-strings-truncation]] about truncation and other considerations. @@ -3265,8 +3265,9 @@ credential. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialUserEntity/displayName}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. - [=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 so that it fits within 64 bytes. See [[#sctn-strings-truncation]] about truncation and other considerations. + [=Authenticators=] MUST accept and store a {{PublicKeyCredentialUserEntity/displayName}} member's value + whose UTF-8 encoding is 64 bytes or shorter. + Authenticators MAY truncate a {{PublicKeyCredentialUserEntity/displayName}} member's value so that its UTF-8 encoding fits within 64 bytes. See [[#sctn-strings-truncation]] about truncation and other considerations. From bdb2dab3d1f1fb38c0421f7910c29b4db50fb7a4 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Mon, 22 Jan 2024 16:55:36 +0100 Subject: [PATCH 2/8] Apply suggestions from review --- index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 5757b2a1b..a76010e3e 100644 --- a/index.bs +++ b/index.bs @@ -3194,7 +3194,7 @@ associated with or [=scoped=] to, respectively. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialEntity/name}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. - Authenticators MAY truncate a {{PublicKeyCredentialEntity/name}} member's value so that its UTF-8 encoding fits within 64 bytes, if the authenticator stores the value. See [[#sctn-strings-truncation]] about truncation and other considerations. + Authenticators MAY truncate characters from the end of a {{PublicKeyCredentialEntity/name}} member's value so that when encoded in UTF-8, its length fits within 64 bytes. See [[#sctn-strings-truncation]] about truncation and other considerations. @@ -3266,8 +3266,8 @@ credential. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialUserEntity/displayName}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. [=Authenticators=] MUST accept and store a {{PublicKeyCredentialUserEntity/displayName}} member's value - whose UTF-8 encoding is 64 bytes or shorter. - Authenticators MAY truncate a {{PublicKeyCredentialUserEntity/displayName}} member's value so that its UTF-8 encoding fits within 64 bytes. See [[#sctn-strings-truncation]] about truncation and other considerations. + whose length in the UTF-8 character encoding is 64 bytes or shorter. + Authenticators MAY truncate characters from the end of a {{PublicKeyCredentialEntity/displayName}} member's value so that when encoded in UTF-8, its length fits within 64 bytes. See [[#sctn-strings-truncation]] about truncation and other considerations. From 01279024e16533770295ab74248d5e2d4dbd76c5 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Mon, 22 Jan 2024 17:22:33 +0100 Subject: [PATCH 3/8] Unify language on truncation between name/displayName, and simplify both --- index.bs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/index.bs b/index.bs index a76010e3e..4978280fb 100644 --- a/index.bs +++ b/index.bs @@ -3194,7 +3194,9 @@ associated with or [=scoped=] to, respectively. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialEntity/name}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. - Authenticators MAY truncate characters from the end of a {{PublicKeyCredentialEntity/name}} member's value so that when encoded in UTF-8, its length fits within 64 bytes. See [[#sctn-strings-truncation]] about truncation and other considerations. + When storing a {{PublicKeyCredentialEntity/name}} member's value, + [=authenticators=] MUST support any value whose length in the UTF-8 character encoding is 64 bytes or less. + Authenticators MAY truncate the value as described in [[#sctn-strings-truncation]]. @@ -3265,9 +3267,9 @@ credential. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialUserEntity/displayName}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. - [=Authenticators=] MUST accept and store a {{PublicKeyCredentialUserEntity/displayName}} member's value - whose length in the UTF-8 character encoding is 64 bytes or shorter. - Authenticators MAY truncate characters from the end of a {{PublicKeyCredentialEntity/displayName}} member's value so that when encoded in UTF-8, its length fits within 64 bytes. See [[#sctn-strings-truncation]] about truncation and other considerations. + When storing a {{PublicKeyCredentialUserEntity/displayName}} member's value, + [=authenticators=] MUST support any value whose length in the UTF-8 character encoding is 64 bytes or less. + Authenticators MAY truncate the value as described in [[#sctn-strings-truncation]]. From 527629ceb30f9040accf137f9e41b8d2b1d397eb Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Mon, 22 Jan 2024 17:22:43 +0100 Subject: [PATCH 4/8] Add missing "to" in "equal to or greater than" --- index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.bs b/index.bs index 4978280fb..aca532177 100644 --- a/index.bs +++ b/index.bs @@ -4922,7 +4922,7 @@ Authenticators may be required to store arbitrary strings chosen by a [=[RP]=], ### String Truncation ### {#sctn-strings-truncation} -Each arbitrary string in the API will have some accommodation for the potentially limited resources available to an [=authenticator=]. If string value truncation is the chosen accommodation then authenticators MAY truncate in order to make the string fit within a length equal or greater than the specified minimum supported length. Such truncation SHOULD also respect UTF-8 sequence boundaries or [=grapheme cluster=] boundaries [[UAX29]]. This defines the maximum truncation permitted and authenticators MUST NOT truncate further. +Each arbitrary string in the API will have some accommodation for the potentially limited resources available to an [=authenticator=]. If string value truncation is the chosen accommodation then authenticators MAY truncate in order to make the string fit within a length equal to or greater than the specified minimum supported length. Such truncation SHOULD also respect UTF-8 sequence boundaries or [=grapheme cluster=] boundaries [[UAX29]]. This defines the maximum truncation permitted and authenticators MUST NOT truncate further. For example, in figure the string is 65 bytes long. If truncating to 64 bytes then the final 0x88 byte must be removed purely because of space reasons. Since that leaves a partial UTF-8 sequence the remainder of that sequence may also be removed. Since that leaves a partial [=grapheme cluster=] an authenticator may remove the remainder of that cluster. From f337fcecd074d3329ad032219d33fdef05fb6760 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 28 Feb 2024 13:17:26 +0100 Subject: [PATCH 5/8] Address review comments --- index.bs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/index.bs b/index.bs index aca532177..6d169c2e0 100644 --- a/index.bs +++ b/index.bs @@ -3195,8 +3195,8 @@ associated with or [=scoped=] to, respectively. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialEntity/name}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. When storing a {{PublicKeyCredentialEntity/name}} member's value, - [=authenticators=] MUST support any value whose length in the UTF-8 character encoding is 64 bytes or less. - Authenticators MAY truncate the value as described in [[#sctn-strings-truncation]]. + [=authenticators=] MAY truncate the value as described in [[#sctn-strings-truncation]] + using a size limit greater than or equal to 64 bytes. @@ -3268,8 +3268,8 @@ credential. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialUserEntity/displayName}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. When storing a {{PublicKeyCredentialUserEntity/displayName}} member's value, - [=authenticators=] MUST support any value whose length in the UTF-8 character encoding is 64 bytes or less. - Authenticators MAY truncate the value as described in [[#sctn-strings-truncation]]. + [=authenticators=] MAY truncate the value as described in [[#sctn-strings-truncation]] + using a size limit greater than or equal to 64 bytes. @@ -4922,7 +4922,13 @@ Authenticators may be required to store arbitrary strings chosen by a [=[RP]=], ### String Truncation ### {#sctn-strings-truncation} -Each arbitrary string in the API will have some accommodation for the potentially limited resources available to an [=authenticator=]. If string value truncation is the chosen accommodation then authenticators MAY truncate in order to make the string fit within a length equal to or greater than the specified minimum supported length. Such truncation SHOULD also respect UTF-8 sequence boundaries or [=grapheme cluster=] boundaries [[UAX29]]. This defines the maximum truncation permitted and authenticators MUST NOT truncate further. +Each arbitrary string in the API will have some accommodation for the potentially limited resources available to an [=authenticator=]. +If string truncation is the chosen accommodation, +then the authenticator MAY choose a size limit equal to or greater than the specified minimum supported length +and truncate the string so that its length in the UTF-8 character encoding satisfies that limit. +Such truncation SHOULD also respect UTF-8 code point boundaries or [=grapheme cluster=] boundaries [[UAX29]]. +The resulting truncated value MAY be shorter than the chosen size limit +but MUST NOT be shorter than the longest prefix substring that satisfies the size limit and ends on a [=grapheme cluster=] boundary. For example, in figure the string is 65 bytes long. If truncating to 64 bytes then the final 0x88 byte must be removed purely because of space reasons. Since that leaves a partial UTF-8 sequence the remainder of that sequence may also be removed. Since that leaves a partial [=grapheme cluster=] an authenticator may remove the remainder of that cluster. From 8f89a8eda647b866a042e935ded702ccb128e41a Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 28 Feb 2024 13:17:52 +0100 Subject: [PATCH 6/8] Rewrite "UTF-8 sequence(s)" to "UTF-8 code point(s)" --- index.bs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index 6d169c2e0..fb4bead3f 100644 --- a/index.bs +++ b/index.bs @@ -4930,7 +4930,7 @@ Such truncation SHOULD also respect UTF-8 code point boundaries or [=grapheme cl The resulting truncated value MAY be shorter than the chosen size limit but MUST NOT be shorter than the longest prefix substring that satisfies the size limit and ends on a [=grapheme cluster=] boundary. -For example, in figure the string is 65 bytes long. If truncating to 64 bytes then the final 0x88 byte must be removed purely because of space reasons. Since that leaves a partial UTF-8 sequence the remainder of that sequence may also be removed. Since that leaves a partial [=grapheme cluster=] an authenticator may remove the remainder of that cluster. +For example, in figure the string is 65 bytes long. If truncating to 64 bytes then the final 0x88 byte must be removed purely because of space reasons. Since that leaves a partial UTF-8 code point the remainder of that code point may also be removed. Since that leaves a partial [=grapheme cluster=] an authenticator may remove the remainder of that cluster.
@@ -4939,7 +4939,7 @@ For example, in figure figure the string is 65 bytes long. If truncating to 64 bytes then the final 0x88 byte must be removed purely because of space reasons. Since that leaves a partial UTF-8 code point the remainder of that code point may also be removed. Since that leaves a partial [=grapheme cluster=] an authenticator may remove the remainder of that cluster. +For example, truncation based on Unicode code points alone may cause a [=grapheme cluster=] to be truncated. +This could make the grapheme cluster render as a different glyph, +potentially changing the meaning of the string, instead of removing the glyph entirely. +For example, figure +shows the end of a UTF-8 encoded string whose encoding is 65 bytes long. +If truncating to 64 bytes then the final 0x88 byte is removed first to satisfy the size limit. +Since that leaves a partial UTF-8 code point, the remainder of that code point must also be removed. +Since that leaves a partial [=grapheme cluster=], the remainder of that cluster should also be removed.
The end of a UTF-8 encoded string showing the positions of different truncation boundaries.
-[=Conforming User Agents=] are responsible for ensuring that the authenticator behavior observed by [=[RPS]=] conforms to this specification with respect to string handling. For example, if an authenticator is known to behave incorrectly when asked to store large strings, the user agent SHOULD perform the truncation for it in order to maintain the model from the point of view of the [=[RP]=]. User-agents that do this SHOULD truncate at [=grapheme cluster=] boundaries. +The responsibility for handling these concerns falls primarily on the [=client=], +to avoid burdening [=authenticators=] with understanding character encodings and Unicode character properties. +The following subsections define requirements for how clients and authenticators, +respectively, may perform string truncation. + + +#### String Truncation by Clients #### {#sctn-strings-truncation-client} + +When a [=[WAC]=] truncates a string, +the truncation behaviour observable by the [=[RP]=] MUST satisfy the following requirements: + +Choose a size limit equal to or greater than the specified minimum supported length. +The string MAY be truncated so that its length in bytes in the UTF-8 character encoding satisfies that limit. +This truncation MUST respect UTF-8 code point boundaries, and SHOULD respect [=grapheme cluster=] boundaries [[UAX29]]. +The resulting truncated value MAY be shorter than the chosen size limit +but MUST NOT be shorter than the longest prefix substring that satisfies the size limit and ends on a [=grapheme cluster=] boundary. -Truncation based on UTF-8 code points alone may cause a [=grapheme cluster=] to be truncated. This could make the grapheme cluster render as a different glyph, potentially changing the meaning of the string, instead of removing the glyph entirely. +The client MAY let the [=authenticator=] perform the truncation if it satisfies these requirements; +otherwise the client MUST perform the truncation before relaying the string value to the authenticator. -In addition to that, truncating on byte boundaries alone causes a known issue that user agents should be aware of: 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. 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: +In addition to the above, truncating on byte boundaries alone causes a known issue that user agents should be aware of: 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. 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). + +#### String Truncation by Authenticators #### {#sctn-strings-truncation-authenticator} + +Because a [=[WAA]=] may be implemented in a constrained environment, +the requirements on authenticators are relaxed compared to those for [=clients=]. + +When a [=[WAA]=] truncates a string, +the truncation behaviour MUST satisfy the following requirements: + +Choose a size limit equal to or greater than the specified minimum supported length. +The string MAY be truncated so that its length in bytes in the UTF-8 character encoding satisfies that limit. +This truncation SHOULD respect UTF-8 code point boundaries, and MAY respect [=grapheme cluster=] boundaries [[UAX29]]. +The resulting truncated value MAY be shorter than the chosen size limit +but MUST NOT be shorter than the longest prefix substring that satisfies the size limit and ends on a [=grapheme cluster=] boundary. + + ### Language and Direction Encoding ### {#sctn-strings-langdir} In order to be correctly displayed in context, the language and base direction of a string [may be required](https://www.w3.org/TR/string-meta/#why-is-this-important). Strings in this API may have to be written to fixed-function [=authenticators=] and then later read back and displayed on a different platform. Thus language and direction metadata is encoded in the string itself to ensure that it is transported atomically. From ccf4e32df1449273437ed6aa1d68cf695435f9ca Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 20 Mar 2024 16:25:37 +0100 Subject: [PATCH 8/8] Don't mention only authenticators in reference to string truncation section --- index.bs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index c691e889e..7eb852b28 100644 --- a/index.bs +++ b/index.bs @@ -3195,7 +3195,7 @@ associated with or [=scoped=] to, respectively. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialEntity/name}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. When storing a {{PublicKeyCredentialEntity/name}} member's value, - [=authenticators=] MAY truncate the value as described in [[#sctn-strings-truncation]] + the value MAY be truncated as described in [[#sctn-strings-truncation]] using a size limit greater than or equal to 64 bytes. @@ -3268,7 +3268,7 @@ credential. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialUserEntity/displayName}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. When storing a {{PublicKeyCredentialUserEntity/displayName}} member's value, - [=authenticators=] MAY truncate the value as described in [[#sctn-strings-truncation]] + the value MAY be truncated as described in [[#sctn-strings-truncation]] using a size limit greater than or equal to 64 bytes.