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 */ /* for sniffer */
CYASSL_LOCAL int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, 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); 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; if ((ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ) != size)
word32 idx = *inOutIdx; return BUFFER_ERROR;
#ifdef CYASSL_CALLBACKS #ifdef CYASSL_CALLBACKS
if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo); if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo); if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
#endif #endif
if (sniff == NO_SNIFF) { 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"); CYASSL_MSG("Verify finished error on hashes");
return VERIFY_FINISHED_ERROR; 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) { if (ssl->options.side == CYASSL_CLIENT_END) {
ssl->options.serverState = SERVER_FINISHED_COMPLETE; ssl->options.serverState = SERVER_FINISHED_COMPLETE;
if (!ssl->options.resuming) { if (!ssl->options.resuming) {
ssl->options.handShakeState = HANDSHAKE_DONE; ssl->options.handShakeState = HANDSHAKE_DONE;
#ifdef CYASSL_DTLS #ifdef CYASSL_DTLS
if (ssl->options.dtls) { if (ssl->options.dtls) {
/* Other side has received our Finished, go to next epoch */ /* 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; ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
if (ssl->options.resuming) { if (ssl->options.resuming) {
ssl->options.handShakeState = HANDSHAKE_DONE; ssl->options.handShakeState = HANDSHAKE_DONE;
#ifdef CYASSL_DTLS #ifdef CYASSL_DTLS
if (ssl->options.dtls) { if (ssl->options.dtls) {
/* Other side has received our Finished, go to next epoch */ /* 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; return 0;
} }
@ -3818,7 +3826,7 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
case finished: case finished:
CYASSL_MSG("processing finished"); CYASSL_MSG("processing finished");
ret = DoFinished(ssl, input, inOutIdx, NO_SNIFF); ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
break; break;
#ifndef NO_CYASSL_SERVER #ifndef NO_CYASSL_SERVER

View File

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