Subject: [TLS] TLS ALPN (rfc7301), no reserved seperator char and why is 0 no banned

From: [email-masked] (Martin Rex)
Date: Mon, 13 Apr 2015 23:18:11 +0200 (CEST)

I have only recently looked at the TLS extension ALPN spec (RFC7301)
and it seems that there currently is no reserved character for the
ALPN ID registry that could be used as seperator character if one
wanted to facilitate the admin/user UI and tracing/logging.

While I don't allowing UTF8, I would have really appreciated
reserving at least one character (or octet value) for the obvious
purpose of printing all currently offered protocols in a single line.

I'm also puzzled why the octet value 0 was not banned from the
ALPN ID either.  That seems like calling for trouble.

-Martin

---

From: Andrei Popov <[email-masked]>
Date: Mon, 13 Apr 2015 21:32:22 +0000

Hi Martin,

Although the currently defined ALPN IDs consist of printable characters (which admittedly helps when looking at network traces), generally speaking ALPN IDs are octet strings and could contain arbitrary bytes.

Cheers,

Andrei

-----Original Message-----
From: TLS [mailto:[email-masked]] On Behalf Of Martin Rex
Sent: Monday, April 13, 2015 2:18 PM
To: [email-masked]
Subject: [TLS] TLS ALPN (rfc7301), no reserved seperator char and why is 0 no banned

I have only recently looked at the TLS extension ALPN spec (RFC7301) and it seems that there currently is no reserved character for the ALPN ID registry that could be used as seperator character if one wanted to facilitate the admin/user UI and tracing/logging.

While I don't allowing UTF8, I would have really appreciated reserving at least one character (or octet value) for the obvious purpose of printing all currently offered protocols in a single line.

I'm also puzzled why the octet value 0 was not banned from the ALPN ID either.  That seems like calling for trouble.

-Martin

_______________________________________________
TLS mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tls

---

From: [email-masked] (Martin Rex)
Date: Mon, 13 Apr 2015 23:44:53 +0200 (CEST)

Andrei Popov wrote:
> 
> Although the currently defined ALPN IDs consist of printable characters
> (which admittedly helps when looking at network traces), generally
> speaking ALPN IDs are octet strings and could contain arbitrary bytes.

I do understand what the current specification (rfc7301) says.

But I just fail to see a rationale why it needs to be that artificially
awkward with no pressing need.

Being able to handle (rather than being allowed to reject upfront)
arbitrary octet string blobs here makes it extremely painful to
implement APIs for this.  You can not allow the pretty common
0-terminated strings API semantics if embedded 0 characters are
permitted, and might get registered in the future.

I'm wondering what specific rationale (other than calling for trouble)
justifies making this extension extra painful to implement and use?

-Martin

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Apr 2015 14:51:01 -0700

> awkward with no pressing need.

The rationale could be as simple as the fact that no one made any
attempt to constrain the value-space when the RFC was discussed in the
working group.

Apparently, people who had NPN implementations were already doing the
ugly API thing (the API in NSS is definitely not an examplar here) and
so no one objected at the time.

I agree that it's more painful than absolutely necessary.

---

From: Andrei Popov <[email-masked]>
Date: Mon, 13 Apr 2015 21:58:11 +0000

Yes, this is an example of NPN legacy in ALPN, and yes there is some API pain involved.

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Monday, April 13, 2015 2:51 PM
To: [email-masked]
Cc: Andrei Popov; [email-masked]
Subject: Re: [TLS] TLS ALPN (rfc7301), no reserved seperator char and why is 0 no banned

On 13 April 2015 at 14:44, Martin Rex <[email-masked]> wrote:
> But I just fail to see a rationale why it needs to be that 
> artificially awkward with no pressing need.

The rationale could be as simple as the fact that no one made any attempt to constrain the value-space when the RFC was discussed in the working group.

Apparently, people who had NPN implementations were already doing the ugly API thing (the API in NSS is definitely not an examplar here) and so no one objected at the time.

---

From: [email-masked] (Martin Rex)
Date: Tue, 14 Apr 2015 00:30:49 +0200 (CEST)

> and yes there is some API pain involved.

I'm not trying to break things and I'm not advocating to change
any existing APIs.  But I've just been asked for support of this
and am looking into newly implementing it, and I would appreciate
if we (i.e. the IETF TLS working group) could restrict the TLS ALPN IDs
at least by banning the character 0 from TLS ALPN ID registrations now.

Being allowed to reject embedded NULs would facilitate some aspects
(save me a few lines of code).

I can live with UTF8.

A single reserved character (such as colon ':' or pipe '|' or comma ',')
would allow me to avoid a character escaping scheme for the API I'm
trying to create, but I could live with this issue being a proprietary thing.

-Martin

---

From: Hubert Kario <[email-masked]>
Date: Tue, 14 Apr 2015 20:04:20 +0200

> trying to create, but I could live with this issue being a proprietary

You don't prevent CVE-2009-2408-like exploits by banning nulls in fields.

If anything, the RFC could be updated to explicitly state that implementations 
MUST be able to handle the case where the IDs include null bytes.

But this is the case for basically all fields both in TLS and X509...
-- 
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic

---

From: Watson Ladd <[email-masked]>
Date: Tue, 14 Apr 2015 11:19:47 -0700

> But this is the case for basically all fields both in TLS and X509...

And this has been a continuous source of pain, leading to exploits. Moreso
on the X.509 side.

Sincerely,
Watson Ladd

---

From: [email-masked] (Martin Rex)
Date: Wed, 15 Apr 2015 00:53:28 +0200 (CEST)

Hubert Kario wrote:

> Martin Rex wrote:

I was talking about *API* stuff, not about wire-level encoding and
TLS protocol stuff.

To be able to support the currently (unreasonably broad) set of
what TLS ALPN IDs may be registered, you would have to create an
API where the caller would have to supply the *input* (from application
to TLS implementation) as an array-of-blobs, i.e. explicit length fields

A concatenated flat-string representation would be *MUCH* simpler
and nicer at the API level.

> 
> If anything, the RFC could be updated to explicitly state that
> implementations MUST be able to handle the case where the IDs
> include null bytes.

That would be insane.

If anything, an implementation receiving a ALPN ID with embedded
NUL characters should drop and ignore that bogus ALPN ID.

> But this is the case for basically all fields both in TLS and X509...

That applies only to fields with unreasonable definitions.

Look at the TLS Server Name Indication extension:

  https://tools.ietf.org/html/rfc6066#section-3

this has a reasonable definition for the "host_name(0)" is limited to
"fully qualified DNS hostname", which means that not just embedded
NULs are prohibited (and can be immediately dropped and ignored by the TLS
ClientHello PDU parser), but also "host_name(0)" > 255 chars and
there are several other constraints on DNS hostnames.

Robust and conservative design means that you check and skip invalid data
as early as possible, to limit the attack surface.  With how TLS ALPN
is currently defined, you can *ALWAYS* target the application on top
of TLS with attacks, because the TLS implementation is not currently
allowed to weed out obvious crap right away. 

-Martin

---

From: Hubert Kario <[email-masked]>
Date: Wed, 15 Apr 2015 11:07:51 +0200

> I was talking about *API* stuff, not about wire-level encoding and

and API needs to be able to handle all the stuff that can be sent over the 
wire

> and nicer at the API level.

even in C like languages you just need memory pointer and a length value, I 
wouldn't call that, compared to just memory pointer, to be "MUCH" simpler

the first makes buffer overruns impossible - something C like languages could 
use more of

In some languages, like Python, you can't even have a byte array of indefinite 
length, making the embedded nulls a complete non-issue
 
> > implementations MUST be able to handle the case where the IDs

So current RFC is insane...?

The above is just implicit, not explicit.
 
> there are several other constraints on DNS hostnames.

that's just in relation to host_name, not to SNI or TLS in general

> allowed to weed out obvious crap right away.

It's true, it exposes the app on top.

On the other hand, the values already passed between peers are non null 
terminated, so the API has to support non-null terminated strings anyway.

...please tell me you're not null terminating the ID before passing them to 
application....
-- 
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic

---

From: Andrei Popov <[email-masked]>
Date: Wed, 15 Apr 2015 18:14:57 +0000

Martin's desire for a simple API that takes a list of NUL-terminated ASCII strings is very understandable. I've seen other developers ask for the same. 

Having said that, ALPN RFC allows the use of arbitrary octet strings as ALPN IDs, so unfortunately the simple API that assumes NUL-terminated ASCII IDs is not sufficient. And of course any code that matches ALPN IDs has to perform the comparison of byte arrays rather than some form of string comparison.

Cheers,

Andrei

-----Original Message-----
From: Hubert Kario [mailto:[email-masked]] 
Sent: Wednesday, April 15, 2015 2:08 AM
To: [email-masked]
Cc: [email-masked]; Andrei Popov
Subject: Re: [TLS] TLS ALPN (rfc7301), no reserved seperator char and why is 0 no banned

On Wednesday 15 April 2015 00:53:28 Martin Rex wrote:
> >> I'm not trying to break things and I'm not advocating to change any 
> >> existing APIs.  But I've just been asked for support of this and am 
> >> looking into newly implementing it, and I would appreciate if we 
> >> (i.e. the IETF TLS working group) could restrict the TLS ALPN IDs 
> >> A single reserved character (such as colon ':' or pipe '|' or comma 
> >> ',') would allow me to avoid a character escaping scheme for the 
> >> API I'm trying to create, but I could live with this issue being a 
> >> proprietary thing.
> > 
> I was talking about *API* stuff, not about wire-level encoding and TLS 
> protocol stuff.

and API needs to be able to handle all the stuff that can be sent over the wire

> To be able to support the currently (unreasonably broad) set of what 
> TLS ALPN IDs may be registered, you would have to create an API where 
> the caller would have to supply the *input* (from application to TLS 
> implementation) as an array-of-blobs, i.e. explicit length fields
> 
> A concatenated flat-string representation would be *MUCH* simpler and 
> nicer at the API level.

even in C like languages you just need memory pointer and a length value, I wouldn't call that, compared to just memory pointer, to be "MUCH" simpler

the first makes buffer overruns impossible - something C like languages could use more of

In some languages, like Python, you can't even have a byte array of indefinite length, making the embedded nulls a complete non-issue

 
> If anything, an implementation receiving a ALPN ID with embedded NUL 
> characters should drop and ignore that bogus ALPN ID.
> 
> NULs are prohibited (and can be immediately dropped and ignored by the 
> TLS ClientHello PDU parser), but also "host_name(0)" > 255 chars and 

> Robust and conservative design means that you check and skip invalid 
> data as early as possible, to limit the attack surface.  With how TLS 
> ALPN is currently defined, you can *ALWAYS* target the application on 
> top of TLS with attacks, because the TLS implementation is not 
> currently allowed to weed out obvious crap right away.

On the other hand, the values already passed between peers are non null terminated, so the API has to support non-null terminated strings anyway.

...please tell me you're not null terminating the ID before passing them to application....
--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic

---

From: Martin Thomson <[email-masked]>
Date: Wed, 15 Apr 2015 11:38:10 -0700

> Having said that, ALPN RFC allows the use of arbitrary octet strings as ALPN IDs, so unfortunately the simple API that assumes NUL-terminated ASCII IDs is not sufficient. And of course any code tha…

Well, you *could* implement something that only took NUL-terminated
ASCII labels.  That could still work, even if it encountered junk as
long as the implementation correctly checked lengths first.  It would
only fail to work if you actually need to talk to someone who wanted
to include a crazy value.

---

From: Andrei Popov <[email-masked]>
Date: Wed, 15 Apr 2015 18:59:55 +0000

Since the ALPN RFC allows the use of octet strings as ALPN IDs, it seems wrong to characterize non-ASCII IDs as "junk" or "crazy" values. ALPN IDs are not intended for display to the user, and don't have to consist of ASCII characters.

It is true that one could implement an API that only takes NUL-terminated ASCII ALPN IDs. Such an API would be limited in that it's only useable with a subset of allowed ALPN IDs (but admittedly some people can live with that). It is more important that the ALPN I-D matching code treat the IDs correctly, as length-prefixed byte arrays.

Cheers,

Andrei

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Wednesday, April 15, 2015 11:38 AM
To: Andrei Popov
Cc: Hubert Kario; [email-masked]; [email-masked]
Subject: Re: [TLS] TLS ALPN (rfc7301), no reserved seperator char and why is 0 no banned

> Having said that, ALPN RFC allows the use of arbitrary octet strings as ALPN IDs, so unfortunately the simple API that assumes NUL-terminated ASCII IDs is not sufficient. And of course any code tha…

Well, you *could* implement something that only took NUL-terminated ASCII labels.  That could still work, even if it encountered junk as long as the implementation correctly checked lengths first.  It would only fail to work if you actually need to talk to someone who wanted to include a crazy value.

---

From: Martin Thomson <[email-masked]>
Date: Wed, 15 Apr 2015 12:07:28 -0700

> Since the ALPN RFC allows the use of octet strings as ALPN IDs, it seems wrong to characterize non-ASCII IDs as "junk" or "crazy" values. ALPN IDs are not intended for display to the user, and don'…

I was only getting into character :)  Obviously, "crazy" is
subjective.  I would hope that the IETF doesn't get into the business
of using the whole expressive range provided by ALPN, because that
only makes it harder to use.

---

From: Andrei Popov <[email-masked]>
Date: Wed, 15 Apr 2015 19:24:20 +0000

Understood, but if you want to save bytes in the ClientHello (e.g. to avoid issues with certain middle boxes), then short ALPN IDs such as 0x01 become highly attractive:).

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Wednesday, April 15, 2015 12:07 PM
To: Andrei Popov
Cc: Hubert Kario; [email-masked]; [email-masked]
Subject: Re: [TLS] TLS ALPN (rfc7301), no reserved seperator char and why is 0 no banned

> Since the ALPN RFC allows the use of octet strings as ALPN IDs, it seems wrong to characterize non-ASCII IDs as "junk" or "crazy" values. ALPN IDs are not intended for display to the user, and don'…

I was only getting into character :)  Obviously, "crazy" is subjective.  I would hope that the IETF doesn't get into the business of using the whole expressive range provided by ALPN, because that only makes it harder to use.