Skip to content

Commit

Permalink
Merge pull request #9507 from ronald-cron-arm/disable-new-session-tic…
Browse files Browse the repository at this point in the history
…kets

3.6: Disable new session tickets at runtime
  • Loading branch information
gilles-peskine-arm authored Aug 28, 2024
2 parents 7defa41 + c46edd4 commit 72064b2
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 27 deletions.
14 changes: 14 additions & 0 deletions ChangeLog.d/disable-new-session-tickets.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Bugfix
* Fix TLS connection failure in applications using an Mbed TLS client in
the default configuration connecting to a TLS 1.3 server sending tickets.
See the documentation of
mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets() for more
information.
Fixes #8749.

Changes
* By default, the handling of TLS 1.3 tickets by the Mbed TLS client is now
disabled at runtime. Applications that were using TLS 1.3 tickets
signalled by MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET return values now
need to enable the handling of TLS 1.3 tickets through the new
mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets() API.
82 changes: 70 additions & 12 deletions include/mbedtls/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@
/** Processing of the Certificate handshake message failed. */
#define MBEDTLS_ERR_SSL_BAD_CERTIFICATE -0x7A00
/* Error space gap */
/**
* Received NewSessionTicket Post Handshake Message.
* This error code is experimental and may be changed or removed without notice.
*/
/** A TLS 1.3 NewSessionTicket message has been received. */
#define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00
/** Not possible to read early data */
#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80
Expand Down Expand Up @@ -324,6 +321,9 @@
#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0
#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1

#define MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED 0
#define MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED 1

#define MBEDTLS_SSL_PRESET_DEFAULT 0
#define MBEDTLS_SSL_PRESET_SUITEB 2

Expand Down Expand Up @@ -1446,6 +1446,12 @@ struct mbedtls_ssl_config {
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_CLI_C)
/** Encodes two booleans, one stating whether TLS 1.2 session tickets are
* enabled or not, the other one whether the handling of TLS 1.3
* NewSessionTicket messages is enabled or not. They are respectively set
* by mbedtls_ssl_conf_session_tickets() and
* mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets().
*/
uint8_t MBEDTLS_PRIVATE(session_tickets); /*!< use session tickets? */
#endif

Expand Down Expand Up @@ -4465,21 +4471,50 @@ int mbedtls_ssl_conf_max_frag_len(mbedtls_ssl_config *conf, unsigned char mfl_co
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)
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
/**
* \brief Enable / Disable session tickets (client only).
* (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.)
* \brief Enable / Disable TLS 1.2 session tickets (client only,
* TLS 1.2 only). Enabled by default.
*
* \note On server, use \c mbedtls_ssl_conf_session_tickets_cb().
*
* \param conf SSL configuration
* \param use_tickets Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or
* MBEDTLS_SSL_SESSION_TICKETS_DISABLED)
* \param use_tickets Enable or disable (#MBEDTLS_SSL_SESSION_TICKETS_ENABLED or
* #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 */

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/**
* \brief Enable / Disable handling of TLS 1.3 NewSessionTicket messages
* (client only, TLS 1.3 only).
*
* The handling of TLS 1.3 NewSessionTicket messages is disabled by
* default.
*
* In TLS 1.3, servers may send a NewSessionTicket message at any time,
* and may send multiple NewSessionTicket messages. By default, TLS 1.3
* clients ignore NewSessionTicket messages.
*
* To support session tickets in TLS 1.3 clients, call this function
* with #MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED. When
* this is enabled, when a client receives a NewSessionTicket message,
* the next call to a message processing functions (notably
* mbedtls_ssl_handshake() and mbedtls_ssl_read()) will return
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET. The client should then
* call mbedtls_ssl_get_session() to retrieve the session ticket before
* calling the same message processing function again.
*
* \param conf SSL configuration
* \param signal_new_session_tickets Enable or disable
* (#MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED or
* #MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED)
*/
void mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
mbedtls_ssl_config *conf, int signal_new_session_tickets);

#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_SRV_C) && \
Expand Down Expand Up @@ -4887,6 +4922,10 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
* and the client did not demonstrate reachability yet - in
* this case you must stop using the context (see below).
* \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3
* NewSessionTicket message has been received. See the
* documentation of mbedtls_ssl_read() for more information
* about this error code.
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
Expand All @@ -4903,6 +4942,7 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
Expand Down Expand Up @@ -4977,6 +5017,7 @@ static inline int mbedtls_ssl_is_handshake_over(mbedtls_ssl_context *ssl)
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, you must stop using
* the SSL context for reading or writing, and either free it
* or call \c mbedtls_ssl_session_reset() on it before
Expand Down Expand Up @@ -5045,6 +5086,17 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
* \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
* side of a DTLS connection and the client is initiating a
* new connection using the same source port. See below.
* \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3
* NewSessionTicket message has been received.
* This error code is only returned on the client side. It is
* only returned if handling of TLS 1.3 NewSessionTicket
* messages has been enabled through
* mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets().
* This error code indicates that a TLS 1.3 NewSessionTicket
* message has been received and parsed successfully by the
* client. The ticket data can be retrieved from the SSL
* context by calling mbedtls_ssl_get_session(). It remains
* available until the next call to mbedtls_ssl_read().
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
Expand All @@ -5062,6 +5114,7 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT or
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
Expand Down Expand Up @@ -5127,6 +5180,10 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
* operation is in progress (see mbedtls_ecp_set_max_ops()) -
* in this case you must call this function again to complete
* the handshake when you're done attending other tasks.
* \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3
* NewSessionTicket message has been received. See the
* documentation of mbedtls_ssl_read() for more information
* about this error code.
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
Expand All @@ -5143,6 +5200,7 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
Expand Down
29 changes: 29 additions & 0 deletions library/ssl_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2934,8 +2934,37 @@ static inline void mbedtls_ssl_tls13_session_clear_ticket_flags(
{
session->ticket_flags &= ~(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
}

#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */

#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT 0
#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT 1

#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK \
(1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT)
#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK \
(1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT)

static inline int mbedtls_ssl_conf_get_session_tickets(
const mbedtls_ssl_config *conf)
{
return conf->session_tickets & MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK ?
MBEDTLS_SSL_SESSION_TICKETS_ENABLED :
MBEDTLS_SSL_SESSION_TICKETS_DISABLED;
}

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
static inline int mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(
const mbedtls_ssl_config *conf)
{
return conf->session_tickets & MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK ?
MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED :
MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED;
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl);
#endif
Expand Down
16 changes: 11 additions & 5 deletions library/ssl_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -5595,13 +5595,19 @@ static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
if (ssl_tls13_is_new_session_ticket(ssl)) {
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received"));
ssl->keep_current_message = 1;
if (mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(ssl->conf) ==
MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED) {
ssl->keep_current_message = 1;

mbedtls_ssl_handshake_set_state(ssl,
MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
return MBEDTLS_ERR_SSL_WANT_READ;
mbedtls_ssl_handshake_set_state(ssl,
MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
return MBEDTLS_ERR_SSL_WANT_READ;
} else {
MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, handling disabled."));
return 0;
}
#else
MBEDTLS_SSL_DEBUG_MSG(3, ("Ignore NewSessionTicket, not supported."));
MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, not supported."));
return 0;
#endif
}
Expand Down
45 changes: 42 additions & 3 deletions library/ssl_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -3009,11 +3009,24 @@ void mbedtls_ssl_conf_renegotiation_period(mbedtls_ssl_config *conf,

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
#if defined(MBEDTLS_SSL_CLI_C)

void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets)
{
conf->session_tickets = use_tickets;
conf->session_tickets &= ~MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK;
conf->session_tickets |= (use_tickets != 0) <<
MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT;
}
#endif

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
void mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
mbedtls_ssl_config *conf, int signal_new_session_tickets)
{
conf->session_tickets &= ~MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK;
conf->session_tickets |= (signal_new_session_tickets != 0) <<
MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT;
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#endif /* MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_SRV_C)

Expand Down Expand Up @@ -5878,7 +5891,33 @@ int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
mbedtls_ssl_conf_session_tickets(conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED);
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/* Contrary to TLS 1.2 tickets, TLS 1.3 NewSessionTicket message
* handling is disabled by default in Mbed TLS 3.6.x for backward
* compatibility with client applications developed using Mbed TLS 3.5
* or earlier with the default configuration.
*
* Up to Mbed TLS 3.5, in the default configuration TLS 1.3 was
* disabled, and a Mbed TLS client with the default configuration would
* establish a TLS 1.2 connection with a TLS 1.2 and TLS 1.3 capable
* server.
*
* Starting with Mbed TLS 3.6.0, TLS 1.3 is enabled by default, and thus
* an Mbed TLS client with the default configuration establishes a
* TLS 1.3 connection with a TLS 1.2 and TLS 1.3 capable server. If
* following the handshake the TLS 1.3 server sends NewSessionTicket
* messages and the Mbed TLS client processes them, this results in
* Mbed TLS high level APIs (mbedtls_ssl_read(),
* mbedtls_ssl_handshake(), ...) to eventually return an
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET non fatal error code
* (see the documentation of mbedtls_ssl_read() for more information on
* that error code). Applications unaware of that TLS 1.3 specific non
* fatal error code are then failing.
*/
mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
conf, MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED);
#endif
#endif
}
#endif
Expand Down
6 changes: 4 additions & 2 deletions library/ssl_tls12_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,8 @@ static int ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,

*olen = 0;

if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
if (mbedtls_ssl_conf_get_session_tickets(ssl->conf) ==
MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
return 0;
}

Expand Down Expand Up @@ -787,7 +788,8 @@ static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{
if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
if ((mbedtls_ssl_conf_get_session_tickets(ssl->conf) ==
MBEDTLS_SSL_SESSION_TICKETS_DISABLED) ||
len != 0) {
MBEDTLS_SSL_DEBUG_MSG(1,
("non-matching session ticket extension"));
Expand Down
19 changes: 16 additions & 3 deletions programs/ssl/ssl_client2.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ int main(void)
#define DFL_CID_VALUE_RENEGO NULL
#define DFL_RECONNECT_HARD 0
#define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED
#define DFL_NEW_SESSION_TICKETS MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED
#define DFL_ALPN_STRING NULL
#define DFL_GROUPS NULL
#define DFL_SIG_ALGS NULL
Expand Down Expand Up @@ -198,7 +199,8 @@ int main(void)

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
#define USAGE_TICKETS \
" tickets=%%d default: 1 (enabled)\n"
" tickets=%%d default: 1 (enabled)\n" \
" new_session_tickets=%%d default: 1 (enabled)\n"
#else
#define USAGE_TICKETS ""
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Expand Down Expand Up @@ -514,7 +516,8 @@ struct options {
int reco_delay; /* delay in seconds before resuming session */
int reco_mode; /* how to keep the session around */
int reconnect_hard; /* unexpectedly reconnect from the same port */
int tickets; /* enable / disable session tickets */
int tickets; /* enable / disable session tickets (TLS 1.2) */
int new_session_tickets; /* enable / disable new session tickets (TLS 1.3) */
const char *groups; /* list of supported groups */
const char *sig_algs; /* supported TLS 1.3 signature algorithms */
const char *alpn_string; /* ALPN supported protocols */
Expand Down Expand Up @@ -969,6 +972,7 @@ int main(int argc, char *argv[])
opt.reco_mode = DFL_RECO_MODE;
opt.reconnect_hard = DFL_RECONNECT_HARD;
opt.tickets = DFL_TICKETS;
opt.new_session_tickets = DFL_NEW_SESSION_TICKETS;
opt.alpn_string = DFL_ALPN_STRING;
opt.groups = DFL_GROUPS;
opt.sig_algs = DFL_SIG_ALGS;
Expand Down Expand Up @@ -1226,6 +1230,11 @@ int main(int argc, char *argv[])
if (opt.tickets < 0) {
goto usage;
}
} else if (strcmp(p, "new_session_tickets") == 0) {
opt.new_session_tickets = atoi(q);
if (opt.new_session_tickets < 0) {
goto usage;
}
} else if (strcmp(p, "alpn") == 0) {
opt.alpn_string = q;
} else if (strcmp(p, "extended_ms") == 0) {
Expand Down Expand Up @@ -1936,7 +1945,11 @@ int main(int argc, char *argv[])

#if defined(MBEDTLS_SSL_SESSION_TICKETS)
mbedtls_ssl_conf_session_tickets(&conf, opt.tickets);
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
&conf, opt.new_session_tickets);
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#endif /* MBEDTLS_SSL_SESSION_TICKETS */

if (opt.force_ciphersuite[0] != DFL_FORCE_CIPHER) {
mbedtls_ssl_conf_ciphersuites(&conf, opt.force_ciphersuite);
Expand Down
Loading

0 comments on commit 72064b2

Please sign in to comment.