Draft: draft-ietf-tls-esni

Commentary: DNSOP adopted HTTPSSVC recently [ 1 ] . This is a generalized Resource Record that supports the same functionality as the custom ESNI RRType , including direct IP address specification and ENSI key delivery . This change drops the custom DNS bits from the ESNI document and delegates this to HTTPSSVC , where it probably belongs . This change also renames ESNIKeys to ESNIConfig to more accurately capture its intended purpose , i.e. , as a struct for conveying ESNI keys and  . This should address , , , and . [ 1 ] 
 I 'm not sure that this is going to work with HTTPSSVC as currently defined . The current ESNIKeys record specifies the IP address explicitly and you are supposed to favor that . However , assuming I am reading HTTPSSVC S 6.4 correctly , ipv[46]hint are not in fact favored but are actually disfavored . " The " ipv4hint " and " ipv6hint " keys represent IP address hints for the service . If A and AAAA records for SvcDomainName are locally available , the client SHOULD ignore these hints . Otherwise , clients MUST perform A and/or AAAA queries for SvcDomainName as in Section 3 , and clients SHOULD switch to an IP address in those records as soon as possible . " This is counter to what we agreed upon for ESNI and resurrects the A / AAAA vs. ESNIKeys mismatch problem . Unless I am misunderstanding this , we should first fix HTTPSSVC before making this change . 
 I think the intent with HTTPSSVC is that , if you 're using the HTTPSSVC record , you 'd look up A / AAAA from the SvcDomainName not the origin name you queried . That way there 's still a binding between A / AAAA and ESNIKeys . This does , however , cost an extra DNS round - trip , so this plan does require the recursive resolvers follow HTTPSSVC for you like they do CNAME , otherwise it would not meet the performance requirements . DoT / DoH are an ecosystem reset , so maybe that 's plausible ? I think this goes back to how sacred you believe A and AAAA are and whether you believe it 's rude to get IP addresses elsewhere . The HTTPSSVC record evidently has different views on this point than the ESNI record . 
 I would choose to interpret their " SHOULD ignore " advice as optional to ensure the ESNIRecord functionality is maintained . perhaps we can clarify this in the HTTPSVC draft ? 
 Yep , that 's exactly right . I 'm not sure I understand you . The purpose of " SHOULD ignore " is to ensure that DNS - based load balancing of A / AAAA on SvcDomainName continues to work correctly . Whether the client uses an ipv6hint or a AAAA record for SvcDomainName , it will be contacting a server that has the corresponding ESNI private key ; there 's no possibility of mismatch either way . I think the confusion here is that in HTTPSSVC , clients use the IP of SvcDomainName , not the IP of the origin hostname . There 's no way for a client to accidentally combine the ESNIConfig for the SvcDomainName with the IP of the origin hostname ( or of a different SvcDomainName ) . I think the draft is pretty clear on this point ( e.g. the ) , but the authors always think that :) . Suggestions are welcome . 
 Well , so as points out , this requires a second resolution , which is a performance problem . 
 Yes , waiting for a second resolution is the performance problem that ipv6hint solves , by giving the client an IP address along with the ESNIConfig in the same response . 
 then I just do n't see the point of doing the second resolution . It seems disruptive and does n't add anything . Once I have connected to the server , it can    me itself . 
 I should add , I 'm not quite sure how I would implement this in Firefox . Say I resolve and get 1.2.3.4 for ipv4 hints . Now I am supposed to in parallel connect to the server and try to resolve SvcDomainName ? But what then ? I 've already started the connection so I 'm not going to abort it if I get a 5.6.7.8 .... 
 Consider a CDN customer with their own ( old - fashioned , static ) DNS . The customer publishes an HTTPSSVC record whose SvcDomainName , ESNIConfig , and IP hint are the CDN 's domain , ESNIConfig , and IP . Clients connect to the IP from the hint , use this ESNIConfig , and everything works ... but the customer has broken the CDN 's load balancing . All of their traffic is going to a single CDN IP . The point of the second resolution is to move customer traffic onto the CDN 's preferred IP . True , but HTTPSSVC does n't require clients to support    . (  , for example , does not support this feature of    . ) The draft says clients " SHOULD switch to an IP address in those records as soon as possible " . An aggressive implementation might start connecting to 5.6.7.8 , and close the connection to 1.2.3.4 once it is connected . ( This is roughly what  does for QUIC upgrade . ) A less aggressive implementation might just let the A record sit in the local DNS cache , so that any subsequent connections to this origin can go to the CDN 's preferred IP . 
 OK , so I think that this text needs a bunch of work before I would be comfortable with it , as I do not think your " less aggressive implementation " would be conformant with this SHOULD 
 if that ’s the case , can you please suggest concrete changes to the text ? 
 is there some place I can send a PR ? 
 yes , 
 OK , the new text has been merged , so I am now OK with this PR . 
 I think that the current ESNI record is maybe a little too complicated . The ESNI key is really a property of the public server , yet the ESNI record is defined as a property of the hidden server . If the public server rolls a new key , all the ESNI records of all the hidden servers that mentioned the old key need to be updated . I think it would be simpler to have the ESNI record as a property of the public server , and to just have a pointer to the public server in the context of the hidden server . May an SRV record . The chain would be something like : 1 ) Look up whether the SRV record for 2 ) If there are such records , select the appropriate public server , say 3 ) Look up ESNI , A , AAAA for In that architecture , there is no need to encode the public server name in the ESNI record . I think there will be several advantages . The ESNI record 's TTL can be set to the lifetime of the key . The SRV record 's TTL can be set to the expected lifetime of the relation between ' hidden " and " public " . If the SRV lifetime is long enough , the value can be efficiently cached by the client . If multiple clients share the same hidden server , the ESNI record is fetched only once , and can be cached . At connection time , the client would only need to query the A / AAAA records of the public server , i.e. exactly the same DNS transaction as an access to the public server . 
 Issue proposes something similar , using PTR records . I think the semantic of SRV records is closer to what we need . 
 The practical consequence would be to remove the " public name " component from the ESNI record . 
 IIRC , the principle that we have so far followed is that ESNI should not introduce additional latency ( i.e. roundtrip ) . TLS WG has spent great effort in reducing the number of roundtrips spent during the handshake . It would be very unfortunate to add latency with ESNI . Also , I am not sure how much the issue is a practical concern , because I 'd assume that most if not all of the DNS records of the hidden hostnames would be a CNAME to the public name . The ESNI record would be associated to that public name . To rephrase , the ESNI record would be associated to the public name in the current scheme . 
 I agree that if the typical implementation is to have the hidden server name point to the public server with a CNAME , then the current record format is just fine . We may want to document this hidden CNAME assumption in the document . On the other hand , I am still not convinced that CNAME is the proper tool . We definitely want to use DNSSEC to sign the record pointing from hidden to public . Otherwise , it becomes very simple to inject a false record pointing to a compromised public server , and then track clients . At a minimum , if we expect the hidden servers to use CNAME , we should explain how to use DNSSEC to secure that . Apart from DNSSEC , the other feature that we want is the support for multiple public servers , in case one of them is blocked . I do n't think that CNAME can do that . In practice , the simplest way will be to have multiple ESNI records listed directly in the context of the hidden server . That works , and doing DNSSEC is straightforward . But it implies replication of the public server ESNI record in many places , which brings in the issues of managing replication . 
 I think that elaborating on the expected practice is a good idea . While I appreciate the possibility , I am not sure if it is a good idea to endorse ESNI to be used as a tool to circumvent blocking . Because doing so would lead to ESNI being blocked . Rather , my preference goes to promoting ESNI as a tool for protecting privacy . 
 Fixed by . 
 This will let us adopt another delivery mechanism ( HTTPSVC ? ) if needed later on . 
 We already have and as different structures , would n't a different delivery mechanism be able to simply wrap in its own transport , without the DNS record ? I guess this point could be clarified though . 
 This is mostly an editorial change to make it easy to remove , if needed , without changing any other text . 
 Fixed by . 
 To maximize the cover range for clients and simplify management of the ESNI records , it is more useful to associate the ESNI records with the server rather than the query domain name . This has the additional benefit of allowing different client - facing servers to use different rotating private DH keys . This eliminates the issues with CNAMEs , individual query domain holders having to make changes , DNS namespace issues etc . For example a large hoster wishing to provide cover for some clients by having their primary / CDN front ends offer ESNI for all requests can then simply enable the code on their server then add the ESNI records . They can even do this gradually over a large pool of servers , thus having some servers with different ( or no ) ESNI support during each careful rollout of ESNI software upgrades . In practice the following conventions would be used : ESNI server IP must have exactly one PTR record ( typically pointing to the hoster domain , such as a typical systematic CDN node DNS name ) . Lets call this name ESNI records would be under with most PTR records is expected to have exactly one AAAA or A record pointing back at the same IP ( if the starting IP is IPv6 only AAAA need to satisfy this , if IPv4 only A , the same can be used for one IPv4 and one IPv6 address if the ESNI records would be the same ) . address - less server types such as tor hidden services , the ESNI records would be published via whatever DNS or DNS - like mechanism is used for that transport , or queried by sending a DNS query for the record to the target , allowing the target to respond within that transport . Benefits : B1 . Large client - facing servers such as CDNs and shared IP hosters can deploy ESNI without having to negotiate DNS changes with all their customers ( in fact with any of their customers).B2 . Operators of large pools of client - facing servers such as CDNs can roll out ESNI support and ESNI implementation upgrades in a piecemeal and controlled manner similar to how other system updates are rolled out . Simply because each IP address will have its own ESNI records . B3 . ESNI key rotation becomes much simpler as there is no need to synchronize it between different servers in a pool ( except where a pure layer 1/2/3 load balancer shares a single IP among multiple physical / virtual servers , such as the layer 2 HALinux scheme).B4 . ESNI private key protection can be much stronger when it is not shared among all the servers . The private key may be kept in protected hardware and/or in volatile RAM . The latter case would require clients to fall back to a different A or AAAA record until the DNS entries for now forgotten keys to have expired , but only in case of a server crash or similar event . B5 . Client queries for ESNI records do not reveal the actual query domain that will be encrypted , only the IP address to which the ESNI extension will be sent . B6 . The whole discussion about esni prefix or no esni prefix becomes a lot simpler when there is no need to put ESNI records in every end query domain , only domains of the client - facing servers , allowing to keep the unprefixed TXT name space clean for existing uses such as SPF . Downsides : P1 : Clients will have to postpone the esni DNS query until after receiving the answer to the A or AAAA query , thus adding an extra DNS roundtrip before the first connection to a name . The usual DNS caching hierarchy should mitigate this . In particular for popular CDNs , a client will typically use the same handful of IPs for lots of unrelated traffic , thus getting the ESNI records in its local cache .  : VM hosting / Physical hosting / connectivity providers not granting PTR name assignment control to IP address customers will cause the same problems as for other protocols ( such as mail ) and should thus be under the same or greater pressure to add that service . However since the greatest ESNI benefit is with IPs shared among many unrelated domains , and the operators of such IPs typically have full IP space ownership or the leverage to get PTR records where normal customers cannnot , the effect on ESNI deployment should be limited . P3 : This may or may not make it easier to do spoofing attacks , as an MitM attacker can spoof DNS responses either for the A / AAAA records of a target query domain ( pointing to servers entirely under the attackers control , including legitimate ESNI records for that server ) OR spoof the ESNI records of a server address for which the attacker has obtained traffic intercept ability . However these can be secured with the same DNS countermeasures already applicable to those DNS domains . P4 : query domains wishing to remain available in massively blocking markets ( the kind that would not hesitate to block an entire CDN to stop access to a single web page ) may have more difficulty opting out of ESNI so such blocking filters can recognize them as a permitted service . 
 This has been kicked around before and generally not selected based on the downsides you identify - prinicipally the serialization issue as well as practical matters of control of PTR records . It also prohibits the use of more than 1 key on an address - that 's obviously a bad thing for the anonymity pool at its extreme , but some architectures might require more than one pool . You can fix the latter two issues by using another suggestion that has previously been made : connect to the server and validate an IP based certificate and then get the ESNI key via a REST API ( or equivalent ) - but that is still likely too slow and comes with the challenges of IP based certificate management . 
 The PTR record problem is a real issue , but less so for the servers best placed to be anonymity pools . There are other mechanisms of cause . The key part is making ESNI a server property rather than an origin property , bypassing most of the issues with configuring each of the non - controversial origin domains that are just used as cover traffic . Hard part is finding a hello content that does n't stick out by using any values specific to using a controversial domain . Per origin ESNI would stick out as most origins would feel pressured to not actively join the pool , while having to do something difficult or even pricey to stay out of the pool would be less easy to encourage via generic mass pressure . For the following approaches compare to a normal first TLS connection : Round 1 : DNS query for A and DNS query for AAAA ( happy eyeballs ) Round 2 : TCP SYN Round 3 : TLS Handshake round 1 With the PTR based approach the parallelizing would go like this for first contact ( later contacts benefit from DNS caching ): Round 1 : DNS query for A and DNS query for AAAA ( happy eyeballs ) Round 2 : TCP SYN , DNS query for PTR and DNS query for ESNI keys directly in i*.arpa Round 3 : DNS query for ESNI keys at PTR name ( perhaps cached at nearby resolver ) . This round is done only if A : no ESNI record ( not even an empty one ) returned in round 2 AND B : PTR name returned and contains the substring " esni . " For example example or would cause queries of esni.example or Round 4 : TLS Handshake round 1 Rule 3 B would require ESNI client facing servers without ability to add arbitrary reverse records to at least be able to choose a PTR name of the magic form . Note that the magic form contains no underscore but will only cost an extra DNS lookup returning NXDOMAIN if a non - ESNI server has that name form by chance . The rule may require further refinement to deal with common provider practices . One technique requiring less round trips than a full HTTP REST API would be to use a clever sequence of TLS extensions , signalling suites etc . to do everything in the TLS layer at the cost of extra TCP round trips compared to the current draft . A hybrid approach could go like this ( first contact ): Round 1 : DNS query for A and DNS query for AAAA ( happy eyeballs ) Round 2 : TCP SYN , DNS query for esni.$ If esni returned with " no " record : Round 3 : TLS Hello with the signalling suite and normal SNI , server responds normally If esni returned with key : Round 3 : TLS hello with ESNI as per  If esni returned with " ask " record : Round 3 : TCP hello with invalid right - size data in ESNI extension , server sends keys in encrypted ESNI response . Round 4 : Send new hello with real ESNI extension inside encrypted stream , server forwards to origin server , once encrypted by origin server , client - side server drops the outer encryption and forwards remaining packets unchanged . If no esni record returned from DNS , server is actually ESNI : Round 3 : TLS Hello with a signalling suite and no SNI or ESNI , server sends keys in encrypted ESNI response . In parallel a new TCP SYN . Round 4 : Send new hello with real ESNI extension inside encrypted stream , server forwards to origin server , once encryption activated by origin server , client - side server drops the outer encryption and forwards remaining packets unchanged . ( Second TCP connection may be used or closed ) If no esni record returned from DNS , server is not ESNI and has a default certificate matching desired SNI : Round 3 : TLS Hello with a signalling suite and no SNI or ESNI , server server responds normally using its default certificate , client uses the connection . In parallel a new TCP SYN . ( Second TCP connection may be used or closed ) If no esni record returned from DNS , server is not ESNI and has a default certificate not matching desired SNI : Round 3 : TLS Hello with a signalling suite and no SNI or ESNI , server server responds normally using its default certificate , client aborts . In parallel a new TCP SYN . Round 4 : TLS Hello with the signalling suite and normal SNI , server responds normally . In parallel the first session is closed . If no esni record returned from DNS , server is not ESNI and has no default certificate : Round 3 : TLS Hello with a signalling suite and no SNI or ESNI , server aborts . In parallel a new TCP SYN . Round 4 : TLS Hello with the signalling suite and normal SNI , server responds normally In parallel the first session is closed . ( Inclusion of the signalling suite after concluding its a non - esni server is to detect downgrade attacks ) Intent is that the 4 round cases will be less common than the 3 round cases . All subsequent contacts to same server IP ( up to a cache period ) will be simply : Round 1 : TCP SYN Round 2 : TLS Hello according to cached type and keys ( with or without session resumption ) , Server responds as expected . Neither approach requires special IP address certificates . 
 I agree that this method does not introduce an additional round - trip for TCP . But it will for QUIC , and I do not think we 'd want to have that overhead always for QUIC . 
 Since QUIC is a new undeployed protocol running on UDP instead of TCP , it can move its SNI - like operation into the encrypted part and ( where applicable ) use some kind of in - protocol session resumption to switch from client - facing server public keys to origin server public keys . QUIC can also design its own mechanism for providing an encrypted non - repeating origin server indication in the early client to server packets . 
 Given that QUIC is already using TLS 1.3 , I 'd prefer that it be able to share mechanisms . 
 I think this is orthogonal to the contents of the draft . Namely , servers could maintain this sort of IP<-key association on their own without any client changes . Thus , closing as is . Please re - open if you think otherwise and have a suggested change for the document ! 
 Closing reason seems a complete misunderstanding . I have not checked how my old wording fits or does not fit the current draft . Issue is about handling multiple public servers ( with different " client - facing " server IPs and different configuration ) , not about tracking client IPs . 
 The reasoning above is n’t about tracking client IPs . Please give the latest draft a review and re - open if you think it ’s needed . And please provide suggested changes if they ’re needed !
Mailing list commentary: All The call for adoption period has drawn to a close , and there was strong consensus to adopt this document and begin working on the details . The chairs look forward to working on this document in the near future
Paragraph (version A):
First, the provider publishes a public key and metadata which is used
for SNI encryption for all the domains for which it serves directly
or indirectly (via Split Mode).  This document defines a publication
mechanism using DNS, but other mechanisms are also possible.  In
particular, if some of the clients of a private server are
applications rather than Web browsers, those applications might have
the public key and metadata preconfigured.
Paragraph (version B):
SNI encryption requires that each provider publish a public key and
metadata which is used for SNI encryption for all the domains for
which it serves directly or indirectly (via Split Mode).  This
document defines the format of the SNI encryption public key and
metadata, referred to as an ESNI configuration, and delegates DNS
publication details to HTTPSSVC, though other delivery mechanisms are
possible.  In particular, if some of the clients of a private server
are applications rather than Web browsers, those applications might
have the public key and metadata preconfigured.
Paragraph (version A):
Publishing ESNI keys in the DNS requires care to ensure correct
behavior.  There are deployment environments in which a domain is
served by multiple server operators who do not manage the ESNI keys.
Because ESNI and A/AAAA lookups are independent, it is therefore
possible to obtain an ESNI record which does not match the A/AAAA
records.  (That is, the host to which an A or AAAA record refers is
not in possession of the ESNI keys.)  The design of the system must
therefore allow clients to detect and recover from this situation
(see esni-resolution for more details).
Paragraph (version A):
The following sections describe a DNS record format that achieve
these goals.
Paragraph (version A):
SNI Encryption keys can be published using the following ESNIRecord
structure.
Paragraph (version A):
An ESNIKeys structure that contains the actual keys used to
encrypt the SNI as well as some metadata related to those keys.
Paragraph (version A):
A list of extensions that the client can take into consideration
when resolving the target DNS name.  The format is defined in
RFC8446; Section 4.2.  The purpose of the field is to provide room
for additional features in the future.  An extension may be tagged
as mandatory by using an extension type codepoint with the high
order bit set to 1.  A client which receives a mandatory extension
they do not understand must reject the ESNIRecord values.
Paragraph (version A):
padded_length The length to pad the ServerNameList value to prior to
encryption.  This value SHOULD be set to the largest ServerNameList
the server expects to support rounded up the nearest multiple of 16.
If the server supports arbitrary wildcard names, it SHOULD set this
value to 260.  Clients SHOULD reject ESNIKeys as invalid if
padded_length is greater than 260.
Paragraph (version A):
A list of extensions that the client can take into consideration
when generating a Client Hello message.  The format is defined in
RFC8446; Section 4.2.  The purpose of the field is to provide room
for additional features in the future.  An extension may be tagged
as mandatory by using an extension type codepoint with the high
order bit set to 1.  A client which receives a mandatory extension
they do not understand must reject the ESNIRecord value.
Paragraph (version A):
Any of the listed keys in the ESNIKeys value may be used to encrypt
the SNI for the associated domain name.  The cipher suite list is
orthogonal to the list of keys, so each key may be used with any
cipher suite.  Clients MUST parse the extension list and check for
unsupported mandatory extensions.  If an unsupported mandatory
extension is present, clients MUST reject the ESNIRecord value.
Paragraph (version A):
The ESNIRecord structure is placed in the RRData section of an ESNI
record as-is.  Servers MAY supply multiple ESNIRecord values, with
ESNIKeys either of the same or of different versions.  This allows a
server to support multiple versions at once.  If the server does not
supply any ESNIRecord values with an ESNIKeys version known to the
client, then the client MUST behave as if no ESNI records were found.
Paragraph (version A):
In the event that ESNIKeys is corrupt in transit or otherwise
invalid, servers will initiate the retry mechanism described in
server-behavior and deliver valid ESNIKeys to clients.
Paragraph (version A):
Note that the length of the ESNIRecord structure MUST NOT exceed 2^16
- 1, as the RDLENGTH is only 16 bits RFC1035.
Paragraph (version A):
This section describes a client ESNI resolution algorithm using an
"address_set" extension for the ESNIRecord structure.  Future
specifications may introduce new ESNIRecord extensions and
corresponding resolution algorithms.
Paragraph (version A):
The body of this extension is encoded using the following structure.
Paragraph (version A):
A set of Address structures containing IPv4 or IPv6 addresses to
hosts which have the corresponding private ESNI key.
Paragraph (version A):
This extension MUST NOT be placed in the ESNIKeys extensions field,
but only in the ESNIRecord dns_extensions field.
Paragraph (version A):
Clients SHOULD initiate ESNI queries in parallel alongside normal A
or AAAA queries to obtain address information in a timely manner in
the event that ESNI is available.  The following algorithm describes
a procedure by which clients can process ESNI responses as they
arrive to produce addresses for ESNI-capable hosts.
Paragraph (version A):
CD (Connection Delay) is a configurable parameter.  The recommended
value is 50 milliseconds, as per the guidance in RFC8305.
Paragraph (version A):
A cryptographic hash of the ESNIKeys structure from which the ESNI
key was obtained, i.e., from the first byte of "version" to the
end of the structure.  This hash is computed using the hash
function associated with "suite".
Paragraph (version B):
A cryptographic hash of the ESNIConfig structure from which the
ESNI key was obtained, i.e., from the first byte of "version" to
the end of the structure.  This hash is computed using the hash
function associated with "suite".
Paragraph (version A):
One or more ESNIKeys structures containing the keys that the
client should use on subsequent connections to encrypt the
ClientESNIInner structure.
Paragraph (version B):
One or more ESNIConfig structures containing the keys that the
client should use on subsequent connections to encrypt the
ClientESNIInner structure.
Paragraph (version A):
In order to send an encrypted SNI, the client MUST first select one
of the server ESNIKeyShareEntry values and generate an (EC)DHE share
in the matching group.  This share will then be sent to the server in
the "encrypted_server_name" extension and used to derive the SNI
encryption key.  It does not affect the (EC)DHE shared secret used in
the TLS key schedule.  The client MUST also select an appropriate
cipher suite from the list of suites offered by the server.  If the
client is unable to select an appropriate group or suite it SHOULD
ignore that ESNIKeys value and MAY attempt to use another value
provided by the server.  (Recall that servers might provide multiple
ESNIRecord values in response to a ESNI record query, each containing
an ESNIKeys value.)  The client MUST NOT send encrypted SNI using
groups or cipher suites not advertised by the server.
Paragraph (version A):
Zero padding whose length makes the serialized
PaddedServerNameList struct have a length equal to
ESNIKeys.padded_length.
Paragraph (version A):
This value consists of the serialized ServerNameList from the
"server_name" extension, padded with enough zeroes to make the total
structure ESNIKeys.padded_length bytes long.  The purpose of the
padding is to prevent attackers from using the length of the
"encrypted_server_name" extension to determine the true SNI.  If the
serialized ServerNameList is longer than ESNIKeys.padded_length, the
client MUST NOT use the "encrypted_server_name" extension.
Paragraph (version A):
The client MUST place the value of ESNIKeys.public_name in the
"server_name" extension.  (This is required for technical conformance
with RFC7540; Section 9.2.)  The client MUST NOT send a "cached_info"
extension RFC7924 with a CachedObject entry whose
CachedInformationType is "cert", since this indication would divulge
the true server name.
Paragraph (version A):
If the value is "esni_retry_request", the client proceeds with the
handshake, authenticating for ESNIKeys.public_name as described in
auth-public-name.  If authentication or the handshake fails, the
client MUST return a failure to the calling application.  It MUST
NOT use the retry keys.
Paragraph (version A):
If the server negotiates an earlier version of TLS, or if it does not
provide an "encrypted_server_name" extension in EncryptedExtensions,
the client proceeds with the handshake, authenticating for
ESNIKeys.public_name as described in auth-public-name.  If an earlier
version was negotiated, the client MUST NOT enable the False Start
optimization RFC7918 for this handshake.  If authentication or the
handshake fails, the client MUST return a failure to the calling
application.  It MUST NOT treat this as a secure signal to disable
ESNI.
Paragraph (version A):
The client MUST verify that the certificate is valid for
ESNIKeys.public_name.  If invalid, it MUST abort the connection
with the appropriate alert.
Paragraph (version A):
Compare ClientEncryptedSNI.record_digest against cryptographic
hashes of known ESNIKeys and choose the one that matches.
Paragraph (version A):
Use trial decryption of ClientEncryptedSNI.encrypted_sni with
known ESNIKeys and choose the one that succeeds.
Paragraph (version A):
Some uses of ESNI, such as local discovery mode, may omit the
ClientEncryptedSNI.record_digest since it can be used as a tracking
vector.  In such cases, trial decryption should be used for matching
ClientEncryptedSNI to known ESNIKeys.  Unless specified by the
application using (D)TLS or externally configured on both sides,
implementations MUST use the first method.
Paragraph (version A):
It MUST include the "encrypted_server_name" extension in
EncryptedExtensions message with the "response_type" field set to
"esni_retry_requested" and the "retry_keys" field set to one or
more ESNIKeys structures with up-to-date keys.  Servers MAY supply
multiple ESNIKeys values of different versions.  This allows a
server to support multiple versions at once.
Paragraph (version B):
Compare ClientEncryptedSNI.record_digest against cryptographic
hashes of known ESNIConfig and choose the one that matches.
Paragraph (version B):
Use trial decryption of ClientEncryptedSNI.encrypted_sni with
known ESNIConfig and choose the one that succeeds.
Paragraph (version B):
Some uses of ESNI, such as local discovery mode, may omit the
ClientEncryptedSNI.record_digest since it can be used as a tracking
vector.  In such cases, trial decryption should be used for matching
ClientEncryptedSNI to known ESNIConfig.  Unless specified by the
application using (D)TLS or externally configured on both sides,
implementations MUST use the first method.
Paragraph (version A):
If the ClientEncryptedSNI.key_share group does not match one in
the ESNIKeys.keys, it MUST abort the connection with an
"illegal_parameter" alert.
Paragraph (version A):
If the decrypted value's length is different from the advertised
ESNIKeys.padded_length or the padding consists of any value other
than 0, then the server MUST abort the connection with an
"illegal_parameter" alert.  Otherwise, the server uses the
PaddedServerNameList.sni value as if it were the "server_name"
extension.  Any actual "server_name" extension is ignored, which also
means the server MUST NOT send the "server_name" extension to the
client.
Paragraph (version A):
This design depends upon DNS as a vehicle for semi-static public key
distribution.  Server operators may partition their private keys
however they see fit provided each server behind an IP address has
the corresponding private key to decrypt a key.  Thus, when one ESNI
key is provided, sharing is optimally bound by the number of hosts
that share an IP address.  Server operators may further limit sharing
by sending different Resource Records containing ESNIRecord and
ESNIKeys values with different keys using a short TTL.
Paragraph (version B):
This design depends upon DNS as a vehicle for semi-static public key
distribution.  Server operators may partition their private keys
however they see fit provided each server behind an IP address has
the corresponding private key to decrypt a key.  Thus, when one ESNI
key is provided, sharing is optimally bound by the number of hosts
that share an IP address.  Server operators may further limit sharing
by publishing different DNS records containing ESNIConfig values with
different keys using a short TTL.