diff --git a/src/internal.c b/src/internal.c index 067b7a6c08..f90e07c2b9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -25909,6 +25909,10 @@ int SendCertificateStatus(WOLFSSL* ssl) if (idx > chain->length) break; + if ((i + 1) >= MAX_CERT_EXTENSIONS) { + ret = MAX_CERT_EXTENSIONS_ERR; + break; + } ret = CreateOcspRequest(ssl, request, cert, der.buffer, der.length, &ctxOwnsRequest); if (ret == 0) { @@ -25937,6 +25941,11 @@ int SendCertificateStatus(WOLFSSL* ssl) else { while (ret == 0 && NULL != (request = ssl->ctx->chainOcspRequest[i])) { + if ((i + 1) >= MAX_CERT_EXTENSIONS) { + ret = MAX_CERT_EXTENSIONS_ERR; + break; + } + request->ssl = ssl; ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling, request, &responses[++i], ssl->heap); diff --git a/src/sniffer.c b/src/sniffer.c index e8664721b1..c00915070b 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -4195,6 +4195,9 @@ static int ProcessClientHello(const byte* input, int* sslBytes, { word16 listLen = 0, offset = 0; + if (extLen < OPAQUE16_LEN) + return BUFFER_ERROR; + ato16(input + offset, &listLen); offset += OPAQUE16_LEN; @@ -4228,7 +4231,13 @@ static int ProcessClientHello(const byte* input, int* sslBytes, #ifdef WOLFSSL_TLS13 case EXT_KEY_SHARE: { - word16 ksLen = (word16)((input[0] << 8) | input[1]); + word16 ksLen = 0; + if (extLen < OPAQUE16_LEN) { + SetError(BUFFER_ERROR_STR, error, session, FATAL_ERROR_STATE); + return BUFFER_ERROR; + } + + ksLen = (word16)((input[0] << 8) | input[1]); if (ksLen + OPAQUE16_LEN > extLen) { SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); return WOLFSSL_FATAL_ERROR; @@ -4252,6 +4261,11 @@ static int ProcessClientHello(const byte* input, int* sslBytes, word32 ticketAge; const byte *identity, *binders; + if (extLen < OPAQUE16_LEN) { + SetError(BUFFER_ERROR_STR, error, session, FATAL_ERROR_STATE); + return BUFFER_ERROR; + } + idsLen = (word16)((input[idx] << 8) | input[idx+1]); if ((word32)idsLen + OPAQUE16_LEN + idx > (word32)extLen) { SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); diff --git a/src/tls.c b/src/tls.c index b854b8f8cd..a329c935a6 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2800,6 +2800,9 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, } else { word16 listLen; + if (extLen < OPAQUE16_LEN) + return BUFFER_ERROR; + ato16(clientHello + offset, &listLen); offset += OPAQUE16_LEN; @@ -3611,6 +3614,14 @@ int ProcessChainOCSPRequest(WOLFSSL* ssl) if (chain && chain->buffer) { while (ret == 0 && pos + OPAQUE24_LEN < chain->length) { + if (i >= MAX_CERT_EXTENSIONS) { + WOLFSSL_MSG_EX( + "OCSP request cert chain exceeds maximum length: " + "i=%d, MAX_CERT_EXTENSIONS=%d", i, MAX_CERT_EXTENSIONS); + ret = MAX_CERT_EXTENSIONS_ERR; + break; + } + c24to32(chain->buffer + pos, &der.length); pos += OPAQUE24_LEN; der.buffer = chain->buffer + pos; diff --git a/src/tls13.c b/src/tls13.c index a591532be2..573751c4b9 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -8871,7 +8871,7 @@ static word32 NextCert(byte* data, word32 length, word32* idx) * extIdx The index number of certificate status request data * for the certificate. * offset index offset - * returns Total number of bytes written. + * returns Total number of bytes written on success or negative value on error. */ static int WriteCSRToBuffer(WOLFSSL* ssl, DerBuffer** certExts, word16* extSz, word16 extSz_num) @@ -8886,6 +8886,9 @@ static int WriteCSRToBuffer(WOLFSSL* ssl, DerBuffer** certExts, word32 extIdx; DerBuffer* der; + if (extSz_num > MAX_CERT_EXTENSIONS) + return MAX_CERT_EXTENSIONS_ERR; + ext = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); csr = ext ? (CertificateStatusRequest*)ext->data : NULL; @@ -9137,8 +9140,11 @@ static int SendTls13Certificate(WOLFSSL* ssl) if (ret != 0) return ret; - ret = WriteCSRToBuffer(ssl, &ssl->buffers.certExts[0], &extSz[0], - 1 /* +1 for leaf */ + (word16)ssl->buffers.certChainCnt); + if ((1 + ssl->buffers.certChainCnt) > MAX_CERT_EXTENSIONS) + ret = MAX_CERT_EXTENSIONS_ERR; + if (ret == 0) + ret = WriteCSRToBuffer(ssl, &ssl->buffers.certExts[0], &extSz[0], + 1 /* +1 for leaf */ + (word16)ssl->buffers.certChainCnt); if (ret < 0) return ret; totalextSz += ret;