Cap the size of the transmit and receive DTLS message lists at 255.

This commit is contained in:
John Safranek
2016-11-01 18:10:35 -07:00
parent ffe905afbf
commit a3ea8378ec
3 changed files with 60 additions and 39 deletions

View File

@@ -3644,13 +3644,11 @@ void SSL_ResourceFree(WOLFSSL* ssl)
if (ssl->buffers.outputBuffer.dynamicFlag) if (ssl->buffers.outputBuffer.dynamicFlag)
ShrinkOutputBuffer(ssl); ShrinkOutputBuffer(ssl);
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (ssl->dtls_tx_msg_list != NULL) { DtlsMsgPoolReset(ssl);
DtlsMsgListDelete(ssl->dtls_tx_msg_list, ssl->heap); if (ssl->dtls_rx_msg_list != NULL) {
ssl->dtls_tx_msg_list = NULL; DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
} ssl->dtls_rx_msg_list = NULL;
if (ssl->dtls_msg_list != NULL) { ssl->dtls_rx_msg_list_sz = 0;
DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
ssl->dtls_msg_list = NULL;
} }
XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR); XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
ssl->buffers.dtlsCtx.peer.sa = NULL; ssl->buffers.dtlsCtx.peer.sa = NULL;
@@ -3813,10 +3811,10 @@ void FreeHandshakeResources(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
/* DTLS_POOL */ /* DTLS_POOL */
if (ssl->options.dtls) { if (ssl->options.dtls) {
DtlsMsgListDelete(ssl->dtls_tx_msg_list, ssl->heap); DtlsMsgPoolReset(ssl);
ssl->dtls_tx_msg_list = NULL; DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap); ssl->dtls_rx_msg_list = NULL;
ssl->dtls_msg_list = NULL; ssl->dtls_rx_msg_list_sz = 0;
} }
#endif #endif
@@ -4230,10 +4228,9 @@ DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
} }
DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data, void DtlsMsgStore(WOLFSSL* ssl, word32 seq, const byte* data,
word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap) word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
{ {
/* See if seq exists in the list. If it isn't in the list, make /* See if seq exists in the list. If it isn't in the list, make
* a new item of size dataSz, copy fragSz bytes from data to msg->msg * a new item of size dataSz, copy fragSz bytes from data to msg->msg
* starting at offset fragOffset, and add fragSz to msg->fragSz. If * starting at offset fragOffset, and add fragSz to msg->fragSz. If
@@ -4251,6 +4248,8 @@ DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
* belongs without overlaps. * belongs without overlaps.
*/ */
DtlsMsg* head = ssl->dtls_rx_msg_list;
if (head != NULL) { if (head != NULL) {
DtlsMsg* cur = DtlsMsgFind(head, seq); DtlsMsg* cur = DtlsMsgFind(head, seq);
if (cur == NULL) { if (cur == NULL) {
@@ -4259,11 +4258,13 @@ DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
if (DtlsMsgSet(cur, seq, data, type, if (DtlsMsgSet(cur, seq, data, type,
fragOffset, fragSz, heap) < 0) { fragOffset, fragSz, heap) < 0) {
DtlsMsgDelete(cur, heap); DtlsMsgDelete(cur, heap);
return head;
} }
else {
ssl->dtls_rx_msg_list_sz++;
head = DtlsMsgInsert(head, cur); head = DtlsMsgInsert(head, cur);
} }
} }
}
else { else {
/* If this fails, the data is just dropped. */ /* If this fails, the data is just dropped. */
DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz, heap); DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz, heap);
@@ -4273,11 +4274,14 @@ DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
head = DtlsMsgNew(dataSz, heap); head = DtlsMsgNew(dataSz, heap);
if (DtlsMsgSet(head, seq, data, type, fragOffset, fragSz, heap) < 0) { if (DtlsMsgSet(head, seq, data, type, fragOffset, fragSz, heap) < 0) {
DtlsMsgDelete(head, heap); DtlsMsgDelete(head, heap);
return NULL; head = NULL;
}
else {
ssl->dtls_rx_msg_list_sz++;
} }
} }
return head; ssl->dtls_rx_msg_list = head;
} }
@@ -4318,6 +4322,9 @@ int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz)
DtlsMsg* item; DtlsMsg* item;
int ret = 0; int ret = 0;
if (ssl->dtls_tx_msg_list_sz > DTLS_POOL_SZ)
return DTLS_POOL_SZ_E;
item = DtlsMsgNew(dataSz, ssl->heap); item = DtlsMsgNew(dataSz, ssl->heap);
if (item != NULL) { if (item != NULL) {
@@ -4334,6 +4341,7 @@ int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz)
cur = cur->next; cur = cur->next;
cur->next = item; cur->next = item;
} }
ssl->dtls_tx_msg_list_sz++;
} }
else else
ret = MEMORY_E; ret = MEMORY_E;
@@ -4358,9 +4366,12 @@ int DtlsMsgPoolTimeout(WOLFSSL* ssl)
* value. */ * value. */
void DtlsMsgPoolReset(WOLFSSL* ssl) void DtlsMsgPoolReset(WOLFSSL* ssl)
{ {
if (ssl->dtls_tx_msg_list) {
DtlsMsgListDelete(ssl->dtls_tx_msg_list, ssl->heap); DtlsMsgListDelete(ssl->dtls_tx_msg_list, ssl->heap);
ssl->dtls_tx_msg_list = NULL; ssl->dtls_tx_msg_list = NULL;
ssl->dtls_tx_msg_list_sz = 0;
ssl->dtls_timeout = ssl->dtls_timeout_init; ssl->dtls_timeout = ssl->dtls_timeout_init;
}
} }
@@ -4368,7 +4379,7 @@ int VerifyForDtlsMsgPoolSend(WOLFSSL* ssl, byte type, word32 fragOffset)
{ {
/** /**
* only the first message from previous flight should be valid * only the first message from previous flight should be valid
* to be used for triggering retransmission of whole DtlsPool. * to be used for triggering retransmission of whole DtlsMsgPool.
* change cipher suite type is not verified here * change cipher suite type is not verified here
*/ */
return ((fragOffset == 0) && return ((fragOffset == 0) &&
@@ -7938,7 +7949,7 @@ static INLINE int DtlsUpdateWindow(WOLFSSL* ssl)
static int DtlsMsgDrain(WOLFSSL* ssl) static int DtlsMsgDrain(WOLFSSL* ssl)
{ {
DtlsMsg* item = ssl->dtls_msg_list; DtlsMsg* item = ssl->dtls_rx_msg_list;
int ret = 0; int ret = 0;
/* While there is an item in the store list, and it is the expected /* While there is an item in the store list, and it is the expected
@@ -7952,9 +7963,10 @@ static int DtlsMsgDrain(WOLFSSL* ssl)
ssl->keys.dtls_expected_peer_handshake_number++; ssl->keys.dtls_expected_peer_handshake_number++;
ret = DoHandShakeMsgType(ssl, item->msg, ret = DoHandShakeMsgType(ssl, item->msg,
&idx, item->type, item->sz, item->sz); &idx, item->type, item->sz, item->sz);
ssl->dtls_msg_list = item->next; ssl->dtls_rx_msg_list = item->next;
DtlsMsgDelete(item, ssl->heap); DtlsMsgDelete(item, ssl->heap);
item = ssl->dtls_msg_list; item = ssl->dtls_rx_msg_list;
ssl->dtls_rx_msg_list_sz--;
} }
return ret; return ret;
@@ -7998,10 +8010,11 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
* the client could be sending multiple new client hello messages * the client could be sending multiple new client hello messages
* with newer and newer cookies.) */ * with newer and newer cookies.) */
if (type != client_hello) { if (type != client_hello) {
ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list, if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) {
ssl->keys.dtls_peer_handshake_number, DtlsMsgStore(ssl, ssl->keys.dtls_peer_handshake_number,
input + *inOutIdx, size, type, input + *inOutIdx, size, type,
fragOffset, fragSz, ssl->heap); fragOffset, fragSz, ssl->heap);
}
*inOutIdx += fragSz; *inOutIdx += fragSz;
ret = 0; ret = 0;
} }
@@ -8030,16 +8043,18 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
} }
} }
else if (fragSz < size) { else if (fragSz < size) {
/* Since this branch is in order, but fragmented, dtls_msg_list will be /* Since this branch is in order, but fragmented, dtls_rx_msg_list will
* pointing to the message with this fragment in it. Check it to see * be pointing to the message with this fragment in it. Check it to see
* if it is completed. */ * if it is completed. */
ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list, if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) {
ssl->keys.dtls_peer_handshake_number, input + *inOutIdx, DtlsMsgStore(ssl, ssl->keys.dtls_peer_handshake_number,
size, type, fragOffset, fragSz, ssl->heap); input + *inOutIdx, size, type,
fragOffset, fragSz, ssl->heap);
}
*inOutIdx += fragSz; *inOutIdx += fragSz;
ret = 0; ret = 0;
if (ssl->dtls_msg_list != NULL && if (ssl->dtls_rx_msg_list != NULL &&
ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz) ssl->dtls_rx_msg_list->fragSz >= ssl->dtls_rx_msg_list->sz)
ret = DtlsMsgDrain(ssl); ret = DtlsMsgDrain(ssl);
} }
else { else {
@@ -8047,7 +8062,7 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz); ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
if (ret == 0) { if (ret == 0) {
ssl->keys.dtls_expected_peer_handshake_number++; ssl->keys.dtls_expected_peer_handshake_number++;
if (ssl->dtls_msg_list != NULL) { if (ssl->dtls_rx_msg_list != NULL) {
ret = DtlsMsgDrain(ssl); ret = DtlsMsgDrain(ssl);
} }
} }
@@ -11626,6 +11641,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case EXT_MASTER_SECRET_NEEDED_E: case EXT_MASTER_SECRET_NEEDED_E:
return "Extended Master Secret must be enabled to resume EMS session"; return "Extended Master Secret must be enabled to resume EMS session";
case DTLS_POOL_SZ_E:
return "Maximum DTLS pool size exceeded";
default : default :
return "unknown error number"; return "unknown error number";
} }

View File

@@ -150,6 +150,7 @@ enum wolfSSL_ErrorCodes {
INPUT_SIZE_E = -412, /* input size too big error */ INPUT_SIZE_E = -412, /* input size too big error */
CTX_INIT_MUTEX_E = -413, /* initialize ctx mutex error */ CTX_INIT_MUTEX_E = -413, /* initialize ctx mutex error */
EXT_MASTER_SECRET_NEEDED_E = -414, /* need EMS enabled to resume */ EXT_MASTER_SECRET_NEEDED_E = -414, /* need EMS enabled to resume */
DTLS_POOL_SZ_E = -415, /* exceeded DTLS pool size */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
/* begin negotiation parameter errors */ /* begin negotiation parameter errors */

View File

@@ -952,7 +952,7 @@ enum Misc {
DTLS_RECORD_EXTRA = 8, /* diff from normal */ DTLS_RECORD_EXTRA = 8, /* diff from normal */
DTLS_HANDSHAKE_SEQ_SZ = 2, /* handshake header sequence number */ DTLS_HANDSHAKE_SEQ_SZ = 2, /* handshake header sequence number */
DTLS_HANDSHAKE_FRAG_SZ = 3, /* fragment offset and length are 24 bit */ DTLS_HANDSHAKE_FRAG_SZ = 3, /* fragment offset and length are 24 bit */
DTLS_POOL_SZ = 5, /* buffers to hold in the retry pool */ DTLS_POOL_SZ = 255,/* allowed number of list items in TX pool */
DTLS_EXPORT_PRO = 165,/* wolfSSL protocol for serialized session */ DTLS_EXPORT_PRO = 165,/* wolfSSL protocol for serialized session */
DTLS_EXPORT_VERSION = 2, /* wolfSSL version for serialized session */ DTLS_EXPORT_VERSION = 2, /* wolfSSL version for serialized session */
DTLS_EXPORT_OPT_SZ = 57, /* amount of bytes used from Options */ DTLS_EXPORT_OPT_SZ = 57, /* amount of bytes used from Options */
@@ -2751,8 +2751,10 @@ struct WOLFSSL {
int dtls_timeout_init; /* starting timeout value */ int dtls_timeout_init; /* starting timeout value */
int dtls_timeout_max; /* maximum timeout value */ int dtls_timeout_max; /* maximum timeout value */
int dtls_timeout; /* current timeout value, changes */ int dtls_timeout; /* current timeout value, changes */
word32 dtls_tx_msg_list_sz;
word32 dtls_rx_msg_list_sz;
DtlsMsg* dtls_tx_msg_list; DtlsMsg* dtls_tx_msg_list;
DtlsMsg* dtls_msg_list; DtlsMsg* dtls_rx_msg_list;
void* IOCB_CookieCtx; /* gen cookie ctx */ void* IOCB_CookieCtx; /* gen cookie ctx */
word32 dtls_expected_rx; word32 dtls_expected_rx;
wc_dtls_export dtls_export; /* export function for session */ wc_dtls_export dtls_export; /* export function for session */
@@ -3069,7 +3071,7 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength);
WOLFSSL_LOCAL int DtlsMsgSet(DtlsMsg*, word32, const byte*, byte, WOLFSSL_LOCAL int DtlsMsgSet(DtlsMsg*, word32, const byte*, byte,
word32, word32, void*); word32, word32, void*);
WOLFSSL_LOCAL DtlsMsg* DtlsMsgFind(DtlsMsg*, word32); WOLFSSL_LOCAL DtlsMsg* DtlsMsgFind(DtlsMsg*, word32);
WOLFSSL_LOCAL DtlsMsg* DtlsMsgStore(DtlsMsg*, word32, const byte*, word32, WOLFSSL_LOCAL void DtlsMsgStore(WOLFSSL*, word32, const byte*, word32,
byte, word32, word32, void*); byte, word32, word32, void*);
WOLFSSL_LOCAL DtlsMsg* DtlsMsgInsert(DtlsMsg*, DtlsMsg*); WOLFSSL_LOCAL DtlsMsg* DtlsMsgInsert(DtlsMsg*, DtlsMsg*);