mirror of https://github.com/wolfSSL/wolfssl
Boundaries check for DoCertificate .
-- added size in the function parameters; -- BUFFER_ERROR returned in case of message overflow (piece larger than the hello size); -- OPAQUE24_LEN used whenever 3 bytes are needed; -- removed unnecessary variable i; -- Moved BUFFER_E check outside of the while, check against certSz is not needed, in this case the problem is a malformed packet since certSz can never be bigger than listSz.
This commit is contained in:
parent
2d2d1341cf
commit
0a5b758de3
|
@ -3242,9 +3242,10 @@ int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert)
|
||||||
#endif /* KEEP_PEER_CERT || SESSION_CERTS */
|
#endif /* KEEP_PEER_CERT || SESSION_CERTS */
|
||||||
|
|
||||||
|
|
||||||
static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx,
|
||||||
|
word32 size)
|
||||||
{
|
{
|
||||||
word32 listSz, i = *inOutIdx;
|
word32 listSz, begin = *inOutIdx;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int anyError = 0;
|
int anyError = 0;
|
||||||
int totalCerts = 0; /* number of certs in certs buffer */
|
int totalCerts = 0; /* number of certs in certs buffer */
|
||||||
|
@ -3256,46 +3257,58 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||||
if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
|
if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
|
||||||
if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
|
if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
|
||||||
#endif
|
#endif
|
||||||
c24to32(&input[i], &listSz);
|
|
||||||
i += CERT_HEADER_SZ;
|
if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
c24to32(input + *inOutIdx, &listSz);
|
||||||
|
*inOutIdx += OPAQUE24_LEN;
|
||||||
|
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
if (listSz > ssl->max_fragment)
|
||||||
|
return BUFFER_E;
|
||||||
|
#else
|
||||||
|
if (listSz > MAX_RECORD_SIZE)
|
||||||
|
return BUFFER_E;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((*inOutIdx - begin) + listSz != size)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
CYASSL_MSG("Loading peer's cert chain");
|
CYASSL_MSG("Loading peer's cert chain");
|
||||||
/* first put cert chain into buffer so can verify top down
|
/* first put cert chain into buffer so can verify top down
|
||||||
we're sent bottom up */
|
we're sent bottom up */
|
||||||
while (listSz) {
|
while (listSz) {
|
||||||
/* cert size */
|
|
||||||
word32 certSz;
|
word32 certSz;
|
||||||
|
|
||||||
if (totalCerts >= MAX_CHAIN_DEPTH)
|
if (totalCerts >= MAX_CHAIN_DEPTH)
|
||||||
return MAX_CHAIN_ERROR;
|
return MAX_CHAIN_ERROR;
|
||||||
|
|
||||||
c24to32(&input[i], &certSz);
|
if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
|
||||||
i += CERT_HEADER_SZ;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
#ifdef HAVE_MAX_FRAGMENT
|
c24to32(input + *inOutIdx, &certSz);
|
||||||
if (listSz > ssl->max_fragment || certSz > ssl->max_fragment)
|
*inOutIdx += OPAQUE24_LEN;
|
||||||
return BUFFER_E;
|
|
||||||
#else
|
if ((*inOutIdx - begin) + certSz > size)
|
||||||
if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
|
return BUFFER_ERROR;
|
||||||
return BUFFER_E;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
certs[totalCerts].length = certSz;
|
certs[totalCerts].length = certSz;
|
||||||
certs[totalCerts].buffer = input + i;
|
certs[totalCerts].buffer = input + *inOutIdx;
|
||||||
|
|
||||||
#ifdef SESSION_CERTS
|
#ifdef SESSION_CERTS
|
||||||
if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
|
if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
|
||||||
certSz < MAX_X509_SIZE) {
|
certSz < MAX_X509_SIZE) {
|
||||||
ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
|
ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
|
||||||
XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
|
XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
|
||||||
input + i, certSz);
|
input + *inOutIdx, certSz);
|
||||||
ssl->session.chain.count++;
|
ssl->session.chain.count++;
|
||||||
} else {
|
} else {
|
||||||
CYASSL_MSG("Couldn't store chain cert for session");
|
CYASSL_MSG("Couldn't store chain cert for session");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i += certSz;
|
*inOutIdx += certSz;
|
||||||
listSz -= certSz + CERT_HEADER_SZ;
|
listSz -= certSz + CERT_HEADER_SZ;
|
||||||
|
|
||||||
totalCerts++;
|
totalCerts++;
|
||||||
|
@ -3625,7 +3638,6 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*inOutIdx = i;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3816,7 +3828,7 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
case certificate:
|
case certificate:
|
||||||
CYASSL_MSG("processing certificate");
|
CYASSL_MSG("processing certificate");
|
||||||
ret = DoCertificate(ssl, input, inOutIdx);
|
ret = DoCertificate(ssl, input, inOutIdx, size);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue