Merge 4c214ce86a428e20931c035bfa6f24a38b8ca1c6 into 03e1438089654fb884ac48e0f3cd0049cfe2c102

This commit is contained in:
Joachim Bauernberger 2026-10-27 10:46:03 -04:00 committed by GitHub
commit ab0dbaddb4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 7 deletions

View File

@ -0,0 +1,13 @@
Bugfix
* In a TLS 1.3 server, protect alerts sent after the server Finished
message, such as those sent when a required client certificate is
missing or invalid, with the application traffic keys, as required by
RFC 8446 section 4.4.4. Previously these alerts were encrypted with the
handshake traffic keys, so the peer reported a MAC failure instead of
decoding the alert. Fixes #10877.
* In TLS 1.3, send the alerts described in RFC 8446 section 4.4.2.4. A
server that requires a client certificate and receives none now sends a
certificate_required alert, and a client that receives an empty server
Certificate message now sends a decode_error alert. Both previously sent
the no_certificate alert, which is reserved in TLS 1.3. Fixes #10720,
fixes #10900, fixes #10724, fixes #10884.

View File

@ -677,16 +677,14 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_SRV_C)
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
/* The client was asked for a certificate but didn't send
* one. The client should know what's going on, so we
* don't send an alert.
*/
/* No client certificate: optional auth continues, required auth
* aborts with certificate_required (RFC 8446 4.4.2.4). */
ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL) {
return 0;
} else {
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_NO_CERT,
MBEDTLS_SSL_ALERT_MSG_CERT_REQUIRED,
MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE);
return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
}
@ -698,9 +696,10 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
* certificate chain. (Last paragraph before 4.4.2.1 in RFC 8446: "The
* server's certificate_list MUST always be non-empty.") With authmode
* optional/none, we continue the handshake if we can't validate the
* server's cert, but we still break it if no certificate was sent. */
* server's cert, but we still break it if no certificate was sent.
* RFC 8446, section 4.4.2.4 requires a "decode_error" alert here. */
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_NO_CERT,
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE);
return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE;
}

View File

@ -2888,6 +2888,14 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
return ret;
}
/* RFC 8446 4.4.4: records after the server Finished use the application
* keys. Switch the outbound transform now; inbound stays on the handshake
* (or early-data) keys until the client's second flight. */
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to application keys for outbound traffic "
"( K_send = application )"));
mbedtls_ssl_set_outbound_transform(ssl, ssl->transform_application);
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->handshake->early_data_accepted) {
/* See RFC 8446 section A.2 for more information */

View File

@ -13310,7 +13310,10 @@ run_test "TLS 1.3: Server side check - mbedtls with client empty certificate"
-s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
-s "=> write certificate request" \
-s "SSL - No client certification received from the client, but required by the authentication mode" \
-s "send alert level=2 message=116" \
-c "client state: MBEDTLS_SSL_CERTIFICATE_REQUEST" \
-c "is a fatal alert message (msg 116)" \
-C "0x7180" \
-s "=> parse client hello" \
-s "<= parse client hello"