Draft: draft-ietf-tls-esni

Commentary: This is a temporary mitigation for the compatibility risks from , as any clients experimenting with GREASE will impact servers that otherwise do n't expect ECH . To resolve this issue overall , we may need a more involved solution . 
 I just noticed this as I was pondering our various HRR issues . RFC8446 , section 4.1.2 says : The " and present in the HelloRetryRequest " portion is fun . In RFC8446 as written , we 're not allowed to change the extension on the second ClientHello unless the server sent in HelloRetryRequest , which it does n't . With the protocol as - is , it seems we 'll at least need some text to deal with the contradiction . The impact is practice is thankfully limited . If the servers does not enforce consistency between the two ClientHellos , it does n't matter . ( They 're not required to , but they 're not explicitly forbidden from it either , and a stateless server may need to enforce some minimum consistency to avoid getting into a broken state . ) If a server does , ECH 's behavior on HRR will break it . Such a server is supposed to handshake with ClientHelloOuter , so it just affects the retry flow . That 's maybe okay , but mildly annoying . Administrators using server software that checks need to know to first upgrade to a version that does n't check before trying to deploy ECH . We can also add an ECH extension to  . Then , on ECH - reject + HRR , the server perhaps would n't send the extension and the client would be required to replay the extension . This is a waste in many ways , but would work . This would break do n't stick out , but some threat models , do n't stick out with  is hopeless anyway . ( See ) It would also be weirdly asymmetric between ECH and SH . That said , this constraint is also pretty obnoxious . For instance , currently adds a new padding extension codepoint , because the old one is n't defined for other messages . However , the RFC8446 allowance only works for the existing padding code point , so you do n't want to send any other code points in ClientHello , lest the server force you to keep it unchanged in ClientHello2 . So maybe we should confirm no servers did the fully strict check and undo that constraint ? ( Although , for , I personally favor the padding message strategy anyway . ) 
 points out the Go implementation does check CH1 and CH2 consistency . Fortunately , it only checks known extensions , so it 's still compatible with the ECH draft . Checking only know extensions is basically saying we should strike " and present in the HelloRetryRequest " in rfc8446bis and make sure everyone knows not to check this . 
 I do n't think we can just strike this text because the point of that text was that you could n't like change your KeyShares if the HRR did n't tell you to . But I agree we can sharpen this in some sensible way . 
 I figured that case was covered by " defined in the future " , which I 'm not proposing we delete .  is n't defined in the future , so it falls under existing rules . The existing rules ( bullet points over that one ) only let you change keyshare " [ i]f a " key_share " extension was supplied in the HelloRetryRequest " . But perhaps that 's a little roundabout . The rules I 'm thinking of are ( changes emphasized ): Each extension gets to define how it reacts to HRR . It typically is sensitive the corresponding HRR extension , but does n't have to be . RFC8446(bis ) defines the rules for all existing extensions . Future extensions define their own rules . ( And probably if they do n't say anything , we assume they do n't get to change . ) As a server , you can make assumptions based on the rules for extensions you know about . You have to tolerate random changes in extensions you do n't know about , because you do n't know their rules . * I 'm running a probe on a bunch of servers to see how they react to changes in cipher suites , curves , and a random extension . It seems most do n't notice . Some ( I 'm guessing Go ) notice cipher suites and curves . None notice a random extension . That suggests the change will be compatible . 
 I spoke too soon . LibreSSL breaks if you change an extension they do n't recognize . :-( 
 So draft-09 is n't tied up with this , I 've uploaded as a bandaid for the potential compatibility issue . ( I say potential because it 's only a problem if the server checks unknown extensions and has different enough key share preferences from the client that it needs  .  is pretty rare , so it may not actually be an issue . For  , at least , I do n't think the particular servers I found actually trigger  . But it is still a risk for clients or servers with different configurations . ) 
 Given the compatibility concerns found , and based on discussion in IETF 109 , I think this is prudent to merge for -09 . Doing so now .
Paragraph (version A):
When sending a second ClientHello in response to a HelloRetryRequest,
the client copies the "cipher_suite" field from the first
ClientHello.  It sets "config_id", and "enc" to the empty string.
Finally, it generates a new "payload" field, using the length of a
padded second EncodedClientHelloInner for L.
Paragraph (version B):
When sending a second ClientHello in response to a HelloRetryRequest,
the client copies the entire "encrypted_client_hello" extension from
the first ClientHello.