Merge branch 'dtls'
Conflicts: cyassl/ctaocrypt/types.h
This commit is contained in:
commit
6ff39cffe4
@ -230,6 +230,7 @@ enum {
|
|||||||
DYNAMIC_TYPE_LIBZ = 36,
|
DYNAMIC_TYPE_LIBZ = 36,
|
||||||
DYNAMIC_TYPE_ECC = 37,
|
DYNAMIC_TYPE_ECC = 37,
|
||||||
DYNAMIC_TYPE_TMP_BUFFER = 38,
|
DYNAMIC_TYPE_TMP_BUFFER = 38,
|
||||||
|
DYNAMIC_TYPE_DTLS_MSG = 39,
|
||||||
DYNAMIC_TYPE_CAVIUM_TMP = 40,
|
DYNAMIC_TYPE_CAVIUM_TMP = 40,
|
||||||
DYNAMIC_TYPE_CAVIUM_RSA = 41
|
DYNAMIC_TYPE_CAVIUM_RSA = 41
|
||||||
};
|
};
|
||||||
|
@ -1280,9 +1280,6 @@ typedef struct Buffers {
|
|||||||
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
|
#ifdef CYASSL_DTLS
|
||||||
buffer dtlsHandshake; /* DTLS handshake defragment buf */
|
|
||||||
word32 dtlsUsed; /* DTLS bytes used in buffer */
|
|
||||||
byte dtlsType; /* DTLS handshake frag type */
|
|
||||||
CYASSL_DTLS_CTX dtlsCtx; /* DTLS connection context */
|
CYASSL_DTLS_CTX dtlsCtx; /* DTLS connection context */
|
||||||
#endif
|
#endif
|
||||||
} Buffers;
|
} Buffers;
|
||||||
@ -1401,6 +1398,16 @@ typedef struct DtlsPool {
|
|||||||
int used;
|
int used;
|
||||||
} DtlsPool;
|
} DtlsPool;
|
||||||
|
|
||||||
|
typedef struct DtlsMsg {
|
||||||
|
struct DtlsMsg* next;
|
||||||
|
word32 seq; /* Handshake sequence number */
|
||||||
|
word32 sz; /* Length of whole mesage */
|
||||||
|
word32 fragSz; /* Length of fragments received */
|
||||||
|
byte type;
|
||||||
|
byte* buf;
|
||||||
|
byte* msg;
|
||||||
|
} DtlsMsg;
|
||||||
|
|
||||||
|
|
||||||
/* CyaSSL ssl type */
|
/* CyaSSL ssl type */
|
||||||
struct CYASSL {
|
struct CYASSL {
|
||||||
@ -1473,6 +1480,7 @@ struct CYASSL {
|
|||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
int dtls_timeout;
|
int dtls_timeout;
|
||||||
DtlsPool* dtls_pool;
|
DtlsPool* dtls_pool;
|
||||||
|
DtlsMsg* dtls_msg_list;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
HandShakeInfo handShakeInfo; /* info saved during handshake */
|
HandShakeInfo handShakeInfo; /* info saved during handshake */
|
||||||
@ -1696,6 +1704,16 @@ CYASSL_LOCAL int GrowInputBuffer(CYASSL* ssl, int size, int usedLength);
|
|||||||
CYASSL_LOCAL int DtlsPoolTimeout(CYASSL*);
|
CYASSL_LOCAL int DtlsPoolTimeout(CYASSL*);
|
||||||
CYASSL_LOCAL int DtlsPoolSend(CYASSL*);
|
CYASSL_LOCAL int DtlsPoolSend(CYASSL*);
|
||||||
CYASSL_LOCAL void DtlsPoolReset(CYASSL*);
|
CYASSL_LOCAL void DtlsPoolReset(CYASSL*);
|
||||||
|
|
||||||
|
CYASSL_LOCAL DtlsMsg* DtlsMsgNew(word32, void*);
|
||||||
|
CYASSL_LOCAL void DtlsMsgDelete(DtlsMsg*, void*);
|
||||||
|
CYASSL_LOCAL void DtlsMsgListDelete(DtlsMsg*, void*);
|
||||||
|
CYASSL_LOCAL void DtlsMsgSet(DtlsMsg*, word32, const byte*, byte,
|
||||||
|
word32, word32);
|
||||||
|
CYASSL_LOCAL DtlsMsg* DtlsMsgFind(DtlsMsg*, word32);
|
||||||
|
CYASSL_LOCAL DtlsMsg* DtlsMsgStore(DtlsMsg*, word32, const byte*, word32,
|
||||||
|
byte, word32, word32, void*);
|
||||||
|
CYASSL_LOCAL DtlsMsg* DtlsMsgInsert(DtlsMsg*, DtlsMsg*);
|
||||||
#endif /* CYASSL_DTLS */
|
#endif /* CYASSL_DTLS */
|
||||||
|
|
||||||
#ifndef NO_TLS
|
#ifndef NO_TLS
|
||||||
|
312
src/internal.c
312
src/internal.c
@ -1219,6 +1219,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->keys.dtls_expected_peer_epoch = 0;
|
ssl->keys.dtls_expected_peer_epoch = 0;
|
||||||
ssl->dtls_timeout = DTLS_DEFAULT_TIMEOUT;
|
ssl->dtls_timeout = DTLS_DEFAULT_TIMEOUT;
|
||||||
ssl->dtls_pool = NULL;
|
ssl->dtls_pool = NULL;
|
||||||
|
ssl->dtls_msg_list = NULL;
|
||||||
#endif
|
#endif
|
||||||
ssl->keys.encryptionOn = 0; /* initially off */
|
ssl->keys.encryptionOn = 0; /* initially off */
|
||||||
ssl->keys.decryptedCur = 0; /* initially off */
|
ssl->keys.decryptedCur = 0; /* initially off */
|
||||||
@ -1266,9 +1267,6 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->buffers.weOwnDH = 0;
|
ssl->buffers.weOwnDH = 0;
|
||||||
|
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
ssl->buffers.dtlsHandshake.length = 0;
|
|
||||||
ssl->buffers.dtlsHandshake.buffer = NULL;
|
|
||||||
ssl->buffers.dtlsType = 0;
|
|
||||||
ssl->buffers.dtlsCtx.fd = -1;
|
ssl->buffers.dtlsCtx.fd = -1;
|
||||||
ssl->buffers.dtlsCtx.peer.sa = NULL;
|
ssl->buffers.dtlsCtx.peer.sa = NULL;
|
||||||
ssl->buffers.dtlsCtx.peer.sz = 0;
|
ssl->buffers.dtlsCtx.peer.sz = 0;
|
||||||
@ -1465,12 +1463,14 @@ void SSL_ResourceFree(CYASSL* ssl)
|
|||||||
if (ssl->buffers.outputBuffer.dynamicFlag)
|
if (ssl->buffers.outputBuffer.dynamicFlag)
|
||||||
ShrinkOutputBuffer(ssl);
|
ShrinkOutputBuffer(ssl);
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
if (ssl->buffers.dtlsHandshake.buffer != NULL)
|
|
||||||
XFREE(ssl->buffers.dtlsHandshake.buffer, ssl->heap, DYNAMIC_TYPE_NONE);
|
|
||||||
if (ssl->dtls_pool != NULL) {
|
if (ssl->dtls_pool != NULL) {
|
||||||
DtlsPoolReset(ssl);
|
DtlsPoolReset(ssl);
|
||||||
XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
|
XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
|
||||||
}
|
}
|
||||||
|
if (ssl->dtls_msg_list != NULL) {
|
||||||
|
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;
|
||||||
#endif
|
#endif
|
||||||
@ -1703,7 +1703,167 @@ int DtlsPoolSend(CYASSL* ssl)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
/* functions for managing DTLS datagram reordering */
|
||||||
|
|
||||||
|
/* Need to allocate space for the handshake message header. The hashing
|
||||||
|
* routines assume the message pointer is still within the buffer that
|
||||||
|
* has the headers, and will include those headers in the hash. The store
|
||||||
|
* routines need to take that into account as well. New will allocate
|
||||||
|
* extra space for the headers. */
|
||||||
|
DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
|
||||||
|
{
|
||||||
|
DtlsMsg* msg = NULL;
|
||||||
|
|
||||||
|
msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||||
|
|
||||||
|
if (msg != NULL) {
|
||||||
|
msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
|
||||||
|
heap, DYNAMIC_TYPE_NONE);
|
||||||
|
if (msg->buf != NULL) {
|
||||||
|
msg->next = NULL;
|
||||||
|
msg->seq = 0;
|
||||||
|
msg->sz = sz;
|
||||||
|
msg->fragSz = 0;
|
||||||
|
msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||||
|
msg = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DtlsMsgDelete(DtlsMsg* item, void* heap)
|
||||||
|
{
|
||||||
|
(void)heap;
|
||||||
|
|
||||||
|
if (item != NULL) {
|
||||||
|
if (item->buf != NULL)
|
||||||
|
XFREE(item->buf, heap, DYNAMIC_TYPE_NONE);
|
||||||
|
XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DtlsMsgListDelete(DtlsMsg* head, void* heap)
|
||||||
|
{
|
||||||
|
DtlsMsg* next;
|
||||||
|
while (head) {
|
||||||
|
next = head->next;
|
||||||
|
DtlsMsgDelete(head, heap);
|
||||||
|
head = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
|
||||||
|
word32 fragOffset, word32 fragSz)
|
||||||
|
{
|
||||||
|
if (msg != NULL && data != NULL && msg->fragSz <= msg->sz) {
|
||||||
|
msg->seq = seq;
|
||||||
|
msg->type = type;
|
||||||
|
msg->fragSz += fragSz;
|
||||||
|
/* If fragOffset is zero, this is either a full message that is out
|
||||||
|
* of order, or the first fragment of a fragmented message. Copy the
|
||||||
|
* handshake message header as well as the message data. */
|
||||||
|
if (fragOffset == 0)
|
||||||
|
XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
|
||||||
|
fragSz + DTLS_HANDSHAKE_HEADER_SZ);
|
||||||
|
else {
|
||||||
|
/* If fragOffet is non-zero, this is an additional fragment that
|
||||||
|
* needs to be copied to its location in the message buffer. Also
|
||||||
|
* copy the total size of the message over the fragment size. The
|
||||||
|
* hash routines look at a defragmented message if it had actually
|
||||||
|
* come across as a single handshake message. */
|
||||||
|
XMEMCPY(msg->msg + fragOffset, data, fragSz);
|
||||||
|
c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
|
||||||
|
{
|
||||||
|
while (head != NULL && head->seq != seq) {
|
||||||
|
head = head->next;
|
||||||
|
}
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
|
||||||
|
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
|
||||||
|
* 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
|
||||||
|
* the seq is in the list and it isn't full, copy fragSz bytes from
|
||||||
|
* data to msg->msg starting at offset fragOffset, and add fragSz to
|
||||||
|
* msg->fragSz. The new item should be inserted into the list in its
|
||||||
|
* proper position.
|
||||||
|
*
|
||||||
|
* 1. Find seq in list, or where seq should go in list. If seq not in
|
||||||
|
* list, create new item and insert into list. Either case, keep
|
||||||
|
* pointer to item.
|
||||||
|
* 2. If msg->fragSz + fragSz < sz, copy data to msg->msg at offset
|
||||||
|
* fragOffset. Add fragSz to msg->fragSz.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (head != NULL) {
|
||||||
|
DtlsMsg* cur = DtlsMsgFind(head, seq);
|
||||||
|
if (cur == NULL) {
|
||||||
|
cur = DtlsMsgNew(dataSz, heap);
|
||||||
|
DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
|
||||||
|
head = DtlsMsgInsert(head, cur);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
head = DtlsMsgNew(dataSz, heap);
|
||||||
|
DtlsMsgSet(head, seq, data, type, fragOffset, fragSz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* DtlsMsgInsert() is an in-order insert. */
|
||||||
|
DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
|
||||||
|
{
|
||||||
|
if (head == NULL || item->seq < head->seq) {
|
||||||
|
item->next = head;
|
||||||
|
head = item;
|
||||||
|
}
|
||||||
|
else if (head->next == NULL) {
|
||||||
|
head->next = item;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DtlsMsg* cur = head->next;
|
||||||
|
DtlsMsg* prev = head;
|
||||||
|
while (cur) {
|
||||||
|
if (item->seq < cur->seq) {
|
||||||
|
item->next = cur;
|
||||||
|
prev->next = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
if (cur == NULL) {
|
||||||
|
prev->next = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CYASSL_DTLS */
|
||||||
|
|
||||||
#ifndef NO_OLD_TLS
|
#ifndef NO_OLD_TLS
|
||||||
|
|
||||||
@ -2186,7 +2346,9 @@ static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
return VERSION_ERROR; /* only use requested version */
|
return VERSION_ERROR; /* only use requested version */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
/* Instead of this, check the datagram against the sliding window of
|
||||||
|
* received datagram goodness. */
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
/* If DTLS, check the sequence number against expected. If out of
|
/* If DTLS, check the sequence number against expected. If out of
|
||||||
* order, drop the record. Allows newer records in and resets the
|
* order, drop the record. Allows newer records in and resets the
|
||||||
@ -2204,7 +2366,7 @@ static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
/* record layer length check */
|
/* record layer length check */
|
||||||
if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
|
if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
|
||||||
return LENGTH_ERROR;
|
return LENGTH_ERROR;
|
||||||
@ -2262,7 +2424,6 @@ static int GetDtlsHandShakeHeader(CYASSL* ssl, const byte* input,
|
|||||||
c24to32(input + idx, fragOffset);
|
c24to32(input + idx, fragOffset);
|
||||||
idx += DTLS_HANDSHAKE_FRAG_SZ;
|
idx += DTLS_HANDSHAKE_FRAG_SZ;
|
||||||
c24to32(input + idx, fragSz);
|
c24to32(input + idx, fragSz);
|
||||||
idx += DTLS_HANDSHAKE_FRAG_SZ;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2991,6 +3152,31 @@ static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
|
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
|
static int DtlsMsgDrain(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
DtlsMsg* item = ssl->dtls_msg_list;
|
||||||
|
int ret = 0;
|
||||||
|
word32 idx = 0;
|
||||||
|
|
||||||
|
/* While there is an item in the store list, and it is the expected
|
||||||
|
* message, and it is complete, and there hasn't been an error in the
|
||||||
|
* last messge... */
|
||||||
|
while (item != NULL &&
|
||||||
|
ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
|
||||||
|
item->fragSz == item->sz &&
|
||||||
|
ret == 0) {
|
||||||
|
ssl->keys.dtls_expected_peer_handshake_number++;
|
||||||
|
ret = DoHandShakeMsgType(ssl, item->msg,
|
||||||
|
&idx, item->type, item->sz, item->sz);
|
||||||
|
ssl->dtls_msg_list = item->next;
|
||||||
|
DtlsMsgDelete(item, ssl->heap);
|
||||||
|
item = ssl->dtls_msg_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|
static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|
||||||
word32 totalSz)
|
word32 totalSz)
|
||||||
{
|
{
|
||||||
@ -3007,74 +3193,49 @@ static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
if (*inOutIdx + fragSz > totalSz)
|
if (*inOutIdx + fragSz > totalSz)
|
||||||
return INCOMPLETE_DATA;
|
return INCOMPLETE_DATA;
|
||||||
|
|
||||||
if (fragSz < size) {
|
/* Check the handshake sequence number first. If out of order,
|
||||||
/* message is fragmented, knit back together */
|
* add the current message to the list. If the message is in order,
|
||||||
byte* buf = ssl->buffers.dtlsHandshake.buffer;
|
* but it is a fragment, add the current message to the list, then
|
||||||
if (ssl->buffers.dtlsHandshake.length == 0) {
|
* check the head of the list to see if it is complete, if so, pop
|
||||||
/* Need to add a header back into the data. The Hash is calculated
|
* it out as the current message. If the message is complete and in
|
||||||
* as if this were a single message, not several fragments. */
|
* order, process it. Check the head of the list to see if it is in
|
||||||
buf = (byte*)XMALLOC(size + DTLS_HANDSHAKE_HEADER_SZ,
|
* order, if so, process it. (Repeat until list exhausted.) If the
|
||||||
ssl->heap, DYNAMIC_TYPE_NONE);
|
* head is out of order, return for more processing.
|
||||||
if (buf == NULL)
|
*/
|
||||||
return MEMORY_ERROR;
|
if (ssl->keys.dtls_peer_handshake_number >
|
||||||
|
|
||||||
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()", 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (ssl->keys.dtls_peer_handshake_number ==
|
|
||||||
ssl->keys.dtls_expected_peer_handshake_number) {
|
ssl->keys.dtls_expected_peer_handshake_number) {
|
||||||
word32 idx = 0;
|
/* Current message is out of order. It will get stored in the list.
|
||||||
totalSz = size;
|
* Storing also takes care of defragmentation. */
|
||||||
ssl->keys.dtls_expected_peer_handshake_number++;
|
ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
|
||||||
ret = DoHandShakeMsgType(ssl, buf, &idx, type, size, totalSz);
|
ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
|
||||||
}
|
size, type, fragOffset, fragSz, ssl->heap);
|
||||||
else {
|
*inOutIdx += fragSz;
|
||||||
*inOutIdx += size;
|
ret = 0;
|
||||||
ret = 0;
|
}
|
||||||
}
|
else if (ssl->keys.dtls_peer_handshake_number <
|
||||||
}
|
ssl->keys.dtls_expected_peer_handshake_number) {
|
||||||
|
/* Already saw this message and processed it. It can be ignored. */
|
||||||
|
*inOutIdx += fragSz;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else if (fragSz < size) {
|
||||||
|
/* Since this branch is in order, but fragmented, dtls_msg_list will be
|
||||||
|
* pointing to the message with this fragment in it. Check it to see
|
||||||
|
* if it is completed. */
|
||||||
|
ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
|
||||||
|
ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
|
||||||
|
size, type, fragOffset, fragSz, ssl->heap);
|
||||||
|
*inOutIdx += fragSz;
|
||||||
|
ret = 0;
|
||||||
|
if (ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz)
|
||||||
|
ret = DtlsMsgDrain(ssl);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ssl->keys.dtls_peer_handshake_number ==
|
/* This branch is in order next, and a complete message. */
|
||||||
ssl->keys.dtls_expected_peer_handshake_number) {
|
ssl->keys.dtls_expected_peer_handshake_number++;
|
||||||
ssl->keys.dtls_expected_peer_handshake_number++;
|
ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
|
||||||
ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
|
if (ret == 0 && ssl->dtls_msg_list != NULL)
|
||||||
}
|
ret = DtlsMsgDrain(ssl);
|
||||||
else {
|
|
||||||
*inOutIdx += size;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
@ -4032,7 +4193,8 @@ int ProcessReply(CYASSL* ssl)
|
|||||||
&ssl->curRL, &ssl->curSize);
|
&ssl->curRL, &ssl->curSize);
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
|
if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
|
||||||
/* This message is out of order. Forget it ever happened. */
|
/* This message is out of order. If we are handshaking, save
|
||||||
|
*it for later. Otherwise go ahead and process it. */
|
||||||
ssl->options.processReply = doProcessInit;
|
ssl->options.processReply = doProcessInit;
|
||||||
ssl->buffers.inputBuffer.length = 0;
|
ssl->buffers.inputBuffer.length = 0;
|
||||||
ssl->buffers.inputBuffer.idx = 0;
|
ssl->buffers.inputBuffer.idx = 0;
|
||||||
|
@ -2519,6 +2519,8 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl)
|
|||||||
{
|
{
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
int result = SSL_SUCCESS;
|
int result = SSL_SUCCESS;
|
||||||
|
DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
|
||||||
|
ssl->dtls_msg_list = NULL;
|
||||||
if (DtlsPoolTimeout(ssl) < 0 || DtlsPoolSend(ssl) < 0) {
|
if (DtlsPoolTimeout(ssl) < 0 || DtlsPoolSend(ssl) < 0) {
|
||||||
result = SSL_FATAL_ERROR;
|
result = SSL_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user