RFC 6347 - 4.1. Record layer
4. Differences from TLS
Come indicato nella sezione 3, DTLS è deliberatamente molto simile a TLS. Invece di presentare DTLS come protocollo nuovo, lo presentiamo come una serie di delta rispetto a TLS 1.2 [TLS12]. Dove non si evidenziano differenze, DTLS coincide con [TLS12].
4.1. Record Layer
Il record layer DTLS è estremamente simile a quello di TLS 1.2. L'unica modifica è l'inclusione di un numero di sequenza esplicito nel record, che consente al destinatario di verificare correttamente il MAC TLS. Il formato del record DTLS è mostrato di seguito:
struct {
ContentType type;
ProtocolVersion version;
uint16 epoch; // New field
uint48 sequence_number; // New field
uint16 length;
opaque fragment[DTLSPlaintext.length];
} DTLSPlaintext;
type
Equivalente al campo type di un record TLS 1.2.
version
Versione del protocollo impiegata. Questo documento descrive DTLS 1.2 con versione { 254, 253 }. Il valore 254.253 è il complemento a 1 della versione DTLS 1.2. L'ampio scarto tra numeri di versione TLS e DTLS consente di distinguere facilmente i record. I numeri DTLS sul filo diminuiranno in futuro mentre il vero numero di versione aumenterà.
epoch
Contatore incrementato ad ogni cambio di stato di cifratura.
sequence_number
Numero di sequenza di questo record.
length
Come il campo length in TLS 1.2; non deve superare 2^14.
fragment
Come il campo fragment in TLS 1.2.
DTLS usa un numero di sequenza esplicito nel campo sequence_number. I numeri sono mantenuti separatamente per ogni epoch, inizialmente 0. Un messaggio di handshake dell'epoch 0 ritrasmetto può avere numero successivo a un messaggio dell'epoch 1 anche se quest'ultimo è stato inviato per primo. Durante l'handshake occorre assicurarsi che le ritrasmissioni usino epoch e materiale di chiave corretti.
Se si eseguono più handshake ravvicinati, possono esserci record con lo stesso numero di sequenza ma stati di cifratura diversi; il campo epoch li distingue. L'epoch parte da zero e si incrementa a ogni ChangeCipherSpec. Per garantire l'unicità di ogni coppia sequenza/epoch, le implementazioni NON DEVONO riusare lo stesso valore di epoch entro il doppio della massima durata di segmento TCP. In pratica i nuovi handshake sono rari.
Poiché i record DTLS possono essere riordinati, un record dell'epoch 1 può arrivare dopo l'inizio dell'epoch 2. In generale, le implementazioni DOVREBBERO scartare i pacchetti di epoch precedenti; se le perdite creano problemi, POSSONO conservare il materiale di chiave delle epoch precedenti fino alla MSL TCP predefinita [TCP] per tollerare il riordino. (Si intendono le linee guida IETF attuali sulla MSL, non l'interrogazione della MSL dello stack TCP.) Finché l'handshake non è completato, le implementazioni DEVONO accettare pacchetti della vecchia epoch.
Viceversa, record protetti dal nuovo contesto negoziato possono arrivare prima del completamento dell'handshake (es. il server invia Finished e poi dati). Le implementazioni POSSONO mettere in buffer o scartare; su trasporto affidabile (es. SCTP) DOVREBBERO bufferizzare ed elaborare al termine dell'handshake. Restano valide le restrizioni TLS sull'invio; il ricevente tratta i pacchetti come se fossero in ordine. In particolare è ancora vietato inviare dati prima del completamento del primo handshake.
Nel caso speciale di nuovo handshake su association esistente, è sicuro elaborare subito i dati anche senza ChangeCipherSpec o Finished se il handshake riprende la sessione o usa esattamente gli stessi parametri di sicurezza. Altrimenti l'implementazione DEVE attendere Finished per prevenire attacchi di downgrade.
Come in TLS, le implementazioni DEVONO abbandonare l'association o rifare handshake prima che il numero di sequenza faccia wrap.
Analogamente, l'epoch NON DEVE fare wrap; occorre stabilire una nuova association terminando quella vecchia come in 4.2.8. Handshake ripetuti sullo stesso canale sono rari.
4.1.1. Transport Layer Mapping
Ogni record DTLS DEVE stare in un singolo datagramma. Per evitare frammentazione IP, i clienti del record layer DOVREBBERO dimensionare i record in base alle stime PMTU disponibili.
A differenza di IPsec, i record DTLS non contengono identificatori di association; le applicazioni devono multiplexare (con UDP tipicamente host/porta).
Più record DTLS possono essere messi nello stesso datagramma in codifica consecutiva; il framing determina i confini. Il primo byte del payload deve essere l'inizio di un record; i record non possono attraversare datagrammi.
Alcuni trasporti (DCCP [DCCP]) hanno numeri di sequenza propri; entrambi sono presenti. C'è una piccola inefficienza ma scopi diversi; concettualmente è preferibile usare entrambi. Estensioni future potrebbero usare un solo insieme in ambienti vincolati.
Su DCCP, finestre di congestione strette possono ritardare le ritrasmissioni di handshake e causare timeout spurii; non superare la probabile finestra di congestione. [DCCPDTLS] definisce il mapping DTLS su DCCP.
4.1.1.1. PMTU Issues
In generale DTLS lascia la scoperta PMTU all'applicazione, ma non può ignorarla del tutto:
-
Il framing DTLS aumenta il datagramma e riduce la PMTU effettiva per l'applicazione.
-
A volte l'applicazione non parla direttamente con la rete; lo stack DTLS può assorbire ICMP [RFC1191] "Datagram Too Big" o ICMPv6 [RFC4443] "Packet Too Big".
-
I messaggi di handshake possono superare la PMTU.
Per i primi due punti, il record layer DOVREBBE comportarsi come segue.
Se il trasporto fornisce stime PMTU, devono essere esposte ai protocolli superiori:
-
DTLS su UDP: il protocollo superiore DOVREBBE poter ottenere la stima PMTU del livello IP.
-
DTLS su DCCP: il protocollo superiore DOVREBBE poter ottenere la stima PMTU corrente.
-
DTLS su TCP/SCTP: frammentazione automatica; nessun limite PMTU, ma il protocollo superiore NON DEVE scrivere record oltre 2^14 byte.
Il record layer DOVREBBE consentire di stimare l'espansione del record dovuta a DTLS (solo stima, per padding a blocchi e possibile compressione DTLS).
Se c'è un'indicazione di errore di trasporto (ICMP o rifiuto di invio come nella sezione 14 di [DCCP]), il record layer DEVE informare il protocollo superiore.
Il record layer NON DOVREBBE interferire con la scoperta PMTU del protocollo superiore tramite [RFC1191] o [RFC4821]: consentire DF IPv4 o vietare frammentazione locale IPv6 se permesso; onorare sonde PMTU (es. DCCP).
Per l'handshake: eventi rari e brevi; la gestione PMTU privilegia il completamento rapido. Le implementazioni DOVREBBERO:
-
Se un messaggio è troppo grande, tentare subito la frammentazione con le informazioni PMTU disponibili.
-
Se ritrasmissioni ripetute non ottengono risposta e la PMTU è sconosciuta, ridurre la dimensione del record e frammentare; 2-3 tentativi prima del backoff sono plausibili (non normativo).
4.1.2. Record Payload Protection
Come TLS, DTLS trasmette dati come serie di record protetti; il resto della sezione descrive il formato.
4.1.2.1. MAC
Il MAC DTLS è lo stesso di TLS 1.2, ma invece del numero di sequenza implicito di TLS si usa il valore a 64 bit formato concatenando epoch e numero di sequenza nell'ordine sul filo (stessa lunghezza del numero di sequenza TLS).
Il calcolo del MAC è parametrizzato sulla versione sul filo, per DTLS 1.2 {254, 253}.
In TLS gli errori MAC richiedono la terminazione della connessione; in DTLS l'implementazione PUÒ scartare il record difettoso e continuare perché i record non sono interdipendenti come in TLS.
In generale le implementazioni DOVREBBERO scartare silenziosamente i record con MAC errato o altrimenti non validi; POSSONO registrare un errore. Se si invia un alert per MAC non valido, DEVE essere bad_record_mac a livello fatal e lo stato di connessione termina. Poiché gli errori non terminano sempre la connessione, gli stack DTLS sono oracoli di tipo errore più efficienti; è quindi essenziale seguire la sezione 6.2.3.2 di [TLS12].
4.1.2.2. Null or Standard Stream Cipher
Il cifrario NULL DTLS è identico a TLS 1.2.
L'unico cifrario a flusso in TLS 1.2 è RC4, che non consente accesso casuale. RC4 NON DEVE essere usato con DTLS.
4.1.2.3. Block Cipher
Cifratura e decifratura a blocchi come in TLS 1.2.
4.1.2.4. AEAD Ciphers
TLS 1.2 ha introdotto suite AEAD; quelle definite in [ECCGCM] e [RSAGCM] si usano con DTLS come con TLS 1.2.
4.1.2.5. New Cipher Suites
Alla registrazione, le nuove suite TLS DEVONO indicare se sono adatte a DTLS e quali adattamenti servono (sezione 7).
4.1.2.6. Anti-Replay
I record contengono un numero di sequenza per la protezione da replay. La verifica DOVREBBE usare la finestra scorrevole della sezione 3.4.3 di [ESP].
Il contatore pacchetti del ricevente DEVE essere inizializzato a zero all'istituzione della sessione. Per ogni record, il ricevente DEVE verificare che il numero di sequenza non duplichi altri ricevuti nella vita della sessione. Questo DOVREBBE essere il primo controllo dopo l'abbinamento alla sessione.
I duplicati si scartano con una finestra di ricezione scorrevole (implementazione locale). La dimensione minima 32 DEVE essere supportata; 64 è preferita e DOVREBBE essere il default. Altre dimensioni MAGGIORE del minimo sono consentite (senza notifica al mittente).
Il bordo "destro" della finestra è il massimo numero di sequenza validato. I numeri a sinistra sono rifiutati; entro la finestra si confronta con l'elenco dei pacchetti ricevuti (bitmask, vedi [ESP]).
Se il record è nuovo nella finestra o a destra di essa, si procede alla verifica MAC. Se fallisce, il record DEVE essere scartato. La finestra si aggiorna solo dopo MAC riuscito.
4.1.2.7. Handling Invalid Records
A differenza di TLS, DTLS è resiliente ai record non validi (formato, lunghezza, MAC, ecc.). In generale i record non validi DOVREBBERO essere scartati silenziosamente per preservare l'association; è possibile registrare un errore a fini diagnostici. Se si generano alert, DEVONO essere fatal per evitare sonde ripetute. Su UDP ciò rende l'implementazione molto vulnerabile al DoS per la facilità di falsificazione UDP; la pratica NON È RACCOMANDATA.
Su trasporto resistente alla falsificazione (es. SCTP con SCTP-AUTH) gli alert sono più sicuri.