Boundaries check for DoCertificateRequest.

-- added size in the function parameters;
-- BUFFER_ERROR returned in case of message overflow (piece larger than the message size);
-- OPAQUE16_LEN used where 2 bytes are needed.
This commit is contained in:
Moisés Guimarães
2014-03-10 12:44:45 -03:00
parent 7630b1d222
commit eba36226dc
2 changed files with 44 additions and 14 deletions

View File

@@ -586,7 +586,6 @@ enum Misc {
SEQ_SZ = 8, /* 64 bit sequence number */ SEQ_SZ = 8, /* 64 bit sequence number */
BYTE3_LEN = 3, /* up to 24 bit byte lengths */ BYTE3_LEN = 3, /* up to 24 bit byte lengths */
ALERT_SIZE = 2, /* level + description */ ALERT_SIZE = 2, /* level + description */
REQUEST_HEADER = 2, /* always use 2 bytes */
VERIFY_HEADER = 2, /* always use 2 bytes */ VERIFY_HEADER = 2, /* always use 2 bytes */
EXT_ID_SZ = 2, /* always use 2 bytes */ EXT_ID_SZ = 2, /* always use 2 bytes */
MAX_DH_SIZE = 513, /* 4096 bit plus possible leading 0 */ MAX_DH_SIZE = 513, /* 4096 bit plus possible leading 0 */

View File

@@ -74,7 +74,8 @@ CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32); static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*); static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*);
#ifndef NO_CERTS #ifndef NO_CERTS
static int DoCertificateRequest(CYASSL* ssl, const byte* input,word32*); static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*,
word32);
#endif #endif
#endif #endif
@@ -3801,7 +3802,7 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
#ifndef NO_CERTS #ifndef NO_CERTS
case certificate_request: case certificate_request:
CYASSL_MSG("processing certificate request"); CYASSL_MSG("processing certificate request");
ret = DoCertificateRequest(ssl, input, inOutIdx); ret = DoCertificateRequest(ssl, input, inOutIdx, size);
break; break;
#endif #endif
@@ -7653,9 +7654,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
#ifndef NO_CERTS #ifndef NO_CERTS
/* just read in and ignore for now TODO: */ /* just read in and ignore for now TODO: */
static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32* static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*
inOutIdx) inOutIdx, word32 size)
{ {
word16 len; word16 len;
word32 begin = *inOutIdx;
#ifdef CYASSL_CALLBACKS #ifdef CYASSL_CALLBACKS
if (ssl->hsInfoOn) if (ssl->hsInfoOn)
@@ -7663,28 +7665,57 @@ static void PickHashSigAlgo(CYASSL* ssl,
if (ssl->toInfoOn) if (ssl->toInfoOn)
AddLateName("CertificateRequest", &ssl->timeoutInfo); AddLateName("CertificateRequest", &ssl->timeoutInfo);
#endif #endif
if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
return BUFFER_ERROR;
len = input[(*inOutIdx)++]; len = input[(*inOutIdx)++];
if ((*inOutIdx - begin) + len > size)
return BUFFER_ERROR;
/* types, read in here */ /* types, read in here */
*inOutIdx += len; *inOutIdx += len;
/* signature and hash signature algorithm */
if (IsAtLeastTLSv1_2(ssl)) { if (IsAtLeastTLSv1_2(ssl)) {
/* hash sig format */ if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
ato16(&input[*inOutIdx], &len); return BUFFER_ERROR;
*inOutIdx += LENGTH_SZ;
PickHashSigAlgo(ssl, &input[*inOutIdx], len); ato16(input + *inOutIdx, &len);
*inOutIdx += OPAQUE16_LEN;
if ((*inOutIdx - begin) + len > size)
return BUFFER_ERROR;
PickHashSigAlgo(ssl, input + *inOutIdx, len);
*inOutIdx += len; *inOutIdx += len;
} }
/* authorities */ /* authorities */
ato16(&input[*inOutIdx], &len); if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
*inOutIdx += LENGTH_SZ; return BUFFER_ERROR;
ato16(input + *inOutIdx, &len);
*inOutIdx += OPAQUE16_LEN;
if ((*inOutIdx - begin) + len > size)
return BUFFER_ERROR;
while (len) { while (len) {
word16 dnSz; word16 dnSz;
ato16(&input[*inOutIdx], &dnSz); if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
*inOutIdx += (REQUEST_HEADER + dnSz); return BUFFER_ERROR;
len -= dnSz + REQUEST_HEADER;
ato16(input + *inOutIdx, &dnSz);
*inOutIdx += OPAQUE16_LEN;
if ((*inOutIdx - begin) + dnSz > size)
return BUFFER_ERROR;
*inOutIdx += dnSz;
len -= OPAQUE16_LEN + dnSz;
} }
/* don't send client cert or cert verify if user hasn't provided /* don't send client cert or cert verify if user hasn't provided