Lo standard TLS corrente non è molto chiaro su come devono essere gestite le versioni. L'allegato E.1 contiene alcune informazioni, dalle quali possiamo vedere che l'idea implicita è che la versione selezionata dipende da ciò che il supporto del client e del server , non da ciò che il client e il server può scegliere di usarlo per un capriccio. Se un client supporta fino a TLS 1.2 e un server fino a TLS 1.1, allora dovrebbe utilizzare TLS 1.1, sempre. Pertanto, non ci dovrebbe essere alcuna domanda su "cambiare la versione" quando si riprende una sessione o si rinegozia.
Esistono diversi campi di versione:
- Ogni "record" ha un campo versione.
- Il messaggio ClientHello contiene la versione più alta supportata dal client.
- Il messaggio ServerHello contiene la versione che sarà utilizzata su questa connessione.
Presumibilmente, il client invierà il suo primo ClientHello come un record con un numero di versione 3.x per un certo valore di "x"; 3.0 ottimizzerà l'interoperabilità. Una volta che il server ha risposto con un ServerHello che indica che verrà utilizzata la versione 3.y, sia il client che il server devono utilizzare i record 3.y. Ciò rende la versione estremamente delicata durante una rinegoziazione. Inoltre, i record TLS 1.1+ crittografati CBC non sono compatibili con i record SSL 3.0 / TLS 1.0 (a causa del IV per record aggiuntivo), quindi le versioni a livello di record sono importanti una volta che il primo ChangeCipherSpec è stato inviato / ricevuto.
Per la ripresa della sessione, l'allegato E.1 afferma che:
Whenever a client already knows the highest protocol version known to
a server (for example, when resuming a session), it SHOULD initiate
the connection in that native protocol.
da cui deduco che se la sessione precedente usasse la versione 3.y, allora il client dovrebbe usare records con la versione 3.y. Tuttavia, nulla impedisce di pubblicizzare un numero di versione più elevato in ClientHello.
Inoltre, la derivazione della chiave master nella crittografia e le chiavi MAC utilizzano il TLS PRF, che dipende dalla versione del protocollo (TLS 1.0 e 1.1 utilizzano lo stesso PRF, ma non SSL 3.0 e né TLS 1.2). Riprendere una sessione con una versione diversa è in cerca di problemi.
L'intera area è torbida. Vedi ad esempio questo bug report di Mozilla / Firefox . Nella mia esperienza, le seguenti regole dovrebbero essere seguite per ridurre al minimo i problemi:
Regole per il cliente:
- Invia il primo record come versione 3.0.
- Pubblicizza sempre nella versione ClientHello la versione massima supportata (ad esempio 3.3 per TLS 1.2).
- Quando il server risponde con ServerHello, usa la versione inviata dal server come nuova versione per tutti i record successivi, i calcoli crittografici e i dettagli del protocollo.
- Una volta che il server ha inviato un ServerHello, applica le versioni dei record in entrata: i record successivi dal server dovrebbero usare quella . Se un record del server pubblicizza un'altra versione, interrompi.
- Quando si rinegozia, se il server tenta di utilizzare un'altra versione rispetto a quella precedente, annulla
Regole per il server:
- Ignora la versione sui record in entrata, durante i primi passi della connessione.
- Una volta inviato ServerHello, applica le versioni dei record: tutti i record successivi del client devono utilizzare quella versione.
- Quando si riprende una sessione, riutilizzare la stessa versione, a condizione che la versione in ClientHello lo consenta; in caso contrario, eseguire una stretta di mano completa (ad esempio se la sessione precedente era TLS 1.1 e il nuovo ClientHello dice 1.2, riprendere con la versione 1.1, se la sessione precedente era TLS 1.1 e il nuovo ClientHello dice 1.0, non riprendere, eseguire una nuova versione completa 1.0 stretta di mano).
- Quando si rinegozia, verificare che la versione pubblicizzata nel nuovo ClientHello sia compatibile con la versione corrente, ma non modificare la versione corrente. Se il primo handshake era 1.1, il secondo handshake sarà 1.1, anche se il nuovo ClientHello dice 1.2.
È praticamente garantito che ci siano alcune implementazioni ampiamente implementate che a un certo punto sbagliano.