Subject: Re: [TLS] DNS-based Encrypted SNI
From: Kazuho Oku <[email-masked]>
To: Eric Rescorla <[email-masked]>
Cc: Stephen Farrell <[email-masked]>, "<[email-masked]>" <[email-masked]>
Date: Thu, 5 Jul 2018 10:29:06 +0900
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>

2018-07-05 3:23 GMT+09:00 Eric Rescorla <[email-masked]>:
>
>
> On Wed, Jul 4, 2018 at 11:07 AM, Stephen Farrell <[email-masked]>
> wrote:
>>
>>
>> Hiya,
>>
>> Just on this bit...
>>
>> On 04/07/18 18:20, Eric Rescorla wrote:
>> > The structure started a bit simpler and got new features to
>> > deal with new issues. Specifically:
>> >
>> > - The checksum is intended to deal with corruption
>>
>> I'm not sure I see why that's needed, but I believe you if
>> you say it might help with some home routers. (Though I'd
>> also be interested in information/citation about the
>> details of the problems seen there.)
>
>
> Sure. that's a fair question. Kazuho proposed this, so I'd be interested in
> his view.

IMO, when used, ESNIKeys is part of the handshake, and therefore
deserves (at least) the same level of end-to-end integrity protection
as what is provided by TCP.

ESNIKeys becomes part of the handshake in the following sense:

* a corrupt ESNIKeys will cause the handshake to fail
* ENSIKeys is used to negotiate the use of a TLS extension
* the value of ESNIKeys is part of the handshake transcript though
`EncryptedSNI.record_digest` which is a full digest of ESNIKeys, much
like the 1st CH when HRR is involved

TLS records (even the non-encrypted ones) are resistant to accidental
corruption thanks to the integrity check provided by TCP. OTOH,
ESNIKeys is transmitted though DNS authoritative server (by setting up
the DNS record either automatically or by hand), then a recursive
resolver, then a stub resolver, before reaching the client.

As Stephen says, some resolvers (e.g. home routers) could be the
source of corruption of DNS records. But even if we bypass them by
using DoH or DNS over TLS, the lack of end-to-end integrity check will
still be an issue. Corruption could for example happen when the record
is installed to the authoritative server, or when they are stored (or
cached) within the resolvers.

Considering the varying degree of the reliability provided by the
multiple parties involved in forwarding the ESNIKeys as DNS records,
my perception has been that it is a good idea to have end-to-end
integrity protection.

>> > - The keys and cipher suites seem kind of mandatory
>>
>> Yep. OTOH, given we need to support >1 value for the RR, if
>> mostly people just need one key+CS per-RR, it may be possible
>> to use multiple RRs to provide additional keys/CSes. (If most
>> uses would have a variable number of keys/CSes then I agree
>> the current structure is better.)
>
>
> I think it's bad to provide multiple options that aren't coupled together.
> Moreover, from the perspective of the TLS stack, it's actually easier
> to have them all bundled.

I also prefer them to be bundled, because it makes us easier and
faster to detect downgrade attacks.

Current draft uses a full digest of ENSIKeys (i.e.
`EncryptedSNI.record_digest`) to identify the ESNIKeys being used. If
a middlebox drops some key-share from ESNIKeys, the server will fail
to identify the ESNIKeys being used, and the handshake fails. This
would be the case even when DNSSEC is _not_ used.

If we use different DNS record for every key-share being negotiated,
the client will be required to wait for the response of all the
queries it has sent (more likely to suffer from delays), and there
will be no protection against a downgrade attack when DNSSEC is not
used.

>> > - I think it's clear what not_before and not_after are for. If you have
>> >   more concrete feedback about better ways to do that, we'd welcome
>> >   this.
>>
>> With not_before/not_after (and the TTL) there'll need to be some
>> consideration of the various overlaps, which has been a source of
>> bugs and ops screw-ups in other scenarios. I also don't like the
>> forced expiry of not_after - people will just put in 2038 all over,
>
>
> Note that this is 64 bits, so you can go far past 2038 :)

FWIW, the intent of having not_after in the draft is to avoid issues
when a DNS authoritative server and the TLS server (i.e. the entity
that generates the ESNIKeys) get out-of-sync [1].

When the TLS server rotates the ESNIKeys (which should happen
frequently), it needs to make sure that all the authoritative servers
receive the update. If that attempt fails, we'd rather fallback to
plaintext SNI rather than seeing handshake failures. Minimizing (or
nullifying) the increased chance of seeing handshake failures is
important for ESNI, because we want as many domains as possible (even
those that are not strongly interested in having their SNI protected)
to participate in the effort; otherwise, the domains using ESNI will
"stick out" [2].

However, DNS as a standard does not provide a way to set absolute
expiration dates. Not only the responses to queries but also AFXR
carries only the TTL. Therefore, an out-of-sync authoritative server
will continue to respond with the outdated ESNIKeys. The fact makes it
harder for server administrators to manage the keys.

To summarize, what we want is consistency (stop sending valid ESNIKeys
when authoritative servers get out-of-sync) over availability
(continue sending ESNIKeys when out-of-sync), which is contrary to
what DNS tries to provide.

Considering that and also the fact that we might want to distribute
ESNIKeys using methods other than DNS, I think it is a good idea to
have not_after (and not_before) in the specification.

[1] https://github.com/ekr/draft-rescorla-tls-esni/pull/23
[2] https://tools.ietf.org/html/draft-ietf-tls-sni-encryption-03#section-3.4

>
>
>> > - Extensions is just there because we're trying to be safe.
>>
>> Sure, but I hope we consider dropping 'em if there's no need..
>> New RRTYPEs could always be used for extensions (if new RRTYPEs
>> are cheap, that is:-)
>
>
> I would not be in favor of this. It's trivial to parse and ignore.
>
>
>> > (thus making the internal structure opaque to DNS). Removing
>> > things won't make it much smaller because a big chunk of
>> > the data is in the keys. For instance, in my implementation,
>> > the object is 70 bytes long and 34 bytes of that is key (X25519)
>> > and 8 bytes is cipher suite (each of these has 2 bytes of length).
>>
>> That's good. But I was more thinking about how friendly this
>> would be for the DNS admin folks. One thing I like about TLSA
>> and CAA is that (for my use-cases:-) I can just cut'n'paste
>> the values into zone files and they'll be good until a CA root
>> key or name changes, which is pretty rare and would be widely
>> advertised ahead of time.
>>
>> With RRSIGs and similar, I can also easily inspect values by
>> just looking at zonefiles and/or using dig, which is helpful
>> for me at least. But I don't have to deal with large zones so
>> that kind of inspection may not be of much use to larger
>> operators. So, I'd defer to real DNS server folks on whether
>> or not being able to directly view the internals of ESNIKeys
>> encoding makes any difference.
>>
>> All that said, I did just suggest adding in the dummy sni
>> value:-) So I mostly think if this goes ahead (as I hope it
>> does), we spend a bit of time considering the above issues
>> before we're done.
>
>
> Sure, that seems reasonable. I think you are getting to something
> important here: my philosophy here is that this should be a more
> or less opaque blob which you provide to the TLS stack. So I'm
> optimizing for what's convenient for that. I can understand that
> others might feel differently.
>
> -Ekr
>
>>
>> Cheers,
>> S.
>>
>
>
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

-- 
Kazuho Oku