Skip to content

Commit dc326f8

Browse files
authored
Merge pull request #10691 from julek-wolfssl/tls13-fragmented-sessionticket-defrag
TLS 1.3: reassemble fragmented post-handshake messages after FreeArrays
2 parents ec37935 + 0963541 commit dc326f8

6 files changed

Lines changed: 210 additions & 72 deletions

File tree

src/internal.c

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8339,8 +8339,6 @@ void FreeArrays(WOLFSSL* ssl, int keep)
83398339
XFREE(ssl->arrays->preMasterSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
83408340
ssl->arrays->preMasterSecret = NULL;
83418341
}
8342-
XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
8343-
ssl->arrays->pendingMsg = NULL;
83448342
ForceZero(ssl->arrays, sizeof(Arrays)); /* clear arrays struct */
83458343
}
83468344
XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
@@ -8863,6 +8861,15 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
88638861

88648862
FreeCiphers(ssl);
88658863
FreeArrays(ssl, 0);
8864+
/* Defrag buffer for fragmented handshake messages. Lives in WOLFSSL (not
8865+
* Arrays) so it survives FreeArrays()/FreeHandshakeResources() and can be
8866+
* used to reassemble post-handshake messages; release it here. */
8867+
XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
8868+
ssl->pendingMsg = NULL;
8869+
/* Reset the rest of the defrag state for a possible object reuse. */
8870+
ssl->pendingMsgSz = 0;
8871+
ssl->pendingMsgOffset = 0;
8872+
ssl->pendingMsgType = 0;
88668873
FreeKeyExchange(ssl);
88678874
#ifdef WOLFSSL_ASYNC_IO
88688875
/* Cleanup async */
@@ -19182,7 +19189,7 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1918219189

1918319190
/* If there is a pending fragmented handshake message,
1918419191
* pending message size will be non-zero. */
19185-
if (ssl->arrays->pendingMsgSz == 0) {
19192+
if (ssl->pendingMsgSz == 0) {
1918619193
byte type;
1918719194
word32 size;
1918819195

@@ -19210,34 +19217,33 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1921019217

1921119218
/* size is the size of the certificate message payload */
1921219219
if (inputLength - HANDSHAKE_HEADER_SZ < size) {
19213-
ssl->arrays->pendingMsgType = type;
19214-
ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
19215-
ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
19216-
ssl->heap,
19217-
DYNAMIC_TYPE_ARRAYS);
19218-
if (ssl->arrays->pendingMsg == NULL)
19220+
/* Commit pending state only after the allocation succeeds. */
19221+
ssl->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
19222+
ssl->heap, DYNAMIC_TYPE_ARRAYS);
19223+
if (ssl->pendingMsg == NULL)
1921919224
return MEMORY_E;
19220-
XMEMCPY(ssl->arrays->pendingMsg,
19225+
ssl->pendingMsgType = type;
19226+
ssl->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
19227+
XMEMCPY(ssl->pendingMsg,
1922119228
input + *inOutIdx - HANDSHAKE_HEADER_SZ,
1922219229
inputLength);
19223-
ssl->arrays->pendingMsgOffset = inputLength;
19230+
ssl->pendingMsgOffset = inputLength;
1922419231
*inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
1922519232
return 0;
1922619233
}
1922719234

1922819235
ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
1922919236
}
1923019237
else {
19231-
word32 pendSz =
19232-
ssl->arrays->pendingMsgSz - ssl->arrays->pendingMsgOffset;
19238+
word32 pendSz = ssl->pendingMsgSz - ssl->pendingMsgOffset;
1923319239

1923419240
/* Catch the case where there may be the remainder of a fragmented
1923519241
* handshake message and the next handshake message in the same
1923619242
* record. */
1923719243
if (inputLength > pendSz)
1923819244
inputLength = pendSz;
1923919245

19240-
ret = EarlySanityCheckMsgReceived(ssl, ssl->arrays->pendingMsgType,
19246+
ret = EarlySanityCheckMsgReceived(ssl, ssl->pendingMsgType,
1924119247
inputLength);
1924219248
if (ret != 0) {
1924319249
WOLFSSL_ERROR(ret);
@@ -19250,32 +19256,32 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1925019256
{
1925119257
/* for async this copy was already done, do not replace, since
1925219258
* contents may have been changed for inline operations */
19253-
XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
19259+
XMEMCPY(ssl->pendingMsg + ssl->pendingMsgOffset,
1925419260
input + *inOutIdx, inputLength);
1925519261
}
19256-
ssl->arrays->pendingMsgOffset += inputLength;
19262+
ssl->pendingMsgOffset += inputLength;
1925719263
*inOutIdx += inputLength;
1925819264

19259-
if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
19265+
if (ssl->pendingMsgOffset == ssl->pendingMsgSz)
1926019266
{
1926119267
word32 idx = HANDSHAKE_HEADER_SZ;
1926219268
ret = DoHandShakeMsgType(ssl,
19263-
ssl->arrays->pendingMsg,
19264-
&idx, ssl->arrays->pendingMsgType,
19265-
ssl->arrays->pendingMsgSz - idx,
19266-
ssl->arrays->pendingMsgSz);
19269+
ssl->pendingMsg,
19270+
&idx, ssl->pendingMsgType,
19271+
ssl->pendingMsgSz - idx,
19272+
ssl->pendingMsgSz);
1926719273
#ifdef WOLFSSL_ASYNC_CRYPT
1926819274
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
1926919275
/* setup to process fragment again */
19270-
ssl->arrays->pendingMsgOffset -= inputLength;
19276+
ssl->pendingMsgOffset -= inputLength;
1927119277
*inOutIdx -= inputLength;
1927219278
}
1927319279
else
1927419280
#endif
1927519281
{
19276-
XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
19277-
ssl->arrays->pendingMsg = NULL;
19278-
ssl->arrays->pendingMsgSz = 0;
19282+
XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
19283+
ssl->pendingMsg = NULL;
19284+
ssl->pendingMsgSz = 0;
1927919285
}
1928019286
}
1928119287
}

src/ssl.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7960,6 +7960,13 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
79607960
ssl->keys.encryptionOn = 0;
79617961
XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
79627962

7963+
/* Discard any partial handshake-message reassembly on reuse. */
7964+
XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
7965+
ssl->pendingMsg = NULL;
7966+
ssl->pendingMsgSz = 0;
7967+
ssl->pendingMsgOffset = 0;
7968+
ssl->pendingMsgType = 0;
7969+
79637970
FreeCiphers(ssl);
79647971
InitCiphers(ssl);
79657972
InitCipherSpecs(&ssl->specs);

src/tls13.c

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14117,24 +14117,6 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1411714117

1411814118
WOLFSSL_ENTER("DoTls13HandShakeMsg");
1411914119

14120-
if (ssl->arrays == NULL) {
14121-
if (GetHandshakeHeader(ssl, input, inOutIdx, &type, &size,
14122-
totalSz) != 0) {
14123-
SendAlert(ssl, alert_fatal, unexpected_message);
14124-
WOLFSSL_ERROR_VERBOSE(PARSE_ERROR);
14125-
return PARSE_ERROR;
14126-
}
14127-
14128-
ret = EarlySanityCheckMsgReceived(ssl, type, size);
14129-
if (ret != 0) {
14130-
WOLFSSL_ERROR(ret);
14131-
return ret;
14132-
}
14133-
14134-
return DoTls13HandShakeMsgType(ssl, input, inOutIdx, type, size,
14135-
totalSz);
14136-
}
14137-
1413814120
/* totalSz is now curStartIdx + curSize (content-only, padSz already
1413914121
* subtracted in ProcessReply). */
1414014122
if (*inOutIdx > totalSz)
@@ -14143,7 +14125,7 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1414314125

1414414126
/* If there is a pending fragmented handshake message,
1414514127
* pending message size will be non-zero. */
14146-
if (ssl->arrays->pendingMsgSz == 0) {
14128+
if (ssl->pendingMsgSz == 0) {
1414714129

1414814130
if (GetHandshakeHeader(ssl, input, inOutIdx, &type, &size,
1414914131
totalSz) != 0) {
@@ -14170,17 +14152,17 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1417014152

1417114153
/* size is the size of the certificate message payload */
1417214154
if (inputLength - HANDSHAKE_HEADER_SZ < size) {
14173-
ssl->arrays->pendingMsgType = type;
14174-
ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
14175-
ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
14176-
ssl->heap,
14177-
DYNAMIC_TYPE_ARRAYS);
14178-
if (ssl->arrays->pendingMsg == NULL)
14155+
/* Commit pending state only after the allocation succeeds. */
14156+
ssl->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
14157+
ssl->heap, DYNAMIC_TYPE_ARRAYS);
14158+
if (ssl->pendingMsg == NULL)
1417914159
return MEMORY_E;
14180-
XMEMCPY(ssl->arrays->pendingMsg,
14160+
ssl->pendingMsgType = type;
14161+
ssl->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
14162+
XMEMCPY(ssl->pendingMsg,
1418114163
input + *inOutIdx - HANDSHAKE_HEADER_SZ,
1418214164
inputLength);
14183-
ssl->arrays->pendingMsgOffset = inputLength;
14165+
ssl->pendingMsgOffset = inputLength;
1418414166
*inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
1418514167
return 0;
1418614168
}
@@ -14189,45 +14171,43 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1418914171
totalSz);
1419014172
}
1419114173
else {
14192-
if (inputLength + ssl->arrays->pendingMsgOffset >
14193-
ssl->arrays->pendingMsgSz) {
14194-
inputLength = ssl->arrays->pendingMsgSz -
14195-
ssl->arrays->pendingMsgOffset;
14174+
if (inputLength + ssl->pendingMsgOffset > ssl->pendingMsgSz) {
14175+
inputLength = ssl->pendingMsgSz - ssl->pendingMsgOffset;
1419614176
}
1419714177

14198-
ret = EarlySanityCheckMsgReceived(ssl, ssl->arrays->pendingMsgType,
14178+
ret = EarlySanityCheckMsgReceived(ssl, ssl->pendingMsgType,
1419914179
inputLength);
1420014180
if (ret != 0) {
1420114181
WOLFSSL_ERROR(ret);
1420214182
return ret;
1420314183
}
1420414184

14205-
XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
14185+
XMEMCPY(ssl->pendingMsg + ssl->pendingMsgOffset,
1420614186
input + *inOutIdx, inputLength);
14207-
ssl->arrays->pendingMsgOffset += inputLength;
14187+
ssl->pendingMsgOffset += inputLength;
1420814188
*inOutIdx += inputLength;
1420914189

14210-
if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
14190+
if (ssl->pendingMsgOffset == ssl->pendingMsgSz)
1421114191
{
1421214192
word32 idx = 0;
1421314193
ret = DoTls13HandShakeMsgType(ssl,
14214-
ssl->arrays->pendingMsg + HANDSHAKE_HEADER_SZ,
14215-
&idx, ssl->arrays->pendingMsgType,
14216-
ssl->arrays->pendingMsgSz - HANDSHAKE_HEADER_SZ,
14217-
ssl->arrays->pendingMsgSz);
14194+
ssl->pendingMsg + HANDSHAKE_HEADER_SZ,
14195+
&idx, ssl->pendingMsgType,
14196+
ssl->pendingMsgSz - HANDSHAKE_HEADER_SZ,
14197+
ssl->pendingMsgSz);
1421814198
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
1421914199
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) ||
1422014200
ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) {
1422114201
/* setup to process fragment again */
14222-
ssl->arrays->pendingMsgOffset -= inputLength;
14202+
ssl->pendingMsgOffset -= inputLength;
1422314203
*inOutIdx -= inputLength;
1422414204
}
1422514205
else
1422614206
#endif
1422714207
{
14228-
XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
14229-
ssl->arrays->pendingMsg = NULL;
14230-
ssl->arrays->pendingMsgSz = 0;
14208+
XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
14209+
ssl->pendingMsg = NULL;
14210+
ssl->pendingMsgSz = 0;
1423114211
}
1423214212
}
1423314213
}

0 commit comments

Comments
 (0)