From 09dedfbe1791480c1afdb74e6c37c99da77970ad Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 18 Mar 2020 12:00:57 -0600 Subject: [PATCH 1/3] maintenance to PKCS12 create for outputting encrypted bundles --- wolfcrypt/src/asn.c | 144 +++++----- wolfcrypt/src/pkcs12.c | 595 +++++++++++++++++++++++------------------ 2 files changed, 408 insertions(+), 331 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 58a726fe34f..ef7d43b98a4 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3426,7 +3426,8 @@ int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, /* check key type and get OID if ECC */ if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))< 0) { - return ret; + WOLFSSL_MSG("Error getting key OID"); + return ret; } /* PKCS#8 wrapping around key */ @@ -3937,6 +3938,9 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password, * heap possible heap hint for mallocs/frees * * returns the total size of encrypted content on success. + * + * data returned is : + * [ seq - obj [ seq -salt,itt]] , construct with encrypted data */ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, const char* password, int passwordSz, int vPKCS, int vAlgo, @@ -3947,6 +3951,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, word32 tmpIdx = 0; word32 totalSz = 0; word32 seqSz; + word32 innerSz; int ret; int version, id, blockSz = 0; #ifdef WOLFSSL_SMALL_STACK @@ -3956,6 +3961,11 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, byte saltTmp[MAX_SALT_SIZE]; byte cbcIv[MAX_IV_SIZE]; #endif + byte seq[MAX_SEQ_SZ]; + byte shr[MAX_SHORT_SZ]; + word32 maxShr = MAX_SHORT_SZ; + word32 algoSz; + const byte* algoName; (void)heap; @@ -3976,58 +3986,51 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, return BAD_FUNC_ARG; } - if (out == NULL) { - sz = inputSz; - switch (id) { - #if !defined(NO_DES3) && (!defined(NO_MD5) || !defined(NO_SHA)) - case PBE_MD5_DES: - case PBE_SHA1_DES: - case PBE_SHA1_DES3: - /* set to block size of 8 for DES operations. This rounds up - * to the nearest multiple of 8 */ - sz &= 0xfffffff8; - sz += 8; - break; - #endif /* !NO_DES3 && (!NO_MD5 || !NO_SHA) */ - #if !defined(NO_RC4) && !defined(NO_SHA) - case PBE_SHA1_RC4_128: - break; - #endif - case -1: - break; - - default: - return ALGO_ID_E; - } + /* calculate size */ + /* size of constructed string at end */ + sz = Pkcs8Pad(NULL, inputSz, blockSz); + totalSz = ASN_TAG_SZ; + totalSz += SetLength(sz, seq); + totalSz += sz; - if (saltSz == 0) { - sz += MAX_SALT_SIZE; - } - else { - sz += saltSz; - } + /* size of sequence holding object id and sub sequence of salt and itt */ + algoName = OidFromId(id, oidPBEType, &algoSz); + if (algoName == NULL) { + WOLFSSL_MSG("Unknown Algorithm"); + return 0; + } + innerSz = SetObjectId(algoSz, seq); + innerSz += algoSz; - /* add 2 for tags */ - totalSz = sz + MAX_ALGO_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ + - MAX_LENGTH_SZ + MAX_LENGTH_SZ + MAX_SHORT_SZ + 2; + /* get subsequence of salt and itt */ + if (salt == NULL || saltSz == 0) { + sz = 8; + } + else { + sz = saltSz; + } + seqSz = SetOctetString(sz, seq); + seqSz += sz; - /* adjust size to pad */ - totalSz = Pkcs8Pad(NULL, totalSz, blockSz); + tmpIdx = 0; + seqSz += SetShortInt(shr, &tmpIdx, itt, maxShr); + innerSz += seqSz + SetSequence(seqSz, seq); + totalSz += innerSz + SetSequence(innerSz, seq); - /* return result */ + if (out == NULL) { *outSz = totalSz; - return LENGTH_ONLY_E; } - if (inOutIdx + MAX_ALGO_SZ + MAX_SEQ_SZ + 1 > *outSz) + inOutIdx = 0; + if (totalSz > *outSz) return BUFFER_E; - sz = SetAlgoID(id, out + inOutIdx, oidPBEType, 0); - inOutIdx += sz; totalSz += sz; - tmpIdx = inOutIdx; - tmpIdx += MAX_SEQ_SZ; /* save room for salt and itter sequence */ - out[tmpIdx++] = ASN_OCTET_STRING; + inOutIdx += SetSequence(innerSz, out + inOutIdx); + inOutIdx += SetObjectId(algoSz, out + inOutIdx); + XMEMCPY(out + inOutIdx, algoName, algoSz); + inOutIdx += algoSz; + inOutIdx += SetSequence(seqSz, out + inOutIdx); /* create random salt if one not provided */ if (salt == NULL || saltSz == 0) { @@ -4047,22 +4050,18 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, return ret; } } - - if (tmpIdx + MAX_LENGTH_SZ + saltSz + MAX_SHORT_SZ > *outSz) { + inOutIdx += SetOctetString(saltSz, out + inOutIdx); + if (saltSz + inOutIdx > *outSz) { #ifdef WOLFSSL_SMALL_STACK XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return BUFFER_E; } - - sz = SetLength(saltSz, out + tmpIdx); - tmpIdx += sz; - - XMEMCPY(out + tmpIdx, salt, saltSz); - tmpIdx += saltSz; + XMEMCPY(out + inOutIdx, salt, saltSz); + inOutIdx += saltSz; /* place iteration setting in buffer */ - ret = SetShortInt(out, &tmpIdx, itt, *outSz); + ret = SetShortInt(out, &inOutIdx, itt, *outSz); if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -4070,37 +4069,34 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, return ret; } - /* rewind and place sequence */ - sz = tmpIdx - inOutIdx - MAX_SEQ_SZ; - seqSz = SetSequence(sz, out + inOutIdx); - XMEMMOVE(out + inOutIdx + seqSz, out + inOutIdx + MAX_SEQ_SZ, sz); - inOutIdx += seqSz; totalSz += seqSz; - inOutIdx += sz; totalSz += sz; - -#ifdef WOLFSSL_SMALL_STACK - cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); - if (cbcIv == NULL) { + if (inOutIdx + 1 > *outSz) { + #ifdef WOLFSSL_SMALL_STACK XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - if (inOutIdx + 1 + MAX_LENGTH_SZ + inputSz > *outSz) + #endif return BUFFER_E; - - out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0; totalSz++; - sz = SetLength(inputSz, out + inOutIdx); - inOutIdx += sz; totalSz += sz; + } + out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0; /* get pad size and verify buffer room */ sz = Pkcs8Pad(NULL, inputSz, blockSz); - if (sz + inOutIdx > *outSz) + if (sz + inOutIdx > *outSz) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif return BUFFER_E; + } + inOutIdx += SetLength(sz, out + inOutIdx); /* copy input to output buffer and pad end */ XMEMCPY(out + inOutIdx, input, inputSz); sz = Pkcs8Pad(out + inOutIdx, inputSz, blockSz); - totalSz += sz; +#ifdef WOLFSSL_SMALL_STACK + cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (cbcIv == NULL) { + XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif /* encrypt */ if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id, @@ -4120,7 +4116,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, (void)rng; - return totalSz; + return inOutIdx + sz; } diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 99860fe2888..12efd7bcbc5 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -60,8 +60,8 @@ enum { WC_PKCS12_DATA_OBJ_SZ = 11, }; -/* static const byte WC_PKCS12_ENCRYPTED_OID[] = - {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06}; */ +static const byte WC_PKCS12_ENCRYPTED_OID[] = + {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06}; static const byte WC_PKCS12_DATA_OID[] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01}; static const byte WC_PKCS12_CertBag_Type1_OID[] = @@ -717,14 +717,37 @@ int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz) /* Create the MAC portion */ if ((ret == 0) && (pkcs12->signData != NULL)) { MacData *mac = (MacData*)pkcs12->signData; - word32 aSz = (2 + (2 + 5) + (2)); - word32 bSz = (2 + mac->digestSz); - word32 cSz = (2 + mac->saltSz); - word32 dSz = (2 + sizeof(short int)); - word32 innerSz = aSz + bSz; - word32 outerSz = 2 + innerSz + cSz + dSz; - - sdBufSz = 2 + outerSz; + word32 innerSz = 0; + word32 outerSz = 0; + + /* get exact size */ + { + byte ASNLENGTH[MAX_LENGTH_SZ]; + byte ASNSHORT[MAX_SHORT_SZ]; + byte ASNALGO[MAX_ALGO_SZ]; + word32 tmpIdx = 0; + + /* algo id */ + innerSz += SetAlgoID(mac->oid, ASNALGO, oidHashType, 0); + + /* Octet string holding digest */ + innerSz += ASN_TAG_SZ; + innerSz += SetLength(mac->digestSz, ASNLENGTH); + innerSz += mac->digestSz; + + /* salt */ + outerSz += ASN_TAG_SZ; + outerSz += SetLength(mac->saltSz, ASNLENGTH); + outerSz += mac->saltSz; + + /* MAC iterations */ + outerSz += SetShortInt(ASNSHORT, &tmpIdx, mac->itt, MAX_SHORT_SZ); + + /* sequence of inner data */ + outerSz += SetSequence(innerSz, seq); + outerSz += innerSz; + } + sdBufSz = outerSz + SetSequence(outerSz, seq); sdBuf = (byte*)XMALLOC(sdBufSz, pkcs12->heap, DYNAMIC_TYPE_PKCS); if (sdBuf == NULL) { ret = MEMORY_E; @@ -749,15 +772,15 @@ int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz) } if (ret == 0) { + + /* Octet string holding digest */ - sdBuf[idx++] = ASN_OCTET_STRING; - idx += SetLength(mac->digestSz, &sdBuf[idx]); + idx += SetOctetString(mac->digestSz, &sdBuf[idx]); XMEMCPY(&sdBuf[idx], mac->digest, mac->digestSz); idx += mac->digestSz; /* Set salt */ - sdBuf[idx++] = ASN_OCTET_STRING; - idx += SetLength(mac->saltSz, &sdBuf[idx]); + idx += SetOctetString(mac->saltSz, &sdBuf[idx]); XMEMCPY(&sdBuf[idx], mac->salt, mac->saltSz); idx += mac->saltSz; @@ -765,16 +788,16 @@ int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz) { int tmpSz; word32 tmpIdx = 0; - byte ar[MAX_LENGTH_SZ + 2]; - tmpSz = SetShortInt(ar, &tmpIdx, mac->itt, MAX_LENGTH_SZ + 2); + byte ar[MAX_SHORT_SZ]; + tmpSz = SetShortInt(ar, &tmpIdx, mac->itt, MAX_SHORT_SZ); if (tmpSz < 0) { ret = tmpSz; } else { XMEMCPY(&sdBuf[idx], ar, tmpSz); + idx += tmpSz; } } - totalSz += sdBufSz; } } @@ -882,6 +905,7 @@ int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz) return ret; } + /* helper function to free WC_DerCertList */ void wc_FreeCertList(WC_DerCertList* list, void* heap) { @@ -1687,7 +1711,8 @@ static int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng, word32 length = 0; word32 tmpSz; word32 encSz; - word32 i; + + byte seq[MAX_SEQ_SZ]; WOLFSSL_MSG("encrypting PKCS12 content"); @@ -1701,42 +1726,56 @@ static int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng, * sequence * get object id */ if (type == WC_PKCS12_ENCRYPTED_DATA) { - if (out == NULL) { - *outSz = 1 + MAX_LENGTH_SZ + MAX_SEQ_SZ + MAX_VERSION_SZ + - MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ; - ret = EncryptContent(NULL, contentSz + MAX_SEQ_SZ, NULL, &encSz, - pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap); + word32 outerSz = 0; + + encSz = contentSz; + if ((ret = EncryptContent(NULL, contentSz, NULL, &encSz, + pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) { if (ret != LENGTH_ONLY_E) { return ret; } + } + + /* calculate size */ + totalSz = SetObjectId(sizeof(WC_PKCS12_ENCRYPTED_OID), seq); + totalSz += sizeof(WC_PKCS12_ENCRYPTED_OID); + totalSz += ASN_TAG_SZ; - *outSz += encSz; + length = SetMyVersion(0, seq, 0); + tmpSz = SetObjectId(sizeof(WC_PKCS12_DATA_OID), seq); + tmpSz += sizeof(WC_PKCS12_DATA_OID); + tmpSz += encSz; + length += SetSequence(tmpSz, seq) + tmpSz; + outerSz = SetSequence(length, seq) + length; + + totalSz += SetLength(outerSz, seq) + outerSz; + if (out == NULL) { + *outSz = totalSz + SetSequence(totalSz, seq); return LENGTH_ONLY_E; } - if (*outSz < (1 + MAX_LENGTH_SZ + MAX_SEQ_SZ + MAX_VERSION_SZ)) { + if (*outSz < totalSz + SetSequence(totalSz, seq)) { return BUFFER_E; } - out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); totalSz++; - - /* save room for length and sequence */ - idx += MAX_LENGTH_SZ; - idx += MAX_SEQ_SZ; - - tmpSz = SetMyVersion(0, out + idx, 0); - idx += tmpSz; length += tmpSz; - encSz = contentSz; - if ((ret = EncryptContent(NULL, contentSz, NULL, &encSz, - pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) { - if (ret != LENGTH_ONLY_E) { - return ret; - } + idx = 0; + idx += SetSequence(totalSz, out + idx); + idx += SetObjectId(sizeof(WC_PKCS12_ENCRYPTED_OID), out + idx); + if (idx + sizeof(WC_PKCS12_ENCRYPTED_OID) > *outSz){ + return BUFFER_E; } + XMEMCPY(out + idx, WC_PKCS12_ENCRYPTED_OID, + sizeof(WC_PKCS12_ENCRYPTED_OID)); + idx += sizeof(WC_PKCS12_ENCRYPTED_OID); - if (*outSz < (idx + MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ + encSz)) { + if (idx + 1 > *outSz){ return BUFFER_E; } + out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); + idx += SetLength(outerSz, out + idx); + + idx += SetSequence(length, out + idx); + idx += SetMyVersion(0, out + idx, 0); tmp = (byte*)XMALLOC(encSz, heap, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { return MEMORY_E; @@ -1760,34 +1799,23 @@ static int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng, } #endif - tmpSz = SetSequence(WC_PKCS12_DATA_OBJ_SZ + encSz, out + idx); - idx += tmpSz; length += tmpSz; - - out[idx++] = ASN_OBJECT_ID; length++; - tmpSz = SetLength(sizeof(WC_PKCS12_DATA_OID), out + idx); - idx += tmpSz; length += tmpSz; - for (i = 0; i < sizeof(WC_PKCS12_DATA_OID); i++) { - out[idx++] = WC_PKCS12_DATA_OID[i]; length++; + idx += SetSequence(WC_PKCS12_DATA_OBJ_SZ + encSz, out + idx); + idx += SetObjectId(sizeof(WC_PKCS12_DATA_OID), out + idx); + if (idx + sizeof(WC_PKCS12_DATA_OID) > *outSz){ + WOLFSSL_MSG("Buffer not large enough for DATA OID"); + return BUFFER_E; } + XMEMCPY(out + idx, WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID)); + idx += sizeof(WC_PKCS12_DATA_OID); /* copy over encrypted data */ + if (idx + encSz > *outSz){ + return BUFFER_E; + } XMEMCPY(out + idx, tmp, encSz); XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER); - idx += encSz; length += encSz; - - /* rewind and place sequence */ - idx -= (length + MAX_SEQ_SZ); - tmpSz = SetSequence(length, out + idx); - XMEMMOVE(out + idx + tmpSz, out + idx + MAX_SEQ_SZ, length); - length += tmpSz; - - /* now place length */ - idx -= MAX_LENGTH_SZ; - tmpSz = SetLength(length, out + idx); - XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length); - totalSz += length + tmpSz; - - return totalSz; + idx += encSz; + return idx; } /* DATA @@ -1797,35 +1825,50 @@ static int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng, * length * sequence containing all bags */ if (type == WC_PKCS12_DATA) { + /* calculate size */ + totalSz = SetObjectId(sizeof(WC_PKCS12_DATA_OID), seq); + totalSz += sizeof(WC_PKCS12_DATA_OID); + totalSz += ASN_TAG_SZ; + + length = SetOctetString(contentSz, seq); + length += contentSz; + totalSz += SetLength(length, seq); + totalSz += length; + if (out == NULL) { - *outSz = 1 + MAX_LENGTH_SZ + 1 + MAX_LENGTH_SZ + contentSz; + *outSz = totalSz + SetSequence(totalSz, seq); return LENGTH_ONLY_E; } - if (*outSz < (1 + MAX_LENGTH_SZ + 1 + MAX_LENGTH_SZ + contentSz)) { + if (*outSz < (totalSz + SetSequence(totalSz, seq))) { return BUFFER_E; } - out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); - totalSz++; - - /* save room for length */ - idx += MAX_LENGTH_SZ; + /* place data in output buffer */ + idx = 0; + idx += SetSequence(totalSz, out); + idx += SetObjectId(sizeof(WC_PKCS12_DATA_OID), out + idx); + if (idx + sizeof(WC_PKCS12_DATA_OID) > *outSz){ + WOLFSSL_MSG("Buffer not large enough for DATA OID"); + return BUFFER_E; + } + XMEMCPY(out + idx, WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID)); + idx += sizeof(WC_PKCS12_DATA_OID); - out[idx++] = ASN_OCTET_STRING; length++; - tmpSz = SetLength(contentSz, out + idx); - idx += tmpSz; length += tmpSz; + if (idx + 1 > *outSz){ + return BUFFER_E; + } + out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); + idx += SetLength(length, out + idx); + idx += SetOctetString(contentSz, out + idx); - /* sequence containing all bags */ + if (idx + contentSz > *outSz){ + return BUFFER_E; + } XMEMCPY(out + idx, content, contentSz); - idx += contentSz; length += contentSz; + idx += contentSz; - idx -= (MAX_LENGTH_SZ + length); - tmpSz = SetLength(length, out + idx); - XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length); - totalSz += length + tmpSz; - - return totalSz; + return idx; } WOLFSSL_MSG("Unknown/Unsupported content type"); @@ -1833,74 +1876,23 @@ static int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng, } -/* - * pass : password to use with encryption - * passSz : size of the password buffer - * name : friendlyName to use - * key : DER format of key - * keySz : size of key buffer - * cert : DER format of certificate - * certSz : size of the certificate buffer - * ca : a list of extra certificates - * nidKey : type of encryption to use on the key (-1 means no encryption) - * nidCert : type of encryption to use on the certificate - * (-1 means no encryption) - * iter : number of iterations with encryption - * macIter : number of iterations when creating MAC - * keyType : flag for signature and/or encryption key - * heap : pointer to allocate from memory - * - * returns a pointer to a new WC_PKCS12 structure on success and NULL if failed - */ -WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, - byte* key, word32 keySz, byte* cert, word32 certSz, WC_DerCertList* ca, - int nidKey, int nidCert, int iter, int macIter, int keyType, void* heap) +/* helper function to create the PKCS12 key content + * keyCiSz is output buffer size + * returns a pointer to be free'd by caller on success and NULL on failure */ +static byte* PKCS12_create_key_content(WC_PKCS12* pkcs12, int nidKey, + word32* keyCiSz, WC_RNG* rng, char* pass, word32 passSz, + byte* key, word32 keySz, int iter) { - WC_PKCS12* pkcs12; - AuthenticatedSafe* safe; - ContentInfo* ci; - WC_RNG rng; - int algo; - int ret; - int type; - word32 idx; - word32 sz; - word32 tmpSz; - - byte* certCi = NULL; - word32 certCiSz; - byte* keyCi; - word32 keyCiSz; - - byte* certBuf = NULL; - word32 certBufSz; byte* keyBuf; word32 keyBufSz = 0; + byte* keyCi = NULL; + word32 tmpSz; + int ret; + int algo; - WOLFSSL_ENTER("wc_PKCS12_create()"); - - if ((ret = wc_InitRng_ex(&rng, heap, INVALID_DEVID)) != 0) { - return NULL; - } - - if ((pkcs12 = wc_PKCS12_new()) == NULL) { - wc_FreeRng(&rng); - WOLFSSL_LEAVE("wc_PKCS12_create", MEMORY_E); - return NULL; - } - - if ((ret = wc_PKCS12_SetHeap(pkcs12, heap)) != 0) { - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); - WOLFSSL_LEAVE("wc_PKCS12_create", ret); - return NULL; - } - - if (iter <= 0) { - iter = WC_PKCS12_ITT_DEFAULT; - } + void* heap = wc_PKCS12_GetHeap(pkcs12); - /**** add private key bag ****/ + *keyCiSz = 0; switch (nidKey) { case PBE_SHA1_RC4_128: algo = 1; @@ -1921,39 +1913,30 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, default: WOLFSSL_MSG("Unknown/Unsupported key encryption"); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); return NULL; } /* get max size for key bag */ - ret = wc_PKCS12_create_key_bag(pkcs12, &rng, NULL, &keyBufSz, key, keySz, + ret = wc_PKCS12_create_key_bag(pkcs12, rng, NULL, &keyBufSz, key, keySz, algo, iter, pass, passSz); if (ret != LENGTH_ONLY_E && ret < 0) { - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); - WOLFSSL_LEAVE("wc_PKCS12_create", ret); + WOLFSSL_MSG("Error getting key bag size"); return NULL; } /* account for sequence around bag */ keyBufSz += MAX_SEQ_SZ; - keyBuf = (byte*)XMALLOC(keyBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER); if (keyBuf == NULL) { - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); - WOLFSSL_LEAVE("wc_PKCS12_create", MEMORY_E); + WOLFSSL_MSG("Memory error creating keyBuf buffer"); return NULL; } - ret = wc_PKCS12_create_key_bag(pkcs12, &rng, keyBuf + MAX_SEQ_SZ, &keyBufSz, + ret = wc_PKCS12_create_key_bag(pkcs12, rng, keyBuf + MAX_SEQ_SZ, &keyBufSz, key, keySz, algo, iter, pass, passSz); if (ret < 0) { - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); - WOLFSSL_LEAVE("wc_PKCS12_create", ret); + WOLFSSL_MSG("Error creating key bag"); return NULL; } keyBufSz = ret; @@ -1962,48 +1945,72 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, XMEMMOVE(keyBuf + tmpSz, keyBuf + MAX_SEQ_SZ, keyBufSz); keyBufSz += tmpSz; - ret = wc_PKCS12_encrypt_content(pkcs12, &rng, NULL, &keyCiSz, + #ifdef WOLFSSL_DEBUG_PKCS12 + { + word32 i; + printf("(size %u) Key Bag = ", keyBufSz); + for (i = 0; i < keyBufSz; i++) + printf("%02X", keyBuf[i]); + printf("\n"); + } + #endif + ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, keyCiSz, NULL, keyBufSz, algo, pass, passSz, iter, WC_PKCS12_DATA); if (ret != LENGTH_ONLY_E) { - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); - WOLFSSL_LEAVE("wc_PKCS12_create", ret); + WOLFSSL_MSG("Error getting key encrypt content size"); return NULL; } - keyCi = (byte*)XMALLOC(keyCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER); + keyCi = (byte*)XMALLOC(*keyCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER); if (keyCi == NULL) { - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); return NULL; } - ret = wc_PKCS12_encrypt_content(pkcs12, &rng, keyCi, &keyCiSz, + ret = wc_PKCS12_encrypt_content(pkcs12, rng, keyCi, keyCiSz, keyBuf, keyBufSz, algo, pass, passSz, iter, WC_PKCS12_DATA); + XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); if (ret < 0 ) { - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); - XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - WOLFSSL_LEAVE("wc_PKCS12_create", ret); + WOLFSSL_MSG("Error creating key encrypt content"); return NULL; } - keyCiSz = ret; - XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); + *keyCiSz = ret; #ifdef WOLFSSL_DEBUG_PKCS12 { - byte* p; - for (printf("(size %u) Key Content Info = ", keyCiSz), p = (byte*)keyCi; - p < (byte*)keyCi + keyCiSz; - printf("%02X", *p), p++); + word32 i; + printf("(size %u) Key Content Info = ", *keyCiSz); + for (i = 0; i < *keyCiSz; i++) + printf("%02X", keyCi[i]); printf("\n"); } #endif + return keyCi; +} + + +/* helper function to create the PKCS12 certificate content + * certCiSz is output buffer size + * returns a pointer to be free'd by caller on success and NULL on failure */ +static byte* PKCS12_create_cert_content(WC_PKCS12* pkcs12, int nidCert, + WC_DerCertList* ca, byte* cert, word32 certSz, word32* certCiSz, + WC_RNG* rng, char* pass, word32 passSz, int iter) +{ + int algo; + int ret; + int type; + + byte* certBuf = NULL; + word32 certBufSz; + word32 idx; + word32 sz; + word32 tmpSz; + + byte* certCi; + void* heap = wc_PKCS12_GetHeap(pkcs12); - /**** add main certificate bag and extras ****/ switch (nidCert) { case PBE_SHA1_RC4_128: type = WC_PKCS12_ENCRYPTED_DATA; @@ -2027,18 +2034,12 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, default: WOLFSSL_MSG("Unknown/Unsupported certificate encryption"); - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); return NULL; } /* get max size of buffer needed */ ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &certBufSz, cert, certSz); if (ret != LENGTH_ONLY_E) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); return NULL; } @@ -2051,9 +2052,6 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &curBufSz, current->buffer, current->bufferSz); if (ret != LENGTH_ONLY_E) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); return NULL; } certBufSz += curBufSz; @@ -2067,9 +2065,6 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, /* completed getting max size, now create buffer and start adding bags */ certBuf = (byte*)XMALLOC(certBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER); if (certBuf == NULL) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); WOLFSSL_MSG("Memory error creating certificate bags"); return NULL; } @@ -2080,10 +2075,7 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, sz = certBufSz - idx; if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz, cert, certSz)) < 0) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); return NULL; } idx += ret; @@ -2095,10 +2087,7 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, sz = certBufSz - idx; if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz, current->buffer, current->bufferSz)) < 0) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); return NULL; } idx += ret; @@ -2112,108 +2101,194 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, certBufSz = tmpSz + (idx - MAX_SEQ_SZ); /* get buffer size needed for content info */ - ret = wc_PKCS12_encrypt_content(pkcs12, &rng, NULL, &certCiSz, + ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, certCiSz, NULL, certBufSz, algo, pass, passSz, iter, type); if (ret != LENGTH_ONLY_E) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); WOLFSSL_LEAVE("wc_PKCS12_create()", ret); return NULL; } - certCi = (byte*)XMALLOC(certCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER); + certCi = (byte*)XMALLOC(*certCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER); if (certCi == NULL) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); return NULL; } - ret = wc_PKCS12_encrypt_content(pkcs12, &rng, certCi, &certCiSz, + ret = wc_PKCS12_encrypt_content(pkcs12, rng, certCi, certCiSz, certBuf, certBufSz, algo, pass, passSz, iter, type); + XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); if (ret < 0) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); - wc_FreeRng(&rng); WOLFSSL_LEAVE("wc_PKCS12_create()", ret); return NULL; } - certCiSz = ret; - XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); + *certCiSz = ret; #ifdef WOLFSSL_DEBUG_PKCS12 { - byte* p; - for (printf("(size %u) Encrypted Certificate Content Info = ",certCiSz), - p = (byte*)certCi; - p < (byte*)certCi + certCiSz; - printf("%02X", *p), p++); + word32 i; + printf("(size %u) Encrypted Certificate Content Info = ", *certCiSz); + for (i = 0; i < *certCiSz; i++) + printf("%02X", certCi[i]); printf("\n"); } #endif - /**** create safe and and Content Info ****/ - safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), heap, - DYNAMIC_TYPE_PKCS); - if (safe == NULL) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - wc_PKCS12_free(pkcs12); + return certCi; +} + + +/* helper function to create the PKCS12 safe + * returns 0 on success */ +static int PKCS12_create_safe(WC_PKCS12* pkcs12, byte* certCi, word32 certCiSz, + byte* keyCi, word32 keyCiSz, WC_RNG* rng, char* pass, word32 passSz, + int iter) +{ + int length; + int ret; + byte seq[MAX_SEQ_SZ]; + word32 safeDataSz; + word32 innerDataSz; + byte *innerData = NULL; + byte *safeData = NULL; + word32 idx; + + innerDataSz = certCiSz + keyCiSz+SetSequence(certCiSz + keyCiSz, seq); + + /* add Content Info structs to safe, key first then cert */ + ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, &safeDataSz, + NULL, innerDataSz, 0, NULL, 0, 0, WC_PKCS12_DATA); + if (ret != LENGTH_ONLY_E) { + return ret; + } + + safeData = (byte*)XMALLOC(safeDataSz, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (safeData == NULL) { + WOLFSSL_MSG("Error malloc'ing safe data buffer"); + return MEMORY_E; + } + + /* create sequence of inner data */ + innerData = (byte*)XMALLOC(innerDataSz, pkcs12->heap, DYNAMIC_TYPE_PKCS); + if (innerData == NULL) { + WOLFSSL_MSG("Error malloc'ing inner data buffer"); + return MEMORY_E; + } + idx = 0; + idx += SetSequence(certCiSz + keyCiSz, innerData); + XMEMCPY(innerData + idx, certCi, certCiSz); + XMEMCPY(innerData + idx + certCiSz, keyCi, keyCiSz); + + ret = wc_PKCS12_encrypt_content(pkcs12, rng, safeData, &safeDataSz, + innerData, innerDataSz, 0, pass, passSz, iter, WC_PKCS12_DATA); + XFREE(innerData, pkcs12->heap, DYNAMIC_TYPE_PKCS); + if (ret < 0 ) { + WOLFSSL_MSG("Error setting data type for safe contents"); + XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } + idx = 0; + + ret = GetSequence(safeData, &idx, &length, safeDataSz); + if (ret < 0) { + WOLFSSL_MSG("Error getting first sequence of safe"); + XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } + + ret = GetSafeContent(pkcs12, safeData, &idx, safeDataSz); + XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ret < 0) { + WOLFSSL_MSG("Unable to create safe contents"); + return ret; + } + return 0; +} + + +/* + * pass : password to use with encryption + * passSz : size of the password buffer + * name : friendlyName to use + * key : DER format of key + * keySz : size of key buffer + * cert : DER format of certificate + * certSz : size of the certificate buffer + * ca : a list of extra certificates + * nidKey : type of encryption to use on the key (-1 means no encryption) + * nidCert : type of encryption to use on the certificate + * (-1 means no encryption) + * iter : number of iterations with encryption + * macIter : number of iterations when creating MAC + * keyType : flag for signature and/or encryption key + * heap : pointer to allocate from memory + * + * returns a pointer to a new WC_PKCS12 structure on success and NULL if failed + */ +WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, + byte* key, word32 keySz, byte* cert, word32 certSz, WC_DerCertList* ca, + int nidKey, int nidCert, int iter, int macIter, int keyType, void* heap) +{ + WC_PKCS12* pkcs12; + WC_RNG rng; + int ret; + + byte* certCi = NULL; + byte* keyCi = NULL; + word32 certCiSz; + word32 keyCiSz; + + WOLFSSL_ENTER("wc_PKCS12_create()"); + + if ((ret = wc_InitRng_ex(&rng, heap, INVALID_DEVID)) != 0) { + return NULL; + } + + if ((pkcs12 = wc_PKCS12_new()) == NULL) { wc_FreeRng(&rng); + WOLFSSL_LEAVE("wc_PKCS12_create", MEMORY_E); return NULL; } - pkcs12->safe = safe; /* set so all of safe is free'd with wc_PKCS12_free */ - XMEMSET(safe, 0, sizeof(AuthenticatedSafe)); - safe->dataSz = certCiSz + keyCiSz; - safe->data = (byte*)XMALLOC(safe->dataSz, heap, DYNAMIC_TYPE_PKCS); - if (safe->data == NULL) { - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER); + if ((ret = wc_PKCS12_SetHeap(pkcs12, heap)) != 0) { wc_PKCS12_free(pkcs12); wc_FreeRng(&rng); + WOLFSSL_LEAVE("wc_PKCS12_create", ret); return NULL; } - XMEMCPY(safe->data, certCi, certCiSz); - XMEMCPY(safe->data + certCiSz, keyCi, keyCiSz); - XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); - safe->numCI = 2; + if (iter <= 0) { + iter = WC_PKCS12_ITT_DEFAULT; + } - /* add Content Info structs to safe, key first then cert */ - ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), heap, DYNAMIC_TYPE_PKCS); - if (ci == NULL) { + /**** add private key bag ****/ + keyCi = PKCS12_create_key_content(pkcs12, nidKey, &keyCiSz, &rng, + pass, passSz, key, keySz, iter); + if (keyCi == NULL) { wc_PKCS12_free(pkcs12); wc_FreeRng(&rng); return NULL; } - XMEMSET(ci, 0, sizeof(ContentInfo)); - safe->CI = ci; - ci->data = safe->data + certCiSz; - ci->dataSz = keyCiSz; - ci->type = WC_PKCS12_DATA; - ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), heap, DYNAMIC_TYPE_PKCS); - if (ci == NULL) { + /**** add main certificate bag and extras ****/ + certCi = PKCS12_create_cert_content(pkcs12, nidCert, ca, cert, certSz, + &certCiSz, &rng, pass, passSz, iter); + if (certCi == NULL) { + XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS12_free(pkcs12); wc_FreeRng(&rng); return NULL; } - XMEMSET(ci, 0, sizeof(ContentInfo)); - ci->next = safe->CI; - safe->CI = ci; - ci->data = safe->data; - ci->dataSz = certCiSz; - if (nidCert < 0) { - ci->type = WC_PKCS12_DATA; - } - else { - ci->type = WC_PKCS12_ENCRYPTED_DATA; + + /**** create safe and Content Info ****/ + ret = PKCS12_create_safe(pkcs12, certCi, certCiSz, keyCi, keyCiSz, &rng, + pass, passSz, iter); + XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ret != 0) { + WOLFSSL_MSG("Unable to create PKCS12 safe"); + wc_PKCS12_free(pkcs12); + wc_FreeRng(&rng); + return NULL; } /* create MAC */ @@ -2225,6 +2300,7 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, if (mac == NULL) { wc_PKCS12_free(pkcs12); wc_FreeRng(&rng); + WOLFSSL_MSG("Error malloc'ing mac data buffer"); return NULL; } XMEMSET(mac, 0, sizeof(MacData)); @@ -2254,6 +2330,7 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, if (mac->salt == NULL) { wc_PKCS12_free(pkcs12); wc_FreeRng(&rng); + WOLFSSL_MSG("Error malloc'ing salt data buffer"); return NULL; } @@ -2263,17 +2340,21 @@ WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, wc_FreeRng(&rng); return NULL; } - ret = wc_PKCS12_create_mac(pkcs12, safe->data, safe->dataSz, - (const byte*)pass, passSz, digest, WC_MAX_DIGEST_SIZE); + ret = wc_PKCS12_create_mac(pkcs12, pkcs12->safe->data, + pkcs12->safe->dataSz, (const byte*)pass, passSz, digest, + WC_MAX_DIGEST_SIZE); if (ret < 0) { wc_PKCS12_free(pkcs12); wc_FreeRng(&rng); + WOLFSSL_MSG("Error creating mac"); + WOLFSSL_LEAVE("wc_PKCS12_create", ret); return NULL; } mac->digestSz = ret; mac->digest = (byte*)XMALLOC(ret, heap, DYNAMIC_TYPE_PKCS); if (mac->digest == NULL) { + WOLFSSL_MSG("Error malloc'ing mac digest buffer"); wc_PKCS12_free(pkcs12); wc_FreeRng(&rng); return NULL; From ce6aeebdb498e62e900ae062fba2e9241a98a2c8 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 19 Mar 2020 16:34:02 -0600 Subject: [PATCH 2/3] fixes for static analysis checks --- wolfcrypt/src/pkcs12.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 12efd7bcbc5..d9eb874d3c8 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -795,7 +795,6 @@ int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz) } else { XMEMCPY(&sdBuf[idx], ar, tmpSz); - idx += tmpSz; } } totalSz += sdBufSz; @@ -1889,9 +1888,9 @@ static byte* PKCS12_create_key_content(WC_PKCS12* pkcs12, int nidKey, word32 tmpSz; int ret; int algo; + void* heap; - void* heap = wc_PKCS12_GetHeap(pkcs12); - + heap = wc_PKCS12_GetHeap(pkcs12); *keyCiSz = 0; switch (nidKey) { case PBE_SHA1_RC4_128: @@ -1987,6 +1986,7 @@ static byte* PKCS12_create_key_content(WC_PKCS12* pkcs12, int nidKey, } #endif + (void)heap; return keyCi; } @@ -2009,8 +2009,9 @@ static byte* PKCS12_create_cert_content(WC_PKCS12* pkcs12, int nidCert, word32 tmpSz; byte* certCi; - void* heap = wc_PKCS12_GetHeap(pkcs12); + void* heap; + heap = wc_PKCS12_GetHeap(pkcs12); switch (nidCert) { case PBE_SHA1_RC4_128: type = WC_PKCS12_ENCRYPTED_DATA; @@ -2133,6 +2134,7 @@ static byte* PKCS12_create_cert_content(WC_PKCS12* pkcs12, int nidCert, } #endif + (void)heap; return certCi; } @@ -2171,6 +2173,7 @@ static int PKCS12_create_safe(WC_PKCS12* pkcs12, byte* certCi, word32 certCiSz, innerData = (byte*)XMALLOC(innerDataSz, pkcs12->heap, DYNAMIC_TYPE_PKCS); if (innerData == NULL) { WOLFSSL_MSG("Error malloc'ing inner data buffer"); + XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } idx = 0; From 2116c20f5dea6257c107f60e5bcbfd507fe7ff6f Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 25 Mar 2020 10:38:18 -0600 Subject: [PATCH 3/3] add test case for PKCS12 to DER and back --- tests/api.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 47a8843bb4e..95a84547f7f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -4550,6 +4550,7 @@ static void test_wolfSSL_PKCS12(void) d2i_PKCS12_bio(bio, &pkcs12); AssertNotNull(pkcs12); + BIO_free(bio); /* check verify MAC fail case */ ret = PKCS12_parse(pkcs12, "bad", &pkey, &cert, NULL); @@ -4631,6 +4632,13 @@ static void test_wolfSSL_PKCS12(void) X509_free(cert); sk_X509_free(ca); + /* convert to DER then back and parse */ + AssertNotNull(bio = BIO_new(BIO_s_mem())); + AssertIntEQ(i2d_PKCS12_bio(bio, pkcs12_2), SSL_SUCCESS); + PKCS12_free(pkcs12_2); + + AssertNotNull(pkcs12_2 = d2i_PKCS12_bio(bio, NULL)); + BIO_free(bio); AssertIntEQ(PKCS12_parse(pkcs12_2, "a password", &pkey, &cert, &ca), SSL_SUCCESS); @@ -4661,7 +4669,6 @@ static void test_wolfSSL_PKCS12(void) EVP_PKEY_free(pkey); X509_free(cert); - BIO_free(bio); PKCS12_free(pkcs12); PKCS12_free(pkcs12_2); sk_X509_free(ca);