Boundaries check for DoFinished.

-- added size and totalSz in the function parameters;
-- BUFFER_ERROR returned in case of message overflow (piece larger than the message size);
-- INCOMPLETE_DATA returned in case of buffer overflow (piece smaller than the expected size);
-- removed unnecessary variable idx;
-- fixed the sniffer to adapt to the changes.
This commit is contained in:
Moisés Guimarães 2014-03-04 11:41:18 -03:00
parent 4821b5d5fe
commit 244e335e81
3 changed files with 23 additions and 13 deletions

View File

@ -820,7 +820,7 @@ CYASSL_LOCAL void InitSSL_Method(CYASSL_METHOD*, ProtocolVersion);
/* for sniffer */
CYASSL_LOCAL int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx,
int sniff);
word32 size, word32 totalSz, int sniff);
CYASSL_LOCAL int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx);

View File

@ -3664,28 +3664,36 @@ static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx)
}
int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, word32 size,
word32 totalSz, int sniff)
{
int finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ;
word32 idx = *inOutIdx;
if ((ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ) != size)
return BUFFER_ERROR;
#ifdef CYASSL_CALLBACKS
if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
#endif
if (sniff == NO_SNIFF) {
if (XMEMCMP(input + idx, &ssl->verifyHashes, finishedSz) != 0) {
if (XMEMCMP(input + *inOutIdx, &ssl->verifyHashes, size) != 0) {
CYASSL_MSG("Verify finished error on hashes");
return VERIFY_FINISHED_ERROR;
}
}
idx += finishedSz;
idx += ssl->keys.padSz;
/* increment beyond input + size should be checked against totalSz */
if (*inOutIdx + size + ssl->keys.padSz > totalSz)
return INCOMPLETE_DATA;
/* force input exhaustion at ProcessReply consuming padSz */
*inOutIdx += size + ssl->keys.padSz;
if (ssl->options.side == CYASSL_CLIENT_END) {
ssl->options.serverState = SERVER_FINISHED_COMPLETE;
if (!ssl->options.resuming) {
ssl->options.handShakeState = HANDSHAKE_DONE;
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
/* Other side has received our Finished, go to next epoch */
@ -3699,6 +3707,7 @@ int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
if (ssl->options.resuming) {
ssl->options.handShakeState = HANDSHAKE_DONE;
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
/* Other side has received our Finished, go to next epoch */
@ -3709,7 +3718,6 @@ int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
}
}
*inOutIdx = idx;
return 0;
}
@ -3818,7 +3826,7 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
case finished:
CYASSL_MSG("processing finished");
ret = DoFinished(ssl, input, inOutIdx, NO_SNIFF);
ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
break;
#ifndef NO_CYASSL_SERVER

View File

@ -1444,7 +1444,7 @@ static int ProcessClientHello(const byte* input, int* sslBytes,
/* Process Finished */
static int ProcessFinished(const byte* input, int* sslBytes,
static int ProcessFinished(const byte* input, int size, int* sslBytes,
SnifferSession* session, char* error)
{
SSL* ssl;
@ -1455,7 +1455,9 @@ static int ProcessFinished(const byte* input, int* sslBytes,
ssl = session->sslServer;
else
ssl = session->sslClient;
ret = DoFinished(ssl, input, &inOutIdx, SNIFF);
ret = DoFinished(ssl, input, &inOutIdx, (word32) size, (word32) *sslBytes,
SNIFF);
*sslBytes -= (int)inOutIdx;
if (ret < 0) {
@ -1533,7 +1535,7 @@ static int DoHandShake(const byte* input, int* sslBytes,
break;
case finished:
Trace(GOT_FINISHED_STR);
ret = ProcessFinished(input, sslBytes, session, error);
ret = ProcessFinished(input, size, sslBytes, session, error);
break;
case client_hello:
Trace(GOT_CLIENT_HELLO_STR);