mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-06 11:20:50 +02:00
Harden chain depth bounds and parser input validation
Enforce MAX_CHAIN_DEPTH limits in OCSP chain processing (SendCertificateStatus, ProcessChainOCSPRequest), certificate loading (ProcessUserChain), and TLS 1.3 certificate sending (SendTls13Certificate). Add idx bounds checks to chain accessors in ssl.c. Harden SNI extension parser (TLSX_SNI_GetFromBuffer) with length checks preventing buffer overreads on malformed ClientHello. Fix off-by-one in TLSX_CSR_Free where <= should be < since csr->requests is a count, not a max index. Add remaining-buffer bounds checks to PKCS7 decoders: DecodeEnvelopedData, DecodeAuthEnvelopedData (encryptedContentSz and authTagSz), DecodeEncryptedData, SignedData null signature tag, and PwriKek_KeyUnWrap cekLen validation.
This commit is contained in:
+3
-2
@@ -26208,7 +26208,8 @@ int SendCertificateStatus(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
if (chain && chain->buffer) {
|
||||
while (ret == 0 && idx + OPAQUE24_LEN < chain->length) {
|
||||
while (ret == 0 && i < MAX_CHAIN_DEPTH &&
|
||||
idx + OPAQUE24_LEN < chain->length) {
|
||||
c24to32(chain->buffer + idx, &der.length);
|
||||
idx += OPAQUE24_LEN;
|
||||
|
||||
@@ -26249,7 +26250,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
|
||||
WC_FREE_VAR_EX(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
|
||||
}
|
||||
else {
|
||||
while (ret == 0 &&
|
||||
while (ret == 0 && i < MAX_CHAIN_DEPTH &&
|
||||
NULL != (request = ssl->ctx->chainOcspRequest[i])) {
|
||||
if ((i + 1) >= MAX_CERT_EXTENSIONS) {
|
||||
ret = MAX_CERT_EXTENSIONS_ERR;
|
||||
|
||||
@@ -14121,7 +14121,7 @@ int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
|
||||
int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_get_chain_length");
|
||||
if (chain)
|
||||
if (chain && idx >= 0 && idx < chain->count)
|
||||
return chain->certs[idx].length;
|
||||
|
||||
return 0;
|
||||
@@ -14132,7 +14132,7 @@ int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
|
||||
byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_get_chain_cert");
|
||||
if (chain)
|
||||
if (chain && idx >= 0 && idx < chain->count)
|
||||
return chain->certs[idx].buffer;
|
||||
|
||||
return 0;
|
||||
@@ -14147,7 +14147,7 @@ WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
|
||||
WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_get_chain_X509");
|
||||
if (chain != NULL && idx < MAX_CHAIN_DEPTH) {
|
||||
if (chain != NULL && idx >= 0 && idx < chain->count) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
|
||||
DYNAMIC_TYPE_DCERT);
|
||||
|
||||
@@ -325,6 +325,13 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
|
||||
while ((ret == 0) && (consumed < sz)) {
|
||||
DerBuffer* part = NULL;
|
||||
|
||||
/* Enforce maximum chain depth. */
|
||||
if (cnt >= MAX_CHAIN_DEPTH) {
|
||||
WOLFSSL_MSG("Chain depth limit reached");
|
||||
ret = MAX_CHAIN_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get a certificate as DER. */
|
||||
ret = DataToDerBuffer(buff + consumed, (word32)(sz - consumed),
|
||||
format, type, info, heap, &part, NULL);
|
||||
|
||||
@@ -2826,6 +2826,9 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
|
||||
ato16(clientHello + offset, &listLen);
|
||||
offset += OPAQUE16_LEN;
|
||||
|
||||
if (listLen != extLen - OPAQUE16_LEN)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
if (helloSz < offset + listLen)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
@@ -2836,6 +2839,9 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
|
||||
ato16(clientHello + offset, &sniLen);
|
||||
offset += OPAQUE16_LEN;
|
||||
|
||||
if (sniLen > listLen - (ENUM_LEN + OPAQUE16_LEN))
|
||||
return BUFFER_ERROR;
|
||||
|
||||
if (helloSz < offset + sniLen)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
@@ -3393,7 +3399,7 @@ static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap)
|
||||
|
||||
switch (csr->status_type) {
|
||||
case WOLFSSL_CSR_OCSP:
|
||||
for (i = 0; i <= csr->requests; i++) {
|
||||
for (i = 0; i < csr->requests; i++) {
|
||||
FreeOcspRequest(&csr->request.ocsp[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -9520,6 +9520,10 @@ static int SendTls13Certificate(WOLFSSL* ssl)
|
||||
}
|
||||
/* Certificate Data */
|
||||
certSz = ssl->buffers.certificate->length;
|
||||
if (ssl->buffers.certChainCnt > MAX_CHAIN_DEPTH) {
|
||||
WOLFSSL_MSG("Certificate chain count exceeds maximum depth");
|
||||
return MAX_CHAIN_ERROR;
|
||||
}
|
||||
/* Cert Req Ctx Len | Cert Req Ctx | Cert List Len | Cert Data Len */
|
||||
headerSz = OPAQUE8_LEN + certReqCtxLen + CERT_HEADER_SZ +
|
||||
CERT_HEADER_SZ;
|
||||
|
||||
@@ -14968,6 +14968,12 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in,
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && encryptedContentSz > (int)(pkiMsgSz - idx)) {
|
||||
#ifdef NO_PKCS7_STREAM
|
||||
ret = BUFFER_E;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
@@ -15230,6 +15236,12 @@ authenv_atrbend:
|
||||
#endif
|
||||
idx = localIdx;
|
||||
|
||||
#ifdef NO_PKCS7_STREAM
|
||||
if (ret == 0 && authTagSz > (word32)(pkiMsgSz - idx)) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == 0 && authTagSz > (word32)sizeof(authTag)) {
|
||||
WOLFSSL_MSG("AuthEnvelopedData authTag too large for buffer");
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
Reference in New Issue
Block a user