TLS-RFC Compliance
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 3.7.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] GnuTLS accepts session resumption via session IDs even if the previous session has been terminated by a fatal alert
- RFC 5246 - 7.2.2 Error Alerts
Thus, any connection terminated with a fatal alert MUST NOT be resumed.
- RFC 5246 - 7.2.2 Error Alerts
-
[S] GnuTLS server enforces that a TLS 1.3 client sends a key share for the first mutually supported group within the supported groups extension. As an example if a client offers secp521r1 and secp256r1 (in this order) but sends a key share for secp256r1, GnuTLS sends a HelloRetryRequest demanding a secp521r1 key share.
-
[C] GnuTLS seems to struggle with very small records, i.e records with a fragment length of 1, when a HelloRetryRequest is sent.
- These records yield a 'decode error' and GnuTLS prints "Fatal error: Error decoding the received TLS packet."
-
[C] GnuTLS does not ignore the legacy version field in a ServerHello that negotiates TLS 1.3 and aborts the handshake for invalid values like 0x0304 or 0x0505
- 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.
- Note that the RFC also defines that a server MUST use 0x0303 as the legacy version but specifically says that the client MUST ignore the field when SupportedVersions has been received
- RFC 8446 - 4.2.1 Supported Versions
-
[C+S] When encrypt-then-MAC is negotiated, GnuTLS does not validate the padding bytes
Session not aborted
-
[S] upon receiving a ClientHello with an unsolicited 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
-
[S] upon receiving a ClientHello proposing TLS 1.3 which does not use 0x0303 for the legacy version field
- 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
-
[C] upon receiving a ClientHello message interleaved with a warning alert
- Note that this only applies if no HelloRetryRequest has been sent by the server. If a server sends an HRR and interleaves the subsequent ServerHello, GnuTLS closes the connection without an alert.
- 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.
-
[C] upon receiving a TLS 1.3 HelloRetryRequest that does not result in any changes for the subsequent ClientHello
- RFC 8446 - 4.1.4 Hello Retry Request
Clients MUST abort the handshake with an "illegal_parameter" alert if the HelloRetryRequest would not result in any change in the ClientHello.
- RFC 8446 - 4.1.4 Hello Retry Request
-
[C] upon receiving a TLS 1.3 HelloRetryRequest that selects an unproposed or TLS 1.2 cipher suite
- Note that it is not possible to actually negotiate this cipher suite with a subsequent ServerHello
- 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
-
[C+S] upon receiving a ChangeCipherSpec message with an invalid content (such as 0x7D) as long as this content consists of one byte
- RFC 5246 - 7.1 Change Cipher Spec Protocol
The message consists of a single byte of value 1.
- RFC 5246 - 7.1 Change Cipher Spec Protocol
-
[C] when a server chooses a non-CBC cipher suite but negotiates encrypt-then-MAC
- RFC 7366 - 3. Applying Encrypt-then-MAC
If a server receives an encrypt-then-MAC request extension from a client and then selects a stream or Authenticated Encryption with Associated Data (AEAD) ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the client.
- RFC 7366 - 3. Applying Encrypt-then-MAC
-
[C] upon receiving a GREASE extension as part of a ServerHello, HelloRetryRequest, or EncryptedExtensions message
- Note that this is likely caused by an unknown extension type, not a specific GREASE value
- RFC 9701 - 3.1. Client Behavior
In particular, the client MUST fail the connection if a GREASE value appears in any of the following: [...] Any ServerHello extension, [...] Any EncryptedExtensions extension
- In general a client MUST reject such an extension if it wasn't proposed
-
[C] upon receiving a forbidden extension in the EncryptedExtensions message (specifically tested with Padding extension)
- RFC 8446 - 4.3.1 Encrypted Extensions
The client MUST check EncryptedExtensions for the presence of any forbidden extensions and if any are found MUST abort the handshake with an "illegal_parameter" alert.
- RFC 8446 - 4.3.1 Encrypted Extensions
-
[C] upon receiving a ServerHello negotiating TLS 1.3 that does not echo the empty session ID sent by GnuTLS
- 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
-
[S] upon receiving a Padding extension that contains bytes other 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.
-
[S] upon receiving a SupportedPointFormat extension that only accepts compressed points or an invalid format
- 8422 - 5.1. Client Hello Extensions
If the client sends the extension and the extension does not contain the uncompressed point format, and the client has used the Supported Groups extension to indicate support for any of the curves defined in this specification, then the server MUST abort the handshake and return an illegal_parameter alert.
- 8422 - 5.1. Client Hello Extensions
Only session closed but no alert sent
-
[C] upon receiving a record with an invalid MAC / AEAD tag or with an invalid padding (for CBC cipher suites)
-
[C] upon receiving a record without any content
-
[C] upon receiving a record that exceeds the maximum ciphertext or plaintext fragment length
-
[C] upon receiving an encrypted legacy ChangeCipherSpec message or an unprotected ChangeCipherSpec after a completed handshake in a TLS 1.3 session
Different alert sent than defined by the RFC
-
[S] upon receiving a ClientHello proposing TLS 1.3 without a SignatureAlgorithms extension. GnuTLS sends a 'handshake failure' alert.
- 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
-
[C] upon receiving a ServerHello that negotiates TLS 1.3 and selects an unproposed cipher suite. GnuTLS sends a 'handshake failure' alert.
- RFC 8446 - 4.1.3 Server Hello
A client which receives a cipher suite that was not offered MUST abort the handshake with an "illegal_parameter" alert.
- RFC 8446 - 4.1.3 Server Hello
-
[C] upon receiving an EncryptedExtensions message that contains a SupportedVersions extension. GnuTLS sends an 'unsupported extension' alert.
- RFC 8446 - 4.3.1 Encrypted Extensions
The client MUST check EncryptedExtensions for the presence of any forbidden extensions and if any are found MUST abort the handshake with an "illegal_parameter" alert.
- RFC 8446 - 4.3.1 Encrypted Extensions
-
[C+S] upon receiving a 'close notify' alert during the handshake. GnuTLS sends an 'internal error'
- This may be a corner case due to the uncompleted handshake
- RFC 5246 7.2.1 Closure Alerts
The other party MUST respond with a close_notify alert of its own and close down the connection immediately, discarding any pending writes.
-
[S] upon receiving a record with the undefined record content type 0xff at the beginning of the handshake, GnuTLS responds with a 'record overflow' alert
- Note that this may be related to legacy SSL2 parsing code
- RFC 8446 - 5. Record Protocol
If a TLS implementation receives an unexpected record type, it MUST terminate the connection with an "unexpected_message" alert.