Skip to content

Commit fc7c19b

Browse files
authored
Merge pull request #9934 from SparkiDev/tls_length_fixes_1
TLS: Better handling of parsing TLS extensions
2 parents 2db5fbb + 0683dab commit fc7c19b

1 file changed

Lines changed: 58 additions & 31 deletions

File tree

src/tls.c

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4085,7 +4085,7 @@ static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length,
40854085
return BUFFER_ERROR;
40864086

40874087
ato16(input + offset, &size);
4088-
if (length - offset < size)
4088+
if (length - offset - OPAQUE16_LEN < size)
40894089
return BUFFER_ERROR;
40904090

40914091
offset += OPAQUE16_LEN + size;
@@ -6611,11 +6611,27 @@ static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length,
66116611
/* total length, not include itself */
66126612
ato16(input, &profile_len);
66136613
offset += OPAQUE16_LEN;
6614+
/* Check profile length is not bigger than remaining length. */
6615+
if (profile_len > length - offset) {
6616+
return BUFFER_ERROR;
6617+
}
6618+
/* Protection profiles are 2 bytes long - ensure not an odd no. bytes. */
6619+
if ((profile_len & 1) == 1) {
6620+
return BUFFER_ERROR;
6621+
}
6622+
/* Ignoring srtp_mki field - SRTP Make Key Identifier.
6623+
* Defined to be 0..255 bytes long.
6624+
*/
6625+
if ((length - profile_len - offset) > 255) {
6626+
return BUFFER_ERROR;
6627+
}
66146628

66156629
if (!isRequest) {
66166630
#ifndef NO_WOLFSSL_CLIENT
6617-
if (length < offset + OPAQUE16_LEN)
6631+
/* Only one SRTP Protection Profile can be chosen. */
6632+
if (profile_len != OPAQUE16_LEN) {
66186633
return BUFFER_ERROR;
6634+
}
66196635

66206636
ato16(input + offset, &profile_value);
66216637

@@ -6630,14 +6646,8 @@ static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length,
66306646
else {
66316647
/* parse remainder one profile at a time, looking for match in CTX */
66326648
ret = 0;
6633-
for (i=offset; i<length; i+=OPAQUE16_LEN) {
6634-
if (length < (i + OPAQUE16_LEN)) {
6635-
WOLFSSL_MSG("Unexpected length when parsing SRTP profile");
6636-
ret = BUFFER_ERROR;
6637-
break;
6638-
}
6639-
6640-
ato16(input+i, &profile_value);
6649+
for (i = 0; i < profile_len; i += OPAQUE16_LEN) {
6650+
ato16(input + offset + i, &profile_value);
66416651
/* find first match */
66426652
if (profile_value < 16 &&
66436653
ssl->dtlsSrtpProfiles & (1 << profile_value)) {
@@ -6669,7 +6679,6 @@ static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length,
66696679
ssl->dtlsSrtpId = 0;
66706680
TLSX_UseSRTP_Free(srtp, ssl->heap);
66716681
}
6672-
(void)profile_len;
66736682

66746683
return ret;
66756684
}
@@ -7457,7 +7466,7 @@ static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input,
74577466
return BUFFER_ERROR;
74587467

74597468
while (length) {
7460-
word32 idx = 0;
7469+
word16 idx = 0;
74617470
WOLFSSL_X509_NAME* name = NULL;
74627471
int ret = 0;
74637472
int didInit = FALSE;
@@ -7480,7 +7489,7 @@ static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input,
74807489
ato16(input, &extLen);
74817490
idx += OPAQUE16_LEN;
74827491

7483-
if (idx + extLen > length)
7492+
if (extLen > length - idx)
74847493
ret = BUFFER_ERROR;
74857494
}
74867495

@@ -7510,7 +7519,7 @@ static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input,
75107519
return ret;
75117520

75127521
input += idx;
7513-
length -= (word16)idx;
7522+
length -= idx;
75147523
}
75157524
return 0;
75167525
}
@@ -7641,12 +7650,11 @@ static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, const byte* input,
76417650
if (length != OPAQUE16_LEN + len)
76427651
return BUFFER_ERROR;
76437652

7653+
/* Truncate hashSigAlgo list if too long. */
7654+
suites->hashSigAlgoSz = len;
76447655
/* Sig Algo list size must be even. */
76457656
if (suites->hashSigAlgoSz % 2 != 0)
76467657
return BUFFER_ERROR;
7647-
7648-
/* truncate hashSigAlgo list if too long */
7649-
suites->hashSigAlgoSz = len;
76507658
if (suites->hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
76517659
WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
76527660
suites->hashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
@@ -13556,7 +13564,11 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1355613564
WOLFSSL_EchConfig* echConfig;
1355713565
byte* aadCopy;
1355813566
byte* readBuf_p = (byte*)readBuf;
13567+
word32 offset = 0;
13568+
word16 len;
13569+
1355913570
WOLFSSL_MSG("TLSX_ECH_Parse");
13571+
1356013572
if (size == 0)
1356113573
return BAD_FUNC_ARG;
1356213574
if (ssl->options.disableECH) {
@@ -13591,43 +13603,58 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1359113603
/* read the ech parameters before the payload */
1359213604
ech->type = *readBuf_p;
1359313605
readBuf_p++;
13606+
offset += 1;
1359413607
if (ech->type == ECH_TYPE_INNER) {
1359513608
ech->state = ECH_PARSED_INTERNAL;
1359613609
return 0;
1359713610
}
13598-
/* technically the payload would only be 1 byte at this length */
13599-
if (size < 11 + ech->encLen)
13600-
return BAD_FUNC_ARG;
13611+
/* Must have kdfId, aeadId, configId, enc len and payload len. */
13612+
if (size < offset + 2 + 2 + 1 + 2 + 2) {
13613+
return BUFFER_ERROR;
13614+
}
1360113615
/* read kdfId */
1360213616
ato16(readBuf_p, &ech->cipherSuite.kdfId);
1360313617
readBuf_p += 2;
13618+
offset += 2;
1360413619
/* read aeadId */
1360513620
ato16(readBuf_p, &ech->cipherSuite.aeadId);
1360613621
readBuf_p += 2;
13622+
offset += 2;
1360713623
/* read configId */
1360813624
ech->configId = *readBuf_p;
1360913625
readBuf_p++;
13626+
offset++;
13627+
/* read encLen */
13628+
ato16(readBuf_p, &len);
13629+
readBuf_p += 2;
13630+
offset += 2;
13631+
/* Check encLen isn't more than remaining bytes minus payload length. */
13632+
if (len > size - offset - 2) {
13633+
return BAD_FUNC_ARG;
13634+
}
13635+
if (len > HPKE_Npk_MAX) {
13636+
return BAD_FUNC_ARG;
13637+
}
1361013638
/* only get enc if we don't already have the hpke context */
1361113639
if (ech->hpkeContext == NULL) {
13612-
/* read encLen */
13613-
ato16(readBuf_p, &ech->encLen);
13614-
readBuf_p += 2;
13615-
if (ech->encLen > HPKE_Npk_MAX)
13616-
return BAD_FUNC_ARG;
1361713640
/* read enc */
13618-
XMEMCPY(ech->enc, readBuf_p, ech->encLen);
13619-
readBuf_p += ech->encLen;
13620-
}
13621-
else {
13622-
readBuf_p += 2;
13641+
XMEMCPY(ech->enc, readBuf_p, len);
13642+
ech->encLen = len;
1362313643
}
13644+
readBuf_p += len;
13645+
offset += len;
1362413646
/* read hello inner len */
1362513647
ato16(readBuf_p, &ech->innerClientHelloLen);
13648+
readBuf_p += 2;
13649+
offset += 2;
13650+
/* Check payload is no biffer than remaining bytes. */
13651+
if (ech->innerClientHelloLen > size - offset) {
13652+
return BAD_FUNC_ARG;
13653+
}
1362613654
if (ech->innerClientHelloLen < WC_AES_BLOCK_SIZE) {
1362713655
return BUFFER_ERROR;
1362813656
}
1362913657
ech->innerClientHelloLen -= WC_AES_BLOCK_SIZE;
13630-
readBuf_p += 2;
1363113658
ech->outerClientPayload = readBuf_p;
1363213659
/* make a copy of the aad */
1363313660
aadCopy = (byte*)XMALLOC(ech->aadLen, ssl->heap,

0 commit comments

Comments
 (0)