Skip to content

Commit 6f2d48c

Browse files
committed
Fix from review
1 parent 412c428 commit 6f2d48c

1 file changed

Lines changed: 50 additions & 15 deletions

File tree

src/tls.c

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15125,11 +15125,20 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
1512515125
{
1512615126
int ret = 0;
1512715127
TLSX* extension;
15128-
word16 offset = 0;
15129-
word16 length_offset = 0;
15128+
/* Use word32 to symmetrize with TLSX_GetSize -- a single extension can
15129+
* contribute up to 0x10003 bytes (4-byte type/length header + 0xFFFF
15130+
* payload), which would word16-overflow undetectably (e.g. wrap to a
15131+
* value still above prevOffset). Per-iteration and aggregate bounds are
15132+
* checked below before truncating back into the word16 wire fields.
15133+
* Callees that take a word16* offset use the cbShim pattern (init to 0,
15134+
* then add the returned delta to the word32 accumulator). */
15135+
word32 offset = 0;
15136+
word32 length_offset = 0;
1513015137
word32 prevOffset;
15138+
word16 cbShim = 0;
1513115139
byte isRequest = (msgType == client_hello ||
1513215140
msgType == certificate_request);
15141+
(void)cbShim;
1513315142

1513415143
while ((extension = list)) {
1513515144
list = extension->next;
@@ -15249,28 +15258,36 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
1524915258
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
1525015259
case TLSX_ENCRYPT_THEN_MAC:
1525115260
WOLFSSL_MSG("Encrypt-Then-Mac extension to write");
15252-
ret = ETM_WRITE(extension->data, output, msgType, &offset);
15261+
cbShim = 0;
15262+
ret = ETM_WRITE(extension->data, output, msgType, &cbShim);
15263+
offset += cbShim;
1525315264
break;
1525415265
#endif /* HAVE_ENCRYPT_THEN_MAC */
1525515266

1525615267
#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
1525715268
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
1525815269
case TLSX_PRE_SHARED_KEY:
1525915270
WOLFSSL_MSG("Pre-Shared Key extension to write");
15271+
cbShim = 0;
1526015272
ret = PSK_WRITE((PreSharedKey*)extension->data, output + offset,
15261-
msgType, &offset);
15273+
msgType, &cbShim);
15274+
offset += cbShim;
1526215275
break;
1526315276

1526415277
#ifdef WOLFSSL_TLS13
1526515278
case TLSX_PSK_KEY_EXCHANGE_MODES:
1526615279
WOLFSSL_MSG("PSK Key Exchange Modes extension to write");
15280+
cbShim = 0;
1526715281
ret = PKM_WRITE((byte)extension->val, output + offset, msgType,
15268-
&offset);
15282+
&cbShim);
15283+
offset += cbShim;
1526915284
break;
1527015285
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
1527115286
case TLSX_CERT_WITH_EXTERN_PSK:
1527215287
WOLFSSL_MSG("Cert with external PSK extension to write");
15273-
ret = PSK_WITH_CERT_WRITE(output + offset, msgType, &offset);
15288+
cbShim = 0;
15289+
ret = PSK_WITH_CERT_WRITE(output + offset, msgType, &cbShim);
15290+
offset += cbShim;
1527415291
break;
1527515292
#endif
1527615293
#endif
@@ -15284,28 +15301,36 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
1528415301
#ifdef WOLFSSL_TLS13
1528515302
case TLSX_SUPPORTED_VERSIONS:
1528615303
WOLFSSL_MSG("Supported Versions extension to write");
15304+
cbShim = 0;
1528715305
ret = SV_WRITE(extension->data, output + offset, msgType,
15288-
&offset);
15306+
&cbShim);
15307+
offset += cbShim;
1528915308
break;
1529015309

1529115310
case TLSX_COOKIE:
1529215311
WOLFSSL_MSG("Cookie extension to write");
15312+
cbShim = 0;
1529315313
ret = CKE_WRITE((Cookie*)extension->data, output + offset,
15294-
msgType, &offset);
15314+
msgType, &cbShim);
15315+
offset += cbShim;
1529515316
break;
1529615317

1529715318
#ifdef WOLFSSL_EARLY_DATA
1529815319
case TLSX_EARLY_DATA:
1529915320
WOLFSSL_MSG("Early Data extension to write");
15321+
cbShim = 0;
1530015322
ret = EDI_WRITE(extension->val, output + offset, msgType,
15301-
&offset);
15323+
&cbShim);
15324+
offset += cbShim;
1530215325
break;
1530315326
#endif
1530415327

1530515328
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
1530615329
case TLSX_POST_HANDSHAKE_AUTH:
1530715330
WOLFSSL_MSG("Post-Handshake Authentication extension to write");
15308-
ret = PHA_WRITE(output + offset, msgType, &offset);
15331+
cbShim = 0;
15332+
ret = PHA_WRITE(output + offset, msgType, &cbShim);
15333+
offset += cbShim;
1530915334
break;
1531015335
#endif
1531115336

@@ -15361,16 +15386,26 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
1536115386
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
1536215387
case TLSX_ECH:
1536315388
WOLFSSL_MSG("ECH extension to write");
15389+
cbShim = 0;
1536415390
ret = ECH_WRITE((WOLFSSL_ECH*)extension->data, msgType,
15365-
output + offset, &offset);
15391+
output + offset, &cbShim);
15392+
offset += cbShim;
1536615393
break;
1536715394
#endif
1536815395
default:
1536915396
break;
1537015397
}
1537115398

15399+
/* Per-extension data length is a 2-byte wire field; reject any
15400+
* single extension whose payload exceeds that before truncating. */
15401+
if (offset - length_offset > WOLFSSL_MAX_16BIT) {
15402+
WOLFSSL_MSG("TLSX_Write single extension length exceeds word16");
15403+
return BUFFER_E;
15404+
}
15405+
1537215406
/* writes extension data length. */
15373-
c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN);
15407+
c16toa((word16)(offset - length_offset),
15408+
output + length_offset - OPAQUE16_LEN);
1537415409

1537515410
/* marks the extension as processed so ctx level */
1537615411
/* extensions don't overlap with ssl level ones. */
@@ -15381,7 +15416,7 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
1538115416
break;
1538215417

1538315418
if (offset <= prevOffset) {
15384-
WOLFSSL_MSG("TLSX_Write extension length exceeds word16");
15419+
WOLFSSL_MSG("TLSX_Write extension made no progress");
1538515420
return BUFFER_E;
1538615421
}
1538715422
}
@@ -15391,11 +15426,11 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
1539115426
* unchanged and return the original failure reason so callers
1539215427
* see the real error instead of a masking BUFFER_E. */
1539315428
if (ret == 0) {
15394-
if ((word32)*pOffset + (word32)offset > WOLFSSL_MAX_16BIT) {
15429+
if ((word32)*pOffset + offset > WOLFSSL_MAX_16BIT) {
1539515430
WOLFSSL_MSG("TLSX_Write total extensions length exceeds word16");
1539615431
return BUFFER_E;
1539715432
}
15398-
*pOffset += offset;
15433+
*pOffset += (word16)offset;
1539915434
}
1540015435

1540115436
return ret;

0 commit comments

Comments
 (0)