drop out of order dtls packets

This commit is contained in:
John Safranek 2012-08-23 15:50:56 -07:00
parent f6cca6049f
commit 561a7fc35d
3 changed files with 46 additions and 9 deletions

View File

@ -102,6 +102,7 @@ enum CyaSSL_ErrorCodes {
OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */
MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */
COOKIE_ERROR = -269, /* dtls cookie error */
SEQUENCE_ERROR = -270, /* dtls sequence error */
/* add strings to SetErrorString !!!!! */
/* begin negotiation parameter errors */

View File

@ -956,9 +956,11 @@ typedef struct Keys {
#ifdef CYASSL_DTLS
word32 dtls_sequence_number;
word32 dtls_peer_sequence_number;
word32 dtls_expected_peer_sequence_number;
word16 dtls_handshake_number;
word16 dtls_epoch;
word16 dtls_peer_epoch;
word16 dtls_expected_peer_epoch;
#endif
word32 encryptSz; /* last size of encrypted data */

View File

@ -915,12 +915,14 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->options.processReply = doProcessInit;
#ifdef CYASSL_DTLS
ssl->keys.dtls_sequence_number = 0;
ssl->keys.dtls_peer_sequence_number = 0;
ssl->keys.dtls_handshake_number = 0;
ssl->keys.dtls_epoch = 0;
ssl->keys.dtls_peer_epoch = 0;
ssl->arrays.cookieSz = 0;
ssl->keys.dtls_sequence_number = 0;
ssl->keys.dtls_peer_sequence_number = 0;
ssl->keys.dtls_expected_peer_sequence_number = 0;
ssl->keys.dtls_handshake_number = 0;
ssl->keys.dtls_epoch = 0;
ssl->keys.dtls_peer_epoch = 0;
ssl->keys.dtls_expected_peer_epoch = 0;
ssl->arrays.cookieSz = 0;
#endif
ssl->keys.encryptionOn = 0; /* initially off */
ssl->options.sessionCacheOff = ctx->sessionCacheOff;
@ -1515,7 +1517,8 @@ static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
/* type and version in same sport */
XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
*inOutIdx += ENUM_LEN + VERSION_SZ;
*inOutIdx += 4; /* skip epoch and first 2 seq bytes for now */
ato16(input + *inOutIdx, &ssl->keys.dtls_peer_epoch);
*inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
ato32(input + *inOutIdx, &ssl->keys.dtls_peer_sequence_number);
*inOutIdx += 4; /* advance past rest of seq */
ato16(input + *inOutIdx, size);
@ -1539,6 +1542,22 @@ static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
}
}
#ifdef CYASSL_DTLS
/* If DTLS, check the sequence number against expected. If out of
* order, drop the record. */
if (ssl->options.dtls) {
if ((ssl->keys.dtls_expected_peer_epoch ==
ssl->keys.dtls_peer_epoch) &&
(ssl->keys.dtls_expected_peer_sequence_number ==
ssl->keys.dtls_peer_sequence_number)) {
ssl->keys.dtls_expected_peer_sequence_number++;
}
else {
return SEQUENCE_ERROR;
}
}
#endif
/* record layer length check */
if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
return LENGTH_ERROR;
@ -2793,6 +2812,15 @@ int ProcessReply(CYASSL* ssl)
ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
&ssl->buffers.inputBuffer.idx,
&ssl->curRL, &ssl->curSize);
#ifdef CYASSL_DTLS
if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
/* This message is out of order. Forget it ever happened. */
ssl->options.processReply = doProcessInit;
ssl->buffers.inputBuffer.length = 0;
ssl->buffers.inputBuffer.idx = 0;
continue;
}
#endif
if (ret != 0)
return ret;
@ -2870,8 +2898,10 @@ int ProcessReply(CYASSL* ssl)
ssl->keys.encryptionOn = 1;
#ifdef CYASSL_DTLS
if (ssl->options.dtls)
ssl->keys.dtls_peer_epoch++;
if (ssl->options.dtls) {
ssl->keys.dtls_expected_peer_epoch++;
ssl->keys.dtls_expected_peer_sequence_number = 0;
}
#endif
#ifdef HAVE_LIBZ
@ -3910,6 +3940,10 @@ void SetErrorString(int error, char* str)
XSTRNCPY(str, "DTLS Cookie Error", max);
break;
case SEQUENCE_ERROR:
XSTRNCPY(str, "DTLS Sequence Error", max);
break;
default :
XSTRNCPY(str, "unknown error number", max);
}