forked from wolfSSL/wolfssl
Boundaries check for DoCertificateVerify.
-- switched from totalSz to size in the function parameters; -- BUFFER_ERROR returned in case of message overflow (piece larger than the hello size); -- ENUM_LEN used whenever 1 byte is needed; -- OPAQUE16_LEN used whenever 2 bytes are needed; -- removed unnecessary variables; -- removed unnecessary #ifdef HAVE_ECC and #ifndef NO_RSA.
This commit is contained in:
@ -3835,7 +3835,7 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
#if !defined(NO_RSA) || defined(HAVE_ECC)
|
#if !defined(NO_RSA) || defined(HAVE_ECC)
|
||||||
case certificate_verify:
|
case certificate_verify:
|
||||||
CYASSL_MSG("processing certificate verify");
|
CYASSL_MSG("processing certificate verify");
|
||||||
ret = DoCertificateVerify(ssl, input, inOutIdx, totalSz);
|
ret = DoCertificateVerify(ssl, input, inOutIdx, size);
|
||||||
break;
|
break;
|
||||||
#endif /* !NO_RSA || HAVE_ECC */
|
#endif /* !NO_RSA || HAVE_ECC */
|
||||||
|
|
||||||
@ -10306,15 +10306,14 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(NO_RSA) || defined(HAVE_ECC)
|
#if !defined(NO_RSA) || defined(HAVE_ECC)
|
||||||
static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutsz,
|
static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutIdx,
|
||||||
word32 totalSz)
|
word32 size)
|
||||||
{
|
{
|
||||||
word16 sz = 0;
|
word16 sz = 0;
|
||||||
word32 i = *inOutsz;
|
|
||||||
int ret = VERIFY_CERT_ERROR; /* start in error state */
|
int ret = VERIFY_CERT_ERROR; /* start in error state */
|
||||||
byte* sig;
|
|
||||||
byte hashAlgo = sha_mac;
|
byte hashAlgo = sha_mac;
|
||||||
byte sigAlgo = anonymous_sa_algo;
|
byte sigAlgo = anonymous_sa_algo;
|
||||||
|
word32 begin = *inOutIdx;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
@ -10322,24 +10321,24 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
if (ssl->toInfoOn)
|
if (ssl->toInfoOn)
|
||||||
AddLateName("CertificateVerify", &ssl->timeoutInfo);
|
AddLateName("CertificateVerify", &ssl->timeoutInfo);
|
||||||
#endif
|
#endif
|
||||||
if ( (i + VERIFY_HEADER) > totalSz)
|
|
||||||
return INCOMPLETE_DATA;
|
|
||||||
|
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
hashAlgo = input[i++];
|
if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
|
||||||
sigAlgo = input[i++];
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
hashAlgo = input[(*inOutIdx)++];
|
||||||
|
sigAlgo = input[(*inOutIdx)++];
|
||||||
}
|
}
|
||||||
ato16(&input[i], &sz);
|
|
||||||
i += VERIFY_HEADER;
|
|
||||||
|
|
||||||
if ( (i + sz) > totalSz)
|
if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
|
||||||
return INCOMPLETE_DATA;
|
|
||||||
|
|
||||||
if (sz > ENCRYPT_LEN)
|
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
sig = &input[i];
|
ato16(input + *inOutIdx, &sz);
|
||||||
*inOutsz = i + sz;
|
*inOutIdx += OPAQUE16_LEN;
|
||||||
|
|
||||||
|
if ((*inOutIdx - begin) + sz > size || sz > ENCRYPT_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
/* RSA */
|
/* RSA */
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
@ -10357,7 +10356,7 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
|
|
||||||
if (doUserRsa) {
|
if (doUserRsa) {
|
||||||
#ifdef HAVE_PK_CALLBACKS
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
outLen = ssl->ctx->RsaVerifyCb(ssl, sig, sz,
|
outLen = ssl->ctx->RsaVerifyCb(ssl, input + *inOutIdx, sz,
|
||||||
&out,
|
&out,
|
||||||
ssl->buffers.peerRsaKey.buffer,
|
ssl->buffers.peerRsaKey.buffer,
|
||||||
ssl->buffers.peerRsaKey.length,
|
ssl->buffers.peerRsaKey.length,
|
||||||
@ -10365,7 +10364,8 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
#endif /*HAVE_PK_CALLBACKS */
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outLen = RsaSSL_VerifyInline(sig, sz, &out, ssl->peerRsaKey);
|
outLen = RsaSSL_VerifyInline(input + *inOutIdx, sz, &out,
|
||||||
|
ssl->peerRsaKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
@ -10398,12 +10398,12 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
|
|
||||||
if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig,
|
if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig,
|
||||||
min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
|
min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
|
||||||
ret = 0; /* verified */
|
ret = 0; /* verified */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (outLen == FINISHED_SZ && out && XMEMCMP(out,
|
if (outLen == FINISHED_SZ && out && XMEMCMP(out,
|
||||||
&ssl->certHashes, FINISHED_SZ) == 0)
|
&ssl->certHashes, FINISHED_SZ) == 0)
|
||||||
ret = 0; /* verified */
|
ret = 0; /* verified */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -10416,11 +10416,9 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
byte doUserEcc = 0;
|
byte doUserEcc = 0;
|
||||||
|
|
||||||
#ifdef HAVE_PK_CALLBACKS
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
#ifdef HAVE_ECC
|
if (ssl->ctx->EccVerifyCb)
|
||||||
if (ssl->ctx->EccVerifyCb)
|
doUserEcc = 1;
|
||||||
doUserEcc = 1;
|
#endif
|
||||||
#endif /* HAVE_ECC */
|
|
||||||
#endif /*HAVE_PK_CALLBACKS */
|
|
||||||
|
|
||||||
CYASSL_MSG("Doing ECC peer cert verify");
|
CYASSL_MSG("Doing ECC peer cert verify");
|
||||||
|
|
||||||
@ -10428,6 +10426,7 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
if (sigAlgo != ecc_dsa_sa_algo) {
|
if (sigAlgo != ecc_dsa_sa_algo) {
|
||||||
CYASSL_MSG("Oops, peer sent ECC key but not in verify");
|
CYASSL_MSG("Oops, peer sent ECC key but not in verify");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hashAlgo == sha256_mac) {
|
if (hashAlgo == sha256_mac) {
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
digest = ssl->certHashes.sha256;
|
digest = ssl->certHashes.sha256;
|
||||||
@ -10441,24 +10440,27 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doUserEcc) {
|
if (doUserEcc) {
|
||||||
#ifdef HAVE_PK_CALLBACKS
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
#ifdef HAVE_ECC
|
ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, sz, digest,
|
||||||
ret = ssl->ctx->EccVerifyCb(ssl, sig, sz, digest, digestSz,
|
digestSz,
|
||||||
ssl->buffers.peerEccDsaKey.buffer,
|
ssl->buffers.peerEccDsaKey.buffer,
|
||||||
ssl->buffers.peerEccDsaKey.length,
|
ssl->buffers.peerEccDsaKey.length,
|
||||||
&verify, ssl->EccVerifyCtx);
|
&verify, ssl->EccVerifyCtx);
|
||||||
#endif /* HAVE_ECC */
|
#endif
|
||||||
#endif /*HAVE_PK_CALLBACKS */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
err = ecc_verify_hash(sig, sz, digest, digestSz,
|
err = ecc_verify_hash(input + *inOutIdx, sz, digest, digestSz,
|
||||||
&verify, ssl->peerEccDsaKey);
|
&verify, ssl->peerEccDsaKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == 0 && verify == 1)
|
if (err == 0 && verify == 1)
|
||||||
ret = 0; /* verified */
|
ret = 0; /* verified */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
*inOutIdx += sz;
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ssl->options.havePeerVerify = 1;
|
ssl->options.havePeerVerify = 1;
|
||||||
|
|
||||||
@ -10639,14 +10641,12 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
|
|
||||||
if (doUserRsa) {
|
if (doUserRsa) {
|
||||||
#ifdef HAVE_PK_CALLBACKS
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
#ifndef NO_RSA
|
ret = ssl->ctx->RsaDecCb(ssl,
|
||||||
ret = ssl->ctx->RsaDecCb(ssl,
|
input + *inOutIdx, length, &out,
|
||||||
input + *inOutIdx, length, &out,
|
ssl->buffers.key.buffer,
|
||||||
ssl->buffers.key.buffer,
|
ssl->buffers.key.length,
|
||||||
ssl->buffers.key.length,
|
ssl->RsaDecCtx);
|
||||||
ssl->RsaDecCtx);
|
#endif
|
||||||
#endif /* NO_RSA */
|
|
||||||
#endif /*HAVE_PK_CALLBACKS */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = RsaPrivateDecryptInline(input + *inOutIdx, length,
|
ret = RsaPrivateDecryptInline(input + *inOutIdx, length,
|
||||||
|
Reference in New Issue
Block a user