Re: [TLS] Application-Layer Protocol Settings

2020-07-07 Thread Ilari Liusvaara
On Mon, Jul 06, 2020 at 03:12:45PM -0400, Victor Vasiliev wrote:
> Hello TLS and HTTP working groups,
> 
> (QUIC WG bcc'd as this has been discussed there before)
> 
> Currently, we use SETTINGS frames as an extensibility mechanism in HTTP/2
> and HTTP/3.  The SETTINGS frame is sent at the very beginning of TLS
> application data; this approach, while simple, has some drawbacks.  The
> most notable one is that when SETTINGS are used to negotiate extensions,
> there is an entire round-trip where the client can send requests, but
> doesn't know yet about any server extensions, thus making any
> extension-dependant requests take an extra RTT.
> 
> The proposed solution to this problem is to move HTTP SETTINGS frame into
> the TLS handshake.  Here are some issues where this has been discussed
> before:

I note at least two people have proposed just fixing TLS stacks to allow
sending HTTP/2 SETTINGS in 0.5-RTT data. I used to have a server that
actually did that (only if there was no CertificateRequest, due to
interface limitations, this was not TLS library limitation).

Unfortunately, this is not quite interoperable. There are HTTP/2
clients out there that just puke (with unexpected_message TLS alert,
sent post-Finished) if one tries to send SETTINGS in 0.5-RTT data.

I do not know what clients are involved (IIRC, I have heard about
problems with at least Firefox and Chrome, versions unknown), but I
would presume some sort of MITM by some client software is involved.

That was quite painful to debug. Much nastier than e.g., debugging
handshakes failing with illegal_parameter due to downnegotiation gone
wrong due to server bug (this client is still using TLS 1.3 draft 23,
and is still out there).


-Ilari

___
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls


[TLS] A query related to support the hard-failing when subdomain1.example.com tries to front example.com?

2020-07-07 Thread Avineshwar Singh
In the context of TLS, what can be done to detect a MITM by
*subdomain1.example.com
* of *example.com *?

Can the TLS checks fail (assuming cname contains wildcard)?. Let's say
public key pinning isn't used.

I could think of *blacklistedSubjectAlternativeName* such that they serve
as an overriding *blacklist of SANs*. This may reinforce:

   -

   explicit intent
   -

   protection insider compromise/threats
   -

   undermine a controlling entities' *theoretical* powers
___
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls


Re: [TLS] Application-Layer Protocol Settings

2020-07-07 Thread David Benjamin
Hi Martin,

You’re right that this is closely related to half-RTT data. However, I
don’t think this is a no-op for HTTP/2.

I’m not aware of HTTP/2 clients that wait for the SETTINGS frame today.
Doing so costs a round-trip with servers that don’t send SETTINGS in
half-RTT, and there's no indicator for whether the server will send it.
I’ll see about testing some sites here and will report back, but I expect
most do not. We (correctly) designed TLS 1.3 as a drop-in replacement for
TLS 1.2, which means that we don't get to key new I/O patterns on it.
Half-RTT data is a very weird state and wouldn’t get used by default. This
is the problem with “no standards change is required” style of thinking
around simply changing I/O patterns. A protocol is more than its wire
image. Changing the I/O patterns is a protocol change.

This means we cannot get efficient and reliable feature negotiation today.
Moreover, HTTP/2 servers today may send ServerHello..Finished without
application data in their first flight, so we need *some* change to the TLS
flight, be it ALPS or just some indicator.

Let’s look at what it’d take to make half-RTT SETTINGS work.. We need some
“I will send half-RTT data, so you can safely wait for it” indicator. Then
the client needs to know when it is done waiting. We could say it’s one
SETTINGS frame, but that only allows integer values. (Related:
EXTENDED_SETTINGS

and discussion
.)
Those currently need separate frames, and one cannot wait for the absence
of a frame. Maybe we need an HTTP-level
SETTINGS_WILL_SEND_HALF_RTT_XYZ_FRAME indicator to keep the delimiter in
HTTP, or a TLS-level “end of half-RTT data” delimiter. (Now consider how
that works in QUIC...)

Next we need to tackle 0-RTT. Waiting for half-RTT data costs a round-trip
in 0-RTT, so we need something to persist across the session, with
semantics around mismatch and whatnot. (Another TLS-visible change.)
Anything persisted in the session must have bounded size, and be delivered
in something ordered with NewSessionTicket.

If we place those bytes inside the handshake, we’ve reinvented ALPS.. If we
place them outside, the NewSessionTicket ordering becomes complex,
especially in QUIC
.
To your question about the server repeating its configuration vs. the
client remembering it, I believe the issue was exactly that ordering
mishap. ALPS avoids this because EncryptedExtensions and NewSessionTicket
are ordered.

On top of this, the half-RTT point in a non-0-RTT connection is a weird
state. Not all connection properties (e.g. client certs) have been
established yet, and writes out of turn are tricky. This message

discusses
some of the challenges here. I would argue something like ALPS is the
settings design we should have had all along.

David

On Tue, Jul 7, 2020 at 1:10 AM Martin Thomson  wrote:

> Hi Victor,
>
> For HTTP/2, this is essentially a noop, as endpoints are required to send
> SETTINGS immediately.  Whether these bytes appear before Finished or not
> only affects endpoints that aren't inclined to wait for SETTINGS.  This is
> somewhat complicated by the way that TLS 1.2 and TLS 1.3 differ, but if we
> assume TLS 1.3 here, any uncertainty is easily avoided.
>
> The main justification here appears to be based on the lack of 0.5-RTT
> send capability at some servers.  I don't know how to assess whether the
> cost of greater integration with the TLS stack is preferable to fixing the
> 0.5-RTT send problem.
>
> For HTTP/3, this has some incremental effect beyond that.  In effect, this
> deliberately introduces head-of-line blocking for settings.  You can
> already do that in HTTP/3 if you are not prepared to deal with settings
> being in an ambiguous state.  There's a little more determinism here in
> terms of where you look for the data that unblocks progress, but with
> retransmissions, this is not a difference worth worrying about.
>
> What this head-of-line blocking might allow is the development of new
> extensions that are unable to deal with uncertainty regarding SETTINGS.
> But isn't it also possible to address that problem by saying "if you
> implement extension X, then you MUST NOT send requests prior to receiving
> SETTINGS?"
>
> In QUIC, we decided that having the server repeat its configuration after
> 0-RTT was preferable to remembering it.  This was after a non-trivial
> number of questions about that part of the specification.  You seem to have
> taken the opposite approach.  Is that deliberate?  If so, why?
>
> On Tue, Jul 7, 2020, at 05:12, Victor Vasiliev wrote:
> > Hello TLS and HTTP working groups,
> >
> > (QUIC WG bcc'd as this has been discussed there before)
> >
> > Currently, we use SETTINGS frames as an extensibility mec

Re: [TLS] Application-Layer Protocol Settings

2020-07-07 Thread David Benjamin
Hi Ben,

(I’ve covered many of these points in my reply to Martin, so you may want
to read that first.)

Any solution here involves a TLS change, even for servers which currently
send half-RTT settings. See my reply to Martin for why. The question then
is which is more complex. As a TLS implementor, ALPS would be a very
straightforward extension to implement, while the work involved to make
half-RTT SETTINGS work would be a mess.

Transparently sending a fixed buffer of half-RTT data was indeed something
we’d thought about and rejected. In some circumstances, it may cause
deadlocks with TCP
.
And we still need an indicator for the client to safely wait for it. I/O
patterns are part of the protocol.

It’s also not the case that non-uniform backends must disable 0-RTT.. That
is what 0-RTT rejection logic is for. Non-uniform deployments may get less
0-RTT than a uniform deployment, but it won’t break things. This is already
the case (ALPN must match) and unavoidable with any predictive mechanism
like 0-RTT.

Finally, you’re right to think about the coupling between TLS and HTTP for
0-RTT, but I believe you have the conclusion backwards. The TLS stack must
be deeply aware of what is stored in the TLS session, so the server can
reject 0-RTT when the remembered values are incompatible with its current
configuration (see HTTP/3
).
Otherwise the client will act thinking the server supports some extension
when, in reality, it does not. (Perhaps the server had to roll the feature
back.)

The simpler that TLS/HTTP interaction, the looser the coupling we can
manage, and checking opaque bytes for equality is the simplest possible
option here. Tighter coupling could be aware that, e.g.,
SETTINGS_MAX_CONCURRENT_STREAMS = 500 is compatible with 1000 but not 100..
The draft starts with the simplest option, given settings don’t change
much. It’s already the case that configuration changes, like cipher
preferences, may reject 0-RTT. (Note settings which do change can still be
sent in application data. ALPS’s purpose is to solve the reliable
negotiation problem, and any changing setting won’t be reliable in 0-RTT
anyway. Moving them out of ALPS entirely seems fairly clean.)

David

On Mon, Jul 6, 2020 at 10:23 PM Ben Schwartz  wrote:

> Thanks for this draft.  I believe this is an important problem for HTTP
> extensibility, and I'm glad to see work on a solution.
>
> It occurs to me that this solution requires pretty tight integration
> between the TLS termination and the HTTP backend.  Some TLS load balancers
> already support ALPN, but they would have to be extended to support ALPS,
> and I would worry about the potential for skew between the TLS terminator's
> claimed settings and the backend's actual settings.
>
> The draft says
>1.  While the server is technically capable of sending configuration
>to the peer as soon as it sends its Finished message, most TLS
>implementations do not allow any application data to be sent
>until the Finished message is received from the client.
>
> Fixing this might require a change to some TLS implementations, but the
> change to implement ALPS also seems significant.
>
> The proposed 0-RTT interaction also seems like it would create a
> significant risk of skew when a load balancer is in use, if the backend
> settings can change..  Deployments that can't guarantee uniform backends
> would have to disable 0-RTT (an unfortunate sacrifice for a feature that
> saves 1 RTT!).
>
> For load balancers, or any other situation where TLS and HTTP are loosely
> coupled, sending SETTINGS at 0.5-RTT would seem like a much simpler
> solution.  I know the draft mentions a few cases where this doesn't work
> well, but perhaps there's a middle ground of some sort.  For example:
>
> * If supporting generic 0.5-RTT forwarding is hard, TLS server
> implementations could offer a configuration to send an arbitrary fixed
> buffer at 0.5-RTT (depending on ALPN).  No standards change is required.
> * The application protocol (here HTTP) could indicate what state is
> guaranteed to persist across session resumption.  Although the preserved
> state here (SETTINGS) is ~static, in general this could include dynamic
> session state too.  This would move the change to HTTP, instead of TLS.
>
> On Mon, Jul 6, 2020 at 3:13 PM Victor Vasiliev  40google@dmarc.ietf.org> wrote:
>
>> Hello TLS and HTTP working groups,
>>
>> (QUIC WG bcc'd as this has been discussed there before)
>>
>> Currently, we use SETTINGS frames as an extensibility mechanism in HTTP/2
>> and HTTP/3.  The SETTINGS frame is sent at the very beginning of TLS
>> application data; this approach, while simple, has some drawbacks.  The
>> most notable one is that when SETTINGS are used to negotiate extensions,
>> there is an entire round-trip where the client can send requests, but
>

Re: [TLS] Application-Layer Protocol Settings

2020-07-07 Thread David Benjamin
On Tue, Jul 7, 2020 at 4:38 PM Ben Schwartz  wrote:

>
> On Tue, Jul 7, 2020 at 3:14 PM David Benjamin 
> wrote:
>
>> Any solution here involves a TLS change, even for servers which currently
>> send half-RTT settings. ...
>>
>
> I think a new ALPN protocol ID
> ("h2-but-with-settings-from-the-server-asap-for-real") would suffice.
>

That doesn't suffice. Please see my reply to Martin. This would be one
possible spelling of the indicator, but it would not provide the other
components necessary for half-RTT data to work.


> It’s also not the case that non-uniform backends must disable 0-RTT. That
>> is what 0-RTT rejection logic is for. ...
>>
>
> I would be impressed if there is any TLS load balancer architecture that
> supports 0-RTT rejection by the backend.  This would require an interesting
> new metadata layer, quite different from the usual "decrypt and forward"
> approach.  (Of course, I assume that most load balancers simply won't
> implement 0-RTT at all.)
>

HTTP/3 0-RTT *already* requires such an interaction. In fact, it requires
an even more complex version than ALPS. The link was lost in the quoted
reply, so I'll include it again:
https://quicwg.org/base-drafts/draft-ietf-quic-http.html#section-7.2.4.2-7

This is fundamentally unavoidable if you want 0-RTT to be able to use
negotiated parameters. Any negotiated parameter available to 0-RTT *must* be
available predictively. Because it is predictive, mispredictions may occur.

RFC8470 likewise contains recommendations which also require more than a
"decrypt and forward" approach.


> The simpler that TLS/HTTP interaction, the looser the coupling we can
>> manage, and checking opaque bytes for equality is the simplest possible
>> option here.
>>
>
> I'm not sure what equality check you're proposing; I don't see it in the
> draft.
>

It's right here: https://tools.ietf.org/html/draft-vvv-tls-alps-00#section-3

>   For application protocols that support 0-RTT data, both the client
>   and the server have to remember the settings provided by the both
>   sides during the original connection.  If the client sends 0-RTT data
>   and the server accepts it, the ALPS values SHALL be the same values
>   as were during the original connection.  In all other cases
>   (including session resumption that does not result in server
>   accepting early data), new ALPS values SHALL be negotiated.
>
>   If the client wishes to send different client settings for the 0-RTT
>   session, it MUST NOT offer 0-RTT.  Conversely, if the server would
>   send different server settings, it MUST reject 0-RTT.  Note that the
>   ALPN itself is similarly required to match the one in the original
>   connection, thus the settings only need to be remembered or checked
>   for a single application protocol.


> However, I agree with your conclusion: if the TLS server manages the
> settings-state, it can easily invalidate resumption across a settings
> change.
>
> Ultimately, I think I'm saying something obvious: if the TLS server
> represents multiple backends without distinction, it can't represent a
> property that those backends do not share.  This is true of ALPN, and would
> be true of ALPS too.  This is fine; the ALPS just has to represent the
> intersection of backend capabilities.  All currently defined HTTP/2
> Settings appear to support intersection in a reasonable way, although I'm
> not sure this is guaranteed in general.  However, SETTINGS at 0.5-RTT would
> not have this problem; heterogeneous backends could each report their own
> SETTINGS.
>

I don't think this follows. ALPS and half-RTT data happen at the same
round-trip. If the frontend is able to forward half-RTT data, it has
clearly decided on which backend to use by the time it's assembling the
ServerHello flight. It can as easily pick a backend-specific ALPS value as
it can pick backend-specific half-RTT data.

Beyond that, it's a question of what exactly your frontend/backend split
looks like. I gather you're worried about a deployment scenario where your
frontend is a TLS terminator, which has a boring pipe to the HTTP backend,
without any out-of-band signaling. (As opposed to having an HTTP frontend.)
In that case, the argument is that, since half-RTT data is just bytes, that
can be transparently forwarded over the pipe, whereas an ALPS signal
wouldn't. Is that right?

It's unlikely half-RTT data would work for that scenario. The frontend most
likely waits for the handshake to actually finish, before enabling the
pipe. Indeed, the security properties of the half-RTT point are kind of
subtle (particularly with client certs). Forwarding data then without
appropriate signaling is dangerous.

Such a frontend/backend split would also likely be unable to manage the
recommendations in RFC8470, the remembered settings vs. 0-RTT interactions,
the guarantee of half-RTT data being sent early enough, or the delimiting
information necessary to make a half-RTT settings work. For that matter, it
already needs some out-o

Re: [TLS] Application-Layer Protocol Settings

2020-07-07 Thread Martin Thomson
Hi David,

I think that there is an important difference between something that is hard to 
realize in practice (as many aspects of this clearly are) and using that to say 
that the fundamental protocol definition is wrong.

I appreciate - at least superficially - the complexities involved here.  Having 
implemented them, and having worked around many of the problems you have 
identified, it was not trivial to implement 0-RTT or 0.5-RTT (the latter was 
pretty-much trivial for much the same reason that false start works, but I'll 
concede that I probably didn't fully explore all of the potential problems).

But as much as recognizing implementation complexity is important, that doesn't 
necessarily translate into a requirement to change the protocol.

Let's take an example of a feature you are trying to negotiate in HTTP (/2 or 
/3).  I don't think that it is unreasonable to say to a client that it cannot 
attempt anything that depends on this feature until it receives SETTINGS.  You 
can then require servers that support this extension to send SETTINGS in 
0.5-RTT so that the client is only blocked on the extra bytes and not 
additional round trips.  All of which implies that you need TLS 1.3 for the 
feature.

The drawback there is that the client that wants to use the feature might not 
receive the SETTINGS in time and they don't get a clear indication that this is 
not happening.  Ben's suggestion to use a new version if you care about 
avoiding that case is entirely appropriate.  It depends on what sort of 
extensions are being contemplated here to determine whether this is indeed 
necessary.  I tend to think a h2_tls13 ALPN that mandated use of 0.5-RTT for 
SETTINGS would put a big dent in this negotiation problem.

Either way, your stack might require new changes to support the writing of some 
fixed amount of data on all new connections.  This might turn into a 
requirement on TLS terminators to have per-backend configuration to support 
this new information.  But these don't necessarily turn into new protocol 
mechanisms.  Indeed, these changes are far less disruptive overall than a 
completely new TLS extension, particularly if the TLS extension involves all of 
the same coordination.

I concede that saying that SETTINGS is sufficient isn't free, and that there is 
some additional cost on implementations.  On the other hand, the "cost" is that 
implementations improve some aspects of an existing protocol that provide other 
benefits to those implementations.

On the other hand, new mechanisms like this require the same amount of 
coordination, more work at the TLS layer, and all the delays imposed by 
standardization.

On Wed, Jul 8, 2020, at 05:11, David Benjamin wrote:
> Hi Martin,
> 
> You’re right that this is closely related to half-RTT data. However, I 
> don’t think this is a no-op for HTTP/2.
> 
> I’m not aware of HTTP/2 clients that wait for the SETTINGS frame today. 
> Doing so costs a round-trip with servers that don’t send SETTINGS in 
> half-RTT, and there's no indicator for whether the server will send it. 
> I’ll see about testing some sites here and will report back, but I 
> expect most do not. We (correctly) designed TLS 1.3 as a drop-in 
> replacement for TLS 1.2, which means that we don't get to key new I/O 
> patterns on it. Half-RTT data is a very weird state and wouldn’t get 
> used by default. This is the problem with “no standards change is 
> required” style of thinking around simply changing I/O patterns. A 
> protocol is more than its wire image. Changing the I/O patterns is a 
> protocol change.
> 
> This means we cannot get efficient and reliable feature negotiation 
> today. Moreover, HTTP/2 servers today may send ServerHello..Finished 
> without application data in their first flight, so we need *some* 
> change to the TLS flight, be it ALPS or just some indicator.
> 
> Let’s look at what it’d take to make half-RTT SETTINGS work. We need 
> some “I will send half-RTT data, so you can safely wait for it” 
> indicator. Then the client needs to know when it is done waiting. We 
> could say it’s one SETTINGS frame, but that only allows integer values. 
> (Related: EXTENDED_SETTINGS 
>  
> and discussion 
> .) 
> Those currently need separate frames, and one cannot wait for the absence of 
> a frame. Maybe we need an HTTP-level SETTINGS_WILL_SEND_HALF_RTT_XYZ_FRAME 
> indicator to keep the delimiter in HTTP, or a TLS-level “end of half-RTT 
> data” delimiter. (Now consider how that works in QUIC...)
> 
> Next we need to tackle 0-RTT. Waiting for half-RTT data costs a 
> round-trip in 0-RTT, so we need something to persist across the 
> session, with semantics around mismatch and whatnot. (Another 
> TLS-visible change.) Anything persisted in the session must have 
> bounded size, and be delivered in something ordered with 
> N