Merge cd8c304fc4cf4476b2bff783d85c85449edf9e6a into 03e1438089654fb884ac48e0f3cd0049cfe2c102

This commit is contained in:
JC-000 2026-10-27 10:46:03 -04:00 committed by GitHub
commit c05e694f37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 107 additions and 1 deletions

View File

@ -0,0 +1,5 @@
Bugfix
* Fix the TLS 1.3 client rejecting a HelloRetryRequest that contains a
cookie extension with an unsupported_extension alert. Such
HelloRetryRequests are sent for example by Java (JSSE) servers and by
OpenSSL servers in stateless mode. Fixes #9543.

View File

@ -1658,6 +1658,17 @@ int mbedtls_ssl_tls13_check_received_extension(
}
ssl->handshake->received_extensions |= extension_mask;
/*
* RFC 8446 section 4.2: the "cookie" extension in a HelloRetryRequest is
* the one extension response that may be sent although the client did
* not send the extension.
*/
if (hs_msg_type == MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST &&
received_extension_type == MBEDTLS_TLS_EXT_COOKIE) {
return 0;
}
/*
* If it is a message containing extension responses, check that we
* previously sent the extension.

View File

@ -1070,12 +1070,17 @@ is_polar() {
esac
}
# openssl s_server doesn't have -www with DTLS
# openssl s_server doesn't have -www with DTLS or with -stateless
check_osrv_dtls() {
case "$SRV_CMD" in
*s_server*-dtls*)
NEEDS_INPUT=1
SRV_CMD="$( echo $SRV_CMD | sed s/-www// )";;
*s_server*-stateless*)
# Input that s_server reads before the handshake makes it start
# the handshake without -stateless, so provide it later.
NEEDS_INPUT=2
SRV_CMD="$( echo $SRV_CMD | sed s/-www// )";;
*) NEEDS_INPUT=0;;
esac
}
@ -1086,6 +1091,10 @@ provide_input() {
return
fi
if [ $NEEDS_INPUT -eq 2 ]; then
sleep 1
fi
while true; do
echo "HTTP/1.0 200 OK"
sleep 1
@ -13665,6 +13674,23 @@ run_test "TLS 1.3 m->O HRR both with middlebox compat support" \
-c "Protocol is TLSv1.3" \
-c "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
# With -stateless, the OpenSSL server puts a cookie in its HelloRetryRequest.
# It then rejects a ChangeCipherSpec record before the second ClientHello,
# so this only works without middlebox compatibility mode on the client.
requires_openssl_tls1_3_with_compatible_ephemeral
requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
run_test "TLS 1.3 m->O HRR with cookie" \
"$O_NEXT_SRV -msg -tls1_3 -groups P-384 -stateless -num_tickets 0 -no_cache" \
"$P_CLI debug_level=4 groups=secp256r1,secp384r1" \
0 \
-c "received HelloRetryRequest message" \
-c "client hello, adding cookie extension" \
-c "Protocol is TLSv1.3" \
-c "HTTP/1.0 200 OK"
requires_gnutls_tls1_3
requires_gnutls_next_no_ticket
requires_gnutls_next_disable_tls13_compat

View File

@ -3653,3 +3653,18 @@ tls13_record_boundary_alignment:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HS_FINISHED
TLS 1.3 EndOfEarlyData record boundary alignment enforcement
depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_SESSION_TICKETS
tls13_record_boundary_alignment:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HS_END_OF_EARLY_DATA
TLS 1.3: check received extension: HRR cookie, not sent
ssl_tls13_check_received_extension:MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST:MBEDTLS_TLS_EXT_COOKIE:0:0
TLS 1.3: check received extension: HRR key_share, not sent
ssl_tls13_check_received_extension:MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST:MBEDTLS_TLS_EXT_KEY_SHARE:0:MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION
TLS 1.3: check received extension: HRR key_share, sent
ssl_tls13_check_received_extension:MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST:MBEDTLS_TLS_EXT_KEY_SHARE:1:0
TLS 1.3: check received extension: ServerHello cookie, sent
ssl_tls13_check_received_extension:MBEDTLS_SSL_HS_SERVER_HELLO:MBEDTLS_TLS_EXT_COOKIE:1:MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER
TLS 1.3: check received extension: EE cookie, not sent
ssl_tls13_check_received_extension:MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS:MBEDTLS_TLS_EXT_COOKIE:0:MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER

View File

@ -2419,6 +2419,55 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C */
void ssl_tls13_check_received_extension(int hs_msg_type,
int extension_type,
int sent,
int expected_ret)
{
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
uint32_t extension_mask = mbedtls_ssl_get_extension_mask(extension_type);
uint32_t allowed_mask = 0;
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
MD_OR_USE_PSA_INIT();
switch (hs_msg_type) {
case MBEDTLS_SSL_HS_SERVER_HELLO:
allowed_mask = MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH;
break;
case MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST:
allowed_mask = MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR;
break;
case MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS:
allowed_mask = MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE;
break;
default:
TEST_FAIL("Unsupported handshake message type");
}
TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT), 0);
TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0);
ssl.handshake->sent_extensions = sent ? extension_mask : 0;
TEST_EQUAL(mbedtls_ssl_tls13_check_received_extension(&ssl, hs_msg_type,
extension_type,
allowed_mask),
expected_ret);
exit:
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
MD_OR_USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3 */
void ssl_tls13_record_protection(int ciphersuite,
int endpoint,