From 75762d44b6ac979a0c385730d0f8d27b1ae18f09 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Mon, 29 Jan 2024 10:45:55 -0700 Subject: [PATCH 1/7] PKCS7 streaming with encode/sign --- wolfcrypt/src/asn.c | 95 ++++++++++++ wolfcrypt/src/pkcs7.c | 307 +++++++++++++++++++++++++++++++++----- wolfssl/wolfcrypt/asn.h | 4 + wolfssl/wolfcrypt/pkcs7.h | 8 + 4 files changed, 378 insertions(+), 36 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3b61f6fb5..fa1ab6993 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3460,6 +3460,101 @@ word32 SetBitString(word32 len, byte unusedBits, byte* output) #endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */ #ifdef ASN_BER_TO_DER + +#define BER_OCTET_LENGTH 4096 + + +/* Breaks an octet string up into chunks for use with streaming + * returns 0 on success and updates idx */ +int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, + word32* idx) +{ + word32 i = 0; + word32 outIdx = *idx; + byte* tmp = out; + + if (tmp) tmp += outIdx; + + while (i < inSz) { + int ret, sz; + + sz = BER_OCTET_LENGTH; + + if ((sz + i) > inSz) { + sz = inSz - i; + } + + ret = SetOctetString(sz, tmp); + if (ret > 0) { + outIdx += ret; + } + + if (tmp) { + if (ret + sz + i + outIdx > *outSz) { + return BUFFER_E; + } + XMEMCPY(tmp + ret, in + i, sz); + tmp += sz + ret; + } + outIdx += sz; + i += sz; + } + + if (tmp) { + *idx = outIdx; + return 0; + } + else { + *outSz = outIdx; + return LENGTH_ONLY_E; + } +} + +long SetImplicitBer(byte tag, byte num, const byte* data, word32 dataSz, + byte* out, word32* outSz) +{ + word32 sz = 0; + long outIdx = 0; + byte berTag = tag; + + (void)num; + if (outSz == NULL || data == NULL) { + return BAD_FUNC_ARG; + } + + /* create a list of chuncked up octets */ + if (tag == ASN_OCTET_STRING) { + berTag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC; + } + + if (out != NULL) { + if (*outSz < 2) { + return BUFFER_E; + } + out[outIdx] = berTag; + out[outIdx + 1] = ASN_INDEF_LENGTH; + } + outIdx += 2; + + sz = *outSz; + StreamOctetString(data, dataSz, out, &sz, (word32*)&outIdx); + + if (out) { + out[outIdx] = 0x00; + out[outIdx + 1] = 0x00; + } + outIdx += 2; + + if (out) { + return outIdx; + } + else { + *outSz = outIdx; + return LENGTH_ONLY_E; + } +} + + /* Convert BER to DER */ /* Pull informtation from the ASN.1 BER encoded item header */ diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index e312520a1..31da976be 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2462,7 +2462,22 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->innerContSeqSz = 0; esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz, esd->contentInfoSeq); - } else { + } + else if (pkcs7->encodeStream) { + byte tmp[] = { 0xA0, 0x80 }; + byte tmpSeq[] = { 0x30, 0x80 }; + byte tmpStr[] = { 0x24, 0x80 }; + + XMEMCPY(esd->innerContSeq, tmp, 2); + esd->innerContSeqSz = 2; + + XMEMCPY(esd->contentInfoSeq, tmpSeq, 2); + esd->contentInfoSeqSz = 2; + + XMEMCPY(esd->innerOctets, tmpStr, 2); + esd->innerOctetsSz = 2; + } + else { esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz, esd->innerContSeq); @@ -2577,10 +2592,12 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, /* certificates [0] IMPLICIT CertificateSet */ /* get total certificates size */ - certPtr = pkcs7->certList; - while (certPtr != NULL) { - certSetSz += certPtr->derSz; - certPtr = certPtr->next; + if (pkcs7->noCerts != 1) { + certPtr = pkcs7->certList; + while (certPtr != NULL) { + certSetSz += certPtr->derSz; + certPtr = certPtr->next; + } } certPtr = NULL; @@ -2603,19 +2620,48 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz + esd->contentInfoSeqSz + pkcs7->contentTypeSz + - esd->innerContSeqSz + esd->innerOctetsSz + pkcs7->contentSz; + esd->innerContSeqSz + esd->innerOctetsSz; + + if (pkcs7->encodeStream) { + word32 sz = 0, tmpIdx = 0; + totalSz += 6; /* 00's for BER with inner content */ + + StreamOctetString(pkcs7->content, pkcs7->contentSz, NULL, &sz, &tmpIdx); + totalSz += sz + 6; + } + else { + totalSz += pkcs7->contentSz; + } total2Sz = esd->certsSetSz + certSetSz + signerInfoSz; if (pkcs7->detached) { totalSz -= pkcs7->contentSz; } - esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq); - totalSz += esd->innerSeqSz; - esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent); - totalSz += esd->outerContentSz + signedDataOidSz; - esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq); - totalSz += esd->outerSeqSz; + if (pkcs7->encodeStream) { + byte tmp[] = { 0xA0, 0x80 }; + byte tmpSeq[] = { 0x30, 0x80 }; + + XMEMCPY(esd->innerSeq, tmpSeq, 2); + esd->innerSeqSz = 2; + totalSz += esd->innerSeqSz + 2; + + XMEMCPY(esd->outerContent, tmp, 2); + esd->outerContentSz = 2; + totalSz += esd->outerContentSz + 2 + signedDataOidSz; + + XMEMCPY(esd->outerSeq, tmpSeq, 2); + esd->outerSeqSz = 2; + totalSz += esd->outerSeqSz + 2; + } + else { + esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq); + totalSz += esd->innerSeqSz; + esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent); + totalSz += esd->outerContentSz + signedDataOidSz; + esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq); + totalSz += esd->outerSeqSz; + } /* if using header/footer, we are not returning the content */ if (output2 && output2Sz) { @@ -2690,8 +2736,20 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, } else { if (!pkcs7->detached && pkcs7->content != NULL && pkcs7->contentSz > 0) { - XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); - idx += pkcs7->contentSz; + if (pkcs7->encodeStream) { + StreamOctetString(pkcs7->content, pkcs7->contentSz, output, + outputSz, (word32*)&idx); + output[idx++] = 0x00; + output[idx++] = 0x00; + output[idx++] = 0x00; + output[idx++] = 0x00; + output[idx++] = 0x00; + output[idx++] = 0x00; + } + else { + XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); + idx += pkcs7->contentSz; + } } output2 = output; } @@ -2699,12 +2757,16 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, /* certificates */ XMEMCPY(output2 + idx, esd->certsSet, esd->certsSetSz); idx += esd->certsSetSz; - certPtr = pkcs7->certList; - while (certPtr != NULL) { - XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz); - idx += certPtr->derSz; - certPtr = certPtr->next; + + if (pkcs7->noCerts != 1) { + certPtr = pkcs7->certList; + while (certPtr != NULL) { + XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz); + idx += certPtr->derSz; + certPtr = certPtr->next; + } } + wc_PKCS7_FreeCertSet(pkcs7); XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz); @@ -2756,6 +2818,19 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz); idx += esd->encContentDigestSz; + if (pkcs7->encodeStream) { + byte tmp[] = { 0x00, 0x00 }; + + XMEMCPY(output2 + idx, tmp, 2); + idx += 2; + + XMEMCPY(output2 + idx, tmp, 2); + idx += 2; + + XMEMCPY(output2 + idx, tmp, 2); + idx += 2; + } + if (output2Sz) { *output2Sz = idx; idx = 0; /* success */ @@ -8584,13 +8659,29 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) return ret; } - encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, - encContentOctet); + if (pkcs7->encodeStream) { + int err; + byte tmp[] = { 0x30, 0x80}; - encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + + err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, + encryptedOutSz, NULL, (word32*)&encContentOctetSz); + + if (err != LENGTH_ONLY_E) { + + } + encContentOctetSz -= encryptedOutSz; + + XMEMCPY(encContentSeq, tmp, 2); + encContentSeqSz = 2; + } + else { + encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, + encContentOctet); + encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz, encContentSeq); + } /* keep track of sizes for outer wrapper layering */ totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz + @@ -8598,18 +8689,46 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) encContentOctetSz + encryptedOutSz; /* EnvelopedData */ - envDataSeqSz = SetSequence(totalSz, envDataSeq); + if (pkcs7->encodeStream) { + byte tmp[] = { 0x30, 0x80}; + + /* account for ending of encContentSeq */ + totalSz += 2; + + XMEMCPY(envDataSeq, tmp, 2); + envDataSeqSz = 2; + totalSz += 2; /* 30 80 00 00 */ + } + else { + envDataSeqSz = SetSequence(totalSz, envDataSeq); + } totalSz += envDataSeqSz; /* outer content */ - outerContentSz = SetExplicit(0, totalSz, outerContent); + if (pkcs7->encodeStream) { + byte tmp[] = { 0xA0, 0x80}; + XMEMCPY(outerContent, tmp, 2); + outerContentSz = 2; + totalSz += 2; /* A0 80 00 00 */ + } + else { + outerContentSz = SetExplicit(0, totalSz, outerContent); + } totalSz += outerContentTypeSz; totalSz += outerContentSz; if (pkcs7->contentOID != FIRMWARE_PKG_DATA) { /* ContentInfo */ - contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); - totalSz += contentInfoSeqSz; + if (pkcs7->encodeStream) { + byte tmp[] = { 0x30, 0x80}; + XMEMCPY(contentInfoSeq, tmp, 2); + contentInfoSeqSz = 2; + totalSz += contentInfoSeqSz + 2; /* 30 80 00 00 */ + } + else { + contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); + totalSz += contentInfoSeqSz; + } } if (totalSz > (int)outputSz) { @@ -8628,6 +8747,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XMEMCPY(output + idx, outerContent, outerContentSz); idx += outerContentSz; } + XMEMCPY(output + idx, envDataSeq, envDataSeqSz); idx += envDataSeqSz; XMEMCPY(output + idx, ver, verSz); @@ -8642,6 +8762,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) tmpRecip = tmpRecip->next; } wc_PKCS7_FreeEncodedRecipientSet(pkcs7); + XMEMCPY(output + idx, encContentSeq, encContentSeqSz); idx += encContentSeqSz; XMEMCPY(output + idx, contentType, contentTypeSz); @@ -8652,10 +8773,50 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += ivOctetStringSz; XMEMCPY(output + idx, tmpIv, blockSz); idx += blockSz; - XMEMCPY(output + idx, encContentOctet, encContentOctetSz); - idx += encContentOctetSz; - XMEMCPY(output + idx, encryptedContent, encryptedOutSz); - idx += encryptedOutSz; + + /* stream the content (octet string with multiple octet elements) */ + if (pkcs7->encodeStream) { + int err; + byte* tmp; + byte tmpPad[] = { 0x00, 0x00}; + + tmp = XMALLOC(encContentOctetSz + encryptedOutSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + if (tmp == NULL) { + return MEMORY_E; + } + + err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, + encryptedOutSz, tmp, (word32*)&encContentOctetSz); + if (err <= 0) { + return ASN_PARSE_E; + } + XMEMCPY(output + idx, tmp, err); + idx += err; + + /* end of encrypted content info */ + XMEMCPY(output + idx, tmpPad, 2); + idx += 2; + + /* end of Enveloped Data seq */ + XMEMCPY(output + idx, tmpPad, 2); + idx += 2; + + /* end of outer content set */ + XMEMCPY(output + idx, tmpPad, 2); + idx += 2; + + /* end of outer content info seq */ + XMEMCPY(output + idx, tmpPad, 2); + idx += 2; + XFREE(tmp, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + } + else { + XMEMCPY(output + idx, encContentOctet, encContentOctetSz); + idx += encContentOctetSz; + XMEMCPY(output + idx, encryptedContent, encryptedOutSz); + idx += encryptedOutSz; + } XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); @@ -11655,9 +11816,21 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, return BAD_FUNC_ARG; } - encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, - encContentOctet); + if (pkcs7->encodeStream) { + int err; + err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, + encryptedOutSz, NULL, (word32*)&encContentOctetSz); + + if (err != LENGTH_ONLY_E) { + + } + encContentOctetSz -= encryptedOutSz; + } + else { + encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, + encContentOctet); + } encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz + algoParamSeqSz + encContentOctetSz + @@ -11730,10 +11903,27 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, idx += nonceSz; XMEMCPY(output + idx, macInt, macIntSz); idx += macIntSz; - XMEMCPY(output + idx, encContentOctet, encContentOctetSz); - idx += encContentOctetSz; - XMEMCPY(output + idx, encryptedContent, encryptedOutSz); - idx += encryptedOutSz; + + + if (pkcs7->encodeStream) { + int err; + + byte* tmp = malloc(encContentOctetSz + encryptedOutSz); + + err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, + encryptedOutSz, tmp, (word32*)&encContentOctetSz); + if (err <= 0) { + return ASN_PARSE_E; + } + XMEMCPY(output + idx, tmp, encContentOctetSz); + idx += encContentOctetSz; + } + else { + XMEMCPY(output + idx, encContentOctet, encContentOctetSz); + idx += encContentOctetSz; + XMEMCPY(output + idx, encryptedContent, encryptedOutSz); + idx += encryptedOutSz; + } /* authenticated attributes */ if (flatAuthAttribs && authAttribsSz > 0) { @@ -13095,6 +13285,51 @@ int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx) } #endif /* NO_PKCS7_ENCRYPTED_DATA */ + +/* set stream mode for encoding and signing + * returns 0 on success */ +int wc_PKCS7_SetStreamMode(PKCS7* pkcs7, byte flag) +{ + if (pkcs7 == NULL) { + return BAD_FUNC_ARG; + } + pkcs7->encodeStream = flag; + return 0; +} + + +/* returns to current stream mode flag on success, negative values on fail */ +int wc_PKCS7_GetStreamMode(PKCS7* pkcs7) +{ + if (pkcs7 == NULL) { + return BAD_FUNC_ARG; + } + return pkcs7->encodeStream; +} + + +/* set option to not include certificates when creating a bundle + * returns 0 on success */ +int wc_PKCS7_SetNoCerts(PKCS7* pkcs7, byte flag) +{ + if (pkcs7 == NULL) { + return BAD_FUNC_ARG; + } + pkcs7->noCerts = flag; + return 0; +} + + +/* returns the current noCerts flag value on success, negative values on fail */ +int wc_PKCS7_GetNoCerts(PKCS7* pkcs7) +{ + if (pkcs7 == NULL) { + return BAD_FUNC_ARG; + } + return pkcs7->noCerts; +} + + #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA) /* build PKCS#7 compressedData content type, return encrypted size */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index a1a5e0f62..ccc10e66e 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2100,6 +2100,8 @@ WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx); WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz); +WOLFSSL_LOCAL int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, + word32* idx); WOLFSSL_ASN_API void FreeAltNames(DNS_entry* altNames, void* heap); WOLFSSL_ASN_API DNS_entry* AltNameNew(void* heap); @@ -2279,6 +2281,8 @@ WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output); WOLFSSL_LOCAL word32 SetBitString(word32 len, byte unusedBits, byte* output); WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output); +WOLFSSL_LOCAL long SetImplicitBer(byte tag, byte num, const byte* data, word32 dataSz, + byte* out, word32* outSz); WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output); WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output); WOLFSSL_API word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz); diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 1e2733c83..556a54483 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -247,7 +247,10 @@ struct PKCS7 { #ifdef ASN_BER_TO_DER byte* der; /* DER encoded version of message */ word32 derSz; + byte encodeStream; /* use BER when encoding */ #endif + byte noCerts:1; /* if certificates should be added into bundle + during creation */ byte* cert[MAX_PKCS7_CERTS]; /* array of certs parsed from bundle */ byte* verifyCert; /* cert from array used for verify */ word32 verifyCertSz; @@ -495,6 +498,11 @@ WOLFSSL_API int wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7, WOLFSSL_API int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx); #endif /* NO_PKCS7_ENCRYPTED_DATA */ +WOLFSSL_API int wc_PKCS7_SetStreamMode(PKCS7* pkcs7, byte flag); +WOLFSSL_API int wc_PKCS7_GetStreamMode(PKCS7* pkcs7); +WOLFSSL_API int wc_PKCS7_SetNoCerts(PKCS7* pkcs7, byte flag); +WOLFSSL_API int wc_PKCS7_GetNoCerts(PKCS7* pkcs7); + /* CMS/PKCS#7 CompressedData */ #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA) WOLFSSL_API int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, From c843064681046c878d2baa7e8e44118fded39f87 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 30 Jan 2024 15:23:41 -0700 Subject: [PATCH 2/7] update macro guard --- wolfcrypt/src/pkcs7.c | 63 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 31da976be..fb501781c 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2463,6 +2463,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz, esd->contentInfoSeq); } +#ifdef ASN_BER_TO_DER else if (pkcs7->encodeStream) { byte tmp[] = { 0xA0, 0x80 }; byte tmpSeq[] = { 0x30, 0x80 }; @@ -2477,6 +2478,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(esd->innerOctets, tmpStr, 2); esd->innerOctetsSz = 2; } +#endif else { esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + @@ -2622,6 +2624,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->contentInfoSeqSz + pkcs7->contentTypeSz + esd->innerContSeqSz + esd->innerOctetsSz; +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { word32 sz = 0, tmpIdx = 0; totalSz += 6; /* 00's for BER with inner content */ @@ -2629,7 +2632,9 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, StreamOctetString(pkcs7->content, pkcs7->contentSz, NULL, &sz, &tmpIdx); totalSz += sz + 6; } - else { + else +#endif + { totalSz += pkcs7->contentSz; } total2Sz = esd->certsSetSz + certSetSz + signerInfoSz; @@ -2638,6 +2643,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, totalSz -= pkcs7->contentSz; } +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0xA0, 0x80 }; byte tmpSeq[] = { 0x30, 0x80 }; @@ -2654,7 +2660,9 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->outerSeqSz = 2; totalSz += esd->outerSeqSz + 2; } - else { + else +#endif + { esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq); totalSz += esd->innerSeqSz; esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent); @@ -2736,6 +2744,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, } else { if (!pkcs7->detached && pkcs7->content != NULL && pkcs7->contentSz > 0) { + #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { StreamOctetString(pkcs7->content, pkcs7->contentSz, output, outputSz, (word32*)&idx); @@ -2746,7 +2755,9 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, output[idx++] = 0x00; output[idx++] = 0x00; } - else { + else + #endif + { XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); idx += pkcs7->contentSz; } @@ -2818,6 +2829,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz); idx += esd->encContentDigestSz; +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0x00, 0x00 }; @@ -2830,6 +2842,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(output2 + idx, tmp, 2); idx += 2; } +#endif if (output2Sz) { *output2Sz = idx; @@ -8659,6 +8672,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) return ret; } +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { int err; byte tmp[] = { 0x30, 0x80}; @@ -8674,7 +8688,9 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XMEMCPY(encContentSeq, tmp, 2); encContentSeqSz = 2; } - else { + else +#endif + { encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, encContentOctet); encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + @@ -8689,6 +8705,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) encContentOctetSz + encryptedOutSz; /* EnvelopedData */ +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0x30, 0x80}; @@ -8699,19 +8716,24 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) envDataSeqSz = 2; totalSz += 2; /* 30 80 00 00 */ } - else { + else +#endif + { envDataSeqSz = SetSequence(totalSz, envDataSeq); } totalSz += envDataSeqSz; /* outer content */ +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0xA0, 0x80}; XMEMCPY(outerContent, tmp, 2); outerContentSz = 2; totalSz += 2; /* A0 80 00 00 */ } - else { + else +#endif + { outerContentSz = SetExplicit(0, totalSz, outerContent); } totalSz += outerContentTypeSz; @@ -8719,13 +8741,16 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) if (pkcs7->contentOID != FIRMWARE_PKG_DATA) { /* ContentInfo */ + #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0x30, 0x80}; XMEMCPY(contentInfoSeq, tmp, 2); contentInfoSeqSz = 2; totalSz += contentInfoSeqSz + 2; /* 30 80 00 00 */ } - else { + else + #endif + { contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); totalSz += contentInfoSeqSz; } @@ -8775,6 +8800,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += blockSz; /* stream the content (octet string with multiple octet elements) */ +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { int err; byte* tmp; @@ -8811,7 +8837,9 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += 2; XFREE(tmp, pkcs7->heap, DYNAMIC_TYPE_PKCS7); } - else { + else +#endif + { XMEMCPY(output + idx, encContentOctet, encContentOctetSz); idx += encContentOctetSz; XMEMCPY(output + idx, encryptedContent, encryptedOutSz); @@ -11816,6 +11844,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, return BAD_FUNC_ARG; } +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { int err; @@ -11827,7 +11856,9 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, } encContentOctetSz -= encryptedOutSz; } - else { + else +#endif + { encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, encContentOctet); } @@ -11905,6 +11936,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, idx += macIntSz; +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { int err; @@ -11918,7 +11950,9 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, XMEMCPY(output + idx, tmp, encContentOctetSz); idx += encContentOctetSz; } - else { + else +#endif + { XMEMCPY(output + idx, encContentOctet, encContentOctetSz); idx += encContentOctetSz; XMEMCPY(output + idx, encryptedContent, encryptedOutSz); @@ -13293,8 +13327,13 @@ int wc_PKCS7_SetStreamMode(PKCS7* pkcs7, byte flag) if (pkcs7 == NULL) { return BAD_FUNC_ARG; } +#ifdef ASN_BER_TO_DER pkcs7->encodeStream = flag; return 0; +#else + (void)flag; + return NOT_COMPILED_IN; +#endif } @@ -13304,7 +13343,11 @@ int wc_PKCS7_GetStreamMode(PKCS7* pkcs7) if (pkcs7 == NULL) { return BAD_FUNC_ARG; } +#ifdef ASN_BER_TO_DER return pkcs7->encodeStream; +#else + return 0; +#endif } From bf23357c8c18f3ed982240495fc46bc6caf81907 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 1 Feb 2024 09:55:18 -0700 Subject: [PATCH 3/7] refactor streaming and additional comments --- wolfcrypt/src/asn.c | 123 +++++++-------- wolfcrypt/src/pkcs12.c | 2 +- wolfcrypt/src/pkcs7.c | 308 +++++++++++++------------------------- wolfssl/wolfcrypt/asn.h | 13 +- wolfssl/wolfcrypt/pkcs7.h | 2 +- 5 files changed, 182 insertions(+), 266 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index fa1ab6993..b3210fb40 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3463,6 +3463,18 @@ word32 SetBitString(word32 len, byte unusedBits, byte* output) #define BER_OCTET_LENGTH 4096 +/* sets the terminating 0x00 0x00 at the end of an indefinite length + * returns the number of bytes written */ +word32 SetIndefEnd(byte* in) +{ + byte terminate[] = { 0x00, 0x00 }; + + if (in != NULL) { + XMEMCPY(in, terminate, 2); + } + return 2; +} + /* Breaks an octet string up into chunks for use with streaming * returns 0 on success and updates idx */ @@ -3510,50 +3522,6 @@ int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, } } -long SetImplicitBer(byte tag, byte num, const byte* data, word32 dataSz, - byte* out, word32* outSz) -{ - word32 sz = 0; - long outIdx = 0; - byte berTag = tag; - - (void)num; - if (outSz == NULL || data == NULL) { - return BAD_FUNC_ARG; - } - - /* create a list of chuncked up octets */ - if (tag == ASN_OCTET_STRING) { - berTag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC; - } - - if (out != NULL) { - if (*outSz < 2) { - return BUFFER_E; - } - out[outIdx] = berTag; - out[outIdx + 1] = ASN_INDEF_LENGTH; - } - outIdx += 2; - - sz = *outSz; - StreamOctetString(data, dataSz, out, &sz, (word32*)&outIdx); - - if (out) { - out[outIdx] = 0x00; - out[outIdx + 1] = 0x00; - } - outIdx += 2; - - if (out) { - return outIdx; - } - else { - *outSz = outIdx; - return LENGTH_ONLY_E; - } -} - /* Convert BER to DER */ @@ -15429,6 +15397,16 @@ word32 SetLength(word32 length, byte* output) return i; } +word32 SetLengthEx(word32 length, byte* output, byte isIndef) +{ + if (isIndef) { + output[0] = ASN_INDEF_LENGTH; + return 1; + } + else { + return SetLength(length, output); + } +} /* Encode a DER header - type/tag and length. * * @param [in] tag DER tag of ASN.1 item. @@ -15436,14 +15414,15 @@ word32 SetLength(word32 length, byte* output) * @param [out] output Buffer to encode into. * @return Number of bytes encoded. */ -static word32 SetHeader(byte tag, word32 len, byte* output) +static word32 SetHeader(byte tag, word32 len, byte* output, byte isIndef) { if (output) { /* Encode tag first. */ output[0] = tag; } /* Encode the length. */ - return SetLength(len, output ? output + ASN_TAG_SZ : NULL) + ASN_TAG_SZ; + return SetLengthEx(len, output ? output + ASN_TAG_SZ : NULL, isIndef) + + ASN_TAG_SZ; } /* Encode a SEQUENCE header in DER. @@ -15454,7 +15433,12 @@ static word32 SetHeader(byte tag, word32 len, byte* output) */ word32 SetSequence(word32 len, byte* output) { - return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output); + return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output, 0); +} + +word32 SetSequenceEx(word32 len, byte* output, byte isIndef) +{ + return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output, isIndef); } /* Encode an OCTET STRING header in DER. @@ -15465,7 +15449,14 @@ word32 SetSequence(word32 len, byte* output) */ word32 SetOctetString(word32 len, byte* output) { - return SetHeader(ASN_OCTET_STRING, len, output); + return SetHeader(ASN_OCTET_STRING, len, output, 0); +} + +word32 SetOctetStringEx(word32 len, byte* output, byte indef) +{ + if (indef) + return SetHeader(ASN_OCTET_STRING | ASN_CONSTRUCTED, len, output, indef); + return SetOctetString(len, output); } /* Encode a SET header in DER. @@ -15476,7 +15467,7 @@ word32 SetOctetString(word32 len, byte* output) */ word32 SetSet(word32 len, byte* output) { - return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output); + return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output, 0); } /* Encode an implicit context specific header in DER. @@ -15489,11 +15480,23 @@ word32 SetSet(word32 len, byte* output) * @param [out] output Buffer to encode into. * @return Number of bytes encoded. */ -word32 SetImplicit(byte tag, byte number, word32 len, byte* output) +word32 SetImplicit(byte tag, byte number, word32 len, byte* output, byte isIndef) { - tag = (byte)(((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0) - | ASN_CONTEXT_SPECIFIC | number); - return SetHeader(tag, len, output); + int useIndef = 0; + + if ((tag == ASN_OCTET_STRING) && isIndef) { + tag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number; + } + else { + tag = (byte)(((tag == ASN_SEQUENCE || tag == ASN_SET) ? + ASN_CONSTRUCTED : 0) | ASN_CONTEXT_SPECIFIC | number); + } + + if (isIndef && (tag & ASN_CONSTRUCTED)) { + useIndef = 1; + } + + return SetHeader(tag, len, output, useIndef); } /* Encode an explicit context specific header in DER. @@ -15505,10 +15508,10 @@ word32 SetImplicit(byte tag, byte number, word32 len, byte* output) * @param [out] output Buffer to encode into. * @return Number of bytes encoded. */ -word32 SetExplicit(byte number, word32 len, byte* output) +word32 SetExplicit(byte number, word32 len, byte* output, byte isIndef) { return SetHeader((byte)(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | number), - len, output); + len, output, isIndef); } #if defined(OPENSSL_EXTRA) @@ -15534,8 +15537,8 @@ word32 SetOthername(void *name, byte *output) nameSz = (word32)nm->value->value.utf8string->length; len = nm->type_id->objSz + - SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL) + - SetHeader(CTC_UTF8, nameSz, NULL) + nameSz; + SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL, 0) + + SetHeader(CTC_UTF8, nameSz, NULL, 0) + nameSz; if (output != NULL) { /* otherName OID */ @@ -15543,9 +15546,9 @@ word32 SetOthername(void *name, byte *output) output += nm->type_id->objSz; output += SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, - output); + output, 0); - output += SetHeader(CTC_UTF8, nameSz, output); + output += SetHeader(CTC_UTF8, nameSz, output, 0); XMEMCPY(output, nameStr, nameSz); } @@ -34549,7 +34552,7 @@ int SetAsymKeyDer(const byte* privKey, word32 privKeyLen, /* pubKey */ if (pubKey) { idx += SetHeader(ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY | - 1, pubKeyLen, output + idx); + 1, pubKeyLen, output + idx, 0); XMEMCPY(output + idx, pubKey, pubKeyLen); idx += pubKeyLen; } diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 22e641508..123b2e9db 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -1836,7 +1836,7 @@ static int wc_PKCS12_shroud_key(WC_PKCS12* pkcs12, WC_RNG* rng, /* rewind index and set tag and length */ tmpIdx -= MAX_LENGTH_SZ + 1; - sz = (word32)SetExplicit(0, (word32)ret, out + tmpIdx); + sz = (word32)SetExplicit(0, (word32)ret, out + tmpIdx, 0); tmpIdx += sz; totalSz += sz; XMEMMOVE(out + tmpIdx, out + MAX_LENGTH_SZ + 1, (size_t)ret); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index fb501781c..4998205e5 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2463,29 +2463,16 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz, esd->contentInfoSeq); } -#ifdef ASN_BER_TO_DER - else if (pkcs7->encodeStream) { - byte tmp[] = { 0xA0, 0x80 }; - byte tmpSeq[] = { 0x30, 0x80 }; - byte tmpStr[] = { 0x24, 0x80 }; - - XMEMCPY(esd->innerContSeq, tmp, 2); - esd->innerContSeqSz = 2; - - XMEMCPY(esd->contentInfoSeq, tmpSeq, 2); - esd->contentInfoSeqSz = 2; - - XMEMCPY(esd->innerOctets, tmpStr, 2); - esd->innerOctetsSz = 2; - } -#endif else { - esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); + esd->innerOctetsSz = SetOctetStringEx(pkcs7->contentSz, esd->innerOctets, + pkcs7->encodeStream); esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + - pkcs7->contentSz, esd->innerContSeq); - esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz + + pkcs7->contentSz, esd->innerContSeq, + pkcs7->encodeStream); + esd->contentInfoSeqSz = SetSequenceEx(pkcs7->contentSz + esd->innerOctetsSz + pkcs7->contentTypeSz + - esd->innerContSeqSz, esd->contentInfoSeq); + esd->innerContSeqSz, esd->contentInfoSeq, + pkcs7->encodeStream); } /* SignerIdentifier */ @@ -2512,7 +2499,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, /* SubjectKeyIdentifier */ esd->issuerSKIDSz = SetOctetString(keyIdSize, esd->issuerSKID); esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + keyIdSize, - esd->issuerSKIDSeq); + esd->issuerSKIDSeq, 0); signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz + keyIdSize); /* version MUST be 3 */ @@ -2567,7 +2554,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, FlattenAttributes(pkcs7, flatSignedAttribs, esd->signedAttribs, esd->signedAttribsCount); esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz, - esd->signedAttribSet); + esd->signedAttribSet, 0); } else { esd->signedAttribSetSz = 0; } @@ -2604,7 +2591,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, certPtr = NULL; if (certSetSz > 0) - esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet); + esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet, 0); if (pkcs7->sidType != DEGENERATE_SID) { esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId, @@ -2627,10 +2614,10 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { word32 sz = 0, tmpIdx = 0; - totalSz += 6; /* 00's for BER with inner content */ + totalSz += (3 * ASN_INDEF_END_SZ) ; /* 00's for BER with inner content */ StreamOctetString(pkcs7->content, pkcs7->contentSz, NULL, &sz, &tmpIdx); - totalSz += sz + 6; + totalSz += sz + (3 * ASN_INDEF_END_SZ); } else #endif @@ -2643,32 +2630,27 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, totalSz -= pkcs7->contentSz; } -#ifdef ASN_BER_TO_DER - if (pkcs7->encodeStream) { - byte tmp[] = { 0xA0, 0x80 }; - byte tmpSeq[] = { 0x30, 0x80 }; - - XMEMCPY(esd->innerSeq, tmpSeq, 2); - esd->innerSeqSz = 2; - totalSz += esd->innerSeqSz + 2; - - XMEMCPY(esd->outerContent, tmp, 2); - esd->outerContentSz = 2; - totalSz += esd->outerContentSz + 2 + signedDataOidSz; - - XMEMCPY(esd->outerSeq, tmpSeq, 2); - esd->outerSeqSz = 2; - totalSz += esd->outerSeqSz + 2; - } - else -#endif { - esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq); + esd->innerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->innerSeq, + pkcs7->encodeStream); totalSz += esd->innerSeqSz; - esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent); + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } + + esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, + esd->outerContent, pkcs7->encodeStream); totalSz += esd->outerContentSz + signedDataOidSz; - esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq); + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } + + esd->outerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->outerSeq, + pkcs7->encodeStream); totalSz += esd->outerSeqSz; + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } } /* if using header/footer, we are not returning the content */ @@ -2748,12 +2730,15 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, if (pkcs7->encodeStream) { StreamOctetString(pkcs7->content, pkcs7->contentSz, output, outputSz, (word32*)&idx); - output[idx++] = 0x00; - output[idx++] = 0x00; - output[idx++] = 0x00; - output[idx++] = 0x00; - output[idx++] = 0x00; - output[idx++] = 0x00; + + /* end of content octet string */ + idx += SetIndefEnd(output + idx); + + /* end of inner content seq */ + idx += SetIndefEnd(output + idx); + + /* end of inner content info seq */ + idx += SetIndefEnd(output + idx); } else #endif @@ -2831,16 +2816,14 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { - byte tmp[] = { 0x00, 0x00 }; + /* end of signedData seq */ + idx += SetIndefEnd(output2 + idx); - XMEMCPY(output2 + idx, tmp, 2); - idx += 2; + /* end of outer content set */ + idx += SetIndefEnd(output2 + idx); - XMEMCPY(output2 + idx, tmp, 2); - idx += 2; - - XMEMCPY(output2 + idx, tmp, 2); - idx += 2; + /* end of outer content info seq */ + idx += SetIndefEnd(output2 + idx); } #endif @@ -6097,7 +6080,7 @@ static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID) /* suppPubInfo */ suppPubInfoSeqSz = SetImplicit(ASN_SEQUENCE, 2, kekOctetSz + sizeof(word32), - suppPubInfoSeq); + suppPubInfoSeq, 0); sharedInfoSz += suppPubInfoSeqSz; /* optional ukm/entityInfo */ @@ -6107,7 +6090,7 @@ static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID) entityUInfoExplicitSz = SetExplicit(0, entityUInfoOctetSz + kari->ukmSz, - entityUInfoExplicitSeq); + entityUInfoExplicitSeq, 0); sharedInfoSz += entityUInfoExplicitSz; } @@ -6483,7 +6466,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, /* RecipientKeyIdentifier IMPLICIT [0] */ recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz + - keyIdSize, recipKeyIdSeq); + keyIdSize, recipKeyIdSeq, 0); totalSz += recipKeyIdSeqSz; /* RecipientEncryptedKey */ @@ -6501,7 +6484,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, totalSz += (ukmOctetSz + kari->ukmSz); ukmExplicitSz = SetExplicit(1, ukmOctetSz + kari->ukmSz, - ukmExplicitSeq); + ukmExplicitSeq, 0); totalSz += ukmExplicitSz; } @@ -6535,14 +6518,14 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, /* outer OriginatorPublicKey IMPLICIT [1] */ origPubKeySeqSz = SetImplicit(ASN_SEQUENCE, 1, origAlgIdSz + origPubKeyStrSz + - kari->senderKeyExportSz, origPubKeySeq); + kari->senderKeyExportSz, origPubKeySeq, 0); totalSz += origPubKeySeqSz; /* outer OriginatorIdentifierOrKey IMPLICIT [0] */ origIdOrKeySeqSz = SetImplicit(ASN_SEQUENCE, 0, origPubKeySeqSz + origAlgIdSz + origPubKeyStrSz + kari->senderKeyExportSz, - origIdOrKeySeq); + origIdOrKeySeq, 0); totalSz += origIdOrKeySeqSz; /* version, always 3 */ @@ -6551,7 +6534,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, recip->recipVersion = 3; /* outer IMPLICIT [1] kari */ - kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq); + kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq, 0); totalSz += kariSeqSz; if (totalSz > MAX_RECIP_SZ) { @@ -7666,7 +7649,7 @@ int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb, oriTypeLenSz = SetLength(oriTypeSz, oriTypeLen); recipSeqSz = SetImplicit(ASN_SEQUENCE, 4, 1 + oriTypeLenSz + oriTypeSz + - oriValueSz, recipSeq); + oriValueSz, recipSeq, 0); idx = 0; XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz); @@ -8116,7 +8099,7 @@ int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen, /* set KeyDerivationAlgorithmIdentifier EXPLICIT [0] SEQ */ kdfAlgoIdSeqSz = SetExplicit(0, kdfAlgoIdSz + kdfParamsSeqSz + kdfSaltOctetStrSz + saltSz + kdfIterationsSz, - kdfAlgoIdSeq); + kdfAlgoIdSeq, 0); totalSz += kdfAlgoIdSeqSz; /* set PasswordRecipientInfo CMSVersion, MUST be 0 */ @@ -8125,7 +8108,7 @@ int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen, recip->recipVersion = 0; /* set PasswordRecipientInfo SEQ */ - recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq); + recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq, 0); totalSz += recipSeqSz; if (totalSz > MAX_RECIP_SZ) { @@ -8368,7 +8351,7 @@ int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek, recip->recipVersion = 4; /* KEKRecipientInfo SEQ */ - recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq); + recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq, 0); totalSz += recipSeqSz; if (totalSz > MAX_RECIP_SZ) { @@ -8672,32 +8655,12 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) return ret; } -#ifdef ASN_BER_TO_DER - if (pkcs7->encodeStream) { - int err; - byte tmp[] = { 0x30, 0x80}; - - err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, - encryptedOutSz, NULL, (word32*)&encContentOctetSz); - - if (err != LENGTH_ONLY_E) { - - } - encContentOctetSz -= encryptedOutSz; - - XMEMCPY(encContentSeq, tmp, 2); - encContentSeqSz = 2; - } - else -#endif - { - encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, - encContentOctet); - encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + - ivOctetStringSz + blockSz + - encContentOctetSz + encryptedOutSz, - encContentSeq); - } + encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, + encContentOctet, pkcs7->encodeStream); + encContentSeqSz = SetSequenceEx(contentTypeSz + contentEncAlgoSz + + ivOctetStringSz + blockSz + + encContentOctetSz + encryptedOutSz, + encContentSeq, pkcs7->encodeStream); /* keep track of sizes for outer wrapper layering */ totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz + @@ -8707,53 +8670,47 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) /* EnvelopedData */ #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { - byte tmp[] = { 0x30, 0x80}; + word32 streamSz = 0, tmpIdx = 0; + + /* account for ending of encContentOctet */ + totalSz += ASN_INDEF_END_SZ; /* account for ending of encContentSeq */ - totalSz += 2; + totalSz += ASN_INDEF_END_SZ; - XMEMCPY(envDataSeq, tmp, 2); - envDataSeqSz = 2; - totalSz += 2; /* 30 80 00 00 */ + /* account for asn1 syntax around octet strings */ + StreamOctetString(NULL, encryptedOutSz, NULL, &streamSz, &tmpIdx); + totalSz += (streamSz - encryptedOutSz); } - else #endif - { - envDataSeqSz = SetSequence(totalSz, envDataSeq); - } + envDataSeqSz = SetSequenceEx(totalSz, envDataSeq, pkcs7->encodeStream); totalSz += envDataSeqSz; - - /* outer content */ #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { - byte tmp[] = { 0xA0, 0x80}; - XMEMCPY(outerContent, tmp, 2); - outerContentSz = 2; - totalSz += 2; /* A0 80 00 00 */ + totalSz += ASN_INDEF_END_SZ; } - else #endif - { - outerContentSz = SetExplicit(0, totalSz, outerContent); + + /* outer content */ + outerContentSz = SetExplicit(0, totalSz, outerContent, pkcs7->encodeStream); +#ifdef ASN_BER_TO_DER + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; } +#endif totalSz += outerContentTypeSz; totalSz += outerContentSz; if (pkcs7->contentOID != FIRMWARE_PKG_DATA) { /* ContentInfo */ + contentInfoSeqSz = SetSequenceEx(totalSz, contentInfoSeq, + pkcs7->encodeStream); + totalSz += contentInfoSeqSz; #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { - byte tmp[] = { 0x30, 0x80}; - XMEMCPY(contentInfoSeq, tmp, 2); - contentInfoSeqSz = 2; - totalSz += contentInfoSeqSz + 2; /* 30 80 00 00 */ + totalSz += ASN_INDEF_END_SZ; } - else #endif - { - contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); - totalSz += contentInfoSeqSz; - } } if (totalSz > (int)outputSz) { @@ -8798,50 +8755,35 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += ivOctetStringSz; XMEMCPY(output + idx, tmpIv, blockSz); idx += blockSz; + XMEMCPY(output + idx, encContentOctet, encContentOctetSz); + idx += encContentOctetSz; - /* stream the content (octet string with multiple octet elements) */ #ifdef ASN_BER_TO_DER + /* stream the content (octet string with multiple octet elements) */ if (pkcs7->encodeStream) { - int err; - byte* tmp; - byte tmpPad[] = { 0x00, 0x00}; - - tmp = XMALLOC(encContentOctetSz + encryptedOutSz, pkcs7->heap, - DYNAMIC_TYPE_PKCS7); - if (tmp == NULL) { - return MEMORY_E; + if (StreamOctetString(encryptedContent, encryptedOutSz, output, + &outputSz, (word32*)&idx) != 0) { + return BUFFER_E; } - err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, - encryptedOutSz, tmp, (word32*)&encContentOctetSz); - if (err <= 0) { - return ASN_PARSE_E; - } - XMEMCPY(output + idx, tmp, err); - idx += err; + /* end of encrypted content */ + idx += SetIndefEnd(output + idx); /* end of encrypted content info */ - XMEMCPY(output + idx, tmpPad, 2); - idx += 2; + idx += SetIndefEnd(output + idx); /* end of Enveloped Data seq */ - XMEMCPY(output + idx, tmpPad, 2); - idx += 2; + idx += SetIndefEnd(output + idx); /* end of outer content set */ - XMEMCPY(output + idx, tmpPad, 2); - idx += 2; + idx += SetIndefEnd(output + idx); /* end of outer content info seq */ - XMEMCPY(output + idx, tmpPad, 2); - idx += 2; - XFREE(tmp, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + idx += SetIndefEnd(output + idx); } else #endif { - XMEMCPY(output + idx, encContentOctet, encContentOctetSz); - idx += encContentOctetSz; XMEMCPY(output + idx, encryptedContent, encryptedOutSz); idx += encryptedOutSz; } @@ -11687,7 +11629,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, } authAttribsSetSz = SetImplicit(ASN_SET, 1, authAttribsSz, - authAttribSet); + authAttribSet, 0); /* From RFC5083, "For the purpose of constructing the AAD, the * IMPLICIT [1] tag in the authAttrs field is not used for the @@ -11733,7 +11675,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs, unauthAttribsCount); unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz, - unauthAttribSet); + unauthAttribSet, 0); } /* AES-GCM/CCM does NOT require padding for plaintext content or @@ -11844,24 +11786,8 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, return BAD_FUNC_ARG; } -#ifdef ASN_BER_TO_DER - if (pkcs7->encodeStream) { - int err; - - err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, - encryptedOutSz, NULL, (word32*)&encContentOctetSz); - - if (err != LENGTH_ONLY_E) { - - } - encContentOctetSz -= encryptedOutSz; - } - else -#endif - { - encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, - encContentOctet); - } + encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, + encContentOctet, 0); encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz + algoParamSeqSz + encContentOctetSz + @@ -11881,7 +11807,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, totalSz += envDataSeqSz; /* outer content */ - outerContentSz = SetExplicit(0, totalSz, outerContent); + outerContentSz = SetExplicit(0, totalSz, outerContent, 0); totalSz += outerContentTypeSz; totalSz += outerContentSz; @@ -11936,28 +11862,10 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, idx += macIntSz; -#ifdef ASN_BER_TO_DER - if (pkcs7->encodeStream) { - int err; - - byte* tmp = malloc(encContentOctetSz + encryptedOutSz); - - err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, - encryptedOutSz, tmp, (word32*)&encContentOctetSz); - if (err <= 0) { - return ASN_PARSE_E; - } - XMEMCPY(output + idx, tmp, encContentOctetSz); - idx += encContentOctetSz; - } - else -#endif - { - XMEMCPY(output + idx, encContentOctet, encContentOctetSz); - idx += encContentOctetSz; - XMEMCPY(output + idx, encryptedContent, encryptedOutSz); - idx += encryptedOutSz; - } + XMEMCPY(output + idx, encContentOctet, encContentOctetSz); + idx += encContentOctetSz; + XMEMCPY(output + idx, encryptedContent, encryptedOutSz); + idx += encryptedOutSz; /* authenticated attributes */ if (flatAuthAttribs && authAttribsSz > 0) { @@ -12764,7 +12672,7 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) } encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, - encryptedOutSz, encContentOctet); + encryptedOutSz, encContentOctet, 0); encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + ivOctetStringSz + blockSz + @@ -12810,7 +12718,7 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); return ret; } - attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet); + attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet, 0); } else { attribsSz = 0; @@ -12828,7 +12736,7 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) if (pkcs7->version != 3) { /* outer content */ - outerContentSz = SetExplicit(0, totalSz, outerContent); + outerContentSz = SetExplicit(0, totalSz, outerContent, 0); totalSz += outerContentTypeSz; totalSz += outerContentSz; /* ContentInfo */ @@ -13427,7 +13335,7 @@ int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz) totalSz = contentOctetStrSz + compressedSz; /* EXPLICIT [0] eContentType */ - contentSeqSz = SetExplicit(0, totalSz, contentSeq); + contentSeqSz = SetExplicit(0, totalSz, contentSeq, 0); totalSz += contentSeqSz; /* eContentType OBJECT IDENTIFIER */ @@ -13487,7 +13395,7 @@ int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz) */ /* ContentInfo content EXPLICIT SEQUENCE */ - contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq); + contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq, 0); totalSz += contentInfoContentSeqSz; ret = wc_SetContentType(COMPRESSED_DATA, contentInfoTypeOid, diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index ccc10e66e..78a057131 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1023,6 +1023,7 @@ enum Misc_ASN { #endif TRAILING_ZERO = 1, /* Used for size of zero pad */ ASN_TAG_SZ = 1, /* single byte ASN.1 tag */ + ASN_INDEF_END_SZ = 2, /* 0x00 0x00 at end of indef */ MIN_VERSION_SZ = 3, /* Min bytes needed for GetMyVersion */ MAX_X509_VERSION = 3, /* Max X509 version allowed */ MIN_X509_VERSION = 0, /* Min X509 version allowed */ @@ -2276,14 +2277,18 @@ WOLFSSL_LOCAL word32 SetASNExplicit(byte number, word32 len, byte* output); WOLFSSL_LOCAL word32 SetASNSet(word32 len, byte* output); WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output); +WOLFSSL_LOCAL word32 SetLengthEx(word32 length, byte* output, byte isIndef); WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output); +WOLFSSL_LOCAL word32 SetSequenceEx(word32 len, byte* output, byte isIndef); +WOLFSSL_LOCAL word32 SetIndefEnd(byte* in); WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); +WOLFSSL_LOCAL word32 SetOctetStringEx(word32 len, byte* output, byte indef); WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output); WOLFSSL_LOCAL word32 SetBitString(word32 len, byte unusedBits, byte* output); -WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output); -WOLFSSL_LOCAL long SetImplicitBer(byte tag, byte num, const byte* data, word32 dataSz, - byte* out, word32* outSz); -WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output); +WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output, + byte isIndef); +WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output, + byte isIndef); WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output); WOLFSSL_API word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz); WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header); diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 556a54483..f397a8f26 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -247,8 +247,8 @@ struct PKCS7 { #ifdef ASN_BER_TO_DER byte* der; /* DER encoded version of message */ word32 derSz; - byte encodeStream; /* use BER when encoding */ #endif + byte encodeStream:1; /* use BER when encoding */ byte noCerts:1; /* if certificates should be added into bundle during creation */ byte* cert[MAX_PKCS7_CERTS]; /* array of certs parsed from bundle */ From 8d0dc7a56876a19dc61de8bf76606ac5ec291679 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 1 Feb 2024 10:57:20 -0700 Subject: [PATCH 4/7] fix asn original build, vs warning, and add test cases --- tests/api.c | 100 +++++++++++++++++++++++++++++++++++++----- wolfcrypt/src/asn.c | 4 +- wolfcrypt/src/pkcs7.c | 36 +++++++-------- 3 files changed, 109 insertions(+), 31 deletions(-) diff --git a/tests/api.c b/tests/api.c index d9c75f675..b372b402e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -26916,13 +26916,56 @@ static int test_wc_PKCS7_EncodeSignedData(void) } ExpectIntGT(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), 0); - wc_PKCS7_Free(pkcs7); pkcs7 = NULL; + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0); ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0); +#ifdef ASN_BER_TO_DER + wc_PKCS7_Free(pkcs7); + + /* reinitialize and test setting stream mode */ + { + int signedSz; + + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0); + + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0); + + if (pkcs7 != NULL) { + pkcs7->content = data; + pkcs7->contentSz = (word32)sizeof(data); + pkcs7->privateKey = key; + pkcs7->privateKeySz = (word32)sizeof(key); + pkcs7->encryptOID = RSAk; + #ifdef NO_SHA + pkcs7->hashOID = SHA256h; + #else + pkcs7->hashOID = SHAh; + #endif + pkcs7->rng = &rng; + } + ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 0); + ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1), 0); + ExpectIntEQ(wc_PKCS7_SetStreamMode(NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 1); + + ExpectIntGT(signedSz = wc_PKCS7_EncodeSignedData(pkcs7, output, + outputSz), 0); + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0); + + /* use exact signed buffer size since BER encoded */ + ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, signedSz), 0); + } +#endif + /* Pass in bad args. */ ExpectIntEQ(wc_PKCS7_EncodeSignedData(NULL, output, outputSz), BAD_FUNC_ARG); @@ -27953,6 +27996,9 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) EXPECT_DECLS; #if defined(HAVE_PKCS7) PKCS7* pkcs7 = NULL; +#ifdef ASN_BER_TO_DER + int encodedSz; +#endif #ifdef ECC_TIMING_RESISTANT WC_RNG rng; #endif @@ -28153,6 +28199,39 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) testSz = (int)sizeof(testVectors)/(int)sizeof(pkcs7EnvelopedVector); for (i = 0; i < testSz; i++) { + #ifdef ASN_BER_TO_DER + /* test setting stream mode */ + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (testVectors + i)->cert, + (word32)(testVectors + i)->certSz), 0); + if (pkcs7 != NULL) { + #ifdef ECC_TIMING_RESISTANT + pkcs7->rng = &rng; + #endif + + pkcs7->content = (byte*)(testVectors + i)->content; + pkcs7->contentSz = (testVectors + i)->contentSz; + pkcs7->contentOID = (testVectors + i)->contentOID; + pkcs7->encryptOID = (testVectors + i)->encryptOID; + pkcs7->keyWrapOID = (testVectors + i)->keyWrapOID; + pkcs7->keyAgreeOID = (testVectors + i)->keyAgreeOID; + pkcs7->privateKey = (testVectors + i)->privateKey; + pkcs7->privateKeySz = (testVectors + i)->privateKeySz; + } + ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1), 0); + + ExpectIntGE(encodedSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, output, + (word32)sizeof(output)), 0); + + decodedSz = wc_PKCS7_DecodeEnvelopedData(pkcs7, output, + (word32)encodedSz, decoded, (word32)sizeof(decoded)); + ExpectIntGE(decodedSz, 0); + /* Verify the size of each buffer. */ + ExpectIntEQ((word32)sizeof(input)/sizeof(char), decodedSz); + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + #endif + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (testVectors + i)->cert, (word32)(testVectors + i)->certSz), 0); if (pkcs7 != NULL) { @@ -28170,6 +28249,11 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) pkcs7->privateKeySz = (testVectors + i)->privateKeySz; } + #ifdef ASN_BER_TO_DER + /* test without setting stream mode */ + ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 0); + #endif + ExpectIntGE(wc_PKCS7_EncodeEnvelopedData(pkcs7, output, (word32)sizeof(output)), 0); @@ -28178,6 +28262,7 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) ExpectIntGE(decodedSz, 0); /* Verify the size of each buffer. */ ExpectIntEQ((word32)sizeof(input)/sizeof(char), decodedSz); + /* Don't free the last time through the loop. */ if (i < testSz - 1) { wc_PKCS7_Free(pkcs7); @@ -28871,7 +28956,6 @@ static int test_wc_PKCS7_signed_enveloped(void) #ifdef HAVE_AES_CBC PKCS7* inner = NULL; #endif - void* pt = NULL; WC_RNG rng; unsigned char key[FOURK_BUF/2]; unsigned char cert[FOURK_BUF/2]; @@ -28958,17 +29042,13 @@ static int test_wc_PKCS7_signed_enveloped(void) pkcs7->rng = &rng; } - /* Set no certs in bundle for this test. Hang on to the pointer though to - * free it later. */ + /* Set no certs in bundle for this test. */ if (pkcs7 != NULL) { - pt = (void*)pkcs7->certList; - pkcs7->certList = NULL; /* no certs in bundle */ + ExpectIntEQ(wc_PKCS7_SetNoCerts(pkcs7, 1), 0); + ExpectIntEQ(wc_PKCS7_SetNoCerts(NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_PKCS7_GetNoCerts(pkcs7), 1); } ExpectIntGT((sigSz = wc_PKCS7_EncodeSignedData(pkcs7, sig, sigSz)), 0); - if (pkcs7 != NULL) { - /* restore pointer for PKCS7 free call */ - pkcs7->certList = (Pkcs7Cert*)pt; - } wc_PKCS7_Free(pkcs7); pkcs7 = NULL; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index b3210fb40..c4e88b388 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15482,7 +15482,7 @@ word32 SetSet(word32 len, byte* output) */ word32 SetImplicit(byte tag, byte number, word32 len, byte* output, byte isIndef) { - int useIndef = 0; + byte useIndef = 0; if ((tag == ASN_OCTET_STRING) && isIndef) { tag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number; @@ -36453,7 +36453,7 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size) */ extSz = EncodeOcspRequestExtensions(req, extArray + 2, OCSP_NONCE_EXT_SZ); - extSz += SetExplicit(2, extSz, extArray); + extSz += SetExplicit(2, extSz, extArray, 0); } totalSz = algoSz + issuerSz + issuerKeySz + snSz; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 4998205e5..4f7bbc4b1 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2630,27 +2630,25 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, totalSz -= pkcs7->contentSz; } - { - esd->innerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->innerSeq, - pkcs7->encodeStream); - totalSz += esd->innerSeqSz; - if (pkcs7->encodeStream) { - totalSz += ASN_INDEF_END_SZ; - } + esd->innerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->innerSeq, + pkcs7->encodeStream); + totalSz += esd->innerSeqSz; + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } - esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, - esd->outerContent, pkcs7->encodeStream); - totalSz += esd->outerContentSz + signedDataOidSz; - if (pkcs7->encodeStream) { - totalSz += ASN_INDEF_END_SZ; - } + esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, + esd->outerContent, pkcs7->encodeStream); + totalSz += esd->outerContentSz + signedDataOidSz; + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } - esd->outerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->outerSeq, - pkcs7->encodeStream); - totalSz += esd->outerSeqSz; - if (pkcs7->encodeStream) { - totalSz += ASN_INDEF_END_SZ; - } + esd->outerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->outerSeq, + pkcs7->encodeStream); + totalSz += esd->outerSeqSz; + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; } /* if using header/footer, we are not returning the content */ From 5fbadbb215cf8f362a031de7d9fed9d6391f3881 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 1 Feb 2024 11:00:42 -0700 Subject: [PATCH 5/7] fix warning with test case --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index b372b402e..585c18374 100644 --- a/tests/api.c +++ b/tests/api.c @@ -27997,7 +27997,7 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) #if defined(HAVE_PKCS7) PKCS7* pkcs7 = NULL; #ifdef ASN_BER_TO_DER - int encodedSz; + int encodedSz = 0; #endif #ifdef ECC_TIMING_RESISTANT WC_RNG rng; From ed4b87eb37e5b6db821d55e64c1ab785d5eab82d Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 1 Feb 2024 14:26:13 -0700 Subject: [PATCH 6/7] fix for clang-tidy null dereference error --- wolfcrypt/src/asn.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c4e88b388..f29c990e6 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15400,7 +15400,9 @@ word32 SetLength(word32 length, byte* output) word32 SetLengthEx(word32 length, byte* output, byte isIndef) { if (isIndef) { - output[0] = ASN_INDEF_LENGTH; + if (output != NULL) { + output[0] = ASN_INDEF_LENGTH; + } return 1; } else { From 7592559fd31735189808d5f19cc4ac19050db001 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Fri, 2 Feb 2024 14:50:50 -0700 Subject: [PATCH 7/7] rename argument, fix warnings on casts --- wolfcrypt/src/asn.c | 25 +++++++++++++------------ wolfssl/wolfcrypt/asn.h | 6 +++--- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index f29c990e6..b38ee124d 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3465,20 +3465,21 @@ word32 SetBitString(word32 len, byte unusedBits, byte* output) /* sets the terminating 0x00 0x00 at the end of an indefinite length * returns the number of bytes written */ -word32 SetIndefEnd(byte* in) +word32 SetIndefEnd(byte* output) { - byte terminate[] = { 0x00, 0x00 }; + byte terminate[ASN_INDEF_END_SZ] = { 0x00, 0x00 }; - if (in != NULL) { - XMEMCPY(in, terminate, 2); + if (output != NULL) { + XMEMCPY(output, terminate, ASN_INDEF_END_SZ); } - return 2; + + return (word32)ASN_INDEF_END_SZ; } /* Breaks an octet string up into chunks for use with streaming * returns 0 on success and updates idx */ -int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, +int StreamOctetString(const byte* inBuf, word32 inBufSz, byte* out, word32* outSz, word32* idx) { word32 i = 0; @@ -3487,13 +3488,13 @@ int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, if (tmp) tmp += outIdx; - while (i < inSz) { - int ret, sz; + while (i < inBufSz) { + word32 ret, sz; sz = BER_OCTET_LENGTH; - if ((sz + i) > inSz) { - sz = inSz - i; + if ((sz + i) > inBufSz) { + sz = inBufSz - i; } ret = SetOctetString(sz, tmp); @@ -3502,10 +3503,10 @@ int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, } if (tmp) { - if (ret + sz + i + outIdx > *outSz) { + if ((word32)ret + sz + i + outIdx > *outSz) { return BUFFER_E; } - XMEMCPY(tmp + ret, in + i, sz); + XMEMCPY(tmp + ret, inBuf + i, sz); tmp += sz + ret; } outIdx += sz; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 78a057131..395981407 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2101,8 +2101,8 @@ WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx); WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz); -WOLFSSL_LOCAL int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, - word32* idx); +WOLFSSL_LOCAL int StreamOctetString(const byte* inBuf, word32 inBufSz, + byte* out, word32* outSz, word32* idx); WOLFSSL_ASN_API void FreeAltNames(DNS_entry* altNames, void* heap); WOLFSSL_ASN_API DNS_entry* AltNameNew(void* heap); @@ -2280,7 +2280,7 @@ WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output); WOLFSSL_LOCAL word32 SetLengthEx(word32 length, byte* output, byte isIndef); WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output); WOLFSSL_LOCAL word32 SetSequenceEx(word32 len, byte* output, byte isIndef); -WOLFSSL_LOCAL word32 SetIndefEnd(byte* in); +WOLFSSL_LOCAL word32 SetIndefEnd(byte* output); WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); WOLFSSL_LOCAL word32 SetOctetStringEx(word32 len, byte* output, byte indef); WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output);