Subject: Re: [TLS] Working Group Last Call for draft-ietf-tls-tls13-18

From: [email-masked] (Martin Rex)
Date: Thu, 3 Nov 2016 15:31:26 +0100 (CET)

Ilari Liusvaara wrote:
>>> 
>>> Hiding the types does have its benefits (and it is also used for
>>> zero-overhead padding scheme).
>> 
>> Nope, ZERO benefits.  But it totally breaks the middleware
>> _at_the_endpoints_!
> 
> Also, things like this should have been discussed like year or two
> ago. Right now it is too late for major changes like this without good
> cryptographic justifications (which AFAICT don't exist).

They WERE brought up back then, and several times in between.
But the TLSv1.3 proposal has still not been fixed so far.
Ignorance does not make problems go away.  Instead, it means that
one will have to fix it later.

Since then, I've seen exactly ZERO rationale why the cleartext contenttype,
which has existed through SSLv3->TLSv1.2 would be a problem.  With the
removal of renegotiation from TLSv1.3, it is even less of a problem to
keep the contenttype in the clear.

The removal of visibility of ContentType in TLSv1.3 will be a complete
non-starter for TLSv1.3 as a drop-in replacement to TLSv1.2 for certain
software architectures (including a lot of stuff we've been shipping for the
last 5 years), because it is actively being used to signal state of
the communication channel to the application and to *NOT* break application
architecture that relies on (new) application data remaining visible on
network sockets as "network readable" events.

https://www.ietf.org/mail-archive/web/tls/current/msg13085.html

https://www.ietf.org/mail-archive/web/tls/current/msg13106.html

A similar issue exists for the visibility of Alert ContentTypes
for efficiently detecting client-side connection closure.
This has been described here:

https://www.ietf.org/mail-archive/web/tls/current/msg21123.html

The IETF technical leadership is supposed to prevent backwards-incompatible
changes to be adopted and standardized that provide *ZERO* benefit,
but severely impair interop and consumption.

-Martin

---

From: "Salz, Rich" <[email-masked]>
Date: Thu, 3 Nov 2016 17:19:55 +0000

> which has existed through SSLv3->TLSv1.2 would be a problem.  

Because it's kind of implied in the charter, about making as much private as possible.

> years), because it is actively being used to signal state of the communication
> channel to the application and to *NOT* break application architecture that
> relies on (new) application data remaining visible on network sockets as
> "network readable" events.

One app's data is another adversary's oracle.  Or is it that "signals have no morals"?

	/r$

--  
Senior Architect, Akamai Technologies
Member, OpenSSL Dev Team
IM: [email-masked] Twitter: RichSalz

---

From: Watson Ladd <[email-masked]>
Date: Thu, 3 Nov 2016 10:30:05 -0700

> network sockets as "network readable" events.

This I do not understand. I may make some technical errors in below,
and would appreciate correction.

I assume we have an application that is using poll() or select() or
somesuch for nonblocking IO (maybe something fancier, but that is
okay).

This application grabs data from a ready connection, rams it through
the TLS implementation, and then looks at what comes out. But reading
from the connection clears the data available state! However, it's
never the case that there is visible data absent a network read or
write after the handshake.

So what is the content type doing here? Does the application not call
a TLS implementation provided state function to determine what state
the connection is in? And if so why does the record layer need to
know, as opposed to the handshake one? I'm not seeing why the above
style implementation is impossible: Microsoft doesn't seem to think so
and hasn't complained about this change.

Sincerely,
Watson Ladd

---

From: Yoav Nir <[email-masked]>
Date: Thu, 3 Nov 2016 19:31:27 +0200

> keep the contenttype in the clear.

Here’s some to get this to somewhat >0:

Most TLS 1.2 connections will have a few handshake records, followed by a couple of CCS records followed by a whole bunch of application records, followed possibly by a single Alert.

You only see more handshake records in two cases:
   1. The client decided to re-negotiate. That is exceedingly rare.
   2. The server decided a renegotiation is needed so it sent a HelloRequest followed by a handshake.

With visible content type, you can tell these two flows apart. What’s more, there is rarely any reason to do #2 unless the server decided that before accessing some resource, the client needs to present a certificate. You can verify that by counting the number and adding up the size of the handshake records. Having this happen usually means a privileged resource and a privileged user. That’s quite a bit of information to leak from a supposedly secure protocol. Yes, you won’t know the user identity, but you’ll know enough to associate privileged users with IP addresses, and you’ll know at what times they accessed privileged resources as opposed to something like a landing page. That’s meta-data, but it’s quite a lot of meta-data. If we can avoid leaking that, why not?

Yoav

---

From: Yoav Nir <[email-masked]>
Date: Thu, 3 Nov 2016 19:41:49 +0200

I don’t think this makes any difference in applications written on commodity servers using regular socket APIs.

It’s a kind of architecture that has a quick special purpose processor that terminates the TCP and splits the incoming stream into records. The application records are forwarded to a quick crypto processor that decrypts the records and feeds them into the application. Other types of records are forwarded to the handshake processor usually implemented on general-purpose hardware with perhaps a cryptographic accelerator for asymmetric operations. That performs the handshake and feeds the key to the application processor.

With the change in TLS 1.3, the TCP terminator can no longer tell the records apart. That means that the crypto processor will have to take on that duty. That’s a change in architecture that could require new hardware as opposed to a firmware update for existing hardware.

I tend to believe that if this had been such a big deal we would have heard from more people, but I could be wrong. It’s clear to me that the mid-sized content providers who are likely to use such architectures are not yelling much.

Yoav

> On 3 Nov 2016, at 19:30, Watson Ladd <[email-masked]> wrote:
> 
> On Thu, Nov 3, 2016 at 7:31 AM, Martin Rex <[email-masked] <mailto:[email-masked]>> wrote:
>> Ilari Liusvaara wrote:
>>>>> 
> _______________________________________________
> TLS mailing list
> [email-masked] <mailto:[email-masked]>
> https://www.ietf.org/mailman/listinfo/tls <https://www.ietf.org/mailman/listinfo/tls>

---

From: [email-masked] (Martin Rex)
Date: Thu, 3 Nov 2016 19:15:47 +0100 (CET)

> Or is it that "signals have no morals"?

If you look at TLS records exchanged between two peers,
and in particular if you perform a TLS handshake with same server
yourself and compare, you can easily (heuristically) determine
which TLS records of the original stream are hanshake records,
and which are application data records.

So there is exactly ZERO benefit of concealing the ContentTypes.

But this concealing reliably breaks existing application middleware
at the endpoints, which needs to reliably & quickly tell the difference
between handshake&alert records and application data, so that it can
leave application data records in the network buffer, so that the
socket readable event remains visible for the event-based application
logic.

-Martin

---

From: [email-masked] (Martin Rex)
Date: Thu, 3 Nov 2016 19:20:46 +0100 (CET)

Yoav Nir wrote:
> Here?s some to get this to somewhat >0:
> 
> Most TLS 1.2 connections will have a few handshake records,
> followed by a couple of CCS records followed by a whole bunch of
> application records, followed possibly by a single Alert.
> 
>    2. The server decided a renegotiation is needed
>       so it sent a HelloRequest followed by a handshake.
> 
> With visible content type, you can tell these two flows apart.

 (a) so what?  for those interested, one can tell such flows appart
     pretty reliably by traffic analysis.  So there is exactly ZERO
     protection against bad guys, while breaking the good guys.

 (b) but TLSv1.2 remains unchanged, and this flow does not seem to
     exist in TLSv1.3, since renegotiation no longer exists in TLSv1.3.
     -- so why would we need a backwards-incompatible change in a
     protocol that protects something that no longer exists,
     but which severely breaks existing middleware, making it
     impossible to drop-in replace a TLSv1.2 implementation with
     a TLSv1.3 implementation that has this backwards-incompatibility.

-Martin

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 3 Nov 2016 13:33:15 -0500

> So there is exactly ZERO benefit of concealing the ContentTypes.

Sorry, but that doesn't directly follow. 

With visible content type, an observer can *trivially* tell apart the
two flows you mentioned in your next message.  With current stacks'
(lack of) padding and timing obfuscation, the observer can still tell
the flows apart ... but you have a chance of writing a stack that
prevents the observer from doing so.  I don't think that "goes from
'impossible' to 'you have to write code'" can be construed as exactly
zero benefit.

-Ben

---

From: Yoav Nir <[email-masked]>
Date: Thu, 3 Nov 2016 20:38:32 +0200

> On 3 Nov 2016, at 20:20, Martin Rex <[email-masked]> wrote:
> 
> Yoav Nir wrote:
>> 

There is if you pad the records to the size of application records.

>     exist in TLSv1.3, since renegotiation no longer exists in TLSv1.3.

Re-negoatiation doesn’t, but post-handshake client authentication does:
https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.5.2 <https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.5.2>

>     a TLSv1.3 implementation that has this backwards-incompatibility.

Can you elaborate on that middleware?

Yoav

---

From: Ilari Liusvaara <[email-masked]>
Date: Thu, 3 Nov 2016 21:01:26 +0200

> Can you elaborate on that middleware?

Also, what platform (Java? .NET? Linux?) does that middleware run on,
and some base interfaces from standard library (or widespread
extensions) it uses for its API...

What I think I gathered from the description (and this sounds very
bizarre):

- Upon new data indication, the middleware peeks TLS header from the
  incoming data buffer.
- If it is not appdata, it is read and handled.
- If it appdata, the socket readable indication is passed to the
  application (what supports that without wrapping the socket???)
  which it then reads (and presumably passes for decryption).

That sounds much more bizarre than the zerocopy APIs in btls (the
TLS lib I am working on), and those are already pretty odd.

-Ilari

---

From: [email-masked] (Martin Rex)
Date: Tue, 8 Nov 2016 16:25:58 +0100 (CET)

> There is if you pad the records to the size of application records.

There is no such padding by default.  And the TLS handshake is
half-duplex, and for any interested third party, who performs the
handshake with the server himself for comparison, the PDUs are still
pretty much predictable heuristically (by their ordering), even
when they're padded.

So besides being completely pointless, can you describe any realistic
problem that is worth breaking middleware at the endpoints so badly? 

> Re-negoatiation doesn?t, but post-handshake client authentication does:

As previously mentioned, it is middleware that facilitates using
a TLS-protected communication channel for application callers.  It offers
several different kinds of reading strategies to the caller, which the
caller is free to choose from.  One reading mode is "streaming", where
as many app-data TLS records are read (non-blocking) and decrypted,
as fit into the application-supplied buffer.  This facilitates communication
with servers that fragment app data into pathologically small pieces
(e.g. Google).

Non-Appdata records (such as a final Close-Notify or a renegotiation request)
are left in the network buffers, and will only be fully read&processed
after all AppData preceding it have been properly returned to the application.

In a similar fashion, the reverse proxy part (often in the DMZ), can
check whether a browser prematurely aborts a communication and closes
the network connection, by checking for readable events on the network
socket and peeking whether it is a hard connection closure (TCP RESET,
such as MSIE), or a CloseNotify Alert (Firefox,Chrome), without
reading&decoding any application data.

For large-scale Servers, non-blocking network operations are much more
efficient than blocking network operations, the general wait point of
the application is a select/poll call which waits on sockets, and
it is up to the application to decide whether to "select for read" when
it is ready to receive application data on a communication channel.

With appdata records clearly distinguishable at the outer TLS record layer,
the event-based architecture of the application did not need any changes
when switching from cleartext communication to TLS-encrypted communication,
all app-data socket-readable events remained visible with SSLv3->TLSv1.2,
because TLS appdata records can be clearly distinguished from
Handshake, CCS and Alert.

-Martin

---

From: "Salz, Rich" <[email-masked]>
Date: Tue, 8 Nov 2016 18:18:18 +0000

> the PDUs are still pretty much predictable
> heuristically (by their ordering), even when they're padded.

...
 
> So besides being completely pointless, can you describe any realistic problem
> that is worth breaking middleware at the endpoints so badly?

I found the language difference interesting.  We could conduct an interesting thought experiment by reversing the emphasis on each of the above fragments.  But I won't.

Instead, I'll point out that this is in-charter, in-scope, and WG consensus has generally been to "encrypt all the bits" as much as feasible.

Some applications in some corners of some enterprises, might lose out.

Just like those who depending on static RSA, right?

---

From: [email-masked] (Martin Rex)
Date: Wed, 9 Nov 2016 10:31:22 +0100 (CET)

Salz, Rich wrote:
> I found the language difference interesting.  We could conduct an
> interesting thought experiment by reversing the emphasis on each
> of the above fragments.  But I won't.
> 
> Instead, I'll point out that this is in-charter, in-scope, and WG consensus
> has generally been to "encrypt all the bits" as much as feasible.

The problem here is that this breaks (network) flow control, existing
(network socket) event management, and direction-independent connection
closure, and does so completely without value.

When TLS records with AppData can be left in the network socket while
the application layer is not ready to process & consume it, then TCP flow
control works better in high load situation.

The semantics defined for the TLS Closure Alert in SSLv3->TLSv1.2
is somewhat difficult for full-duplex communication, direction-independent
shutdown, and confirmation of receipt:

   https://tools.ietf.org/html/rfc5246#section-7.2.1

   7.2.1.  Closure Alerts

   The client and the server must share knowledge that the connection is
   ending in order to avoid a truncation attack.  Either party may
   initiate the exchange of closing messages.

   close_notify
      This message notifies the recipient that the sender will not send
      any more messages on this connection.  Note that as of TLS 1.1,
      failure to properly close a connection no longer requires that a
      session not be resumed.  This is a change from TLS 1.0 to conform
      with widespread implementation practice.

   Either party may initiate a close by sending a close_notify alert.
   Any data received after a closure alert is ignored.

   Unless some other fatal alert has been transmitted, each party is
   required to send a close_notify alert before closing the write side
   of the connection.  The other party MUST respond with a close_notify
   alert of its own and close down the connection immediately,
   discarding any pending writes.  It is not required for the initiator
   of the close to wait for the responding close_notify alert before
   closing the read side of the connection.

The issue here is that the receiving TLS stack, when processing an
incoming TLS CloseNotify Alert, will typically immediately respond
with a TLS CloseNotifyAlert on its own, precluding the application
from sending any further data in the other direction in response

When hiding the TLS record ContentType, then pre-reading and coalescing
(=streaming) application data records suddenly becomes a problem, because
receiving and processing a hidden TLS CloseNotify Alert will cause
a TLS CloseNotify Alert response (an alleged indicator for a graceful
connection closure) being generated and returned even before
the application has (a) seen and (b) had a chance to respond to the
latest batch of application data.

To prevent this from happening, and leave the decision to the application
of whether to read a (potential) CloseNotify alert from the wire,
I would have to go back to trickling TLS records (including those
pathologically fragmented ones from Google) to the application
whenever TLSv1.3 is negotiated.

There is a similar (slightly smaller) issuer with the coalesced TLS
handshake/alert/css record processing during the TLS handshake phase,
Feeding the whole "flight" already waiting in network buffers into
the TLS stack at once will no longer be possible, with hidden ContentTypes
I will have to start trickling TLS records with handshake messages into
the TLS stack, and have to poll the handshake state after each TLS record
in order to heuristically determine whether the next record waiting in
the network buffer is (likely) a record with AppData--which I must leave
in the network buffer until the application caller explicitly calls for it.

The really painful issue are constantly mind-changing browsers loosing
interest in responses and sending TLS CloseNotify instead of TCP RSTs
-- I don't know how to deal with these without breaking the current
(network socket) event semantics for the app.

-Martin

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 9 Nov 2016 02:25:03 -0800

> whenever TLSv1.3 is negotiated.

I'm not quite following who's who in this scenario, so some potentially
stupid
questions below.

As I understand it, you have the following situation:

- A Web application server
- Some middleware, which comes in two pieces
  - A crypto-unaware network component
  - The TLS stack (you control this piece as well, right?)
- The client

So, in this case, the client sends a flight of records which (ignoring
rehandshakes
and other TLS 1.3 post-handshake shenanigans such as KeyUpdate) contains
a bunch of application data traffic potentially terminating in a
close_notify. In
TLS 1.2 you inspect the content type, deliver all the app data to the TLS
processor,
but hold the close_notify. And those packets are in turn handed to the Web
server/application. Is that correct? If so, when do you deliver the
close_notify
and how do you know how?

In the TLS 1.3 case, as I understand it, you can't see which packets are
which
so you just have to deliver all the packets to the TLS processor, and if
one of
them contains a close_notify, then it responds with its own close_notify
(I'm getting this from the text above where you say "being generated and
returned even before the application has..."). Is that right as well? Can
you explain
further why this is a problem: are you expecting that if you send
application
data to the client after sending the close_notify itself, the client will
consume
it? Or are we somehow concerned with side effects on the application server?

Can you help me understand?

thanks,
-Ekr

> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Wed, 09 Nov 2016 11:05:27 -0600

> closure, and does so completely without value.

Martin, you keep saying things like "without value", while other people
on this thread (Rich, Ilari, Yoav) have given you examples of the value
it provides.  You don't seem to be trying to understand those positions.

Your description of the problems it causes you are difficult to follow,
and it doesn't sound like they have been experienced by other
implementors.  But other people are actively trying to make sure they
understand your concerns (like ekr's post downthread here).

Could you offer the rest of the list the same courtesy?

Your earlier argument that the hidden data is deducable by traffic
analysis anyway isn't a satisfying argument, for two reasons:

(a) if it were reliably true, then your implementations could simply
    adopt the traffic analysis approach instead of inspecting the
    cleartext content types.  If it causes too much additional expense,
    then it should increase the expense for adversaries who are
    monitoring traffic for these same signals as well, which is a
    security+privacy win.

(b) We're including mechanisms (like padding) to make traffic analysis
    harder.  More research is needed to know how to best provide this
    sort of indistinguishability.  But if we decide instead that it's ok
    to directly publish any data that could possibly be inferred by
    traffic analysis, we will never improve the security of TLS for its
    users against traffic analysis, which will only grow more
    sophisticated over time.  Why should we accept this limitation on
    TLS?

This WG isn't chartered to defend the engineering optimizations made by
any particular middlebox vendor.  It's chartered to improve the privacy
and security guarantees offered to users of TLS.

Regards,

         --dkg

---

From: [email-masked] (Martin Rex)
Date: Wed, 9 Nov 2016 18:42:19 +0100 (CET)

Daniel Kahn Gillmor wrote:
> Martin Rex wrote:

Nobody so far has provide a single example of *REAL* value.
For the hiding of ContentType to provide real value, the prerequisites are:

  (1) this value will be _unconditionally_ provided in TLSv1.3

  (2) this value can be demonstrated to be a real security issue in TLSv1.2,
      for existing usage scenarios, where hiding of ContentType is not
      available

Anyhing less is no value, just an illusion of value.

> and security guarantees offered to users of TLS.

You are confusing _middlebox_ with _middleware_at_the_endpoint_,
which is a huge difference, because the middleboxes are performing
man-in-the-middle attacks, whereas the _middleware_at_the_endpoint_
has regular access to the entire plaintext of the communication.

The problem with hiding of TLS record ContentTypes is that it severely
interferes with efficient streaming network I/O--which is preferably
performed outside/above the TLS implementation and async non-blocking
whenever you get into thousands of parallel connections.

-Martin

---

From: Watson Ladd <[email-masked]>
Date: Wed, 9 Nov 2016 09:58:08 -0800

> whenever you get into thousands of parallel connections.

No one else has reported this. That's including Microsoft whose
implementation does hand over all IO to the application. Absent many more
details you are not convincing me there is a problem.

---

From: [email-masked] (Martin Rex)
Date: Wed, 9 Nov 2016 20:42:10 +0100 (CET)

>   - The TLS stack (you control this piece as well, right?)

This is about any conceivable scenario involving at least one of our
components, just client, just server, or at both peers.

The "middleware" is part of our clients and servers. The middleware
performs all the network I/O and necessary calls into the TLS stack,
offers an appdata streaming convenience option for reading,
variable blocking I/O (non-blocking (0ms) up to infinite timeout).

TLS records of type Handshake, Alert and CCS are always processed
in batch, as many as the network buffers have already received.
TLS records of type AppData are processed based on read strategy
desired by the application caller.  The desired reading strategy
(trickling, efficient, streaming) is a parameter of the middleware
read API call, so the app could change it for every call.

 - Trickling means the traditional TLS record reading, i.e. two network
   read calls for every TLS record.

 - Improved means on average one network read call per TLS record.

 - Streaming means reading and decoding as many TLS appdata record
   as there are present in the network read buffers and can be
   received non-blocking.  Only TLS AppData records will be passed
   to the TLS Stack for decoding, Alerts and Handshake records
   will be left in the middlewares network read buffers until all
   appdata as been properly received by the application caller.
   Only upon the next read call from the application, the alert
   or handshake records will be passed to the TLS stack.

Example: GET https://www.google.de/ HTTP/1.0
(where my call to www.google.com is redirected to...)

currently returns a HTTP-response with a 657 byte Header and 44879 byte Body
The response would easily fit into 3 TLS appdata records
(4 Records if the Header is sent in its own TLS record), however
in reality, the Google servers perform pathological fragmentation
of the AppData and use a whooping 36 TLS records for the response
(curiously no TLS AppData record split between header and body).

Processing overhead for _receiving_ such a badly fragmented response:

Trickling:
  34 Read calls into the middleware
  73 recv() calls to read the TLS AppData records from the socket
  34 calls into the TLS stack

Improved:
  34 Read calls into the middleware
  42 recv() calls to read the TLS AppData records from the socket
  34 calls into the TLS stack

Streaming:
   5 Read calls into the middleware
  14 recv() calls to read the TLS AppData records from the socket
  34 calls into the TLS stack

>
> When do you deliver the close_notify and how do you know how?

When the application calls for read, and has already seen all
prior AppData, then the close_notify will be processed and the
result (connection closure, no more data) reported to the calling app.

There is no magic involved here.

Apps *know* when to perform reads, and when not to perform reads.
The middleware doesn't because it is protocol ignorant (it is used
by SMTP, ldaps, HTTPS, HTTP/2.0, websockets, etc).

Think of a simple HTTP-based server app receiving a HTTP/1.0 request
from a TLS-stack on top of a blocking network socket.  If the App would
keep calling SSL_read() (for an OpenSSL-style API), it would get stuck
(blocked on read), and at some point the client would give up and
close the connection (with close_notify or TCP RST), and the server
waking from either the processing of the close_notify or the TCP RST
would be unable to deliver a response (which the client would not read
anyway).

Whether or not the calling App wants to shutdown a communication
at different times in both directions depends on the existing semantics
of that application (which has just added TLS protection around its
communication).  Reading and processing a close_notify in the TLS stack
(e.g. OpenSSL) will tear down *BOTH* directions immediately, and preclude
any further of sending of responses by the application, so the middleware
really will want to hold of processing of close_notify alerts unless
_explicitly_ asked to read further AppData by the application.

With TLS up to TLSv1.2 streaming is no problem, the middleware can
easily recognize non-AppData records and avoid passing them to
the TLS stack for processing unless the application explicitly asks
the middleware to do so.  When TLSv1.3 hides the ContentType,
the fact that a close_notify was received & processed can only be
determined after the fact, when the shattered pieces are on the floor.
Communication in the other direction will be impossible, and it will
not be possible to prevent this from happening.

While it is conceivable to jump hoops and implement new APIs and
callback for the TLS stack to allow the middleware instrumenting
and holding off the processing of TLS close_notify, this is not
going to allow a drop-in replacement of an existing TLSv1.2 with
a ContentType-hiding TLSv1.3 implementation underneath an existing
application.

For SSLv3->TLSv1.2, there was *NO* such backwards-incompatibilty.
We were able just fine to drop-in a TLSv1.2 implementation underneath
apps that were originally built on top of an SSLv3-only stack.

> 
> Can you explain further why this is a problem: are you expecting that
> if you send application data to the client after sending the close_notify
> itself, the client will consume it?
> 

TCP is a full-duplex communication channel and allows shutdown for each
of the two communication directions performed independently.  There are
existing communication protocols (other than HTTP) that _use_ independent
shutdown, and may want to continue using it even after starting to
protect their original cleatext communication with TLS.

If you're vaguely familiar with OpenSSL:
when SSL_read() has received and processed a TLS record with a close_notify
alert, do you know what happens to further calls of SSL_write() of the same
handle, which technically is _the_other_ communication direction.

If you don't know: SSL_write() will fail, because OpenSSL will push out
a close_notify alert from within SSL_read(), and make the connection
unusable.  Being able to distinguish AppData records from non-AppData
records, an application caller of SSL_read() (such as my middleware)
can prevent loosing the backchannel with no prior warning -- if it
wants to.  For streaming operation, my middleware DESPERATELY wants to
prevent the communication channel becoming unusable in both directions
_before_ the application has received/seen all the app data from the channel.

-Martin

---

From: Adam Langley <[email-masked]>
Date: Wed, 9 Nov 2016 12:22:20 -0800

> (curiously no TLS AppData record split between header and body).

At the beginning of a connection we aim to size TLS records so that they
don't span packets. Since none of a TLS record can be processed until the
whole record is received, spanning packets can mean spanning TCP windows or
loss events and thus add significant latency. Web browsers will
shallow-parse data as it arrives in order to start subresource fetches as
soon as possible, so delays can have a cascading effect. See also
https://hpbn.co/transport-layer-security-tls/#optimize-tls-record-size.

If you download a lot of data on a connection (i.e. some MBs) then you
should find the the record sizes adjust to optimise for throughput.

Cheers

AGL

---

From: Watson Ladd <[email-masked]>
Date: Wed, 9 Nov 2016 14:07:48 -0800

> would be unable to deliver a response (which the client would not read

This is an example of the application not knowing which channels are ready.
So no the app doesn't "know when to read".

> a ContentType-hiding TLSv1.3 implementation underneath an existing

Yes, you will need to update the middleware component as well. Why is this
a problem?

> handle, which technically is _the_other_ communication direction.

Is this the case? Actually alerts trigger teardown of both sides. There is
no half open state for TLS. Nginx manages fine on OpenSSL.

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 10 Nov 2016 11:02:22 -0600

> _explicitly_ asked to read further AppData by the application.

I don't understand.  As Watson notes, TLS does not have a half-closed state.
So, if the application wants to continue receiving data, the application
protocol should not [inform the TLS stack to] generate a close_notify
until the entire application-layer protocol is done, in both
directions.  Maybe that would work on plain TCP (no TLS), but I just
don't see how this should be expected to always work with TCP+TLS
between endpoints using different implementations.

-Ben

---

From: [email-masked] (Martin Rex)
Date: Thu, 10 Nov 2016 18:02:38 +0100 (CET)

I'm sorry for the confusion.  It seems I was wrong about OpenSSL behaviour.

Watson Ladd wrote:
>> when SSL_read() has received and processed a TLS record with a
>> close_notify alert, do you know what happens to further calls
>> of SSL_write() of the same handle, which technically is
>> _the_other_ communication direction.
> 
> Is this the case?

Actually -- no, I'm sorry.

I looked at the OpenSSL code again, and it doesn't seem to do that
on receipt of CLOSE_NOTIFY.  (It's more than 10 years that
I programmed on top of OpenSSL).  CLOSE_NOTIFY seems to only be sent
after an explict call of SSL_shutdown(), and connection state
(for the other direction) does not seem to be harmed by receipt
CLOSE_NOTIFY, nor by sending of CLOSE_NOTIFY (warning-level) alerts.
Only the communication direction that carried CLOSE_NOTIFY seems
(properly) defunct (ignoring further IO requests).

It seems that I was mislead by the semantics described in the TLS 
specification.

>
> Actually alerts trigger teardown of both sides. There is

Teardown of both sides applies to fatal Alerts only.  One of the
reason for warning level alerts is that they should not tear down the
connection state, and close_notify (although the semantics described
in rfc5246 suggest otherwise) should tear down only the direction
on which it was sent.

So essentially, TLS should allow half-closed state, and at least
a glance over the OpenSSL code suggests that this implementation
would support it.

>From the sequence of (data processing) events, I still want to hold
off processing of CloseNotify until all prior TLS AppData records
are properly consumed by the application caller, so that when
the code writes traces about the progress of processing a connection,
the processing of the Alert will follow the passing of all prior
AppData to the application, and never precede it.

-Martin

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 10 Nov 2016 11:06:05 -0600

> Anyhing less is no value, just an illusion of value.

Thanks for clarifying your position.  I don't think many of the other
people in the thread are using the same definition of "value", which has
led to a lot of confusion.

However, I'm not convinced that the concrete benefit needs to be
mandatory-to-use in TLS 1.3 to be considered to provide value.  For
example, I personally value having the option to have my car's air
conditioning unit cool the interior temperature, but I wouldn't want it
to be the only way to cool the interior -- the rush of wind through the
windows is a different experience.  That is, having an option can in
itself provide value to some people in some situations.

-Ben

---

From: [email-masked] (Martin Rex)
Date: Thu, 10 Nov 2016 18:13:53 +0100 (CET)

Benjamin Kaduk wrote:
[ Charset windows-1252 unsupported, converting... ]
> mandatory-to-use in TLS 1.3 to be considered to provide value.

There is a concept called "provable correctness", and folks (such as
those from the miTLS implementation) are using this approach to check/prove
whether TLS provides certain security properties (rather than just
assuming that these properties are provided).

If hiding of ContentType has *real* value, then this property will be
formally provable.  If the properties that someone asserts as value
can be proven to not exist (one counterexample is sufficient),
then the value is an illusion / obscurity, and definitely not real value.

-Martin

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 10 Nov 2016 11:16:24 -0600

> then the value is an illusion / obscurity, and definitely not real value.

My understanding was that our current knowledge of what capabilities
traffic analysis makes possible and the countermeasures against them is
quite poor, certainly not to the level where rigorous proofs are
possible.  So, I fear we must be operating "in the dark" in this regard
for the near future.

-Ben

---

From: "Salz, Rich" <[email-masked]>
Date: Thu, 10 Nov 2016 17:26:39 +0000

> There is a concept called "provable correctness", and folks (such as those

Hm, your arguments against it are that heuristics will expose the information anyway.

Has provability advanced far enough to include that concept?

---

From: [email-masked] (Martin Rex)
Date: Thu, 10 Nov 2016 18:30:55 +0100 (CET)

Benjamin Kaduk wrote:
> possible.  So, I fear we must be operating "in the dark" in this regard

Proving that something is secure can be pretty difficult, that is correct.

Proving that something is insecure can be pretty trivial (one counterexample
is sufficient).

For someone who does this formal proofing stuff regularly, it may already
be possible today to formally proof that hiding the ContentType can not
possibly provide any value.

Where is the value with hiding the ContentType of SSL Alerts?

We know that at least one implementations notoriously _not_ sends any alerts
before closing connnections.  The installed base has somehow managed
to live with it.  But it's often painful to figure out the cause of
handshake failures, and to distinguish a certain kind of server
accept()ing and silently closing a connection after hitting a bug
(or policy) from an overzealous firewall (NAT or "transparent internet proxy").

So if your implementation has anything to hide, performing a dirty
socket closure (resulting in a TCP RST) will be *MUCH* more effective
in hiding information from observers than hiding the TLS Alert ContentType.

Silent connection closures are certainly much more effective for leaving
rightful communication peers (&helpdesk &support) in the dark about why
the heck communication is failing.

-Martin

---

From: Peter Gutmann <[email-masked]>
Date: Fri, 11 Nov 2016 07:10:09 +0000

Martin Rex <[email-masked]> writes:

>There is a concept called "provable correctness", 

The problem with provable whatever is that it merely proves that, as far as
the provers can tell, the thing they're dealing with conforms to some abstract
model.  I don't think you can prove much about whatever hiding the ContentType
is supposed to achieve because there's no model for it that says, for example,
"for an attacker with these capabilities, under these conditions, the
following security guarantees are provided".

However, we do have a pile of empirical data showing that pretty much any
seems-like-a-good-idea traffic-hiding really only works until the moment
someone tries to attack it.  The best reference for this is "Peek-a-Boo, I
Still See You: Why Efficient Traffic Analysis Countermeasures Fail" by Dyer et
al.  So at the moment I'd say that if there's some measure that's completely
free (no downsides for anything else) then you may as well apply it because it
can't make things any worse, but not to say "let's do X because it seems like
a good idea" when it has no empirically-demonstrable benefit but lots of
drawbacks.

And it's the "empirically-demonstrable" that's important, Peek-a-Boo is chock
full of examples of things that seemed like a good idea but that don't
actually provide much, if any, benefit, while at the same time introducing all
sorts of downsides.

Peter.