mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-08 17:20:55 +02:00
Merge pull request #10691 from julek-wolfssl/tls13-fragmented-sessionticket-defrag
TLS 1.3: reassemble fragmented post-handshake messages after FreeArrays
This commit is contained in:
+31
-25
@@ -8339,8 +8339,6 @@ void FreeArrays(WOLFSSL* ssl, int keep)
|
||||
XFREE(ssl->arrays->preMasterSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
|
||||
ssl->arrays->preMasterSecret = NULL;
|
||||
}
|
||||
XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
ssl->arrays->pendingMsg = NULL;
|
||||
ForceZero(ssl->arrays, sizeof(Arrays)); /* clear arrays struct */
|
||||
}
|
||||
XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
@@ -8863,6 +8861,15 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
|
||||
|
||||
FreeCiphers(ssl);
|
||||
FreeArrays(ssl, 0);
|
||||
/* Defrag buffer for fragmented handshake messages. Lives in WOLFSSL (not
|
||||
* Arrays) so it survives FreeArrays()/FreeHandshakeResources() and can be
|
||||
* used to reassemble post-handshake messages; release it here. */
|
||||
XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
ssl->pendingMsg = NULL;
|
||||
/* Reset the rest of the defrag state for a possible object reuse. */
|
||||
ssl->pendingMsgSz = 0;
|
||||
ssl->pendingMsgOffset = 0;
|
||||
ssl->pendingMsgType = 0;
|
||||
FreeKeyExchange(ssl);
|
||||
#ifdef WOLFSSL_ASYNC_IO
|
||||
/* Cleanup async */
|
||||
@@ -19182,7 +19189,7 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
/* If there is a pending fragmented handshake message,
|
||||
* pending message size will be non-zero. */
|
||||
if (ssl->arrays->pendingMsgSz == 0) {
|
||||
if (ssl->pendingMsgSz == 0) {
|
||||
byte type;
|
||||
word32 size;
|
||||
|
||||
@@ -19210,17 +19217,17 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
/* size is the size of the certificate message payload */
|
||||
if (inputLength - HANDSHAKE_HEADER_SZ < size) {
|
||||
ssl->arrays->pendingMsgType = type;
|
||||
ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
|
||||
ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
|
||||
ssl->heap,
|
||||
DYNAMIC_TYPE_ARRAYS);
|
||||
if (ssl->arrays->pendingMsg == NULL)
|
||||
/* Commit pending state only after the allocation succeeds. */
|
||||
ssl->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
|
||||
ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
if (ssl->pendingMsg == NULL)
|
||||
return MEMORY_E;
|
||||
XMEMCPY(ssl->arrays->pendingMsg,
|
||||
ssl->pendingMsgType = type;
|
||||
ssl->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
|
||||
XMEMCPY(ssl->pendingMsg,
|
||||
input + *inOutIdx - HANDSHAKE_HEADER_SZ,
|
||||
inputLength);
|
||||
ssl->arrays->pendingMsgOffset = inputLength;
|
||||
ssl->pendingMsgOffset = inputLength;
|
||||
*inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
|
||||
return 0;
|
||||
}
|
||||
@@ -19228,8 +19235,7 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
|
||||
}
|
||||
else {
|
||||
word32 pendSz =
|
||||
ssl->arrays->pendingMsgSz - ssl->arrays->pendingMsgOffset;
|
||||
word32 pendSz = ssl->pendingMsgSz - ssl->pendingMsgOffset;
|
||||
|
||||
/* Catch the case where there may be the remainder of a fragmented
|
||||
* handshake message and the next handshake message in the same
|
||||
@@ -19237,7 +19243,7 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
if (inputLength > pendSz)
|
||||
inputLength = pendSz;
|
||||
|
||||
ret = EarlySanityCheckMsgReceived(ssl, ssl->arrays->pendingMsgType,
|
||||
ret = EarlySanityCheckMsgReceived(ssl, ssl->pendingMsgType,
|
||||
inputLength);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_ERROR(ret);
|
||||
@@ -19250,32 +19256,32 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
{
|
||||
/* for async this copy was already done, do not replace, since
|
||||
* contents may have been changed for inline operations */
|
||||
XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
|
||||
XMEMCPY(ssl->pendingMsg + ssl->pendingMsgOffset,
|
||||
input + *inOutIdx, inputLength);
|
||||
}
|
||||
ssl->arrays->pendingMsgOffset += inputLength;
|
||||
ssl->pendingMsgOffset += inputLength;
|
||||
*inOutIdx += inputLength;
|
||||
|
||||
if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
|
||||
if (ssl->pendingMsgOffset == ssl->pendingMsgSz)
|
||||
{
|
||||
word32 idx = HANDSHAKE_HEADER_SZ;
|
||||
ret = DoHandShakeMsgType(ssl,
|
||||
ssl->arrays->pendingMsg,
|
||||
&idx, ssl->arrays->pendingMsgType,
|
||||
ssl->arrays->pendingMsgSz - idx,
|
||||
ssl->arrays->pendingMsgSz);
|
||||
ssl->pendingMsg,
|
||||
&idx, ssl->pendingMsgType,
|
||||
ssl->pendingMsgSz - idx,
|
||||
ssl->pendingMsgSz);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
/* setup to process fragment again */
|
||||
ssl->arrays->pendingMsgOffset -= inputLength;
|
||||
ssl->pendingMsgOffset -= inputLength;
|
||||
*inOutIdx -= inputLength;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
ssl->arrays->pendingMsg = NULL;
|
||||
ssl->arrays->pendingMsgSz = 0;
|
||||
XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
ssl->pendingMsg = NULL;
|
||||
ssl->pendingMsgSz = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7960,6 +7960,13 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
|
||||
ssl->keys.encryptionOn = 0;
|
||||
XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
|
||||
|
||||
/* Discard any partial handshake-message reassembly on reuse. */
|
||||
XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
ssl->pendingMsg = NULL;
|
||||
ssl->pendingMsgSz = 0;
|
||||
ssl->pendingMsgOffset = 0;
|
||||
ssl->pendingMsgType = 0;
|
||||
|
||||
FreeCiphers(ssl);
|
||||
InitCiphers(ssl);
|
||||
InitCipherSpecs(&ssl->specs);
|
||||
|
||||
+23
-43
@@ -14117,24 +14117,6 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
WOLFSSL_ENTER("DoTls13HandShakeMsg");
|
||||
|
||||
if (ssl->arrays == NULL) {
|
||||
if (GetHandshakeHeader(ssl, input, inOutIdx, &type, &size,
|
||||
totalSz) != 0) {
|
||||
SendAlert(ssl, alert_fatal, unexpected_message);
|
||||
WOLFSSL_ERROR_VERBOSE(PARSE_ERROR);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
|
||||
ret = EarlySanityCheckMsgReceived(ssl, type, size);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return DoTls13HandShakeMsgType(ssl, input, inOutIdx, type, size,
|
||||
totalSz);
|
||||
}
|
||||
|
||||
/* totalSz is now curStartIdx + curSize (content-only, padSz already
|
||||
* subtracted in ProcessReply). */
|
||||
if (*inOutIdx > totalSz)
|
||||
@@ -14143,7 +14125,7 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
/* If there is a pending fragmented handshake message,
|
||||
* pending message size will be non-zero. */
|
||||
if (ssl->arrays->pendingMsgSz == 0) {
|
||||
if (ssl->pendingMsgSz == 0) {
|
||||
|
||||
if (GetHandshakeHeader(ssl, input, inOutIdx, &type, &size,
|
||||
totalSz) != 0) {
|
||||
@@ -14170,17 +14152,17 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
/* size is the size of the certificate message payload */
|
||||
if (inputLength - HANDSHAKE_HEADER_SZ < size) {
|
||||
ssl->arrays->pendingMsgType = type;
|
||||
ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
|
||||
ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
|
||||
ssl->heap,
|
||||
DYNAMIC_TYPE_ARRAYS);
|
||||
if (ssl->arrays->pendingMsg == NULL)
|
||||
/* Commit pending state only after the allocation succeeds. */
|
||||
ssl->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
|
||||
ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
if (ssl->pendingMsg == NULL)
|
||||
return MEMORY_E;
|
||||
XMEMCPY(ssl->arrays->pendingMsg,
|
||||
ssl->pendingMsgType = type;
|
||||
ssl->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
|
||||
XMEMCPY(ssl->pendingMsg,
|
||||
input + *inOutIdx - HANDSHAKE_HEADER_SZ,
|
||||
inputLength);
|
||||
ssl->arrays->pendingMsgOffset = inputLength;
|
||||
ssl->pendingMsgOffset = inputLength;
|
||||
*inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
|
||||
return 0;
|
||||
}
|
||||
@@ -14189,45 +14171,43 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
totalSz);
|
||||
}
|
||||
else {
|
||||
if (inputLength + ssl->arrays->pendingMsgOffset >
|
||||
ssl->arrays->pendingMsgSz) {
|
||||
inputLength = ssl->arrays->pendingMsgSz -
|
||||
ssl->arrays->pendingMsgOffset;
|
||||
if (inputLength + ssl->pendingMsgOffset > ssl->pendingMsgSz) {
|
||||
inputLength = ssl->pendingMsgSz - ssl->pendingMsgOffset;
|
||||
}
|
||||
|
||||
ret = EarlySanityCheckMsgReceived(ssl, ssl->arrays->pendingMsgType,
|
||||
ret = EarlySanityCheckMsgReceived(ssl, ssl->pendingMsgType,
|
||||
inputLength);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
|
||||
XMEMCPY(ssl->pendingMsg + ssl->pendingMsgOffset,
|
||||
input + *inOutIdx, inputLength);
|
||||
ssl->arrays->pendingMsgOffset += inputLength;
|
||||
ssl->pendingMsgOffset += inputLength;
|
||||
*inOutIdx += inputLength;
|
||||
|
||||
if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
|
||||
if (ssl->pendingMsgOffset == ssl->pendingMsgSz)
|
||||
{
|
||||
word32 idx = 0;
|
||||
ret = DoTls13HandShakeMsgType(ssl,
|
||||
ssl->arrays->pendingMsg + HANDSHAKE_HEADER_SZ,
|
||||
&idx, ssl->arrays->pendingMsgType,
|
||||
ssl->arrays->pendingMsgSz - HANDSHAKE_HEADER_SZ,
|
||||
ssl->arrays->pendingMsgSz);
|
||||
ssl->pendingMsg + HANDSHAKE_HEADER_SZ,
|
||||
&idx, ssl->pendingMsgType,
|
||||
ssl->pendingMsgSz - HANDSHAKE_HEADER_SZ,
|
||||
ssl->pendingMsgSz);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) ||
|
||||
ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) {
|
||||
/* setup to process fragment again */
|
||||
ssl->arrays->pendingMsgOffset -= inputLength;
|
||||
ssl->pendingMsgOffset -= inputLength;
|
||||
*inOutIdx -= inputLength;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
ssl->arrays->pendingMsg = NULL;
|
||||
ssl->arrays->pendingMsgSz = 0;
|
||||
XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
|
||||
ssl->pendingMsg = NULL;
|
||||
ssl->pendingMsgSz = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user