Draft: draft-ietf-tls-tls13

Commentary: This does the following : 1 ) Reorganize the backwards compatibility section into subsections for easier readability 2 ) Freezes the ClientHello record layer version to TLS 1.0 ( its effective compatible version ) 3 ) Adds explicit requirement that all other record layer versions match the negotiated version This plus PR should be sufficient to close issue . The record layer requirements were proposed by   on the list . ( also mentioned by him in other discussions ) 
 I do n't generally use capitals and periods for sentence fragments in parentheticals . Full sentences generally should n't be in parentheticals . Other instances of " ( see _ ) " prefer a lowercase 's ' and no period , but it 's not consistent throughout the whole document . I 'd lean towards that , however upon inspection I do n't think this cross reference is useful at all . I 'll just remove it . I 'll also correct the embarrassingly stupid typo . ( spellchecker does n't work in web interface ) I 'm going to refactor this slightly to move more info down to the end of the section rather than cramming everything in here . 
 Can you think of a good external reference to cite for the buggy server blurb ? If it 's a " complex topic beyond the scope of this document " then it ideally should reference more information elsewhere . 
 Re : other vendors ' ClientHello version strategies : It occurs to me that we might prefer to make the ClientHello record version a SHOULD rather than a MUST to allow for some flexibility in implementation . If anyone is sending different versions in different instances to cope with specific server bugs , that may not need to be completely prohibited . ( if not needed , then a MUST is probably appropriate ) 
 RE : " This document SSL 3.0 . " I disagree that it is unnecessary . Whilst redundant , I think the reason why TLS uses weird version numbers needs to be stated somewhere in this document . Moving it to the backwards compatibility section is an option if you think it 's in the way up here . RE : second section of record layer version text I have that set aside due to formatting concerns . The " version " section is indented in a list and putting lots of text in there risks cluttering things up a bit . I 'd prefer to have the minimum definition and requirements under that heading and additional issues separately , in order to maximize readability . 
 Well crud . I rebased this and GitHub dropped the comments from They have n't vanished entirely into the aether , just not shown above in the threading here . For reference , imagine there are proper " commented on an outdated diff " lines above and that I did n't confuse GitHub and am not talking to myself . I shall endeavor to be less of a GitHub noob in the future . 
 It might be simpler to just change to : TLS clients MUST set this version to { 3 , 1 } for the initial ClientHello and all alert messages . For the ServerHello and all other TLS records this MUST be equal to the negotiated version . Additionally , dropping the version field from TLSCipherText entirely might be worth considering , but that 's outside the scope of this here . 
 ( I assume you mean s / clients / implementations/ ? Otherwise there 's still an unspecified hole . ) All alerts period , or just those before version negotiation ? OpenSSL , after version negotiation , will currently reject any record ( of whatever type ) whose version does not match the negotiated version . Go 's crypto / tls does the same thing . I have n't done a survey of other implementations yet . It can certainly change for TLS 1.3 . But , as an implementer , I would prefer that field be hammered down in a way that can advise older versions , whether or not 1.3 additionally clamps it post - negotiation . If just those before version negotiation , I think a cleaner statement of that rule is : Prior to version negotiation , this version MUST by { 3 , 1 } . This includes the initial ClientHello and any alerts sent during version negotiation . After version negotiation , this MUST be equal to the negotiated version . This includes the ServerHello and all following records . This is fairly straightforward and clean . The record - layer initializes in " proto TLS " which uses { 3 , 1 } . Then it switches one to a concrete version . The one ambiguity left is a client 's alert . That one is sent when one side has done negotiation , but not the other . Which is where the trickiness I mentioned comes up with existing servers [ ] . Whether the complexity is worth bothering with is another matter . ( For context , I 'm coming at this from having recently rewritten BoringSSL 's version negotiation logic . 1.2 's failure to clearly specify version negotiation was a huge pain point . ) [ ] For completeness , OpenSSL client has its own quirks . If the client has a minimum version TLS 1.0 AND the server sends some alert with record - layer { 3 , 1 } , the client will fail to read it . OpenSSL client negotiates based on record - layer version , not ServerHello . But that implementation is sufficiently weird that I do n't think it 's worth bothering about . See links in . 
 I was proposing { 3,1 } for all alerts , yes . ( even old versions should be able to parse new ; an unknown error could just be generically acted on ) However , if there are implementations that would find this inconsistent with current behavior , then I agree it 's not worth it . I like the language you suggested . It deals with the error cases and is quite clear . ( modulo the typo ;) To deal with the protocol_version case , this might cover everything : Prior to version negotiation , this value MUST be { 3 , 1 } . This includes the ClientHello , records sent during negotiation , and errors aborting the negotiation . After version negotiation , this MUST be equal to the negotiated version . This includes the ServerHello and all following records . 
 " records sent during negotiation " would count EarlyDataExtension records as well . Arguably this should be { 3 , 4 } , but I do n't think it 's worth the complexity . 
 Version negotiation is completed by the first packet that the server sends ( ie typically ServerHello ) , and the client typically only sends one packet if it cares about compatibility with versions prior to TLS 1.3 , so forcing the packet version to { 3 , 1 } for the ClientHello should be sufficient . 
 Per proposed resolution at interim , we can now simplify things down to one frozen and deprecated value . This is the ideal solution , IMO . In addition to updates for this , I 've also renamed the field to " record_version " instead of just " version " as people easily mix up the various version fields . It now has a different expected behavior , so a different name is appropriate . 
 I 'm fine with freezing it going forward ( it means that someday in the far far future perhaps we can forget about this craziness altogether ) . But note that implementations supporting TLS < 1.3 will still need to do a swap when negotiating older versions . Existing clients and servers ( including anything derived from OpenSSL ) will reject post - version - negotiation records that do n't have the right record - layer version . I do n't know if advice on that front belongs in this draft or elsewhere or nowhere , but it is a concern implementations will have for a while . 
 Good point . I 've updated backwards compatibility section for that . 
 More fixes and rebasing . 
 Note that I expect a new version negotiation mechanism implemented via an extension will be desired in order to deal with TLS 1.3 intolerance , and thus parts of this will be changed again . ClientHello.client_version would most likely be frozen to { 3,3 } in such a mechanism . That , however , is outside the scope of this PR which is to revise the existing backwards compatibility and freeze the record layer version . 
 ( Apologies if this is the wrong medium . I was n't sure if issues here or emails to the list were preferred since these are n't huge changes . ) How version negotiation interacts with session resumption is n't said explicitly . Two little things that probably should be fixed : On the server , clarify that you MUST NOT resume a session at a version other than the original one . Instead , ignore the offered session and do a full handshake . This is easy to justify : every client ( I tested NSS , OpenSSL , SecureTransport , and SChannel ) will fail the handshake if the server tries to mismatch . It 's also weird . ( Say a future TLS version changed the master secret size ... ) Still , OpenSSL happily did so until . On the client , RFC 5246 , E.1 has this little paragraph that seems to have carried over into 1.3 . This is terrible advice . The parenthetical bit is wrong , but I would push for dropping it completely . The server may have changed , there may be multiple differently - configured servers behind that host , the session may have been established under fallback conditions , etc . OpenSSL takes it to an and . ( I ended up completely rewriting this bit for BoringSSL . ) NSS in something less catastrophic but still has the second " sticky fallback " failure mode . 
 I support removing that text . See also earlier discussion : Note that when a client does not consistently use the same ClientHello.clientversion , it should probably avoid attempting to resume a session X if it used a different ClientHello.clientversion for the connection that created session X than it is attempting to use in the current ClientHello . The consequence of this is that these clients should store ClientHello.clientversion in the session cache entry . However , it is better for them to always consistently set ClientHello.clientversion to TLS 1.2 . 
 Having generic text to take care when mixing session caches between contexts with different parameters is probably worthwhile yeah . Sharing a session cache between a pile of sockets that , say , turn off AEADs and a pile that do n't is also iffy . The clientversion seems rather specific requirement to put in , and requiring TLS impls to store the entire ClientHello in the session cache seems a bit much . I actually do n't see what doing just the clientversion buys for the extra state , at least in contexts where a browser does it . Are you thinking to do that to account for the NSS clientversion clamping behavior , the old OpenSSL server one when combined with fallbacks , or something else ? If the NSS side , that would mean NSS never resumes sessions on any but the highest version . It should just remove that logic ; neither SChannel nor Secure Transport did it when I tested .    does n't either and we have n't had problems . ( It 's hit stable on  and beta on Windows . ) If the old OpenSSL server behavior ( and without FALLBACKSCSV ) and you should have negotiated a stronger TLS-1.2 - only cipher , an attacker could just trigger the fallback again anyway , so we 're not gaining much . That seems best fixed on the server ( and has been now ) . In fact , if the server wants to be extra fancy , it could simulate picking a new cipher and only accept the session if that matched . But probably expiring old sessions when changing server config works just as well there . ( That may also be worth some text : servers should take care when considering old sessions across a server config change . ) 
 I mean this ( acting as the client ): what number ( e.g. TLS 1.2 ) you are going to put in ClientHello.clientversion and what cipher suites you are going to send in the ClientHello . the session cache for a matching entry , where the session was established on a connection where ClientHello.clientversion matches the ClientHello.clientversion you picked in the previous step , and where the cipher suite for the cached session matches a cipher suite in the set of cipher suites you 've enabled for the current ClientHello . Note that we 're matching ClientHello.clientversion to ClientHello.clientversion , NOT to the version that was negotiated ( ServerHello.serverversion ) . the server attempts to resume the session with a different serverversion or a different cipher suite , then something 's gone very wrong ; bail ! The idea here is to avoid cases where the server may do strange things like use a different ServerHello.serverversion or a different cipher suite than what was originally negotiated . As you mentioned , the logic I described is n't enough to prevent all silliness , but I think it would avoid most cases . 
 We removed resumption entirely as of draft-07 so I think this is OBE . 
 It 's renegotiation that was removed . This might still be relevant . 
 Well , we removed explicit resumption as well , and at least technically you could do PSK - resumption with different cipher suites and/or versions .
Paragraph (version B):
Prohibit RC4 negotiation for backwards compatibility.
Paragraph (version B):
Freeze & deprecate record layer version field.
Paragraph (version A):
The version of the protocol being employed.  This document
describes TLS Version 1.3, which uses the version { 3, 4 }.  The
version value 3.4 is historical, deriving from the use of {3, 1}
for TLS 1.0.  (See record-layer-1.)  Note that a client that
supports multiple versions of TLS may not know what version will
be employed before it receives the ServerHello.  See backward-
compatibility for discussion about what record layer version
number should be employed for ClientHello.
Paragraph (version B):
The protocol version the current record is compatible with.  This
value MUST be set to { 3, 1 } for all records.  This field is
deprecated and MUST be ignored for all purposes.
Paragraph (version B):
This document describes TLS Version 1.3, which uses the version { 3,
4 }.  The version value 3.4 is historical, deriving from the use of {
3, 1 } for TLS 1.0 and { 3, 0 } for SSL 3.0.  In order to maximize
backwards compatibility, the record layer version identifies as
simply TLS 1.0.  Endpoints supporting other versions negotiate the
version to use by following the procedure and requirements in
backward-compatibility.
Paragraph (version A):
The version field is identical to TLSPlaintext.version.
Paragraph (version B):
The record_version field is identical to
TLSPlaintext.record_version and is always { 3, 1 }.
Paragraph (version A):
The version of the TLS protocol by which the client wishes to
communicate during this session.  This SHOULD be the latest
(highest valued) version supported by the client.  For this
version of the specification, the version will be 3.4 (see
backward-compatibility for details about backward compatibility).