TLS-RFC Compliance (TLS-Anvil)
Hi, we (@jurajsomorovsky @ic0ns @mmaehren @XoMEX @Kavakuo) are performing an analysis of the RFC-compliance of open-source TLS implementations. Below we list our findings for this implementation. We admit that some are rather nit-picky, but we added them for the sake of completeness. We tried to keep the descriptions brief and didn’t want to spam the issues section so feel free to split up the list into individual issues as you see fit. If you disagree with our interpretation of certain RFC statements, please leave feedback as we’re interested in your view.
Our results apply to the default configuration of version 0.19.0. We used the example implementations for client and server.
[S] = Applies to server [C] = Applies to client [C+S] = Applies to both
Misc
[S] RusTLS won't complete the handshake if a client offers only ECC cipher suites and groups but does not send an EcPointFormatsExtension
- RFC 8422 - 5.1. Client Hello Extensions
A server that receives a ClientHello containing one or both of these [Supported Point Formats and Supported Elliptic Curves] extensions MUST use the client's enumerated capabilities to guide its selection of an appropriate cipher suite.
- Note that the RFC defines that a client must send the extension but also specifically says that the server must not enforce this
- RFC 8422 - 5.1. Client Hello Extensions
[C] RusTLS does not ignore the server's legacy version set in the ServerHello when a SupportedVersions extension was sent but terminates the handshake upon parsing an invalid version (0x0505)
- Note that the RFC also demands that a server 'MUST' set the version to 0303 but a client is supposed to ignore the version
- RFC 8446 - 4.2.1 Supported Versions
If this extension is present, clients MUST ignore the ServerHello.legacy_version value and MUST use only the "supported_versions" extension to determine the selected version.
[C+S] RusTLS accepts zero-length handshakes fragments sent before the record containing the Finished message
- RFC 8446 - 6.2.1 Fragmentation
Implementations MUST NOT send zero-length fragments of Handshake, Alert, or ChangeCipherSpec content types. Zero-length fragments of Application data MAY be sent as they are potentially useful as a traffic analysis countermeasure.
- RFC 8446 - 6.2.1 Fragmentation
[C] Upon receiving an encrypted Finished message that was not preceded by a Change Cipher Spec, RusTLS does not reject the record based on its content type but attempts to parse the payload as an unencrypted message. For records with random IVs at the beginning, RusTLS assumes that the contained message is larger than the record (due to the seemingly high message length which, in fact, are just IV bytes). RusTLS therefore waits for more records.
- The record should be rejected based on its content type or (if a NewSessionTicket message is expected) based on the first byte parsed as the handshake message type
Session not aborted
[S] upon receiving a ClientHello with an unsolicited TLS 1.3 Cookie extension
- RFC 8446 - 4.2.2 Cookie
Clients MUST NOT use cookies in their initial ClientHello in subsequent connections.
- RFC 8446 - 4.2.2 Cookie
[C] upon receiving a ServerHello that negotiates TLS 1.3 but does not echo the client's session ID
- RFC 8446 - 4.1.3 Server Hello
A client which receives a legacy_session_id_echo field that does not match what it sent in the ClientHello MUST abort the handshake with an "illegal_parameter" alert.
- RFC 8446 - 4.1.3 Server Hello
[C] upon receiving a HelloRetryRequest that negotiates an unproposed cipher suite
- RFC 8446 - 4.1.4 Hello Retry Request
Upon receipt of a HelloRetryRequest, the client MUST check the legacy_version, legacy_session_id_echo, cipher_suite, and legacy_compression_method as specified in Section 4.1.3
- RFC 8446 - 4.1.4 Hello Retry Request
[C+S] upon receiving interleaved handshake messages
- Our test interleaves the ServerHello with a warning alert with varying alert descriptions, RusTLS does not terminate the session upon receiving these records if no HelloRetryRequest was sent before or if the alert description 'User Canceled' is used
- Note that when a HRR was sent by the server, the actual ServerHello sent later on is interleaved
- RFC 8446 - 5.1. Record Layer
Handshake messages MUST NOT be interleaved with other record types. That is, if a handshake message is split over two or more records, there MUST NOT be any other records between them.
[S] upon receiving an extension with an invalid combination of lengthfields that results in unprocessed bytes
- Example: a PreSharedKeyExchangeModes extension with a length of 3, followed by the list-lengthfield with a length of 1, followed by 2 key exchange modes. RusTLS ignores that there is a discrepancy between the lengthfields as the last byte is not covered by the list-lengthfield
[S] upon receiving a ClientHello that proposes TLS 1.3 but uses a legacy version other than 0x0303
- RFC 8446 - 4.1.2 Client Hello
In TLS 1.3, the client indicates its version preferences in the "supported_versions" extension (Section 4.2.1) and the legacy_version field MUST be set to 0x0303, which is the version number for TLS 1.2.
- RFC 8446 - 4.1.2 Client Hello
[S] upon receiving a Padding extension that contains other bytes than 0x00
- Please leave a comment if your implementation does not support this extension and hence ignores the content
- RFC 7685 - 3. Padding Extension
The client MUST fill the padding extension completely with zero bytes, although the padding extension_data field may be empty.
Only session closed but no alert sent
[C] upon a parsing error caused by invalid lengthfields within the messages (e.g reduce the length by one so the message can't be processed entirely and a trailing byte is left unprocessed)
[C+S] upon receiving a record with an invalid AEAD tag/ciphertext
[C+S] upon receiving a ChangeCipherSpec message with invalid content (content is not 0x01)
[C] upon receiving an invalid Finished message
[C+S] upon receiving empty (length = 0) Application, Handshake or ChangeCipherSpec records
[C] upon receiving a record whose plaintext or ciphertext poses a record overflow
[C] when a peer omits the ChangeCipherSpec message
[C+S] upon receiving an unexpected record content type
[C+S] upon receiving a Close Notify (a Close Notify should be returned)
[C] upon receiving a ServerHello that selects a version/compression method/cipher suite that is not supported/has not been offered by RusTLS
[C] upon receiving a ServerHello that contains an extension that was not offered by RusTLS
[C] upon receiving an invalid ServerKeyExchangeMessage (invalid algorithm/signature/key share)
[C] upon receiving a message from the server that negotiates a GREASE value (probably not caused by GREASE but rather relates to one of the other cases)
[C] upon receiving a message out of the expected order
[C] upon receiving an empty TLS 1.3 Certificate message
[C] upon receiving an invalid TLS 1.3 CertificateVerify message (invalid algorithm/signature)
[C] upon receiving an EncryptedExtensions message that contains forbidden extensions
[C] upon receiving an invalid HelloRetryRequest(invalid cipher suite/named group/structure or duplicate HRR)
[C] upon receiving a KeyShare extension with an invalid selected named group
[C] upon receiving a PreSharedKeyExchangeModes extension in a ServerHello
[C] upon receiving a TLS 1.2 ServerHello that signals a version downgrade through the random value
[C] upon receiving a SupportedVersions extension with invalid content
Different alert sent than defined by the RFC
- [S] upon receiving a ClientHello proposing TLS 1.3 without a SignatureAlgorithms extension. RusTLS sends a 'handshake failure'
- RFC 8446 - 4.2.3 Signature Algorithms
If a server is authenticating via a certificate and the client has not sent a "signature_algorithms" extension, then the server MUST abort the handshake with a "missing_extension" alert (see Section 9.2).
- RFC 8446 - 4.2.3 Signature Algorithms
Source: rustls/rustls