rfc9147.txt | rfc9147-ekr-15March2022-PM.txt | |||
---|---|---|---|---|
skipping to change at line 1140 ¶ | skipping to change at line 1140 ¶ | |||
wants to receive a CID to negotiate one. | wants to receive a CID to negotiate one. | |||
5.2. DTLS Handshake Message Format | 5.2. DTLS Handshake Message Format | |||
DTLS uses the same Handshake messages as TLS 1.3. However, prior to | DTLS uses the same Handshake messages as TLS 1.3. However, prior to | |||
transmission they are converted to DTLSHandshake messages, which | transmission they are converted to DTLSHandshake messages, which | |||
contain extra data needed to support message loss, reordering, and | contain extra data needed to support message loss, reordering, and | |||
message fragmentation. | message fragmentation. | |||
enum { | enum { | |||
hello_request_RESERVED(0), | ||||
client_hello(1), | client_hello(1), | |||
server_hello(2), | server_hello(2), | |||
hello_verify_request_RESERVED(3), | ||||
new_session_ticket(4), | new_session_ticket(4), | |||
end_of_early_data(5), | end_of_early_data(5), | |||
hello_retry_request_RESERVED(6), | ||||
encrypted_extensions(8), | encrypted_extensions(8), | |||
request_connection_id(9), /* New */ | ||||
new_connection_id(10), /* New */ | ||||
certificate(11), | certificate(11), | |||
server_key_exchange_RESERVED(12), | ||||
certificate_request(13), | certificate_request(13), | |||
server_hello_done_RESERVED(14), | ||||
certificate_verify(15), | certificate_verify(15), | |||
client_key_exchange_RESERVED(16), | ||||
finished(20), | finished(20), | |||
certificate_url_RESERVED(21), | ||||
certificate_status_RESERVED(22), | ||||
supplemental_data_RESERVED(23), | ||||
key_update(24), | key_update(24), | |||
message_hash(254), | message_hash(254), | |||
(255) | (255) | |||
} HandshakeType; | } HandshakeType; | |||
struct { | struct { | |||
HandshakeType msg_type; /* handshake type */ | HandshakeType msg_type; /* handshake type */ | |||
uint24 length; /* bytes in message */ | uint24 length; /* bytes in message */ | |||
uint16 message_seq; /* DTLS-required field */ | uint16 message_seq; /* DTLS-required field */ | |||
uint24 fragment_offset; /* DTLS-required field */ | uint24 fragment_offset; /* DTLS-required field */ | |||
uint24 fragment_length; /* DTLS-required field */ | uint24 fragment_length; /* DTLS-required field */ | |||
select (msg_type) { | select (msg_type) { | |||
case client_hello: ClientHello; | case client_hello: ClientHello; | |||
case server_hello: ServerHello; | case server_hello: ServerHello; | |||
case end_of_early_data: EndOfEarlyData; | case end_of_early_data: EndOfEarlyData; | |||
case new_session_ticket: NewSessionTicket; | ||||
case encrypted_extensions: EncryptedExtensions; | case encrypted_extensions: EncryptedExtensions; | |||
case request_connection_id: RequestedConnectionId; | ||||
case new_connection_id: NewConnectionId; | ||||
case certificate: Certificate; | ||||
case certificate_request: CertificateRequest; | case certificate_request: CertificateRequest; | |||
case certificate: Certificate; | ||||
case certificate_verify: CertificateVerify; | case certificate_verify: CertificateVerify; | |||
case finished: Finished; | case finished: Finished; | |||
case new_session_ticket: NewSessionTicket; | ||||
case key_update: KeyUpdate; | case key_update: KeyUpdate; | |||
case request_connection_id: RequestConnectionId; | ||||
case new_connection_id: NewConnectionId; | ||||
} body; | } body; | |||
} DTLSHandshake; | } DTLSHandshake; | |||
In DTLS 1.3, the message transcript is computed over the original TLS | In DTLS 1.3, the message transcript is computed over the original TLS | |||
1.3-style Handshake messages without the message_seq, | 1.3-style Handshake messages without the message_seq, | |||
fragment_offset, and fragment_length values. Note that this is a | fragment_offset, and fragment_length values. Note that this is a | |||
change from DTLS 1.2 where those values were included in the | change from DTLS 1.2 where those values were included in the | |||
transcript. | transcript. | |||
The first message each side transmits in each association always has | The first message each side transmits in each association always has | |||
skipping to change at line 1750 ¶ | skipping to change at line 1743 ¶ | |||
occur in the context of a handshake. However, a DTLS implementation | occur in the context of a handshake. However, a DTLS implementation | |||
which would ordinarily issue an alert SHOULD generate a new alert | which would ordinarily issue an alert SHOULD generate a new alert | |||
message if the offending record is received again (e.g., as a | message if the offending record is received again (e.g., as a | |||
retransmitted handshake message). Implementations SHOULD detect when | retransmitted handshake message). Implementations SHOULD detect when | |||
a peer is persistently sending bad messages and terminate the local | a peer is persistently sending bad messages and terminate the local | |||
connection state after such misbehavior is detected. Note that | connection state after such misbehavior is detected. Note that | |||
alerts are not reliably transmitted; implementations SHOULD NOT | alerts are not reliably transmitted; implementations SHOULD NOT | |||
depend on receiving alerts in order to signal errors or connection | depend on receiving alerts in order to signal errors or connection | |||
closure. | closure. | |||
Any data received with an epoch/sequence number pair after that of a | ||||
valid received closure alert MUST be ignored. Note: this is a change | ||||
from TLS 1.3 which depends on the order of receipt rather than the | ||||
epoch and sequence number. | ||||
5.11. Establishing New Associations with Existing Parameters | 5.11. Establishing New Associations with Existing Parameters | |||
If a DTLS client-server pair is configured in such a way that | If a DTLS client-server pair is configured in such a way that | |||
repeated connections happen on the same host/port quartet, then it is | repeated connections happen on the same host/port quartet, then it is | |||
possible that a client will silently abandon one connection and then | possible that a client will silently abandon one connection and then | |||
initiate another with the same parameters (e.g., after a reboot). | initiate another with the same parameters (e.g., after a reboot). | |||
This will appear to the server as a new handshake with epoch=0. In | This will appear to the server as a new handshake with epoch=0. In | |||
cases where a server believes it has an existing association on a | cases where a server believes it has an existing association on a | |||
given host/port quartet and it receives an epoch=0 ClientHello, it | given host/port quartet and it receives an epoch=0 ClientHello, it | |||
SHOULD proceed with a new handshake but MUST NOT destroy the existing | SHOULD proceed with a new handshake but MUST NOT destroy the existing | |||
skipping to change at line 2201 ¶ | skipping to change at line 2199 ¶ | |||
With a 128-bit key as in AES-128, rekeying 2^64 times has a high | With a 128-bit key as in AES-128, rekeying 2^64 times has a high | |||
probability of key reuse within a given connection. Note that even | probability of key reuse within a given connection. Note that even | |||
if the key repeats, the IV is also independently generated. In order | if the key repeats, the IV is also independently generated. In order | |||
to provide an extra margin of security, sending implementations MUST | to provide an extra margin of security, sending implementations MUST | |||
NOT allow the epoch to exceed 2^48-1. In order to allow this value | NOT allow the epoch to exceed 2^48-1. In order to allow this value | |||
to be changed later, receiving implementations MUST NOT enforce this | to be changed later, receiving implementations MUST NOT enforce this | |||
rule. If a sending implementation receives a KeyUpdate with | rule. If a sending implementation receives a KeyUpdate with | |||
request_update set to "update_requested", it MUST NOT send its own | request_update set to "update_requested", it MUST NOT send its own | |||
KeyUpdate if that would cause it to exceed these limits and SHOULD | KeyUpdate if that would cause it to exceed these limits and SHOULD | |||
instead ignore the "update_requested" flag. | instead ignore the "update_requested" flag. Note: this overrides the | |||
requirement in TLS 1.3 to always send a KeyUpdate in response to | ||||
"update_requested". | ||||
9. Connection ID Updates | 9. Connection ID Updates | |||
If the client and server have negotiated the "connection_id" | If the client and server have negotiated the "connection_id" | |||
extension [RFC9146], either side can send a new CID that it wishes | extension [RFC9146], either side can send a new CID that it wishes | |||
the other side to use in a NewConnectionId message. | the other side to use in a NewConnectionId message. | |||
enum { | enum { | |||
cid_immediate(0), cid_spare(1), (255) | cid_immediate(0), cid_spare(1), (255) | |||
} ConnectionIdUsage; | } ConnectionIdUsage; | |||
skipping to change at line 2330 ¶ | skipping to change at line 2330 ¶ | |||
Application data messages are carried by the record layer and are | Application data messages are carried by the record layer and are | |||
split into records and encrypted based on the current connection | split into records and encrypted based on the current connection | |||
state. The messages are treated as transparent data to the record | state. The messages are treated as transparent data to the record | |||
layer. | layer. | |||
11. Security Considerations | 11. Security Considerations | |||
Security issues are discussed primarily in [TLS13]. | Security issues are discussed primarily in [TLS13]. | |||
Security issues are also discussed in RFC 7457 [RFC7457]. | ||||
The primary additional security consideration raised by DTLS is that | The primary additional security consideration raised by DTLS is that | |||
of denial of service by excessive resource consumption. DTLS | of denial of service by excessive resource consumption. DTLS | |||
includes a cookie exchange designed to protect against denial of | includes a cookie exchange designed to protect against denial of | |||
service. However, implementations that do not use this cookie | service. However, implementations that do not use this cookie | |||
exchange are still vulnerable to DoS. In particular, DTLS servers | exchange are still vulnerable to DoS. In particular, DTLS servers | |||
that do not use the cookie exchange may be used as attack amplifiers | that do not use the cookie exchange may be used as attack amplifiers | |||
even if they themselves are not experiencing DoS. Therefore, DTLS | even if they themselves are not experiencing DoS. Therefore, DTLS | |||
servers SHOULD use the cookie exchange unless there is good reason to | servers SHOULD use the cookie exchange unless there is good reason to | |||
believe that amplification is not a threat in their environment. | believe that amplification is not a threat in their environment. | |||
Clients MUST be prepared to do a cookie exchange with every | Clients MUST be prepared to do a cookie exchange with every | |||
skipping to change at line 2379 ¶ | skipping to change at line 2377 ¶ | |||
the cookie-generation key on a similar timescale would ensure that | the cookie-generation key on a similar timescale would ensure that | |||
the key rotation functionality is exercised regularly and thus in | the key rotation functionality is exercised regularly and thus in | |||
working order. | working order. | |||
The cookie exchange provides address validation during the initial | The cookie exchange provides address validation during the initial | |||
handshake. DTLS with Connection IDs allows for endpoint addresses to | handshake. DTLS with Connection IDs allows for endpoint addresses to | |||
change during the association; any such updated addresses are not | change during the association; any such updated addresses are not | |||
covered by the cookie exchange during the handshake. DTLS | covered by the cookie exchange during the handshake. DTLS | |||
implementations MUST NOT update the address they send to in response | implementations MUST NOT update the address they send to in response | |||
to packets from a different address unless they first perform some | to packets from a different address unless they first perform some | |||
reachability test; no such test is defined in this specification. | reachability test; no such test is defined in this specification and | |||
Even with such a test, an active on-path adversary can also black- | a future specification would need to specify a complete procedure for | |||
hole traffic or create a reflection attack against third parties | how and when to update addresses. Even with such a test, an active | |||
because a DTLS peer has no means to distinguish a genuine address | on-path adversary can also black-hole traffic or create a reflection | |||
update event (for example, due to a NAT rebinding) from one that is | attack against third parties because a DTLS peer has no means to | |||
malicious. This attack is of concern when there is a large asymmetry | distinguish a genuine address update event (for example, due to a NAT | |||
of request/response message sizes. | rebinding) from one that is malicious. This attack is of concern | |||
when there is a large asymmetry of request/response message sizes. | ||||
With the exception of order protection and non-replayability, the | With the exception of order protection and non-replayability, the | |||
security guarantees for DTLS 1.3 are the same as TLS 1.3. While TLS | security guarantees for DTLS 1.3 are the same as TLS 1.3. While TLS | |||
always provides order protection and non-replayability, DTLS does not | always provides order protection and non-replayability, DTLS does not | |||
provide order protection and may not provide replay protection. | provide order protection and may not provide replay protection. | |||
Unlike TLS implementations, DTLS implementations SHOULD NOT respond | Unlike TLS implementations, DTLS implementations SHOULD NOT respond | |||
to invalid records by terminating the connection. | to invalid records by terminating the connection. | |||
TLS 1.3 requires replay protection for 0-RTT data (or rather, for | TLS 1.3 requires replay protection for 0-RTT data (or rather, for | |||
skipping to change at line 2769 ¶ | skipping to change at line 2768 ¶ | |||
| negotiated) | S - Sequence number length | | negotiated) | S - Sequence number length | |||
+-+-+-+-+-+-+-+-+ L - Length present | +-+-+-+-+-+-+-+-+ L - Length present | |||
| 8 or 16 bit | E - Epoch | | 8 or 16 bit | E - Epoch | |||
|Sequence Number| | |Sequence Number| | |||
+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+ | |||
| 16 bit Length | | | 16 bit Length | | |||
| (if present) | | | (if present) | | |||
+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+ | |||
struct { | struct { | |||
uint16 epoch; | uint64 epoch; | |||
uint48 sequence_number; | uint64 sequence_number; | |||
} RecordNumber; | } RecordNumber; | |||
A.2. Handshake Protocol | A.2. Handshake Protocol | |||
enum { | enum { | |||
hello_request_RESERVED(0), | hello_request_RESERVED(0), | |||
client_hello(1), | client_hello(1), | |||
server_hello(2), | server_hello(2), | |||
hello_verify_request_RESERVED(3), | hello_verify_request_RESERVED(3), | |||
new_session_ticket(4), | new_session_ticket(4), | |||
end_of_early_data(5), | end_of_early_data(5), | |||
hello_retry_request_RESERVED(6), | hello_retry_request_RESERVED(6), | |||
encrypted_extensions(8), | encrypted_extensions(8), | |||
request_connection_id(9), /* New */ | ||||
new_connection_id(10), /* New */ | ||||
certificate(11), | certificate(11), | |||
server_key_exchange_RESERVED(12), | server_key_exchange_RESERVED(12), | |||
certificate_request(13), | certificate_request(13), | |||
server_hello_done_RESERVED(14), | server_hello_done_RESERVED(14), | |||
certificate_verify(15), | certificate_verify(15), | |||
client_key_exchange_RESERVED(16), | client_key_exchange_RESERVED(16), | |||
finished(20), | finished(20), | |||
certificate_url_RESERVED(21), | certificate_url_RESERVED(21), | |||
certificate_status_RESERVED(22), | certificate_status_RESERVED(22), | |||
supplemental_data_RESERVED(23), | supplemental_data_RESERVED(23), | |||
skipping to change at line 2816 ¶ | skipping to change at line 2817 ¶ | |||
case client_hello: ClientHello; | case client_hello: ClientHello; | |||
case server_hello: ServerHello; | case server_hello: ServerHello; | |||
case end_of_early_data: EndOfEarlyData; | case end_of_early_data: EndOfEarlyData; | |||
case encrypted_extensions: EncryptedExtensions; | case encrypted_extensions: EncryptedExtensions; | |||
case certificate_request: CertificateRequest; | case certificate_request: CertificateRequest; | |||
case certificate: Certificate; | case certificate: Certificate; | |||
case certificate_verify: CertificateVerify; | case certificate_verify: CertificateVerify; | |||
case finished: Finished; | case finished: Finished; | |||
case new_session_ticket: NewSessionTicket; | case new_session_ticket: NewSessionTicket; | |||
case key_update: KeyUpdate; | case key_update: KeyUpdate; | |||
case request_connection_id: RequestConnectionId; | ||||
case new_connection_id: NewConnectionId; | ||||
} body; | } body; | |||
} Handshake; | } Handshake; | |||
uint16 ProtocolVersion; | uint16 ProtocolVersion; | |||
opaque Random[32]; | opaque Random[32]; | |||
uint8 CipherSuite[2]; /* Cryptographic suite selector */ | uint8 CipherSuite[2]; /* Cryptographic suite selector */ | |||
struct { | struct { | |||
ProtocolVersion legacy_version = { 254,253 }; // DTLSv1.2 | ProtocolVersion legacy_version = { 254,253 }; // DTLSv1.2 | |||
End of changes. 20 change blocks. | ||||
25 lines changed or deleted | 28 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |