diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 7294bb144..cf1c19a08 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1217,7 +1217,7 @@ struct mbedtls_ssl_session { mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version); #if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t MBEDTLS_PRIVATE(start); /*!< starting time */ + mbedtls_ms_time_t MBEDTLS_PRIVATE(start); /*!< starting time */ #endif int MBEDTLS_PRIVATE(ciphersuite); /*!< chosen ciphersuite */ size_t MBEDTLS_PRIVATE(id_len); /*!< session id length */ @@ -1255,7 +1255,7 @@ struct mbedtls_ssl_session { #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C) - mbedtls_time_t MBEDTLS_PRIVATE(ticket_received); /*!< time ticket was received */ + mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_received); /*!< time ticket was received */ #endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_CLI_C */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ diff --git a/library/ssl_client.c b/library/ssl_client.c index 7a7840662..21114910e 100644 --- a/library/ssl_client.c +++ b/library/ssl_client.c @@ -756,10 +756,9 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl) if (ssl->handshake->resume != 0 && session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 && session_negotiate->ticket != NULL) { - mbedtls_time_t now = mbedtls_time(NULL); - uint64_t age = (uint64_t) (now - session_negotiate->ticket_received); - if (session_negotiate->ticket_received > now || - age > session_negotiate->ticket_lifetime) { + mbedtls_ms_time_t now = mbedtls_ms_time(); + mbedtls_ms_time_t age = now - session_negotiate->ticket_received; + if (age < 0 || age > session_negotiate->ticket_lifetime * 1000) { /* Without valid ticket, disable session resumption.*/ MBEDTLS_SSL_DEBUG_MSG( 3, ("Ticket expired, disable session resumption")); diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c index 875abcbb3..c89a5cdb0 100644 --- a/library/ssl_ticket.c +++ b/library/ssl_ticket.c @@ -495,6 +495,18 @@ int mbedtls_ssl_ticket_parse(void *p_ticket, } #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 = mbedtls_ms_time() - session->start; + 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; + } + } else +#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ { /* Check for expiration */ mbedtls_time_t current_time = mbedtls_time(NULL); @@ -505,7 +517,7 @@ int mbedtls_ssl_ticket_parse(void *p_ticket, goto cleanup; } } -#endif +#endif /* MBEDTLS_HAVE_TIME */ cleanup: #if defined(MBEDTLS_THREADING_C) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index eac632600..32ad7aaed 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -931,28 +931,10 @@ int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext( if (ssl_tls13_ticket_get_identity( ssl, &hash_alg, &identity, &identity_len) == 0) { #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; uint32_t obfuscated_ticket_age = (uint32_t) (now - session->ticket_received); - - /* - * 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; ret = ssl_tls13_write_identity(ssl, p, end, @@ -2837,7 +2819,7 @@ static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl, #if defined(MBEDTLS_HAVE_TIME) /* Store ticket creation time */ - session->ticket_received = mbedtls_time(NULL); + session->ticket_received = mbedtls_ms_time(); #endif ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(session->ciphersuite); diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index b418ee635..8bcb0e407 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -111,9 +111,10 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( unsigned char *ticket_buffer; unsigned int key_exchanges; #if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t now; - uint64_t age_in_s; - int64_t age_diff_in_ms; + mbedtls_ms_time_t now; + mbedtls_ms_time_t server_age; + mbedtls_ms_time_t client_age; + mbedtls_ms_time_t age_diff; #endif ((void) obfuscated_ticket_age); @@ -190,17 +191,16 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; #if defined(MBEDTLS_HAVE_TIME) - now = mbedtls_time(NULL); + now = mbedtls_ms_time(); if (now < session->start) { MBEDTLS_SSL_DEBUG_MSG( - 3, ("Invalid ticket start time ( now=%" MBEDTLS_PRINTF_LONGLONG - ", start=%" MBEDTLS_PRINTF_LONGLONG " )", - (long long) now, (long long) session->start)); + 3, ("Invalid ticket start time ( now=%" MBEDTLS_PRINTF_MS_TIME + ", start=%" MBEDTLS_PRINTF_MS_TIME " )", now, session->start)); goto exit; } - age_in_s = (uint64_t) (now - session->start); + server_age = now - session->start; /* RFC 8446 section 4.6.1 * @@ -213,10 +213,10 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( * * For time being, the age MUST be less than 604800 seconds (7 days). */ - if (age_in_s > 604800) { + if (server_age > 604800*1000) { MBEDTLS_SSL_DEBUG_MSG( - 3, ("Ticket age exceeds limitation ticket_age=%lu", - (long unsigned int) age_in_s)); + 3, ("Ticket age exceeds limitation ticket_age=%" MBEDTLS_PRINTF_MS_TIME, + server_age)); 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 * within a small tolerance of the time since the ticket was issued. * - * NOTE: When `now == session->start`, `age_diff_in_ms` may be negative - * as the age units are different on the server (s) and in the - * client (ms) side. Add a -1000 ms tolerance window to take this - * into account. + * NOTE: Typical crystal RTC accuracy specifications are from ±100 to ±20 + * parts per million (360 to 72 million seconds per hour). Defualt + * tolerance windows is 6000 millionsections, that means client host + * MUST sync up system time every 16 hours. Otherwise, the ticket will + * be invalid. */ - age_diff_in_ms = age_in_s * 1000; - age_diff_in_ms -= (obfuscated_ticket_age - session->ticket_age_add); - if (age_diff_in_ms <= -1000 || - age_diff_in_ms > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) { + client_age = obfuscated_ticket_age - session->ticket_age_add; + age_diff = server_age - client_age; + if (age_diff < -1000 || + age_diff > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) { MBEDTLS_SSL_DEBUG_MSG( - 3, ("Ticket age outside tolerance window ( diff=%d )", - (int) age_diff_in_ms)); + 3, ("Ticket age outside tolerance window ( diff=%" MBEDTLS_PRINTF_MS_TIME ")", + age_diff)); 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")); #if defined(MBEDTLS_HAVE_TIME) - session->start = mbedtls_time(NULL); + session->start = mbedtls_ms_time(); #endif /* Set ticket_flags depends on the advertised psk key exchange mode */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 3e2360ed6..ce53f9274 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1420,16 +1420,16 @@ int dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, case 2: return MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; case 3: - session->start = mbedtls_time(NULL) + 10; + session->start = mbedtls_ms_time() + 10 * 1000; break; case 4: - session->start = mbedtls_time(NULL) - 10 - 7 * 24 * 3600; + session->start = mbedtls_ms_time() - 10 * 1000 - 7 * 24 * 3600 * 1000; break; case 5: - session->start = mbedtls_time(NULL) - 10; + session->start = mbedtls_ms_time() - 10 * 1000; break; case 6: - session->start = mbedtls_time(NULL); + session->start = mbedtls_ms_time(); #if defined(MBEDTLS_SSL_PROTO_TLS1_3) session->ticket_age_add -= 1000; #endif