Merge pull request #6788 from yuhaoth/pr/fix-gnutls_anti_replay_fail

TLS 1.3: Fix anti replay fail from GnuTLS
This commit is contained in:
Ronald Cron 2023-11-21 08:38:57 +00:00 committed by GitHub
commit effdfe7409
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 247 additions and 132 deletions

View file

@ -0,0 +1,5 @@
Bugfix
* Switch to milliseconds as the unit for ticket creation and reception time
instead of seconds. That avoids rounding errors when computing the age of
tickets compared to peer using a millisecond clock (observed with GnuTLS).
Fixes #6623.

View file

@ -120,7 +120,12 @@
/* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */ /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
#if !defined(MBEDTLS_PRINTF_MS_TIME) #if !defined(MBEDTLS_PRINTF_MS_TIME)
#include <inttypes.h>
#if !defined(PRId64)
#define MBEDTLS_PRINTF_MS_TIME MBEDTLS_PRINTF_LONGLONG
#else
#define MBEDTLS_PRINTF_MS_TIME PRId64 #define MBEDTLS_PRINTF_MS_TIME PRId64
#endif
#endif /* MBEDTLS_PRINTF_MS_TIME */ #endif /* MBEDTLS_PRINTF_MS_TIME */
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -4099,20 +4099,23 @@
/** /**
* \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE * \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE
* *
* Maximum time difference in milliseconds tolerated between the age of a * Maximum allowed ticket age difference in milliseconds tolerated between
* ticket from the server and client point of view. * server and client. Default value is 6000. This is not used in TLS 1.2.
* From the client point of view, the age of a ticket is the time difference
* between the time when the client proposes to the server to use the ticket
* (time of writing of the Pre-Shared Key Extension including the ticket) and
* the time the client received the ticket from the server.
* From the server point of view, the age of a ticket is the time difference
* between the time when the server receives a proposition from the client
* to use the ticket and the time when the ticket was created by the server.
* The server age is expected to be always greater than the client one and
* MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE defines the
* maximum difference tolerated for the server to accept the ticket.
* This is not used in TLS 1.2.
* *
* - The client ticket age is the time difference between the time when the
* client proposes to the server to use the ticket and the time the client
* received the ticket from the server.
* - The server ticket age is the time difference between the time when the
* server receives a proposition from the client to use the ticket and the
* time when the ticket was created by the server.
*
* The ages might be different due to the client and server clocks not running
* at the same pace. The typical accuracy of an RTC crystal is ±100 to ±20 parts
* per million (360 to 72 milliseconds per hour). Default tolerance window is
* 6s, thus in the worst case clients and servers must sync up their system time
* every 6000/360/2~=8 hours.
*
* See section 8.3 of the TLS 1.3 specification(RFC 8446) for more information.
*/ */
//#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000 //#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000

View file

@ -1217,7 +1217,7 @@ struct mbedtls_ssl_session {
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version); mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t MBEDTLS_PRIVATE(start); /*!< starting time */ mbedtls_time_t MBEDTLS_PRIVATE(start); /*!< start time of current session */
#endif #endif
int MBEDTLS_PRIVATE(ciphersuite); /*!< chosen ciphersuite */ int MBEDTLS_PRIVATE(ciphersuite); /*!< chosen ciphersuite */
size_t MBEDTLS_PRIVATE(id_len); /*!< session id length */ size_t MBEDTLS_PRIVATE(id_len); /*!< session id length */
@ -1254,9 +1254,14 @@ struct mbedtls_ssl_session {
char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */ char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C) #if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t MBEDTLS_PRIVATE(ticket_received); /*!< time ticket was received */ #if defined(MBEDTLS_SSL_CLI_C)
#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_CLI_C */ mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time); /*!< time when ticket was received. */
#endif
#if defined(MBEDTLS_SSL_SRV_C)
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time); /*!< time when ticket was created. */
#endif
#endif /* MBEDTLS_HAVE_TIME */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */

View file

@ -756,10 +756,9 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl)
if (ssl->handshake->resume != 0 && if (ssl->handshake->resume != 0 &&
session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 && session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
session_negotiate->ticket != NULL) { session_negotiate->ticket != NULL) {
mbedtls_time_t now = mbedtls_time(NULL); mbedtls_ms_time_t now = mbedtls_ms_time();
uint64_t age = (uint64_t) (now - session_negotiate->ticket_received); mbedtls_ms_time_t age = now - session_negotiate->ticket_reception_time;
if (session_negotiate->ticket_received > now || if (age < 0 || age > session_negotiate->ticket_lifetime * 1000) {
age > session_negotiate->ticket_lifetime) {
/* Without valid ticket, disable session resumption.*/ /* Without valid ticket, disable session resumption.*/
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
3, ("Ticket expired, disable session resumption")); 3, ("Ticket expired, disable session resumption"));

View file

@ -2765,6 +2765,9 @@ int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session,
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
#define MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME (604800)
static inline unsigned int mbedtls_ssl_session_get_ticket_flags( static inline unsigned int mbedtls_ssl_session_get_ticket_flags(
mbedtls_ssl_session *session, unsigned int flags) mbedtls_ssl_session *session, unsigned int flags)
{ {

View file

@ -495,7 +495,31 @@ int mbedtls_ssl_ticket_parse(void *p_ticket,
} }
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
{ #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
/* Check for expiration */
mbedtls_ms_time_t ticket_age = -1;
#if defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
ticket_age = mbedtls_ms_time() - session->ticket_creation_time;
}
#endif
#if defined(MBEDTLS_SSL_CLI_C)
if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
ticket_age = mbedtls_ms_time() - session->ticket_reception_time;
}
#endif
mbedtls_ms_time_t ticket_lifetime = ctx->ticket_lifetime * 1000;
if (ticket_age < 0 || ticket_age > ticket_lifetime) {
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
goto cleanup;
}
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
/* Check for expiration */ /* Check for expiration */
mbedtls_time_t current_time = mbedtls_time(NULL); mbedtls_time_t current_time = mbedtls_time(NULL);
@ -505,7 +529,8 @@ int mbedtls_ssl_ticket_parse(void *p_ticket,
goto cleanup; goto cleanup;
} }
} }
#endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#endif /* MBEDTLS_HAVE_TIME */
cleanup: cleanup:
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)

View file

@ -2443,7 +2443,7 @@ mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite(
* *
* struct { * struct {
* opaque hostname<0..2^16-1>; * opaque hostname<0..2^16-1>;
* uint64 ticket_received; * uint64 ticket_reception_time;
* uint32 ticket_lifetime; * uint32 ticket_lifetime;
* opaque ticket<1..2^16-1>; * opaque ticket<1..2^16-1>;
* } ClientOnlyData; * } ClientOnlyData;
@ -2457,7 +2457,7 @@ mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite(
* uint32 max_early_data_size; * uint32 max_early_data_size;
* select ( endpoint ) { * select ( endpoint ) {
* case client: ClientOnlyData; * case client: ClientOnlyData;
* case server: uint64 start_time; * case server: uint64 ticket_creation_time;
* }; * };
* } serialized_session_tls13; * } serialized_session_tls13;
* *
@ -2492,7 +2492,7 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
#endif #endif
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
needed += 8; /* start_time or ticket_received */ needed += 8; /* ticket_creation_time or ticket_reception_time */
#endif #endif
#if defined(MBEDTLS_SSL_CLI_C) #if defined(MBEDTLS_SSL_CLI_C)
@ -2537,7 +2537,7 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
MBEDTLS_PUT_UINT64_BE((uint64_t) session->start, p, 0); MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
p += 8; p += 8;
} }
#endif /* MBEDTLS_HAVE_TIME */ #endif /* MBEDTLS_HAVE_TIME */
@ -2555,7 +2555,7 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_received, p, 0); MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0);
p += 8; p += 8;
#endif #endif
MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0); MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
@ -2616,7 +2616,7 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session,
if (end - p < 8) { if (end - p < 8) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
} }
session->start = MBEDTLS_GET_UINT64_BE(p, 0); session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8; p += 8;
} }
#endif /* MBEDTLS_HAVE_TIME */ #endif /* MBEDTLS_HAVE_TIME */
@ -2651,7 +2651,7 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session,
if (end - p < 8) { if (end - p < 8) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
} }
session->ticket_received = MBEDTLS_GET_UINT64_BE(p, 0); session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8; p += 8;
#endif #endif
if (end - p < 4) { if (end - p < 4) {

View file

@ -931,28 +931,14 @@ int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
if (ssl_tls13_ticket_get_identity( if (ssl_tls13_ticket_get_identity(
ssl, &hash_alg, &identity, &identity_len) == 0) { ssl, &hash_alg, &identity, &identity_len) == 0) {
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t now = mbedtls_time(NULL); mbedtls_ms_time_t now = mbedtls_ms_time();
mbedtls_ssl_session *session = ssl->session_negotiate; mbedtls_ssl_session *session = ssl->session_negotiate;
/* The ticket age has been checked to be smaller than the
* `ticket_lifetime` in ssl_prepare_client_hello() which is smaller than
* 7 days (enforced in ssl_tls13_parse_new_session_ticket()) . Thus the
* cast to `uint32_t` of the ticket age is safe. */
uint32_t obfuscated_ticket_age = uint32_t obfuscated_ticket_age =
(uint32_t) (now - session->ticket_received); (uint32_t) (now - session->ticket_reception_time);
/*
* The ticket timestamp is in seconds but the ticket age is in
* milliseconds. If the ticket was received at the end of a second and
* re-used here just at the beginning of the next second, the computed
* age `now - session->ticket_received` is equal to 1s thus 1000 ms
* while the actual age could be just a few milliseconds or tens of
* milliseconds. If the server has more accurate ticket timestamps
* (typically timestamps in milliseconds), as part of the processing of
* the ClientHello, it may compute a ticket lifetime smaller than the
* one computed here and potentially reject the ticket. To avoid that,
* remove one second to the ticket age if possible.
*/
if (obfuscated_ticket_age > 0) {
obfuscated_ticket_age -= 1;
}
obfuscated_ticket_age *= 1000;
obfuscated_ticket_age += session->ticket_age_add; obfuscated_ticket_age += session->ticket_age_add;
ret = ssl_tls13_write_identity(ssl, p, end, ret = ssl_tls13_write_identity(ssl, p, end,
@ -2762,6 +2748,11 @@ static int ssl_tls13_parse_new_session_ticket(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG(3, MBEDTLS_SSL_DEBUG_MSG(3,
("ticket_lifetime: %u", ("ticket_lifetime: %u",
(unsigned int) session->ticket_lifetime)); (unsigned int) session->ticket_lifetime));
if (session->ticket_lifetime >
MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime exceeds 7 days."));
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 4); session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 4);
MBEDTLS_SSL_DEBUG_MSG(3, MBEDTLS_SSL_DEBUG_MSG(3,
@ -2837,7 +2828,7 @@ static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
/* Store ticket creation time */ /* Store ticket creation time */
session->ticket_received = mbedtls_time(NULL); session->ticket_reception_time = mbedtls_ms_time();
#endif #endif
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(session->ciphersuite); ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(session->ciphersuite);

View file

@ -111,9 +111,10 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
unsigned char *ticket_buffer; unsigned char *ticket_buffer;
unsigned int key_exchanges; unsigned int key_exchanges;
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t now; mbedtls_ms_time_t now;
uint64_t age_in_s; mbedtls_ms_time_t server_age;
int64_t age_diff_in_ms; uint32_t client_age;
mbedtls_ms_time_t age_diff;
#endif #endif
((void) obfuscated_ticket_age); ((void) obfuscated_ticket_age);
@ -190,17 +191,17 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
now = mbedtls_time(NULL); now = mbedtls_ms_time();
if (now < session->start) { if (now < session->ticket_creation_time) {
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
3, ("Invalid ticket start time ( now=%" MBEDTLS_PRINTF_LONGLONG 3, ("Invalid ticket creation time ( now = %" MBEDTLS_PRINTF_MS_TIME
", start=%" MBEDTLS_PRINTF_LONGLONG " )", ", creation_time = %" MBEDTLS_PRINTF_MS_TIME " )",
(long long) now, (long long) session->start)); now, session->ticket_creation_time));
goto exit; goto exit;
} }
age_in_s = (uint64_t) (now - session->start); server_age = now - session->ticket_creation_time;
/* RFC 8446 section 4.6.1 /* RFC 8446 section 4.6.1
* *
@ -211,12 +212,11 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
* Clients MUST NOT attempt to use tickets which have ages greater than * Clients MUST NOT attempt to use tickets which have ages greater than
* the "ticket_lifetime" value which was provided with the ticket. * the "ticket_lifetime" value which was provided with the ticket.
* *
* For time being, the age MUST be less than 604800 seconds (7 days).
*/ */
if (age_in_s > 604800) { if (server_age > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME * 1000) {
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
3, ("Ticket age exceeds limitation ticket_age=%lu", 3, ("Ticket age exceeds limitation ticket_age = %" MBEDTLS_PRINTF_MS_TIME,
(long unsigned int) age_in_s)); server_age));
goto exit; goto exit;
} }
@ -227,18 +227,19 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
* ticket_age_add from PskIdentity.obfuscated_ticket_age modulo 2^32) is * ticket_age_add from PskIdentity.obfuscated_ticket_age modulo 2^32) is
* within a small tolerance of the time since the ticket was issued. * within a small tolerance of the time since the ticket was issued.
* *
* NOTE: When `now == session->start`, `age_diff_in_ms` may be negative * NOTE: The typical accuracy of an RTC crystal is ±100 to ±20 parts per
* as the age units are different on the server (s) and in the * million (360 to 72 milliseconds per hour). Default tolerance
* client (ms) side. Add a -1000 ms tolerance window to take this * window is 6s, thus in the worst case clients and servers must
* into account. * sync up their system time every 6000/360/2~=8 hours.
*/ */
age_diff_in_ms = age_in_s * 1000; client_age = obfuscated_ticket_age - session->ticket_age_add;
age_diff_in_ms -= (obfuscated_ticket_age - session->ticket_age_add); age_diff = server_age - (mbedtls_ms_time_t) client_age;
if (age_diff_in_ms <= -1000 || if (age_diff < -MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE ||
age_diff_in_ms > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) { age_diff > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) {
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
3, ("Ticket age outside tolerance window ( diff=%d )", 3, ("Ticket age outside tolerance window ( diff = %"
(int) age_diff_in_ms)); MBEDTLS_PRINTF_MS_TIME ")",
age_diff));
goto exit; goto exit;
} }
@ -2877,7 +2878,7 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG(2, ("=> prepare NewSessionTicket msg")); MBEDTLS_SSL_DEBUG_MSG(2, ("=> prepare NewSessionTicket msg"));
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
session->start = mbedtls_time(NULL); session->ticket_creation_time = mbedtls_ms_time();
#endif #endif
/* Set ticket_flags depends on the advertised psk key exchange mode */ /* Set ticket_flags depends on the advertised psk key exchange mode */
@ -3024,8 +3025,8 @@ static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl,
* MAY treat a ticket as valid for a shorter period of time than what * MAY treat a ticket as valid for a shorter period of time than what
* is stated in the ticket_lifetime. * is stated in the ticket_lifetime.
*/ */
if (ticket_lifetime > 604800) { if (ticket_lifetime > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
ticket_lifetime = 604800; ticket_lifetime = MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME;
} }
MBEDTLS_PUT_UINT32_BE(ticket_lifetime, p, 0); MBEDTLS_PUT_UINT32_BE(ticket_lifetime, p, 0);
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime: %u", MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime: %u",

View file

@ -1419,22 +1419,29 @@ int dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session,
return MBEDTLS_ERR_SSL_INVALID_MAC; return MBEDTLS_ERR_SSL_INVALID_MAC;
case 2: case 2:
return MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; return MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
case 3: case 3:
session->start = mbedtls_time(NULL) + 10; /* Creation time in the future. */
session->ticket_creation_time = mbedtls_ms_time() + 1000;
break; break;
case 4: case 4:
session->start = mbedtls_time(NULL) - 10 - 7 * 24 * 3600; /* Ticket has reached the end of lifetime. */
session->ticket_creation_time = mbedtls_ms_time() -
(7 * 24 * 3600 * 1000 + 1000);
break; break;
case 5: case 5:
session->start = mbedtls_time(NULL) - 10; /* Ticket is valid, but client age is below the lower bound of the tolerance window. */
session->ticket_age_add += MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + 4 * 1000;
/* Make sure the execution time does not affect the result */
session->ticket_creation_time = mbedtls_ms_time();
break; break;
case 6: case 6:
session->start = mbedtls_time(NULL); /* Ticket is valid, but client age is beyond the upper bound of the tolerance window. */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) session->ticket_age_add -= MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + 4 * 1000;
session->ticket_age_add -= 1000; /* Make sure the execution time does not affect the result */
#endif session->ticket_creation_time = mbedtls_ms_time();
break; break;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
case 7: case 7:
session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE; session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
break; break;

View file

@ -86,7 +86,7 @@ run_test "TLS 1.3 m->m: Session resumption failure, ticket authentication failed
-S "key exchange mode: psk$" \ -S "key exchange mode: psk$" \
-s "ticket is not authentic" \ -s "ticket is not authentic" \
-S "ticket is expired" \ -S "ticket is expired" \
-S "Invalid ticket start time" \ -S "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \ -S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window" -S "Ticket age outside tolerance window"
@ -105,7 +105,7 @@ run_test "TLS 1.3 m->m: Session resumption failure, ticket expired." \
-S "key exchange mode: psk$" \ -S "key exchange mode: psk$" \
-S "ticket is not authentic" \ -S "ticket is not authentic" \
-s "ticket is expired" \ -s "ticket is expired" \
-S "Invalid ticket start time" \ -S "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \ -S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window" -S "Ticket age outside tolerance window"
@ -124,7 +124,7 @@ run_test "TLS 1.3 m->m: Session resumption failure, invalid start time." \
-S "key exchange mode: psk$" \ -S "key exchange mode: psk$" \
-S "ticket is not authentic" \ -S "ticket is not authentic" \
-S "ticket is expired" \ -S "ticket is expired" \
-s "Invalid ticket start time" \ -s "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \ -S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window" -S "Ticket age outside tolerance window"
@ -143,7 +143,7 @@ run_test "TLS 1.3 m->m: Session resumption failure, ticket expired. too old" \
-S "key exchange mode: psk$" \ -S "key exchange mode: psk$" \
-S "ticket is not authentic" \ -S "ticket is not authentic" \
-S "ticket is expired" \ -S "ticket is expired" \
-S "Invalid ticket start time" \ -S "Invalid ticket creation time" \
-s "Ticket age exceeds limitation" \ -s "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window" -S "Ticket age outside tolerance window"
@ -162,7 +162,7 @@ run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window
-S "key exchange mode: psk$" \ -S "key exchange mode: psk$" \
-S "ticket is not authentic" \ -S "ticket is not authentic" \
-S "ticket is expired" \ -S "ticket is expired" \
-S "Invalid ticket start time" \ -S "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \ -S "Ticket age exceeds limitation" \
-s "Ticket age outside tolerance window" -s "Ticket age outside tolerance window"
@ -181,7 +181,7 @@ run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window
-S "key exchange mode: psk$" \ -S "key exchange mode: psk$" \
-S "ticket is not authentic" \ -S "ticket is not authentic" \
-S "ticket is expired" \ -S "ticket is expired" \
-S "Invalid ticket start time" \ -S "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \ -S "Ticket age exceeds limitation" \
-s "Ticket age outside tolerance window" -s "Ticket age outside tolerance window"

View file

@ -1633,6 +1633,7 @@ exit:
} }
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
int mbedtls_test_ssl_tls12_populate_session(mbedtls_ssl_session *session, int mbedtls_test_ssl_tls12_populate_session(mbedtls_ssl_session *session,
int ticket_len, int ticket_len,
const char *crt_file) const char *crt_file)
@ -1729,6 +1730,7 @@ int mbedtls_test_ssl_tls12_populate_session(mbedtls_ssl_session *session,
return 0; return 0;
} }
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session, int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session,
@ -1750,16 +1752,16 @@ int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session,
session->max_early_data_size = 0x87654321; session->max_early_data_size = 0x87654321;
#endif #endif
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
session->start = mbedtls_time(NULL) - 42; session->ticket_creation_time = mbedtls_ms_time() - 42;
} }
#endif #endif
#if defined(MBEDTLS_SSL_CLI_C) #if defined(MBEDTLS_SSL_CLI_C)
if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
session->ticket_received = mbedtls_time(NULL) - 40; session->ticket_reception_time = mbedtls_ms_time() - 40;
#endif #endif
session->ticket_lifetime = 0xfedcba98; session->ticket_lifetime = 0xfedcba98;

View file

@ -1943,16 +1943,21 @@ void ssl_serialize_session_save_load(int ticket_len, char *crt_file,
/* Prepare a dummy session to work on */ /* Prepare a dummy session to work on */
((void) endpoint_type); ((void) endpoint_type);
((void) tls_version); ((void) tls_version);
((void) ticket_len);
((void) crt_file);
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session( TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
&original, 0, endpoint_type) == 0); &original, 0, endpoint_type) == 0);
} else }
#endif #endif
{
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session( TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
&original, ticket_len, crt_file) == 0); &original, ticket_len, crt_file) == 0);
} }
#endif
/* Serialize it */ /* Serialize it */
TEST_ASSERT(mbedtls_ssl_session_save(&original, NULL, 0, &len) TEST_ASSERT(mbedtls_ssl_session_save(&original, NULL, 0, &len)
@ -1968,8 +1973,27 @@ void ssl_serialize_session_save_load(int ticket_len, char *crt_file,
* Make sure both session structures are identical * Make sure both session structures are identical
*/ */
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
TEST_ASSERT(original.start == restored.start); switch (tls_version) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SRV_C)
case MBEDTLS_SSL_VERSION_TLS1_3:
TEST_ASSERT(original.ticket_creation_time == restored.ticket_creation_time);
break;
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
case MBEDTLS_SSL_VERSION_TLS1_2:
TEST_ASSERT(original.start == restored.start);
break;
#endif
default:
/* should never happen */
TEST_ASSERT(0);
break;
}
#endif
TEST_ASSERT(original.tls_version == restored.tls_version); TEST_ASSERT(original.tls_version == restored.tls_version);
TEST_ASSERT(original.ciphersuite == restored.ciphersuite); TEST_ASSERT(original.ciphersuite == restored.ciphersuite);
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
@ -2049,13 +2073,13 @@ void ssl_serialize_session_save_load(int ticket_len, char *crt_file,
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (endpoint_type == MBEDTLS_SSL_IS_SERVER) { if (endpoint_type == MBEDTLS_SSL_IS_SERVER) {
TEST_ASSERT(original.start == restored.start); TEST_ASSERT(original.ticket_creation_time == restored.ticket_creation_time);
} }
#endif #endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
if (endpoint_type == MBEDTLS_SSL_IS_CLIENT) { if (endpoint_type == MBEDTLS_SSL_IS_CLIENT) {
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
TEST_ASSERT(original.ticket_received == restored.ticket_received); TEST_ASSERT(original.ticket_reception_time == restored.ticket_reception_time);
#endif #endif
TEST_ASSERT(original.ticket_lifetime == restored.ticket_lifetime); TEST_ASSERT(original.ticket_lifetime == restored.ticket_lifetime);
TEST_ASSERT(original.ticket_len == restored.ticket_len); TEST_ASSERT(original.ticket_len == restored.ticket_len);
@ -2096,16 +2120,27 @@ void ssl_serialize_session_load_save(int ticket_len, char *crt_file,
/* Prepare a dummy session to work on */ /* Prepare a dummy session to work on */
((void) endpoint_type); ((void) endpoint_type);
((void) tls_version); ((void) ticket_len);
((void) crt_file);
switch (tls_version) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { case MBEDTLS_SSL_VERSION_TLS1_3:
TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session( TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
&session, 0, endpoint_type) == 0); &session, 0, endpoint_type) == 0);
} else break;
#endif #endif
{
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session( #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
&session, ticket_len, crt_file) == 0); case MBEDTLS_SSL_VERSION_TLS1_2:
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
&session, ticket_len, crt_file) == 0);
break;
#endif
default:
/* should never happen */
TEST_ASSERT(0);
break;
} }
/* Get desired buffer size for serializing */ /* Get desired buffer size for serializing */
@ -2159,17 +2194,28 @@ void ssl_serialize_session_save_buf_size(int ticket_len, char *crt_file,
/* Prepare dummy session and get serialized size */ /* Prepare dummy session and get serialized size */
((void) endpoint_type); ((void) endpoint_type);
((void) tls_version); ((void) ticket_len);
((void) crt_file);
switch (tls_version) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { case MBEDTLS_SSL_VERSION_TLS1_3:
TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session( TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
&session, 0, endpoint_type) == 0); &session, 0, endpoint_type) == 0);
} else break;
#endif #endif
{ #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session( case MBEDTLS_SSL_VERSION_TLS1_2:
&session, ticket_len, crt_file) == 0); TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
&session, ticket_len, crt_file) == 0);
break;
#endif
default:
/* should never happen */
TEST_ASSERT(0);
break;
} }
TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len) TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len)
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL); == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
@ -2208,17 +2254,30 @@ void ssl_serialize_session_load_buf_size(int ticket_len, char *crt_file,
/* Prepare serialized session data */ /* Prepare serialized session data */
((void) endpoint_type); ((void) endpoint_type);
((void) tls_version); ((void) ticket_len);
((void) crt_file);
switch (tls_version) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { case MBEDTLS_SSL_VERSION_TLS1_3:
TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session( TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
&session, 0, endpoint_type) == 0); &session, 0, endpoint_type) == 0);
} else break;
#endif #endif
{
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session( #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
&session, ticket_len, crt_file) == 0); case MBEDTLS_SSL_VERSION_TLS1_2:
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
&session, ticket_len, crt_file) == 0);
break;
#endif
default:
/* should never happen */
TEST_ASSERT(0);
break;
} }
TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len) TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len)
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL); == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
TEST_CALLOC(good_buf, good_len); TEST_CALLOC(good_buf, good_len);
@ -2267,16 +2326,26 @@ void ssl_session_serialize_version_check(int corrupt_major,
mbedtls_ssl_session_init(&session); mbedtls_ssl_session_init(&session);
USE_PSA_INIT(); USE_PSA_INIT();
((void) endpoint_type); ((void) endpoint_type);
((void) tls_version);
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
&session, 0, endpoint_type) == 0);
} else
#endif
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
&session, 0, NULL) == 0);
switch (tls_version) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
case MBEDTLS_SSL_VERSION_TLS1_3:
TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
&session, 0, endpoint_type) == 0);
break;
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
case MBEDTLS_SSL_VERSION_TLS1_2:
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
&session, 0, NULL) == 0);
break;
#endif
default:
/* should never happen */
TEST_ASSERT(0);
break;
}
/* Infer length of serialized session. */ /* Infer length of serialized session. */
TEST_ASSERT(mbedtls_ssl_session_save(&session, TEST_ASSERT(mbedtls_ssl_session_save(&session,