mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-07-30 22:43:08 +03:00
Merge pull request #6721 from yuhaoth/pr/tls13-early-data-extension-of-nst
TLS 1.3: EarlyData SRV: Write `early_data` extension of NewSessionTicket
This commit is contained in:
@ -2113,6 +2113,7 @@ int mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange(
|
|||||||
|
|
||||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||||
int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
||||||
|
int in_new_session_ticket,
|
||||||
unsigned char *buf,
|
unsigned char *buf,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
size_t *out_len);
|
size_t *out_len);
|
||||||
@ -2795,6 +2796,13 @@ static inline unsigned int mbedtls_ssl_session_ticket_allow_psk_ephemeral(
|
|||||||
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION);
|
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned int mbedtls_ssl_session_ticket_allow_early_data(
|
||||||
|
mbedtls_ssl_session *session)
|
||||||
|
{
|
||||||
|
return !mbedtls_ssl_session_check_ticket_flags(session,
|
||||||
|
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void mbedtls_ssl_session_set_ticket_flags(
|
static inline void mbedtls_ssl_session_set_ticket_flags(
|
||||||
mbedtls_ssl_session *session, unsigned int flags)
|
mbedtls_ssl_session *session, unsigned int flags)
|
||||||
{
|
{
|
||||||
|
@ -695,10 +695,8 @@ static int ssl_tls13_early_data_has_valid_ticket(mbedtls_ssl_context *ssl)
|
|||||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||||
return ssl->handshake->resume &&
|
return ssl->handshake->resume &&
|
||||||
session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
||||||
(session->ticket_flags &
|
mbedtls_ssl_session_ticket_allow_early_data(session) &&
|
||||||
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA) &&
|
mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, session->ciphersuite);
|
||||||
mbedtls_ssl_tls13_cipher_suite_is_offered(
|
|
||||||
ssl, session->ciphersuite);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1176,7 +1174,9 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
|
|||||||
if (mbedtls_ssl_conf_tls13_some_psk_enabled(ssl) &&
|
if (mbedtls_ssl_conf_tls13_some_psk_enabled(ssl) &&
|
||||||
ssl_tls13_early_data_has_valid_ticket(ssl) &&
|
ssl_tls13_early_data_has_valid_ticket(ssl) &&
|
||||||
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
|
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
|
||||||
ret = mbedtls_ssl_tls13_write_early_data_ext(ssl, p, end, &ext_len);
|
|
||||||
|
ret = mbedtls_ssl_tls13_write_early_data_ext(
|
||||||
|
ssl, 0, p, end, &ext_len);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1402,7 +1402,7 @@ cleanup:
|
|||||||
*
|
*
|
||||||
* struct {
|
* struct {
|
||||||
* select ( Handshake.msg_type ) {
|
* select ( Handshake.msg_type ) {
|
||||||
* ...
|
* case new_session_ticket: uint32 max_early_data_size;
|
||||||
* case client_hello: Empty;
|
* case client_hello: Empty;
|
||||||
* case encrypted_extensions: Empty;
|
* case encrypted_extensions: Empty;
|
||||||
* };
|
* };
|
||||||
@ -1410,20 +1410,37 @@ cleanup:
|
|||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||||
int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
||||||
|
int in_new_session_ticket,
|
||||||
unsigned char *buf,
|
unsigned char *buf,
|
||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
size_t *out_len)
|
size_t *out_len)
|
||||||
{
|
{
|
||||||
unsigned char *p = buf;
|
unsigned char *p = buf;
|
||||||
*out_len = 0;
|
|
||||||
((void) ssl);
|
|
||||||
|
|
||||||
MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
|
#if defined(MBEDTLS_SSL_SRV_C)
|
||||||
|
const size_t needed = in_new_session_ticket ? 8 : 4;
|
||||||
|
#else
|
||||||
|
const size_t needed = 4;
|
||||||
|
((void) in_new_session_ticket);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*out_len = 0;
|
||||||
|
|
||||||
|
MBEDTLS_SSL_CHK_BUF_PTR(p, end, needed);
|
||||||
|
|
||||||
MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EARLY_DATA, p, 0);
|
MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EARLY_DATA, p, 0);
|
||||||
MBEDTLS_PUT_UINT16_BE(0, p, 2);
|
MBEDTLS_PUT_UINT16_BE(needed - 4, p, 2);
|
||||||
|
|
||||||
*out_len = 4;
|
#if defined(MBEDTLS_SSL_SRV_C)
|
||||||
|
if (in_new_session_ticket) {
|
||||||
|
MBEDTLS_PUT_UINT32_BE(ssl->conf->max_early_data_size, p, 4);
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG(
|
||||||
|
4, ("Sent max_early_data_size=%u",
|
||||||
|
(unsigned int) ssl->conf->max_early_data_size));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*out_len = needed;
|
||||||
|
|
||||||
mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_EARLY_DATA);
|
mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_EARLY_DATA);
|
||||||
|
|
||||||
|
@ -1845,6 +1845,13 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mbedtls_ssl_session_ticket_allow_early_data(ssl->session_negotiate)) {
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG(
|
||||||
|
1,
|
||||||
|
("EarlyData: rejected, early_data not allowed in ticket "
|
||||||
|
"permission bits."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
|
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
|
||||||
|
|
||||||
@ -2517,7 +2524,8 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
|
|||||||
|
|
||||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||||
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
|
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
|
||||||
ret = mbedtls_ssl_tls13_write_early_data_ext(ssl, p, end, &output_len);
|
ret = mbedtls_ssl_tls13_write_early_data_ext(
|
||||||
|
ssl, 0, p, end, &output_len);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -3129,6 +3137,15 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
|
|||||||
mbedtls_ssl_session_set_ticket_flags(
|
mbedtls_ssl_session_set_ticket_flags(
|
||||||
session, ssl->handshake->tls13_kex_modes);
|
session, ssl->handshake->tls13_kex_modes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||||
|
if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED &&
|
||||||
|
ssl->conf->max_early_data_size > 0) {
|
||||||
|
mbedtls_ssl_session_set_ticket_flags(
|
||||||
|
session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||||
|
|
||||||
MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
|
MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
|
||||||
|
|
||||||
/* Generate ticket_age_add */
|
/* Generate ticket_age_add */
|
||||||
@ -3212,12 +3229,13 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
|
|||||||
* The following fields are placed inside the ticket by the
|
* The following fields are placed inside the ticket by the
|
||||||
* f_ticket_write() function:
|
* f_ticket_write() function:
|
||||||
*
|
*
|
||||||
* - creation time (start)
|
* - creation time (ticket_creation_time)
|
||||||
* - flags (flags)
|
* - flags (ticket_flags)
|
||||||
* - age add (ticket_age_add)
|
* - age add (ticket_age_add)
|
||||||
* - key (key)
|
* - key (resumption_key)
|
||||||
* - key length (key_len)
|
* - key length (resumption_key_len)
|
||||||
* - ciphersuite (ciphersuite)
|
* - ciphersuite (ciphersuite)
|
||||||
|
* - max_early_data_size (max_early_data_size)
|
||||||
*/
|
*/
|
||||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||||
static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl,
|
static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl,
|
||||||
@ -3232,6 +3250,7 @@ static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl,
|
|||||||
mbedtls_ssl_session *session = ssl->session;
|
mbedtls_ssl_session *session = ssl->session;
|
||||||
size_t ticket_len;
|
size_t ticket_len;
|
||||||
uint32_t ticket_lifetime;
|
uint32_t ticket_lifetime;
|
||||||
|
unsigned char *p_extensions_len;
|
||||||
|
|
||||||
*out_len = 0;
|
*out_len = 0;
|
||||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write NewSessionTicket msg"));
|
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write NewSessionTicket msg"));
|
||||||
@ -3293,15 +3312,35 @@ static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl,
|
|||||||
|
|
||||||
/* Ticket Extensions
|
/* Ticket Extensions
|
||||||
*
|
*
|
||||||
* Note: We currently don't have any extensions.
|
* Extension extensions<0..2^16-2>;
|
||||||
* Set length to zero.
|
|
||||||
*/
|
*/
|
||||||
ssl->handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
|
ssl->handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
|
||||||
|
|
||||||
MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
|
MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
|
||||||
MBEDTLS_PUT_UINT16_BE(0, p, 0);
|
p_extensions_len = p;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||||
|
if (mbedtls_ssl_session_ticket_allow_early_data(session)) {
|
||||||
|
size_t output_len;
|
||||||
|
|
||||||
|
if ((ret = mbedtls_ssl_tls13_write_early_data_ext(
|
||||||
|
ssl, 1, p, end, &output_len)) != 0) {
|
||||||
|
MBEDTLS_SSL_DEBUG_RET(
|
||||||
|
1, "mbedtls_ssl_tls13_write_early_data_ext", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
p += output_len;
|
||||||
|
} else {
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG(
|
||||||
|
4, ("early_data not allowed, "
|
||||||
|
"skip early_data extension in NewSessionTicket"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||||
|
|
||||||
|
MBEDTLS_PUT_UINT16_BE(p - p_extensions_len - 2, p_extensions_len, 0);
|
||||||
|
|
||||||
*out_len = p - buf;
|
*out_len = p - buf;
|
||||||
MBEDTLS_SSL_DEBUG_BUF(4, "ticket", buf, *out_len);
|
MBEDTLS_SSL_DEBUG_BUF(4, "ticket", buf, *out_len);
|
||||||
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket"));
|
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket"));
|
||||||
|
@ -556,6 +556,7 @@ int main(void)
|
|||||||
USAGE_GROUPS \
|
USAGE_GROUPS \
|
||||||
USAGE_SIG_ALGS \
|
USAGE_SIG_ALGS \
|
||||||
USAGE_KEY_OPAQUE_ALGS \
|
USAGE_KEY_OPAQUE_ALGS \
|
||||||
|
USAGE_EARLY_DATA \
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||||
|
@ -490,22 +490,6 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \
|
|||||||
EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 ))
|
EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 ))
|
||||||
EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 ))
|
EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 ))
|
||||||
|
|
||||||
requires_gnutls_next
|
|
||||||
requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \
|
|
||||||
MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
|
|
||||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
|
|
||||||
MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
|
|
||||||
requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
|
|
||||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
|
|
||||||
run_test "TLS 1.3 G->m: EarlyData: feature is disabled, fail." \
|
|
||||||
"$P_SRV force_version=tls13 debug_level=4 max_early_data_size=-1" \
|
|
||||||
"$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL -d 10 -r --earlydata $EARLY_DATA_INPUT" \
|
|
||||||
1 \
|
|
||||||
-s "ClientHello: early_data(42) extension exists." \
|
|
||||||
-s "EncryptedExtensions: early_data(42) extension does not exist." \
|
|
||||||
-s "NewSessionTicket: early_data(42) extension does not exist." \
|
|
||||||
-s "Last error was: -29056 - SSL - Verification of the message MAC failed"
|
|
||||||
|
|
||||||
requires_gnutls_next
|
requires_gnutls_next
|
||||||
requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \
|
requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \
|
||||||
MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
|
MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
|
||||||
@ -518,7 +502,8 @@ run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \
|
|||||||
"$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \
|
"$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \
|
||||||
-d 10 -r --earlydata $EARLY_DATA_INPUT " \
|
-d 10 -r --earlydata $EARLY_DATA_INPUT " \
|
||||||
0 \
|
0 \
|
||||||
|
-s "NewSessionTicket: early_data(42) extension exists." \
|
||||||
|
-s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \
|
||||||
-s "ClientHello: early_data(42) extension exists." \
|
-s "ClientHello: early_data(42) extension exists." \
|
||||||
-s "EncryptedExtensions: early_data(42) extension exists." \
|
-s "EncryptedExtensions: early_data(42) extension exists." \
|
||||||
-s "NewSessionTicket: early_data(42) extension does not exist." \
|
|
||||||
-s "$( tail -1 $EARLY_DATA_INPUT )"
|
-s "$( tail -1 $EARLY_DATA_INPUT )"
|
||||||
|
Reference in New Issue
Block a user