From ff60134ff013855472de5b01767e9de79005eb61 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 15 Apr 2026 15:08:44 +0200 Subject: [PATCH] tests: add TLS 1.3 ticket age out-of-window test (F-1824) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DoClientTicketCheck's ticket-age bounds (-1000 ms low bound and MAX_TICKET_AGE_DIFF*1000+1000 ms high bound) were never exercised by any integration test, so mutations of the constants went undetected. Establish a TLS 1.3 session, read the NewSessionTicket, then shift the client's cached ageAdd by well over 1 second so the server's unobfuscated diff falls outside the valid window on resumption. The server must reject the PSK — session_reused stays 0. --- tests/api.c | 1 + tests/api/test_tls_ext.c | 63 ++++++++++++++++++++++++++++++++++++++++ tests/api/test_tls_ext.h | 1 + 3 files changed, 65 insertions(+) diff --git a/tests/api.c b/tests/api.c index c51c4c264a..148a9942bb 100644 --- a/tests/api.c +++ b/tests/api.c @@ -37580,6 +37580,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_tls13_null_cipher_bad_hmac), TEST_DECL(test_scr_verify_data_mismatch), TEST_DECL(test_tls13_hrr_cipher_suite_mismatch), + TEST_DECL(test_tls13_ticket_age_out_of_window), TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret), TEST_DECL(test_certificate_authorities_certificate_request), TEST_DECL(test_certificate_authorities_client_hello), diff --git a/tests/api/test_tls_ext.c b/tests/api/test_tls_ext.c index 87143fc642..1fcd7e7de7 100644 --- a/tests/api/test_tls_ext.c +++ b/tests/api/test_tls_ext.c @@ -410,6 +410,69 @@ int test_tls13_hrr_cipher_suite_mismatch(void) } +/* F-1824: DoClientTicketCheck must reject a PSK whose obfuscated age + * falls outside the [-1000, MAX_TICKET_AGE_DIFF*1000+1000] ms window. */ +int test_tls13_ticket_age_out_of_window(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \ + defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \ + !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) + struct test_memio_ctx test_ctx; + WOLFSSL_CTX *ctx_c = NULL; + WOLFSSL_CTX *ctx_s = NULL; + WOLFSSL *ssl_c = NULL; + WOLFSSL *ssl_s = NULL; + WOLFSSL_SESSION *session = NULL; + byte tmp; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0); + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + /* Pump post-handshake reads so the NewSessionTicket reaches the + * client. */ + (void)wolfSSL_read(ssl_c, &tmp, sizeof(tmp)); + (void)wolfSSL_read(ssl_s, &tmp, sizeof(tmp)); + (void)wolfSSL_read(ssl_c, &tmp, sizeof(tmp)); + + ExpectNotNull(session = wolfSSL_get1_session(ssl_c)); + + /* Flip the high bit to push the unobfuscated age out of window. */ + if (session != NULL) + session->ticketAdd ^= 0x80000000U; + + wolfSSL_free(ssl_c); + ssl_c = NULL; + wolfSSL_free(ssl_s); + ssl_s = NULL; + test_memio_clear_buffer(&test_ctx, 0); + test_memio_clear_buffer(&test_ctx, 1); + + ExpectNotNull(ssl_c = wolfSSL_new(ctx_c)); + ExpectNotNull(ssl_s = wolfSSL_new(ctx_s)); + wolfSSL_SetIOReadCtx(ssl_c, &test_ctx); + wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx); + wolfSSL_SetIOReadCtx(ssl_s, &test_ctx); + wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx); + ExpectIntEQ(wolfSSL_set_session(ssl_c, session), WOLFSSL_SUCCESS); + + /* PSK rejected, full handshake must still succeed. */ + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + ExpectIntEQ(wolfSSL_session_reused(ssl_s), 0); + + wolfSSL_SESSION_free(session); + wolfSSL_free(ssl_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_c); + wolfSSL_CTX_free(ctx_s); +#endif + return EXPECT_RESULT(); +} + + int test_wolfSSL_DisableExtendedMasterSecret(void) { EXPECT_DECLS; diff --git a/tests/api/test_tls_ext.h b/tests/api/test_tls_ext.h index ad87b3365f..7d0921c9ad 100644 --- a/tests/api/test_tls_ext.h +++ b/tests/api/test_tls_ext.h @@ -28,6 +28,7 @@ int test_tls12_chacha20_poly1305_bad_tag(void); int test_tls13_null_cipher_bad_hmac(void); int test_scr_verify_data_mismatch(void); int test_tls13_hrr_cipher_suite_mismatch(void); +int test_tls13_ticket_age_out_of_window(void); int test_wolfSSL_DisableExtendedMasterSecret(void); int test_certificate_authorities_certificate_request(void); int test_certificate_authorities_client_hello(void);