@@ -10436,6 +10436,78 @@ static int test_wolfSSL_SCR_check_enabled(void)
1043610436 return EXPECT_RESULT();
1043710437}
1043810438
10439+ /* F-2922: wolfSSL_TicketKeyCb must reject a session ticket whose HMAC
10440+ * does not match its encrypted contents. */
10441+ static int test_wolfSSL_ticket_keycb_bad_hmac(void)
10442+ {
10443+ EXPECT_DECLS;
10444+ #if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_TLS12) && \
10445+ defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC) && \
10446+ defined(WOLFSSL_AES_256) && \
10447+ defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
10448+ !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
10449+ struct test_memio_ctx test_ctx;
10450+ WOLFSSL_CTX *ctx_c = NULL;
10451+ WOLFSSL_CTX *ctx_s = NULL;
10452+ WOLFSSL *ssl_c = NULL;
10453+ WOLFSSL *ssl_s = NULL;
10454+ WOLFSSL_SESSION *session = NULL;
10455+
10456+ XMEMSET(&test_ctx, 0, sizeof(test_ctx));
10457+
10458+ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
10459+ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
10460+
10461+ ExpectIntEQ(OpenSSLTicketInit(), 0);
10462+ ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_key_cb(ctx_s,
10463+ myTicketEncCbOpenSSL), WOLFSSL_SUCCESS);
10464+ ExpectIntEQ(wolfSSL_UseSessionTicket(ssl_c), WOLFSSL_SUCCESS);
10465+
10466+ ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
10467+ ExpectNotNull(session = wolfSSL_get1_session(ssl_c));
10468+ ExpectIntGT(session->ticketLen, 0);
10469+
10470+ /* Corrupt a byte of the ticket HMAC so the server's HMAC
10471+ * verification rejects it. */
10472+ if (session != NULL && session->ticket != NULL && session->ticketLen > 0)
10473+ session->ticket[session->ticketLen - 1] ^= 0xFF;
10474+
10475+ wolfSSL_free(ssl_c);
10476+ ssl_c = NULL;
10477+ wolfSSL_free(ssl_s);
10478+ ssl_s = NULL;
10479+ test_memio_clear_buffer(&test_ctx, 0);
10480+ test_memio_clear_buffer(&test_ctx, 1);
10481+
10482+ ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
10483+ ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
10484+ wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
10485+ wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
10486+ wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
10487+ wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
10488+ ExpectIntEQ(wolfSSL_set_session(ssl_c, session), WOLFSSL_SUCCESS);
10489+ /* Disable the process-global session cache lookup on the server so that
10490+ * the ticket is the only resumption path - with WOLFSSL_TICKET_HAVE_ID
10491+ * the server could otherwise resume by session ID. */
10492+ if (ssl_s != NULL)
10493+ ssl_s->options.sessionCacheOff = 1;
10494+
10495+ /* Corrupted ticket bytes fail the HMAC check in
10496+ * wolfSSL_TicketKeyCb; the session must not resume. */
10497+ ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
10498+ ExpectIntEQ(wolfSSL_session_reused(ssl_c), 0);
10499+
10500+ wolfSSL_SESSION_free(session);
10501+ wolfSSL_free(ssl_c);
10502+ wolfSSL_free(ssl_s);
10503+ wolfSSL_CTX_free(ctx_c);
10504+ wolfSSL_CTX_free(ctx_s);
10505+ OpenSSLTicketCleanup();
10506+ #endif
10507+ return EXPECT_RESULT();
10508+ }
10509+
10510+
1043910511#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
1044010512 !defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
1044110513/* Called when writing. */
@@ -36310,6 +36382,7 @@ TEST_CASE testCases[] = {
3631036382 TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
3631136383 TEST_DECL(test_wolfSSL_SCR_Reconnect),
3631236384 TEST_DECL(test_wolfSSL_SCR_check_enabled),
36385+ TEST_DECL(test_wolfSSL_ticket_keycb_bad_hmac),
3631336386 TEST_DECL(test_tls_ext_duplicate),
3631436387 TEST_DECL(test_tls_bad_legacy_version),
3631536388#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
0 commit comments