mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-04 05:04:41 +02:00
added DTLS handshake message defragmentation
This commit is contained in:
@@ -1075,6 +1075,11 @@ typedef struct Buffers {
|
|||||||
byte weOwnCert; /* SSL own cert flag */
|
byte weOwnCert; /* SSL own cert flag */
|
||||||
byte weOwnKey; /* SSL own key flag */
|
byte weOwnKey; /* SSL own key flag */
|
||||||
byte weOwnDH; /* SSL own dh (p,g) flag */
|
byte weOwnDH; /* SSL own dh (p,g) flag */
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
buffer dtlsHandshake; /* DTLS handshake defragment buf */
|
||||||
|
word32 dtlsUsed; /* DTLS bytes used in buffer */
|
||||||
|
byte dtlsType; /* DTLS handshake frag type */
|
||||||
|
#endif
|
||||||
} Buffers;
|
} Buffers;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -954,6 +954,12 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->buffers.weOwnKey = 0;
|
ssl->buffers.weOwnKey = 0;
|
||||||
ssl->buffers.weOwnDH = 0;
|
ssl->buffers.weOwnDH = 0;
|
||||||
|
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
ssl->buffers.dtlsHandshake.length = 0;
|
||||||
|
ssl->buffers.dtlsHandshake.buffer = NULL;
|
||||||
|
ssl->buffers.dtlsType = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
ssl->peerCert.issuer.sz = 0;
|
ssl->peerCert.issuer.sz = 0;
|
||||||
ssl->peerCert.subject.sz = 0;
|
ssl->peerCert.subject.sz = 0;
|
||||||
@@ -1043,6 +1049,10 @@ void SSL_ResourceFree(CYASSL* ssl)
|
|||||||
ShrinkInputBuffer(ssl, FORCED_FREE);
|
ShrinkInputBuffer(ssl, FORCED_FREE);
|
||||||
if (ssl->buffers.outputBuffer.dynamicFlag)
|
if (ssl->buffers.outputBuffer.dynamicFlag)
|
||||||
ShrinkOutputBuffer(ssl);
|
ShrinkOutputBuffer(ssl);
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
if (ssl->buffers.dtlsHandshake.buffer != NULL)
|
||||||
|
XFREE(ssl->buffers.dtlsHandshake.buffer, ssl->heap, DYNAMIC_TYPE_NONE);
|
||||||
|
#endif
|
||||||
#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
|
#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
|
||||||
XFREE(ssl->peerCert.derCert.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
|
XFREE(ssl->peerCert.derCert.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
|
||||||
if (ssl->peerCert.altNames)
|
if (ssl->peerCert.altNames)
|
||||||
@@ -2121,6 +2131,8 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
CYASSL_ENTER("DoHandShakeMsgType");
|
||||||
|
|
||||||
HashInput(ssl, input + *inOutIdx, size);
|
HashInput(ssl, input + *inOutIdx, size);
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
/* add name later, add on record and handshake header part back on */
|
/* add name later, add on record and handshake header part back on */
|
||||||
@@ -2205,6 +2217,7 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
ret = UNKNOWN_HANDSHAKE_TYPE;
|
ret = UNKNOWN_HANDSHAKE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CYASSL_LEAVE("DoHandShakeMsgType()", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2245,11 +2258,62 @@ static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
&size, &fragOffset, &fragSz) != 0)
|
&size, &fragOffset, &fragSz) != 0)
|
||||||
return PARSE_ERROR;
|
return PARSE_ERROR;
|
||||||
|
|
||||||
if (*inOutIdx + size > totalSz)
|
if (*inOutIdx + fragSz > totalSz)
|
||||||
return INCOMPLETE_DATA;
|
return INCOMPLETE_DATA;
|
||||||
|
|
||||||
/* XXX if fragmented, knit back together. */
|
if (fragSz < size) {
|
||||||
ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
|
/* message is fragmented, knit back together */
|
||||||
|
byte* buf = ssl->buffers.dtlsHandshake.buffer;
|
||||||
|
if (ssl->buffers.dtlsHandshake.length == 0) {
|
||||||
|
/* Need to add a header back into the data. The Hash is calculated
|
||||||
|
* as if this were a single message, not several fragments. */
|
||||||
|
buf = XMALLOC(size + DTLS_HANDSHAKE_HEADER_SZ,
|
||||||
|
ssl->heap, DYNAMIC_TYPE_NONE);
|
||||||
|
if (buf == NULL)
|
||||||
|
return MEMORY_ERROR;
|
||||||
|
|
||||||
|
ssl->buffers.dtlsHandshake.length = size;
|
||||||
|
ssl->buffers.dtlsHandshake.buffer = buf;
|
||||||
|
ssl->buffers.dtlsUsed = 0;
|
||||||
|
ssl->buffers.dtlsType = type;
|
||||||
|
|
||||||
|
/* Construct a new header for the reassembled message as if it
|
||||||
|
* were originally sent as one fragment for the hashing later. */
|
||||||
|
XMEMCPY(buf,
|
||||||
|
input + *inOutIdx - DTLS_HANDSHAKE_HEADER_SZ,
|
||||||
|
DTLS_HANDSHAKE_HEADER_SZ - DTLS_HANDSHAKE_FRAG_SZ);
|
||||||
|
XMEMCPY(buf + DTLS_HANDSHAKE_HEADER_SZ - DTLS_HANDSHAKE_FRAG_SZ,
|
||||||
|
input + *inOutIdx - DTLS_HANDSHAKE_HEADER_SZ + ENUM_LEN,
|
||||||
|
DTLS_HANDSHAKE_FRAG_SZ);
|
||||||
|
}
|
||||||
|
/* readjust the buf pointer past the header */
|
||||||
|
buf += DTLS_HANDSHAKE_HEADER_SZ;
|
||||||
|
|
||||||
|
XMEMCPY(buf + fragOffset, input + *inOutIdx, fragSz);
|
||||||
|
ssl->buffers.dtlsUsed += fragSz;
|
||||||
|
*inOutIdx += fragSz;
|
||||||
|
|
||||||
|
if (ssl->buffers.dtlsUsed != size) {
|
||||||
|
CYASSL_LEAVE("DoDtlsHandShakeMsg()", 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
word32 idx = 0;
|
||||||
|
totalSz = size;
|
||||||
|
ret = DoHandShakeMsgType(ssl, buf, &idx, type, size, totalSz);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
|
||||||
|
|
||||||
|
if (ssl->buffers.dtlsHandshake.buffer != NULL) {
|
||||||
|
XFREE(ssl->buffers.dtlsHandshake.buffer, ssl->heap, DYNAMIC_TYPE_NONE);
|
||||||
|
ssl->buffers.dtlsHandshake.length = 0;
|
||||||
|
ssl->buffers.dtlsHandshake.buffer = NULL;
|
||||||
|
ssl->buffers.dtlsUsed = 0;
|
||||||
|
ssl->buffers.dtlsType = 0;
|
||||||
|
}
|
||||||
|
|
||||||
CYASSL_LEAVE("DoDtlsHandShakeMsg()", ret);
|
CYASSL_LEAVE("DoDtlsHandShakeMsg()", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user