Zum Hauptinhalt springen

4. The DTLS Record Layer (Die DTLS-Datensatzschicht)

4. The DTLS Record Layer (Die DTLS-Datensatzschicht)

Die DTLS 1.3-Datensatzschicht unterscheidet sich von der TLS 1.3-Datensatzschicht und auch von der DTLS 1.2-Datensatzschicht.

  1. Die DTLSCiphertext-Struktur lässt die überflüssigen Versionsnummer- und Typfelder aus.

  2. DTLS fügt dem TLS-Datensatz-Header eine Epoche und Sequenznummer hinzu. Diese Sequenznummer ermöglicht es dem Empfänger, DTLS-Datensätze korrekt zu entschlüsseln und zu verifizieren. Die Anzahl der Bits, die für die Epochen- und Sequenznummernfelder in der DTLSCiphertext-Struktur verwendet werden, wurde jedoch gegenüber früheren Versionen reduziert.

  3. Die in DTLSPlaintext serialisierte DTLS-Epoche ist 2 Oktette lang, um die Kompatibilität mit DTLS 1.2 zu gewährleisten. Dieser Wert wird jedoch als die am wenigsten signifikanten 2 Oktette der Verbindungsepoche festgelegt, die ein 8-Oktett-Zähler ist, der bei jedem KeyUpdate inkrementiert wird. Siehe Abschnitt 4.2 für Details. Die Sequenznummer wird auf die niederwertigen 48 Bits der 64-Bit-Sequenznummer gesetzt. Klartext-Datensätze DÜRFEN NICHT mit Sequenznummern gesendet werden, die 2^48-1 überschreiten würden, sodass die oberen 16 Bits immer 0 sein werden.

  4. Die DTLSCiphertext-Struktur hat einen Header variabler Länge.

DTLSPlaintext-Datensätze werden zum Senden ungeschützter Datensätze verwendet, und DTLSCiphertext-Datensätze werden zum Senden geschützter Datensätze verwendet.

Die DTLS-Datensatzformate sind unten dargestellt. Sofern nicht ausdrücklich anders angegeben, ist die Bedeutung der Felder gegenüber früheren TLS/DTLS-Versionen unverändert.

struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 epoch = 0
uint48 sequence_number;
uint16 length;
opaque fragment[DTLSPlaintext.length];
} DTLSPlaintext;

struct {
opaque content[DTLSPlaintext.length];
ContentType type;
uint8 zeros[length_of_padding];
} DTLSInnerPlaintext;

struct {
opaque unified_hdr[variable];
opaque encrypted_record[length];
} DTLSCiphertext;

Abbildung 2: DTLS 1.3-Datensatzformate

legacy_record_version: Dieser Wert MUSS für alle Datensätze außer dem initialen ClientHello (d.h. einem, das nicht nach einem HelloRetryRequest generiert wurde) auf {254, 253} gesetzt werden, wo er aus Kompatibilitätsgründen auch {254, 255} sein kann. Er MUSS für alle Zwecke ignoriert werden. Siehe [TLS13], Anhang D.1 für die Begründung hierfür.

epoch: Die am wenigsten signifikanten 2 Bytes des Verbindungsepochenwerts.

unified_hdr: Der einheitliche Header (unified_hdr) ist eine Struktur variabler Länge, die in Abbildung 3 dargestellt ist.

encrypted_record: Die verschlüsselte Form der serialisierten DTLSInnerPlaintext-Struktur.

  0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|0|0|1|C|S|L|E E|
+-+-+-+-+-+-+-+-+
| Connection ID | Legende:
| (if any, |
/ length as / C - Connection ID (CID) present
| negotiated) | S - Sequence number length
+-+-+-+-+-+-+-+-+ L - Length present
| 8 or 16 bit | E - Epoch
|Sequence Number|
+-+-+-+-+-+-+-+-+
| 16 bit Length |
| (if present) |
+-+-+-+-+-+-+-+-+

Abbildung 3: DTLS 1.3 Einheitlicher Header

Fixed Bits: Die drei hohen Bits des ersten Bytes des einheitlichen Headers sind auf 001 gesetzt. Dies stellt sicher, dass der Wert in den DTLS-Bereich passt, wenn Multiplexing wie in [RFC7983] beschrieben durchgeführt wird. Es stellt auch sicher, dass die Unterscheidung verschlüsselter DTLS 1.3-Datensätze von verschlüsselten DTLS 1.2-Datensätzen möglich ist, wenn sie auf demselben Host/Port-Quartett übertragen werden; ein solches Multiplexing ist nur möglich, wenn CIDs [RFC9146] verwendet werden, in welchem Fall DTLS 1.2-Datensätze den Inhaltstyp tls12_cid (25) haben werden.

C: Das C-Bit (0x10) wird gesetzt, wenn die Connection ID vorhanden ist.

S: Das S-Bit (0x08) gibt die Größe der Sequenznummer an. 0 bedeutet eine 8-Bit-Sequenznummer, 1 bedeutet 16-Bit. Implementierungen KÖNNEN Sequenznummern unterschiedlicher Längen auf derselben Verbindung mischen.

L: Das L-Bit (0x04) wird gesetzt, wenn die Länge vorhanden ist.

E: Die beiden niedrigen Bits (0x03) enthalten die niederwertigen zwei Bits der Epoche.

Connection ID: CID variabler Länge. Die CID-Funktionalität ist in [RFC9146] beschrieben. Ein Beispiel findet sich in Abschnitt 9.1.

Sequence Number: Die niederwertigen 8 oder 16 Bits der Datensatz-Sequenznummer. Dieser Wert ist 16 Bits, wenn das S-Bit auf 1 gesetzt ist, und 8 Bits, wenn das S-Bit 0 ist.

Length: Identisch mit dem Längenfeld in einem TLS 1.3-Datensatz.

Wie bei früheren Versionen von DTLS können mehrere DTLSPlaintext- und DTLSCiphertext-Datensätze im selben zugrunde liegenden Transport-Datagramm enthalten sein.

Abbildung 4 veranschaulicht verschiedene Datensatz-Header.

 0 1 2 3 4 5 6 7       0 1 2 3 4 5 6 7       0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
| Content Type | |0|0|1|1|1|1|E E| |0|0|1|0|0|0|E E|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
| 16 bit | | | |8 bit Seq. No. |
| Version | / Connection ID / +-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+ | | | |
| 16 bit | +-+-+-+-+-+-+-+-+ | Encrypted |
| Epoch | | 16 bit | / Record /
+-+-+-+-+-+-+-+-+ |Sequence Number| | |
| | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
| | | 16 bit |
| 48 bit | | Length | DTLSCiphertext
|Sequence Number| +-+-+-+-+-+-+-+-+ Structure
| | | | (minimal)
| | | Encrypted |
+-+-+-+-+-+-+-+-+ / Record /
| 16 bit | | |
| Length | +-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+
| | DTLSCiphertext
| | Structure
/ Fragment / (full)
| |
+-+-+-+-+-+-+-+-+

DTLSPlaintext
Structure

Abbildung 4: DTLS 1.3 Header-Beispiele

Das Längenfeld KANN durch Löschen des L-Bits weggelassen werden, was bedeutet, dass der Datensatz den gesamten Rest des Datagramms im Transport der unteren Ebene verbraucht. In diesem Fall ist es nicht möglich, mehrere DTLSCiphertext-Format-Datensätze ohne Längenfelder im selben Datagramm zu haben. Das Weglassen des Längenfelds MUSS nur für den letzten Datensatz in einem Datagramm verwendet werden. Implementierungen KÖNNEN Datensätze mit und ohne Längenfelder auf derselben Verbindung mischen.

Wenn eine Connection ID ausgehandelt wurde, dann MUSS sie in allen Datagrammen enthalten sein. Sendende Implementierungen DÜRFEN NICHT Datensätze von mehreren DTLS-Assoziationen im selben Datagramm mischen. Wenn der zweite oder spätere Datensatz eine connection ID hat, die nicht der für frühere Datensätze verwendeten Assoziation entspricht, MUSS der Rest des Datagramms verworfen werden.

Wenn erweitert, können die Epoche und Sequenznummer in eine entpackte RecordNumber-Struktur kombiniert werden, wie unten gezeigt:

struct {
uint64 epoch;
uint64 sequence_number;
} RecordNumber;

Dieser 128-Bit-Wert wird in der ACK-Nachricht sowie in der "record_sequence_number"-Eingabe zur Authenticated Encryption with Associated Data (AEAD)-Funktion verwendet. Der gesamte in Abbildung 4 gezeigte Header-Wert (aber vor der Datensatznummernverschlüsselung; siehe Abschnitt 4.2.3) wird als zusätzlicher Datenwert für die AEAD-Funktion verwendet. Zum Beispiel, wenn die minimale Variante verwendet wird, sind die assoziierten Daten (AD) 2 Oktette lang. Beachten Sie, dass sich dieses Design von der zusätzlichen Datenberechnung für DTLS 1.2 und für DTLS 1.2 mit Connection IDs unterscheidet. In DTLS 1.3 wird die 64-Bit-sequence_number als Sequenznummer für die AEAD-Berechnung verwendet; im Gegensatz zu DTLS 1.2 ist die Epoche nicht enthalten.