Merge pull request #6945 from lpy4105/issue/6935/ticket_flags-kex-mode-determination
TLS 1.3: SRV: Check ticket_flags on kex mode determination when resumption
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 57f5f89..be0b77b 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -2800,6 +2800,26 @@
(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
}
+static inline unsigned int mbedtls_ssl_session_check_ticket_flags(
+ mbedtls_ssl_session *session, unsigned int flags)
+{
+ return mbedtls_ssl_session_get_ticket_flags(session, flags) == 0;
+}
+
+static inline unsigned int mbedtls_ssl_session_ticket_allow_psk(
+ mbedtls_ssl_session *session)
+{
+ return !mbedtls_ssl_session_check_ticket_flags(session,
+ MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION);
+}
+
+static inline unsigned int mbedtls_ssl_session_ticket_allow_psk_ephemeral(
+ mbedtls_ssl_session *session)
+{
+ return !mbedtls_ssl_session_check_ticket_flags(session,
+ MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION);
+}
+
static inline void mbedtls_ssl_session_set_ticket_flags(
mbedtls_ssl_session *session, unsigned int flags)
{
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 815c0a9..954ddff 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -94,6 +94,10 @@
#define SSL_TLS1_3_OFFERED_PSK_MATCH 0
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_check_psk_key_exchange(mbedtls_ssl_context *ssl);
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_check_psk_ephemeral_key_exchange(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_identity_match_ticket(
@@ -105,6 +109,7 @@
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *ticket_buffer;
+ unsigned int key_exchanges;
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t now;
uint64_t age_in_s;
@@ -160,13 +165,19 @@
* We regard the ticket with incompatible key exchange modes as not match.
*/
ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR;
- MBEDTLS_SSL_PRINT_TICKET_FLAGS(4,
- session->ticket_flags);
- if (mbedtls_ssl_tls13_check_kex_modes(
- ssl,
- mbedtls_ssl_session_get_ticket_flags(
- session,
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL))) {
+ MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
+
+ key_exchanges = 0;
+ if (mbedtls_ssl_session_ticket_allow_psk_ephemeral(session) &&
+ ssl_tls13_check_psk_ephemeral_key_exchange(ssl)) {
+ key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
+ }
+ if (mbedtls_ssl_session_ticket_allow_psk(session) &&
+ ssl_tls13_check_psk_key_exchange(ssl)) {
+ key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
+ }
+
+ if (key_exchanges == 0) {
MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode"));
goto exit;
}
@@ -979,6 +990,26 @@
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED */
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_ticket_permission_check(mbedtls_ssl_context *ssl,
+ unsigned int kex_mode)
+{
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ if (ssl->handshake->resume) {
+ if (mbedtls_ssl_session_check_ticket_flags(
+ ssl->session_negotiate, kex_mode)) {
+ return 0;
+ }
+ }
+#else
+ ((void) ssl);
+ ((void) kex_mode);
+#endif
+ return 1;
+}
+#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
+
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_check_ephemeral_key_exchange(mbedtls_ssl_context *ssl)
{
@@ -995,7 +1026,9 @@
static int ssl_tls13_check_psk_key_exchange(mbedtls_ssl_context *ssl)
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
- return mbedtls_ssl_conf_tls13_psk_enabled(ssl) &&
+ return ssl_tls13_ticket_permission_check(
+ ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) &&
+ mbedtls_ssl_conf_tls13_psk_enabled(ssl) &&
mbedtls_ssl_tls13_psk_enabled(ssl) &&
ssl_tls13_client_hello_has_exts_for_psk_key_exchange(ssl);
#else
@@ -1008,7 +1041,9 @@
static int ssl_tls13_check_psk_ephemeral_key_exchange(mbedtls_ssl_context *ssl)
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
- return mbedtls_ssl_conf_tls13_psk_ephemeral_enabled(ssl) &&
+ return ssl_tls13_ticket_permission_check(
+ ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) &&
+ mbedtls_ssl_conf_tls13_psk_ephemeral_enabled(ssl) &&
mbedtls_ssl_tls13_psk_ephemeral_enabled(ssl) &&
ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(ssl);
#else
@@ -1691,9 +1726,8 @@
* - The content up to but excluding the PSK extension, if present.
*/
/* If we've settled on a PSK-based exchange, parse PSK identity ext */
- if (mbedtls_ssl_tls13_some_psk_enabled(ssl) &&
- mbedtls_ssl_conf_tls13_some_psk_enabled(ssl) &&
- (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY))) {
+ if (ssl_tls13_check_psk_key_exchange(ssl) ||
+ ssl_tls13_check_psk_ephemeral_key_exchange(ssl)) {
ret = handshake->update_checksum(ssl, buf,
pre_shared_key_ext - buf);
if (0 != ret) {
diff --git a/tests/opt-testcases/tls13-kex-modes.sh b/tests/opt-testcases/tls13-kex-modes.sh
index 6556cd4..4581bc5 100755
--- a/tests/opt-testcases/tls13-kex-modes.sh
+++ b/tests/opt-testcases/tls13-kex-modes.sh
@@ -550,7 +550,7 @@
-s "found pre_shared_key extension" \
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "Pre shared key found" \
+ -S "Pre shared key found" \
-S "No matched PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
@@ -733,7 +733,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "Pre shared key found" \
+ -S "Pre shared key found" \
-S "No matched PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
@@ -1413,7 +1413,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "Pre shared key found" \
+ -S "Pre shared key found" \
-S "No matched PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh
index 3182b48..27c3453 100755
--- a/tests/opt-testcases/tls13-misc.sh
+++ b/tests/opt-testcases/tls13-misc.sh
@@ -411,7 +411,8 @@
0 \
-c "Pre-configured PSK number = 1" \
-S "No suitable key exchange mode" \
- -s "found matched identity"
+ -s "found matched identity" \
+ -s "key exchange mode: psk_ephemeral"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
@@ -423,7 +424,8 @@
0 \
-c "Pre-configured PSK number = 1" \
-S "No suitable key exchange mode" \
- -s "found matched identity"
+ -s "found matched identity" \
+ -s "key exchange mode: psk_ephemeral"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
@@ -466,7 +468,8 @@
0 \
-c "Pre-configured PSK number = 1" \
-S "No suitable key exchange mode" \
- -s "found matched identity"
+ -s "found matched identity" \
+ -s "key exchange mode: psk_ephemeral"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
@@ -479,7 +482,8 @@
0 \
-c "Pre-configured PSK number = 1" \
-S "No suitable key exchange mode" \
- -s "found matched identity"
+ -s "found matched identity" \
+ -s "key exchange mode: psk_ephemeral"
requires_gnutls_next
requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \