@@ -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 }
0 commit comments