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 */