Subject: [TLS] Narrowing allowed characters in ALPN ?

From: Erik Nygren <[email-masked]>
Date: Wed, 19 May 2021 17:29:33 -0400

With draft-ietf-dnsop-svcb-https being in WGLC in DNSOP, one feedback that
has come up is that the escaping and parsing for SvcParamValues is
complicated.
Most of this complication comes from trying to support 8-bit clean ALPN
values.
Ideally in presentation format the ALPN list would be something like
"h2,h3,http/1.1"
but at the same time the current definition of ALPN as being a series of
binary
octets means that we need parsing and escaping rules.
When httpbis defined Alt-Svc, quite a bit of complexity showed up there
as well for supporting an 8-bit-clean ALPN value while allowing for an ascii
representation for most codepoints.  It seems likely that other
specifications
may run into the same challenge.

Would there be support for updating the ALPN registry to
indicate that registered ALPN values need to conform to a subset of token
characters?   There is a separate question for the process of making
this change, but before even exploring that it seems necessary to ask
the TLS WG if there are strong opinions on this one way or the other.

>From a usability perspective, non-token ALPN values will have challenges
in many of the systems that may try and configure them, as well
as for rendering special characters in various systems that may handle
ALPNs.
The codepoint space is also massive so it isn't clear that there's a
compelling
need to support 8-bit ALPN from a code point conservation perspective.

   Erik

---

From: "Salz, Rich" <[email-masked]>
Date: Wed, 19 May 2021 22:29:43 +0000

If you look at https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids you can see that all of them are ASCII right now, except for some of the GREASE values.

I support limiting it.

---

From: Christian Huitema <[email-masked]>
Date: Wed, 19 May 2021 13:59:05 -1000

On 5/19/2021 12:29 PM, Salz, Rich wrote:

> If you look athttps://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids  you can see that all of them are ASCII right now, except for some of the GREASE values.
>
> I support limiting it.

Internationalization?

-- Christian Huitema

---

From: "Martin Thomson" <[email-masked]>
Date: Thu, 20 May 2021 10:47:25 +1000

I think that we would need stronger reasons than "it's annoying".  There are good reasons to use octets that map to simple ASCII.  We should continue to only define identifiers that use those characters.  However, a specification is also a commitment and whether or not it was a good idea, we (this working group and the IETF as a whole) made that commitment.

I tend to think that as long as it isn't broken, it doesn't need fixing.  And we have - on various occasions - discussed using the capability.

Were we to define this all over, I'd be supportive of restrictions, but it's not worth fixing now.

On Thu, May 20, 2021, at 07:29, Erik Nygren wrote:
> but at the same time the current definition of ALPN as being a series 
> of binary
> as for rendering special characters in various systems that may handle ALPNs.
> The codepoint space is also massive so it isn't clear that there's a compelling
> _______________________________________________
> TLS mailing list
> [email-masked] <mailto:TLS%40ietf.org>
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 20 May 2021 01:55:09 -0400

> I support limiting it.

I concur.  These are not strings used between users to communicate in
their native language.  They are machine-to-machine protocol
identifiers, and use of the narrowest reasonable character set promotes
interoperability.

We don't want to embed ASCII NUL bytes in these, worry about potential
corruption when they get embedded in text strings and undergo transforms
from ISO-Latin to UTF-8 or back, ...

The more vanilla the character set the better.  The HTTPS record
constructs comma-separated lists of these in quotes, so it has to
deal with escaping quotes and commas, and other needless pain.

We're not helping anyone by insisting that the original definition was
wise.  It can and should be revised.

-- 
    Viktor.

---

From: Ryan Sleevi <[email-masked]>
Date: Thu, 20 May 2021 03:06:06 -0400

> identifiers, and use of the narrowest reasonable character set promotes

I'm not sure I understand this. Could you expand further how adding more
normative restrictions promotes, rather than harms, interoperability?

The fact that, as you highlight, they are machine-to-machine, seems like
the greatest path to interoperability, because they shouldn't be assumed to
be "human-readable", and because as specified, no other validation needs to
be performed by either party. They should simply be treated as they're
specified: an opaque series of bytes. Conversions to text strings or
transformations such as character sets seems like fundamentally
misunderstanding/misusing them, rather than being a thing to support.

The idea of restricting the character set seems like it only opens the door
for less interoperability and more complexity. For example, senders need to
make sure they're sending within the allowed character set (meaning
validation before transmission), and receivers that wish to avoid malicious
peers need to similarly validate the identifiers before exposing them as to
API callers. This then adds complexity to the API design, as "no fail"
operations now become "maybe fail" (e.g if a caller attempts to call with
an invalid character string), and that propagates throughout the design of
systems (e.g. config files that may fail to load now).

It seems there's a parallel here to the discussion about whether HTTP/2
should have been a text protocol, like HTTP/1.1 and its predecessors, which
had similar arguments to what's being raised now, versus the binary
protocol that was ultimately adopted.

If the argument is that the extensibility has already rusted shut because
the ecosystem ignored the spec and we didn't GREASE it by using ALPN
identifiers that actually behaved as opaque bytes, then we should at least
make an effort to document why and when that happened, so that mistakes
like that can be avoided in the future.

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 20 May 2021 17:49:56 +1000

For better or worse, these identifiers are being used in places outside the TLS handshake -- for example, in HTTP header fields, as Erik mentioned. That brings the encoding / conversion concerns he mentioned. It would be simpler (and likely safer) to only allow ASCII strings in those uses (at least).

Cheers,

> On 20 May 2021, at 5:06 pm, Ryan Sleevi <[email-masked]> wrote:
> 
> 
> 
> On Thu, May 20, 2021 at 1:56 AM Viktor Dukhovni <[email-masked]> wrote:
> I'm not sure I understand this. Could you expand further how adding more normative restrictions promotes, rather than harms, interoperability?
> 
> The fact that, as you highlight, they are machine-to-machine, seems like the greatest path to interoperability, because they shouldn't be assumed to be "human-readable", and because as specified, no other validation needs to be performed by either party. They should simply be treated as they're specified: an opaque series of bytes. Conversions to text strings or transformations such as character sets seems like fundamentally misunderstanding/misusing them, rather than being a thing to support.
> 
> The idea of restricting the character set seems like it only opens the door for less interoperability and more complexity. For example, senders need to make sure they're sending within the allowed character set (meaning validation before transmission), and receivers that wish to avoid malicious peers need to similarly validate the identifiers before exposing them as to API callers. This then adds complexity to the API design, as "no fail" operations now become "maybe fail" (e.g if a caller attempts to call with an invalid character string), and that propagates throughout the design of systems (e.g. config files that may fail to load now).
> 
> It seems there's a parallel here to the discussion about whether HTTP/2 should have been a text protocol, like HTTP/1.1 and its predecessors, which had similar arguments to what's being raised now, versus the binary protocol that was ultimately adopted.
> 
> If the argument is that the extensibility has already rusted shut because the ecosystem ignored the spec and we didn't GREASE it by using ALPN identifiers that actually behaved as opaque bytes, then we should at least make an effort to document why and when that happened, so that mistakes like that can be avoided in the future. 
> [email-masked]

--
Mark Nottingham   https://www.mnot.net/

---

From: "Salz, Rich" <[email-masked]>
Date: Thu, 20 May 2021 13:30:09 +0000

Look at RFC 701, it says: the precise set of octet values that identifies the protocol. This could be the UTF-8 encoding of the protocol name.

So I changed my mind and think it's okay to leave as-is but wouldn't mind if it became less general or more specific. For example, what if a protocol string matches a truncated UTF8 string?  It makes me think of SNI which could have any format, but really is "any format as long as it's a DNS name"

---

From: Ben Schwartz <[email-masked]>
Date: Thu, 20 May 2021 07:39:59 -0700

On Thu, May 20, 2021 at 6:30 AM Salz, Rich <rsalz=
[email-masked]> wrote:

> Look at RFC 701, it says: the precise set of octet values that identifies
> the protocol. This could be the UTF-8 encoding of the protocol name.
>
> So I changed my mind and think it's okay to leave as-is but wouldn't mind
> if it became less general or more specific. For example, what if a protocol
> string matches a truncated UTF8 string?  It makes me think of SNI which
> could have any format, but really is "any format as long as it's a DNS name"
>

One intermediate option might be to keep the ALPN TLS extension 8-bit
clean, but change the IANA instructions for the ALPN registry to tighten
the registration requirements.

---

From: David Benjamin <[email-masked]>
Date: Thu, 20 May 2021 11:23:15 -0400

SVCB's syntax would need us to not only exclude non-ASCII characters but
also avoid random delimiters like commas, right? I think that's going a bit
too far. As Ryan notes, complex definitions for allowed strings result in
ambiguities around who is responsible for validating what and subtle
variations in different implementations. That ambiguity can lead to
injection attacks when one component of a system expects some validation,
but the other component disagrees.

I think a system that consistently expects a simple data type is more
robust than carefully maneuvering around commas, spaces, newlines, etc.
Text protocol syntaxes aren't universal syntax, and for every
delimiter-based protocol we dodge, there'll be one we hit. For instance,
ALPN identifiers already cannot be used as filenames because "http/1.1"
includes a slash. More generally, the ship has sailed. Applications already
need to tolerate arbitrary 8-bit ALPN strings out of their TLS libraries.

That said, documenting some interop risks when allocating values is
reasonable. IIRC, a lot of Java TLS stacks have issues with non-UTF8
(perhaps even non-ASCII?) identifiers. The getApplicationProtocol() API
reports the ALPN protocol as a String (16-bit) and implementations
sometimes use a random character set without paying attention.

Note this isn't a fundamental limitation of 16-bit strings. It's possible
to convey 8-bit-clean in a 16-bit string, if you define a suitable, if
inelegant, encoding.
https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-nexthopprotocol
https://infra.spec.whatwg.org/#isomorphic-decode

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 20 May 2021 11:26:28 -0400

> normative restrictions promotes, rather than harms, interoperability?

See below.  The idea is not to ask TLS implementations to reject
non-ASCII ALPN values, but rather for non-ASCII values to not be
defined, facilitating better interoperability among systems that
exchange ALPN values outside of TLS in various serialisation contexts.

> specified: an opaque series of bytes.

Yes, in TLS, but once they end up in DNS zones, configuration files,
pasted into web forms (to update DNS HTTPS/SVCB records...) various
pain points arise.

> the registration requirements.

Yes, this, but also a commmitment to keep it that way, so that e.g.
HTTPS/SVCB can rely on not needing to encoding ALPN values that are
non-ASCII, have control characters, commas, double-quotes, ...

So the below should suffice:

    * lower-case ASCII letters a-z
    * ASCII digits 0-9
    * "+", "-", ".", "/" and "_"

-- 
    Viktor.

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 20 May 2021 11:28:27 -0400

> but the other component disagrees.

Just the registry needs to be restricted.  TLS implementations would
support all possible inputs.  HTTPS/SVCB would no longer need to parse
complex quoted input formats.

-- 
    Viktor.

---

From: Christian Huitema <[email-masked]>
Date: Thu, 20 May 2021 06:17:59 -1000

> complex quoted input formats.

Before the WG settles on restrictions, we may want to take a look at how 
ALPNs are used now, and what usage we can predict in the future. My 
personal experience is that they are used liberally. Application 
developers create protocols for a variety of reasons, such as the series 
of "h9-??" or "h3-??" protocols used in the QUIC WG, the "picoquic-test" 
ALPN used in the test suite of the "picoquic" implementation, the 
"picoquic-sample" ALPN used in the picoquic API samples, or the "doq-??" 
ALPN used to test DNS over QUIC.

All the examples I have seen in the wild are indeed ASCII strings, but 
then they come from English speaking developers. If my mother tongue was 
Chinese or Arabic, I might very well have picked non ASCII values. Very 
few of these end up registered with IANA. The registration is really 
useful when the application protocol is somehow standardized, with 
multiple implementations of clients and servers having to agree on the 
value. It is not required in practice when clients and servers are 
developed by the same organization, or by a closely cooperating set of 
organizations. The ALPN is whatever looks expressive to the developers 
and is unlikely to collide with other usage. The occasional collision 
would only be a problem if the same server was supporting multiple 
application protocols with colliding names.

So, maybe, peace and UTF8?

-- Christian Huitema

---

From: Andrei Popov <[email-masked]>
Date: Thu, 20 May 2021 16:45:23 +0000

+1 what Ryan said. Especially the point that added restrictions aren’t a viable path to better interoperability.

ALPN IDs are byte strings; the fact that some of them can be displayed as ASCII character strings merely reflects the fact that those ALPN IDs were chosen by humans😊.

Cheers,

Andrei

From: TLS <[email-masked]> On Behalf Of Ryan Sleevi
Sent: Thursday, May 20, 2021 12:06 AM
To: [email-masked]
Subject: [EXTERNAL] Re: [TLS] Narrowing allowed characters in ALPN ?

On Thu, May 20, 2021 at 1:56 AM Viktor Dukhovni <[email-masked]<mailto:[email-masked]>> wrote:

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 20 May 2021 13:02:45 -0400

On Thu, May 20, 2021 at 04:45:23PM +0000, Andrei Popov wrote:

> ALPN IDs are byte strings; the fact that some of them can be displayed
> as ASCII character strings merely reflects the fact that those ALPN
> IDs were chosen by humans😊.

That's fine when they're just private signalling between a homebrew
client and homebrew server, but for ALNP values registered with IANA,
used in DNS HTTPS/SVCB records, ... the byte strings do need to be
broadly usable, so that any site operator can add them into their DNS
zone, type them into a web form, ...

If ALPN values are BIDI strings, with mixed left-to-right and
right-to-left fragments, comtain accented characters that may have
different NFKC vs. NFKD forms... usability and interoperability suffer.

It is fine for the TLS protocol to not care, but the *standard* ALPN
values in the IANA registry (that might then also appear in DNS
zone files, configuration files, ...) a more restricted character
set would actually be helpful.

-- 
    Viktor.

---

From: Ryan Sleevi <[email-masked]>
Date: Thu, 20 May 2021 13:46:38 -0400

> set would actually be helpful.

I'm a little torn here, because you've again mentioned usability and
interoperability suffer, but it's unclear if you're seeing that as a
generic statement or simply "with respect to configuring DNS zone files".

Saying BIDI, LTR/RTL or NFKC/NFKD are issues here is like saying TLS
wireprotocol version field itself suffers from left-to-right issues. Such a
statement makes no sense, because the version, like the ALPN, is a byte
string. We don't say that the TLS version is "COMBINING TILDE" (U+0303), we
say it's 0x03 0x03, or, if we want to make the string human readable, we
convert it to a value that has no relation to its wire representation -
such as "TLS 1.3"

The suggestion here, of restricting the registered set, seems like it
should equally be obvious as creating and amplifying interoperability
issues, rather than resolving them, because of the assumption again that
values will be ASCII, even though that's not what the wire protocol
assumes. APIs, from the TLS implementation itself to those that expose or
rely on the TLS information (such as the Web APIs previously mentioned)
would, if such a path as you suggest here were adopted, no doubt assume
that despite the spec saying it's a byte string, it's in fact an ASCII
string. Such APIs and design assumptions quickly permeate systems, and as a
consequence, interoperability is harmed.

This issue is, functionally, an example of that. It seems like the issue is
not at all related to the DNS wire format, which is perfectly happy with
this, but rather the configuration text syntax used with DNS, and not
wanting to do things like escape byte sequences. This is why it seems like
it's simply a matter of being inconvenient, but have I misunderstood and
there's a deeper issue I've missed?

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 20 May 2021 14:19:22 -0400

> generic statement or simply "with respect to configuring DNS zone files".

At present, more the latter, but not exclusively so, since there are
likely other places where operators might be recording choices of
supported ALPN values in configuration files.

> string.

And indeed at present also in the DNS wire format.  What's new, is that
those values are now also going to be manipulated by operators in their
presentation form, which gets rather unwieldy when the values happen to
contain commas, double-quotes, control characters, ... let alone strings
that in UTF-8 appear to be NFKD, BIDI, ...

> We don't say that the TLS version is "COMBINING TILDE" (U+0303), we

Of course, we all understand they're plain octet-strings.  But that does
not help the poor operator trying to enter them into a config file or
a web form.

> assumes.

I don't see a substantial risk that TLS stacks will start to not treat
the ALPN string as an opaque byte string, it would take more code to do
otherwise.

> APIs, from the TLS implementation itself to those that expose or
> string.

This is of course possible, but does not look like a substantial risk.
And there's always GREASE.

> wanting to do things like escape byte sequences.

Correct, but more than just DNS, basically any data-at-rest
serialisation of ALPN values in configuration files, or use
with interactive data entry, ...

> This is why it seems like it's simply a matter of being inconvenient,
> but have I misunderstood and there's a deeper issue I've missed?

The incovenience means that applications that process SVCB/HTTPS data
entered by users need much more complex and easier to mess up parsers.

Since the likelihood of actually adding exotic ALPN values to the
registry appears slim, why not say so.  That would leave the exotic
values for private on-the-wire use, while allowing DNS and other
configuration serialisation forms to avail themselves of more
straight-forward parsers.

-- 
    Viktor.

---

From: Nick Harper <[email-masked]>
Date: Thu, 20 May 2021 11:52:50 -0700

> straight-forward parsers.

Encoding ALPN identifiers in hex for these configuration files sounds like
a very straightforward way to support all valid ALPN identifiers. We
already have "exotic" ALPN identifiers in the registry (for GREASE). Any
new scheme that handles ALPN should be designed to handle all possible
values. Not doing so will lead to interoperability issues that others have
already mentioned.

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 20 May 2021 18:55:56 -0400

> values. Not doing so will lead to interoperability issues that others have

I agree it is a straight-forwarding encoding for machines, and it is
well suited for the GREASE code points.

But, it makes for a fairly terrible user interface for the human
operator.  Compare:

    * managesieve
    * 6d616e6167657369657665

Typos in hex values are easy to make and hard to recognise.

-- 
    Viktor.

---

From: Nick Harper <[email-masked]>
Date: Thu, 20 May 2021 16:15:27 -0700

On Thu, May 20, 2021 at 3:56 PM Viktor Dukhovni <[email-masked]>
wrote:

> I agree that it's not a great user interface for the human. A good
solution to that is to let the user define a constant with the hex value
(or build the ALPN constant into the config language), like how with
OpenSSL one can specify "ECDHE-ECDSA-AES128-GCM-SHA256" instead of 0xC02B.
Using your example, one could define a constant ManageSieve = {0x6d 0x61
0x6e 0x61 0x67 0x65 0x73 0x69 0x65 0x76 0x65} and reference that constant,
and if a typo were made (e.g. one put ManageSeive in the config), the
config would fail fast, vs if one configured "manageseive" as the ALPN
directly, the typo would propagate further through a deployment before
being detected/fixed.

There are good solutions to solve the human factors of managing/configuring
ALPN that don't require imposing restrictions on what ALPN can go on the
wire in TLS. Those solutions should be favored over restricting the wire
protocol/code point allocation.

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 20 May 2021 19:23:14 -0400

> directly, the typo would propagate further through a deployment before

The constants would work fine in programming APIs, but they're of no use
in filling in DNS records in web forms, master copies of zone files, ...
or any other configuration file syntax where the context supports only
literals.

> wire in TLS.

Note, I am NOT promising restricting what can go on the wire TLS, only
what can go in the IANA ALPN registry as a standard interoperable ALPN
value.

> Those solutions should be favored over restricting the wire

None come to mind for the alpn field of the proposed HTTPS/SVCB records.
What would you suggest?  (I hope not hex).

The current proposal, even with the rather compex quoting/escaping rules
is better than hex, but is rather fragile.  Developers will get it
badly wrong.

-- 
    Viktor.