Skip to content

Commit 403f0fe

Browse files
authored
Merge pull request #10230 from julek-wolfssl/fenrir/20260415
Fenrir fixes
2 parents aaca094 + 9d49f7f commit 403f0fe

4 files changed

Lines changed: 525 additions & 20 deletions

File tree

src/tls.c

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,16 +1816,20 @@ static void TLSX_ALPN_FreeAll(ALPN *list, void* heap)
18161816
static word16 TLSX_ALPN_GetSize(ALPN *list)
18171817
{
18181818
ALPN* alpn;
1819-
word16 length = OPAQUE16_LEN; /* list length */
1819+
word32 length = OPAQUE16_LEN; /* list length */
18201820

18211821
while ((alpn = list)) {
18221822
list = alpn->next;
18231823

18241824
length++; /* protocol name length is on one byte */
1825-
length += (word16)XSTRLEN(alpn->protocol_name);
1825+
length += (word32)XSTRLEN(alpn->protocol_name);
1826+
1827+
if (length > WOLFSSL_MAX_16BIT) {
1828+
return 0;
1829+
}
18261830
}
18271831

1828-
return length;
1832+
return (word16)length;
18291833
}
18301834

18311835
/** Writes the ALPN objects of a list in a buffer. */
@@ -2951,7 +2955,7 @@ static void TLSX_TCA_FreeAll(TCA* list, void* heap)
29512955
static word16 TLSX_TCA_GetSize(TCA* list)
29522956
{
29532957
TCA* tca;
2954-
word16 length = OPAQUE16_LEN; /* list length */
2958+
word32 length = OPAQUE16_LEN; /* list length */
29552959

29562960
while ((tca = list)) {
29572961
list = tca->next;
@@ -2969,9 +2973,13 @@ static word16 TLSX_TCA_GetSize(TCA* list)
29692973
length += OPAQUE16_LEN + tca->idSz;
29702974
break;
29712975
}
2976+
2977+
if (length > WOLFSSL_MAX_16BIT) {
2978+
return 0;
2979+
}
29722980
}
29732981

2974-
return length;
2982+
return (word16)length;
29752983
}
29762984

29772985
/** Writes the TCA objects of a list in a buffer. */
@@ -7498,7 +7506,7 @@ static word16 TLSX_CA_Names_GetSize(void* data)
74987506
{
74997507
WOLFSSL* ssl = (WOLFSSL*)data;
75007508
WOLF_STACK_OF(WOLFSSL_X509_NAME)* names;
7501-
word16 size = 0;
7509+
word32 size = 0;
75027510

75037511
/* Length of names */
75047512
size += OPAQUE16_LEN;
@@ -7508,11 +7516,14 @@ static word16 TLSX_CA_Names_GetSize(void* data)
75087516

75097517
if (name != NULL) {
75107518
/* 16-bit length | SEQ | Len | DER of name */
7511-
size += (word16)(OPAQUE16_LEN + SetSequence(name->rawLen, seq) +
7519+
size += (word32)(OPAQUE16_LEN + SetSequence(name->rawLen, seq) +
75127520
name->rawLen);
7521+
if (size > WOLFSSL_MAX_16BIT) {
7522+
return 0;
7523+
}
75137524
}
75147525
}
7515-
return size;
7526+
return (word16)size;
75167527
}
75177528

75187529
static word16 TLSX_CA_Names_Write(void* data, byte* output)
@@ -11833,14 +11844,22 @@ static int TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType,
1183311844
{
1183411845
if (msgType == client_hello) {
1183511846
/* Length of identities + Length of binders. */
11836-
word16 len = OPAQUE16_LEN + OPAQUE16_LEN;
11847+
word32 len = OPAQUE16_LEN + OPAQUE16_LEN;
1183711848
while (list != NULL) {
1183811849
/* Each entry has: identity, ticket age and binder. */
1183911850
len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN +
11840-
OPAQUE8_LEN + (word16)list->binderLen;
11851+
OPAQUE8_LEN + (word32)list->binderLen;
11852+
if (len > WOLFSSL_MAX_16BIT) {
11853+
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11854+
return LENGTH_ERROR;
11855+
}
1184111856
list = list->next;
1184211857
}
11843-
*pSz += len;
11858+
if ((word32)*pSz + len > WOLFSSL_MAX_16BIT) {
11859+
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11860+
return LENGTH_ERROR;
11861+
}
11862+
*pSz += (word16)len;
1184411863
return 0;
1184511864
}
1184611865

@@ -11863,7 +11882,7 @@ static int TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType,
1186311882
int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType,
1186411883
word16* pSz)
1186511884
{
11866-
word16 len;
11885+
word32 len;
1186711886

1186811887
if (msgType != client_hello) {
1186911888
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
@@ -11873,11 +11892,15 @@ int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType,
1187311892
/* Length of all binders. */
1187411893
len = OPAQUE16_LEN;
1187511894
while (list != NULL) {
11876-
len += OPAQUE8_LEN + (word16)list->binderLen;
11895+
len += OPAQUE8_LEN + (word32)list->binderLen;
11896+
if (len > WOLFSSL_MAX_16BIT) {
11897+
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11898+
return LENGTH_ERROR;
11899+
}
1187711900
list = list->next;
1187811901
}
1187911902

11880-
*pSz = len;
11903+
*pSz = (word16)len;
1188111904
return 0;
1188211905
}
1188311906

@@ -14837,8 +14860,15 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1483714860

1483814861
case TLSX_TRUSTED_CA_KEYS:
1483914862
/* TCA only sends the list on the request. */
14840-
if (isRequest)
14841-
length += TCA_GET_SIZE((TCA*)extension->data);
14863+
if (isRequest) {
14864+
word16 tcaSz = TCA_GET_SIZE((TCA*)extension->data);
14865+
/* 0 on non-empty list means 16-bit overflow. */
14866+
if (tcaSz == 0 && extension->data != NULL) {
14867+
ret = LENGTH_ERROR;
14868+
break;
14869+
}
14870+
length += tcaSz;
14871+
}
1484214872
break;
1484314873

1484414874
case TLSX_MAX_FRAGMENT_LENGTH:
@@ -14879,9 +14909,16 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1487914909
isRequest);
1488014910
break;
1488114911

14882-
case TLSX_APPLICATION_LAYER_PROTOCOL:
14883-
length += ALPN_GET_SIZE((ALPN*)extension->data);
14912+
case TLSX_APPLICATION_LAYER_PROTOCOL: {
14913+
word16 alpnSz = ALPN_GET_SIZE((ALPN*)extension->data);
14914+
/* 0 on non-empty list means 16-bit overflow. */
14915+
if (alpnSz == 0 && extension->data != NULL) {
14916+
ret = LENGTH_ERROR;
14917+
break;
14918+
}
14919+
length += alpnSz;
1488414920
break;
14921+
}
1488514922
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
1488614923
case TLSX_SIGNATURE_ALGORITHMS:
1488714924
length += SA_GET_SIZE(extension->data);
@@ -14959,9 +14996,16 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1495914996
#endif
1496014997

1496114998
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
14962-
case TLSX_CERTIFICATE_AUTHORITIES:
14963-
length += CAN_GET_SIZE(extension->data);
14999+
case TLSX_CERTIFICATE_AUTHORITIES: {
15000+
word16 canSz = CAN_GET_SIZE(extension->data);
15001+
/* 0 on non-empty list means 16-bit overflow. */
15002+
if (canSz == 0 && extension->data != NULL) {
15003+
ret = LENGTH_ERROR;
15004+
break;
15005+
}
15006+
length += canSz;
1496415007
break;
15008+
}
1496515009
#endif
1496615010
#endif
1496715011
#ifdef WOLFSSL_SRTP
@@ -15001,6 +15045,9 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1500115045
break;
1500215046
}
1500315047

15048+
if (ret != 0)
15049+
return ret;
15050+
1500415051
/* Early exit: stop accumulating as soon as the running total
1500515052
* cannot possibly fit the 2-byte wire length. Check *before*
1500615053
* marking the extension as processed so the semaphore is not

tests/api.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10472,6 +10472,78 @@ static int test_wolfSSL_SCR_check_enabled(void)
1047210472
return EXPECT_RESULT();
1047310473
}
1047410474

10475+
/* F-2922: wolfSSL_TicketKeyCb must reject a session ticket whose HMAC
10476+
* does not match its encrypted contents. */
10477+
static int test_wolfSSL_ticket_keycb_bad_hmac(void)
10478+
{
10479+
EXPECT_DECLS;
10480+
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_TLS12) && \
10481+
defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC) && \
10482+
defined(WOLFSSL_AES_256) && \
10483+
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
10484+
!defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
10485+
struct test_memio_ctx test_ctx;
10486+
WOLFSSL_CTX *ctx_c = NULL;
10487+
WOLFSSL_CTX *ctx_s = NULL;
10488+
WOLFSSL *ssl_c = NULL;
10489+
WOLFSSL *ssl_s = NULL;
10490+
WOLFSSL_SESSION *session = NULL;
10491+
10492+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
10493+
10494+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
10495+
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
10496+
10497+
ExpectIntEQ(OpenSSLTicketInit(), 0);
10498+
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_key_cb(ctx_s,
10499+
myTicketEncCbOpenSSL), WOLFSSL_SUCCESS);
10500+
ExpectIntEQ(wolfSSL_UseSessionTicket(ssl_c), WOLFSSL_SUCCESS);
10501+
10502+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
10503+
ExpectNotNull(session = wolfSSL_get1_session(ssl_c));
10504+
ExpectIntGT(session->ticketLen, 0);
10505+
10506+
/* Corrupt a byte of the ticket HMAC so the server's HMAC
10507+
* verification rejects it. */
10508+
if (session != NULL && session->ticket != NULL && session->ticketLen > 0)
10509+
session->ticket[session->ticketLen - 1] ^= 0xFF;
10510+
10511+
wolfSSL_free(ssl_c);
10512+
ssl_c = NULL;
10513+
wolfSSL_free(ssl_s);
10514+
ssl_s = NULL;
10515+
test_memio_clear_buffer(&test_ctx, 0);
10516+
test_memio_clear_buffer(&test_ctx, 1);
10517+
10518+
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
10519+
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
10520+
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
10521+
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
10522+
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
10523+
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
10524+
ExpectIntEQ(wolfSSL_set_session(ssl_c, session), WOLFSSL_SUCCESS);
10525+
/* Disable the process-global session cache lookup on the server so that
10526+
* the ticket is the only resumption path - with WOLFSSL_TICKET_HAVE_ID
10527+
* the server could otherwise resume by session ID. */
10528+
if (ssl_s != NULL)
10529+
ssl_s->options.sessionCacheOff = 1;
10530+
10531+
/* Corrupted ticket bytes fail the HMAC check in
10532+
* wolfSSL_TicketKeyCb; the session must not resume. */
10533+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
10534+
ExpectIntEQ(wolfSSL_session_reused(ssl_c), 0);
10535+
10536+
wolfSSL_SESSION_free(session);
10537+
wolfSSL_free(ssl_c);
10538+
wolfSSL_free(ssl_s);
10539+
wolfSSL_CTX_free(ctx_c);
10540+
wolfSSL_CTX_free(ctx_s);
10541+
OpenSSLTicketCleanup();
10542+
#endif
10543+
return EXPECT_RESULT();
10544+
}
10545+
10546+
1047510547
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
1047610548
!defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
1047710549
/* Called when writing. */
@@ -37767,6 +37839,12 @@ TEST_CASE testCases[] = {
3776737839
TEST_DECL(test_wolfSSL_select_next_proto),
3776837840
#endif
3776937841
TEST_DECL(test_tls_ems_downgrade),
37842+
TEST_DECL(test_tls_ems_resumption_downgrade),
37843+
TEST_DECL(test_tls12_chacha20_poly1305_bad_tag),
37844+
TEST_DECL(test_tls13_null_cipher_bad_hmac),
37845+
TEST_DECL(test_scr_verify_data_mismatch),
37846+
TEST_DECL(test_tls13_hrr_cipher_suite_mismatch),
37847+
TEST_DECL(test_tls13_ticket_age_out_of_window),
3777037848
TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret),
3777137849
TEST_DECL(test_certificate_authorities_certificate_request),
3777237850
TEST_DECL(test_certificate_authorities_client_hello),
@@ -37776,6 +37854,7 @@ TEST_CASE testCases[] = {
3777637854
TEST_DECL(test_wolfSSL_clear_secure_renegotiation),
3777737855
TEST_DECL(test_wolfSSL_SCR_Reconnect),
3777837856
TEST_DECL(test_wolfSSL_SCR_check_enabled),
37857+
TEST_DECL(test_wolfSSL_ticket_keycb_bad_hmac),
3777937858
TEST_DECL(test_tls_ext_duplicate),
3778037859
TEST_DECL(test_tls_ext_word16_overflow),
3778137860
TEST_DECL(test_tls_bad_legacy_version),

0 commit comments

Comments
 (0)