@@ -10528,6 +10528,83 @@ static int test_tls_ext_word16_overflow(void)
1052810528 wolfSSL_free(ssl);
1052910529 wolfSSL_CTX_free(ctx);
1053010530 XFREE(big, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10531+ ssl = NULL;
10532+ ctx = NULL;
10533+ big = NULL;
10534+
10535+ /* Boundary case: construct a SessionTicket extension sized so that the
10536+ * total extensions length in TLSX_GetRequestSize is exactly
10537+ * WOLFSSL_MAX_16BIT - OPAQUE16_LEN (0xFFFD) *before* the OPAQUE16_LEN
10538+ * block-prefix adjustment, which must succeed. This pins the `>`
10539+ * comparison in the overflow check — mutating it to `>=` would
10540+ * incorrectly reject this valid case and fail this test. */
10541+ {
10542+ WOLFSSL_CTX* ctx2 = NULL;
10543+ WOLFSSL* ssl2 = NULL;
10544+ SessionTicket* ticket2 = NULL;
10545+ byte* buf = NULL;
10546+ word32 baseLen = 0;
10547+ word32 baseInternal = 0;
10548+ word32 tickSz = 0;
10549+ /* TLSX_GetRequestSize rejects when internal sum > 0xFFFD. */
10550+ const word32 target = (word32)WOLFSSL_MAX_16BIT - (word32)OPAQUE16_LEN;
10551+ /* Session ticket extension contributes: type (2) + len (2) + size. */
10552+ const word32 extHdr = (word32)HELLO_EXT_TYPE_SZ
10553+ + (word32)OPAQUE16_LEN;
10554+ int ret;
10555+
10556+ ExpectNotNull(ctx2 = wolfSSL_CTX_new(wolfSSLv23_client_method()));
10557+ ExpectNotNull(ssl2 = wolfSSL_new(ctx2));
10558+
10559+ /* Measure baseline length with no session ticket extension. The
10560+ * returned value already includes the 2-byte block-length prefix
10561+ * when nonzero; strip it to get the raw internal sum. */
10562+ if (EXPECT_SUCCESS()) {
10563+ baseLen = 0;
10564+ ret = TLSX_GetRequestSize(ssl2, client_hello, &baseLen);
10565+ ExpectIntEQ(ret, 0);
10566+ baseInternal = (baseLen > 0)
10567+ ? baseLen - (word32)OPAQUE16_LEN : 0;
10568+ }
10569+
10570+ /* Target: baseInternal + extHdr + tickSz == 0xFFFD. */
10571+ if (EXPECT_SUCCESS() && baseInternal + extHdr < target) {
10572+ tickSz = target - baseInternal - extHdr;
10573+ }
10574+
10575+ if (EXPECT_SUCCESS() && tickSz > 0 && tickSz <= WOLFSSL_MAX_16BIT) {
10576+ buf = (byte*)XMALLOC(tickSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10577+ ExpectNotNull(buf);
10578+ if (buf != NULL)
10579+ XMEMSET(buf, 0x5A, tickSz);
10580+ }
10581+
10582+ if (EXPECT_SUCCESS() && buf != NULL) {
10583+ ticket2 = TLSX_SessionTicket_Create(0, buf, (word16)tickSz,
10584+ ssl2->heap);
10585+ ExpectNotNull(ticket2);
10586+ }
10587+ if (EXPECT_SUCCESS() && ticket2 != NULL) {
10588+ ExpectIntEQ(TLSX_UseSessionTicket(&ssl2->extensions, ticket2,
10589+ ssl2->heap), WOLFSSL_SUCCESS);
10590+ ticket2 = NULL;
10591+ }
10592+
10593+ /* Exact boundary: internal sum == 0xFFFD must succeed, and the
10594+ * final returned length is 0xFFFD + OPAQUE16_LEN == 0xFFFF. */
10595+ if (EXPECT_SUCCESS()) {
10596+ word32 lenBoundary = 0;
10597+ ret = TLSX_GetRequestSize(ssl2, client_hello, &lenBoundary);
10598+ ExpectIntEQ(ret, 0);
10599+ ExpectIntEQ(lenBoundary, (word32)WOLFSSL_MAX_16BIT);
10600+ }
10601+
10602+ if (ticket2 != NULL)
10603+ TLSX_SessionTicket_Free(ticket2, ssl2->heap);
10604+ wolfSSL_free(ssl2);
10605+ wolfSSL_CTX_free(ctx2);
10606+ XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10607+ }
1053110608#endif
1053210609 return EXPECT_RESULT();
1053310610}
0 commit comments