From 92d01611ff5a17bc131c7c36792d638eb1bc17bc Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 13 Jan 2022 13:26:32 +0000 Subject: [PATCH 1/2] Fix buffer overflow in GetOID When converting BER to DER we switched the pointer for pkiMsg to the DER but not the size which could cause buffer overflow. Fixes ZD13471 --- wolfcrypt/src/pkcs7.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 3bcbfec6f..498d50db7 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -10497,8 +10497,10 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, #ifdef ASN_BER_TO_DER /* check if content was BER and has been converted to DER */ - if (pkcs7->derSz > 0) + if (pkcs7->derSz > 0) { pkiMsg = in = pkcs7->der; + pkiMsgSz = inSz = pkcs7->derSz; + } #endif decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap, From 1a4bc322f71e7ed8a8d295d2e426bec9f35b963d Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 13 Jan 2022 14:49:31 +0000 Subject: [PATCH 2/2] Fix buffer overflow in PKCS7_VerifySignedData wc_PKCS7_AddDataToStream() was called the first time prior to BERtoDER conversion, subsequent times afterwards which meant the stream idx pointer was incorrect. This patch restarts the stream after conversion. Fixes ZD13476 --- wolfcrypt/src/pkcs7.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 498d50db7..9336af14c 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -4451,17 +4451,32 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, return ret; pkiMsg = in = pkcs7->der; - pkiMsgSz = pkcs7->derSz = len; + pkiMsgSz = inSz = pkcs7->derSz = len; idx = 0; - if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz, - NO_USER_CHECK) < 0) - return ASN_PARSE_E; - #ifndef NO_PKCS7_STREAM + wc_PKCS7_ResetStream(pkcs7); + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_SEQ_SZ + + MAX_LENGTH_SZ + ASN_TAG_SZ + MAX_OID_SZ + + MAX_SEQ_SZ, &pkiMsg, &idx)) != 0) { + break; + } + + pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: + inSz; + + totalSz = pkiMsgSz; + if (pkiMsg2 && pkiMsg2Sz > 0) { + totalSz += pkiMsg2Sz + pkcs7->contentSz; + } + if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, len)) != 0) { break; } #endif + if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz, + NO_USER_CHECK) < 0) + return ASN_PARSE_E; #else ret = BER_INDEF_E; #endif