fix: allow for warning level TLS alerts prior to version negotiation #5646
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Goal
When a TLS alert is received prior the TLS version being negotiated (for example, the alert record was received on the client prior to the Server Hello indicating the TLS version that was agreed to), we should respect the
S2N_ALERT_IGNORE_WARNINGSsetting and allow the handshake to continue if the alert level was non-fatal.Why
Currently, s2n-tls will initialize a connection as TLS1.3. The
actual_protocol_versionisn't subsequently updated until the Server Hello is parsed. Since TLS1.3 treats all alerts as fatal, this results in s2n-tls terminating a handshake if any alert is received prior to knowing the actual TLS version that was negotiated. This means that if a server only supports TLS1.2, an s2n-tls client will still terminate a handshake if any alert is sent by that server prior to the ServerHello, despite the fact that TLS1.2 allows for warning level alerts.The TLS Working Group had an old thread discussing this issue: https://mailarchive.ietf.org/arch/msg/tls/yjzO04gmgvSCk1VzKHI6iIjw_nQ/
The thread acknowledges the ambiguity and that some clients may close the connection and others will not. Martin Thomson made the statement
Before the client has any confirmation that it is doing TLS 1.3, it has to assume that the server is any TLS version.How
Checking for
conn->actual_protocol_version_establishedwhen deciding if theS2N_ALERT_IGNORE_WARNINGSsetting should be respected.Callouts
Theoretically, a server that supports TLS1.3 could send a warning-level TLS alert prior to the server hello. According to RFC8446§6 this TLS alert should still be considered an error, though even sending such a warning-level TLS alert is not compliant with the TLS1.3 specification:
With this change, such a warning-level alert would NOT be considered an error if it comes prior to the server hello. I believe OpenSSL handles this in the same way (ie it allows for warning TLS alerts to continue the handshake despite it eventually negotiating TLS1.3). If we wanted to address this, we would have to handle additional state to recheck for any alerts after the version is negotiated, which didn't seem worth it.
Testing
Adjusted the s2n alerts unit tests and added a couple more
release summary: warning level TLS alerts may now be non-fatal prior to version negotiation
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.