Skip to content

Commit

Permalink
Merge pull request Mbed-TLS#6180 from yuhaoth/pr/add-tls13-multiple-s…
Browse files Browse the repository at this point in the history
…ession-tickets
  • Loading branch information
yuhaoth committed Nov 27, 2022
2 parents 5ceb6c9 + 2c282c9 commit 0e6d7e8
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 23 deletions.
10 changes: 10 additions & 0 deletions include/mbedtls/mbedtls_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,16 @@
*/
#define MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH 32

/**
* \def MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS
*
* Default number of NewSessionTicket messages to be sent by a TLS 1.3 server
* after handshake completion. This is not used in TLS 1.2 and relevant only if
* the MBEDTLS_SSL_SESSION_TICKETS option is enabled.
*
*/
#define MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS 1

/**
* \def MBEDTLS_SSL_PROTO_DTLS
*
Expand Down
45 changes: 40 additions & 5 deletions include/mbedtls/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1414,10 +1414,17 @@ struct mbedtls_ssl_config
#if defined(MBEDTLS_SSL_RENEGOTIATION)
uint8_t MBEDTLS_PRIVATE(disable_renegotiation); /*!< disable renegotiation? */
#endif
#if ( ( defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) ) || \
( defined(MBEDTLS_SSL_NEW_SESSION_TICKET_REMOVED) ) )
uint8_t MBEDTLS_PRIVATE(session_tickets); /*!< use session tickets? */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_CLI_C)
uint8_t MBEDTLS_PRIVATE(session_tickets); /*!< use session tickets? */
#endif

#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_SRV_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_3)
uint16_t MBEDTLS_PRIVATE(new_session_tickets_count); /*!< number of NewSessionTicket */
#endif

#if defined(MBEDTLS_SSL_SRV_C)
uint8_t MBEDTLS_PRIVATE(cert_req_ca_list); /*!< enable sending CA list in
Certificate Request messages? */
Expand Down Expand Up @@ -4366,7 +4373,8 @@ int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_c
void mbedtls_ssl_conf_preference_order( mbedtls_ssl_config *conf, int order );
#endif /* MBEDTLS_SSL_SRV_C */

#if ( defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) ) || defined(MBEDTLS_SSL_NEW_SESSION_TICKET_REMOVED)
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_CLI_C)
/**
* \brief Enable / Disable session tickets (client only).
* (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.)
Expand All @@ -4378,7 +4386,34 @@ void mbedtls_ssl_conf_preference_order( mbedtls_ssl_config *conf, int order );
* MBEDTLS_SSL_SESSION_TICKETS_DISABLED)
*/
void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets );
#endif /* ( MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C ) || MBEDTLS_SSL_NEW_SESSION_TICKET_REMOVED */
#endif /* MBEDTLS_SSL_SESSION_TICKETS &&
MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_SRV_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_3)
/**
* \brief Number of NewSessionTicket messages for the server to send
* after handshake completion.
*
* \note The default value is
* \c MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS.
*
* \note In case of a session resumption, this setting only partially apply.
* At most one ticket is sent in that case to just renew the pool of
* tickets of the client. The rationale is to avoid the number of
* tickets on the server to become rapidly out of control when the
* server has the same configuration for all its connection instances.
*
* \param conf SSL configuration
* \param num_tickets Number of NewSessionTicket.
*
*/
void mbedtls_ssl_conf_new_session_tickets( mbedtls_ssl_config *conf,
uint16_t num_tickets );
#endif /* MBEDTLS_SSL_SESSION_TICKETS &&
MBEDTLS_SSL_SRV_C &&
MBEDTLS_SSL_PROTO_TLS1_3*/

#if defined(MBEDTLS_SSL_RENEGOTIATION)
/**
Expand Down
3 changes: 3 additions & 0 deletions library/ssl_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,9 @@ struct mbedtls_ssl_handshake_params
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
uint8_t tls13_kex_modes; /*!< Key exchange modes supported by the client */
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
uint16_t new_session_tickets_count; /*!< number of session tickets */
#endif
#endif /* MBEDTLS_SSL_SRV_C */

#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
Expand Down
20 changes: 20 additions & 0 deletions library/ssl_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,13 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
mbedtls_ssl_transform_init( ssl->transform_negotiate );
#endif

#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
defined(MBEDTLS_SSL_SRV_C) && \
defined(MBEDTLS_SSL_SESSION_TICKETS)
ssl->handshake->new_session_tickets_count =
ssl->conf->new_session_tickets_count ;
#endif

#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
Expand Down Expand Up @@ -2873,6 +2880,15 @@ void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets
#endif

#if defined(MBEDTLS_SSL_SRV_C)

#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
void mbedtls_ssl_conf_new_session_tickets( mbedtls_ssl_config *conf,
uint16_t num_tickets )
{
conf->new_session_tickets_count = num_tickets;
}
#endif

void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_ticket_write_t *f_ticket_write,
mbedtls_ssl_ticket_parse_t *f_ticket_parse,
Expand Down Expand Up @@ -5017,6 +5033,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
#endif

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
mbedtls_ssl_conf_new_session_tickets(
conf, MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS );
#endif
/*
* Allow all TLS 1.3 key exchange modes by default.
*/
Expand Down
33 changes: 30 additions & 3 deletions library/ssl_tls13_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -3514,7 +3514,21 @@ static int ssl_tls13_write_new_session_ticket_coordinate( mbedtls_ssl_context *s
/* Check whether the use of session tickets is enabled */
if( ssl->conf->f_ticket_write == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "new session ticket is not enabled" ) );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "NewSessionTicket: disabled,"
" callback is not set" ) );
return( SSL_NEW_SESSION_TICKET_SKIP );
}
if( ssl->conf->new_session_tickets_count == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "NewSessionTicket: disabled,"
" configured count is zero" ) );
return( SSL_NEW_SESSION_TICKET_SKIP );
}

if( ssl->handshake->new_session_tickets_count == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "NewSessionTicket: all tickets have "
"been sent." ) );
return( SSL_NEW_SESSION_TICKET_SKIP );
}

Expand Down Expand Up @@ -3747,6 +3761,15 @@ static int ssl_tls13_write_new_session_ticket( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg(
ssl, buf_len, msg_len ) );

/* Limit session tickets count to one when resumption connection.
*
* See document of mbedtls_ssl_conf_new_session_tickets.
*/
if( ssl->handshake->resume == 1 )
ssl->handshake->new_session_tickets_count = 0;
else
ssl->handshake->new_session_tickets_count--;

mbedtls_ssl_handshake_set_state( ssl,
MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH );
}
Expand Down Expand Up @@ -3911,7 +3934,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
ret = ssl_tls13_handshake_wrapup( ssl );
break;

/* ----- READ CLIENT CERTIFICATE ----*/

case MBEDTLS_SSL_CLIENT_CERTIFICATE:
Expand Down Expand Up @@ -3965,7 +3988,11 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
ret = mbedtls_ssl_flush_output( ssl );
if( ret != 0 )
return( ret );
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER );

if( ssl->handshake->new_session_tickets_count == 0 )
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER );
else
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_NEW_SESSION_TICKET );
break;

#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Expand Down
9 changes: 6 additions & 3 deletions programs/ssl/ssl_client2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1186,7 +1186,7 @@ int main( int argc, char *argv[] )
else if( strcmp( p, "tickets" ) == 0 )
{
opt.tickets = atoi( q );
if( opt.tickets < 0 || opt.tickets > 1 )
if( opt.tickets < 0 )
goto usage;
}
else if( strcmp( p, "alpn" ) == 0 )
Expand Down Expand Up @@ -2824,6 +2824,9 @@ int main( int argc, char *argv[] )
*/
if( opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM )
{
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
int ticket_id = 0;
#endif
do
{
len = sizeof( buf ) - 1;
Expand Down Expand Up @@ -2876,7 +2879,8 @@ int main( int argc, char *argv[] )
case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET:
/* We were waiting for application data but got
* a NewSessionTicket instead. */
mbedtls_printf( " got new session ticket.\n" );
mbedtls_printf( " got new session ticket ( %d ).\n",
ticket_id++ );
if( opt.reconnect != 0 )
{
mbedtls_printf(" . Saving session for reuse..." );
Expand Down Expand Up @@ -2910,7 +2914,6 @@ int main( int argc, char *argv[] )
(unsigned) session_data_len );
}
}

continue;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

Expand Down
15 changes: 7 additions & 8 deletions programs/ssl/ssl_server2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2108,7 +2108,7 @@ int main( int argc, char *argv[] )
else if( strcmp( p, "tickets" ) == 0 )
{
opt.tickets = atoi( q );
if( opt.tickets < 0 || opt.tickets > 1 )
if( opt.tickets < 0 )
goto usage;
}
else if( strcmp( p, "ticket_rotate" ) == 0 )
Expand Down Expand Up @@ -3104,8 +3104,9 @@ int main( int argc, char *argv[] )
mbedtls_ssl_cache_get,
mbedtls_ssl_cache_set );
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) || defined(MBEDTLS_SSL_NEW_SESSION_TICKET_REMOVED)
if( opt.tickets == MBEDTLS_SSL_SESSION_TICKETS_ENABLED )

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
if( opt.tickets != MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
{
if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx,
rng_get, &rng,
Expand All @@ -3121,11 +3122,9 @@ int main( int argc, char *argv[] )
mbedtls_ssl_ticket_parse,
&ticket_ctx );

#if defined(MBEDTLS_SSL_NEW_SESSION_TICKET_REMOVED)
/* Enable use of tickets */
mbedtls_ssl_conf_session_tickets( &conf, opt.tickets );
#endif /* MBEDTLS_SSL_NEW_SESSION_TICKET_REMOVED */

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_conf_new_session_tickets( &conf, opt.tickets );
#endif
/* exercise manual ticket rotation (not required for typical use)
* (used for external synchronization of session ticket encryption keys)
*/
Expand Down
26 changes: 22 additions & 4 deletions tests/ssl-opt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13568,14 +13568,32 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, m->G" \
-c "HTTP/1.0 200 OK" \
-s "This is a resumed session"

requires_openssl_tls1_3
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
# https://github.com/openssl/openssl/issues/10714
# Until now, OpenSSL client does not support reconnect.
skip_next_test
run_test "TLS 1.3: NewSessionTicket: Basic check, O->m" \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4" \
"$O_NEXT_CLI -msg -debug -tls1_3 -reconnect" \
0 \
-s "=> write NewSessionTicket msg" \
-s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET" \
-s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH"

requires_gnutls_tls1_3
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
run_test "TLS 1.3: NewSessionTicket: Basic check, G->m" \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=1" \
"$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:%DISABLE_TLS13_COMPAT_MODE -V -r" \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4" \
"$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r" \
0 \
-c "Connecting again- trying to resume previous session" \
-c "NEW SESSION TICKET (4) was received" \
Expand All @@ -13592,11 +13610,11 @@ requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_SSL_CLI_C
requires_config_enabled MBEDTLS_DEBUG_C
run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=1" \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Protocol is TLSv1.3" \
-c "got new session ticket." \
-c "got new session ticket ( 3 )" \
-c "Saving session for reuse... ok" \
-c "Reconnecting with saved session" \
-c "HTTP/1.0 200 OK" \
Expand Down

0 comments on commit 0e6d7e8

Please sign in to comment.