Merge pull request #10788 from aidangarske/fenrir-tls-batch-2026-06

Various hardening fixes across sniffer, QUIC, PKCS#11, TLS and tooling
This commit is contained in:
David Garske
2026-07-08 13:58:14 -07:00
committed by GitHub
11 changed files with 138 additions and 27 deletions
+6
View File
@@ -36089,6 +36089,12 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
/* Nonces are not critical. The responder may not necessarily add
* the nonce to the response. */
#ifdef WOLFSSL_FORCE_OCSP_NONCE_CHECK
if (req->nonceSz && resp->nonce == NULL) {
WOLFSSL_MSG("\tnonce required but missing from response");
return WOLFSSL_FATAL_ERROR;
}
#endif
if (req->nonceSz && resp->nonce != NULL
#ifndef WOLFSSL_FORCE_OCSP_NONCE_CHECK
&& resp->nonceSz != 0
+26 -13
View File
@@ -213,6 +213,7 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
int result = 0;
int i;
word32 tmpSz = 0;
word32 maxBufSz;
byte* tmp;
(void)memoryType;
@@ -221,14 +222,27 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
if (out == NULL || in == NULL) {
return BAD_FUNC_ARG;
}
/* Cap input so the initial doubling and additive growth in the loop
* cannot overflow word32 or the int return type. */
if (inSz > (word32)(INT_MAX / 2)) {
/* Cap input so the initial doubling and the growth in the loop cannot
* overflow word32 or the int return type. Zero input has no buffer to
* size against. */
if (inSz == 0 || inSz > (word32)(INT_MAX / 2)) {
return BAD_FUNC_ARG;
}
i = (maxSz == 1)? 1 : 2; /* start with output buffer twice the size of input
* unless max was set to 1 */
/* Largest output buffer permitted: inSz * maxSz keeps the historic
* maxSz ratio, clamped to INT_MAX (and unbounded becomes INT_MAX). */
if (maxSz > 0) {
if ((word32)maxSz > (word32)INT_MAX / inSz)
maxBufSz = (word32)INT_MAX;
else
maxBufSz = inSz * (word32)maxSz;
}
else {
maxBufSz = (word32)INT_MAX;
}
stream.next_in = (Bytef*)in;
stream.avail_in = (uInt)inSz;
/* Check for source > 64K on 16-bit machine: */
@@ -277,18 +291,17 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
word32 newSz;
byte* newTmp;
if (maxSz > 0 && i >= maxSz) {
if (tmpSz >= maxBufSz) {
WOLFSSL_MSG("Hit max decompress size!");
break;
}
i++;
if (tmpSz > (word32)INT_MAX - inSz) {
WOLFSSL_MSG("Decompress buffer would exceed INT_MAX");
result = DECOMPRESS_E;
break;
}
newSz = tmpSz + inSz;
/* Double the buffer so cumulative copy work stays linear in the
* output size, clamped to the permitted maximum. */
if (tmpSz > maxBufSz / 2)
newSz = maxBufSz;
else
newSz = tmpSz * 2;
newTmp = (byte*)XMALLOC(newSz, heap, memoryType);
if (newTmp == NULL) {
WOLFSSL_MSG("Memory error with increasing buffer size");
@@ -298,14 +311,14 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
XFREE(tmp, heap, memoryType);
tmp = newTmp;
stream.next_out = tmp + stream.total_out;
stream.avail_out = stream.avail_out + (uInt)inSz;
stream.avail_out = (uInt)(newSz - stream.total_out);
tmpSz = newSz;
result = inflate(&stream, Z_BLOCK);
}
} while (result == Z_OK);
if (result == Z_STREAM_END) {
if (stream.total_out > (uLong)INT_MAX) {
if (stream.total_out >= (uLong)INT_MAX) {
result = DECOMPRESS_E;
}
else {
@@ -1382,6 +1382,13 @@ static esp_err_t wolfssl_esp_crt_bundle_init(const uint8_t *x509_bundle,
ESP_LOGCBI(TAG, "- This certificate at 0x%x, length: %u",
(intptr_t)cur_crt, cert_len);
if (cur_crt + CRT_HEADER_OFFSET + cert_len > bundle_end) {
ESP_LOGE(TAG, "Invalid certificate bundle cert length");
_esp_crt_bundle_is_valid = ESP_FAIL;
ret = ESP_ERR_INVALID_ARG;
break;
}
/* TODO: optional gate out serial check for performance. */
/* Useful only for custom cert bundle, known to have no zeros. */
if (wolfssl_is_zero_serial_number(cur_crt + CRT_HEADER_OFFSET,
+23 -4
View File
@@ -2513,6 +2513,13 @@ static int Pkcs11GetRsaPublicKey(RsaKey* key, Pkcs11Session* session,
if (ret == 0) {
modSz = (int)tmpl[0].ulValueLen;
expSz = (int)tmpl[1].ulValueLen;
/* reject token lengths that do not fit in a positive int */
if (modSz <= 0 || (CK_ULONG)modSz != tmpl[0].ulValueLen ||
expSz <= 0 || (CK_ULONG)expSz != tmpl[1].ulValueLen) {
ret = WC_HW_E;
}
}
if (ret == 0) {
mod = (unsigned char*)XMALLOC(modSz, key->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (mod == NULL)
@@ -2526,7 +2533,9 @@ static int Pkcs11GetRsaPublicKey(RsaKey* key, Pkcs11Session* session,
}
if (ret == 0) {
tmpl[0].pValue = mod;
tmpl[0].ulValueLen = (CK_ULONG)modSz;
tmpl[1].pValue = exp;
tmpl[1].ulValueLen = (CK_ULONG)expSz;
PKCS11_DUMP_TEMPLATE("Get RSA Public Key", tmpl, tmplCnt);
rv = session->func->C_GetAttributeValue(session->handle, pubKey,
@@ -3272,12 +3281,19 @@ static int Pkcs11GetEccPublicKey(ecc_key* key, Pkcs11Session* session,
if (ret == 0) {
pointSz = (int)tmpl[0].ulValueLen;
/* reject a token length that does not fit in a positive int */
if (pointSz <= 0 || (CK_ULONG)pointSz != tmpl[0].ulValueLen) {
ret = WC_HW_E;
}
}
if (ret == 0) {
point = (unsigned char*)XMALLOC(pointSz, key->heap, DYNAMIC_TYPE_ECC);
if (point == NULL)
ret = MEMORY_E;
}
if (ret == 0) {
tmpl[0].pValue = point;
tmpl[0].ulValueLen = (CK_ULONG)pointSz;
PKCS11_DUMP_TEMPLATE("Get Ec Public Key", tmpl, tmplCnt);
rv = session->func->C_GetAttributeValue(session->handle, pubKey,
@@ -6223,6 +6239,7 @@ static int Pkcs11GetCert(Pkcs11Session* session, wc_CryptoInfo* info) {
CK_ULONG count = 0;
CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
byte *certData = NULL;
int certDataSz = 0;
CK_ATTRIBUTE certTemplate[2] = {
{ CKA_CLASS, &certClass, sizeof(certClass) }
};
@@ -6264,19 +6281,21 @@ static int Pkcs11GetCert(Pkcs11Session* session, wc_CryptoInfo* info) {
goto exit;
}
if (tmpl[0].ulValueLen <= 0) {
certDataSz = (int)tmpl[0].ulValueLen;
/* reject a token length that does not fit in a positive int */
if (certDataSz <= 0 || (CK_ULONG)certDataSz != tmpl[0].ulValueLen) {
ret = WC_HW_E;
goto exit;
}
certData = (byte *)XMALLOC(
(int)tmpl[0].ulValueLen, info->cert.heap, DYNAMIC_TYPE_CERT);
certData = (byte *)XMALLOC(certDataSz, info->cert.heap, DYNAMIC_TYPE_CERT);
if (certData == NULL) {
ret = MEMORY_E;
goto exit;
}
tmpl[0].pValue = certData;
tmpl[0].ulValueLen = (CK_ULONG)certDataSz;
rv = session->func->C_GetAttributeValue(
session->handle, certHandle, tmpl, tmplCnt);
PKCS11_RV("C_GetAttributeValue", rv);
@@ -6286,7 +6305,7 @@ static int Pkcs11GetCert(Pkcs11Session* session, wc_CryptoInfo* info) {
}
*info->cert.certDataOut = certData;
*info->cert.certSz = (word32)tmpl[0].ulValueLen;
*info->cert.certSz = (word32)certDataSz;
if (info->cert.certFormatOut != NULL) {
*info->cert.certFormatOut = CTC_FILETYPE_ASN1;
}