From 5006306bb8bcce0706e427d81061ec087436db57 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 23 Nov 2016 15:38:27 -0700 Subject: [PATCH] PKCS#7: add support for optional unprotectedAttributes with EncryptedData --- wolfcrypt/src/pkcs7.c | 240 ++++++++++++++++++++++++++++++++++---- wolfcrypt/test/test.c | 128 +++++++++++++++++--- wolfssl/wolfcrypt/pkcs7.h | 21 +++- 3 files changed, 351 insertions(+), 38 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index ef09d9bc8..be33c1d84 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -211,7 +211,10 @@ int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz) /* releases any memory allocated by a PKCS7 initializer */ void wc_PKCS7_Free(PKCS7* pkcs7) { - (void)pkcs7; + if (pkcs7 == NULL) + return; + + wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap); } @@ -1306,7 +1309,7 @@ int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz, int wc_PKCS7_GenerateIV(WC_RNG* rng, byte* iv, word32 ivSz) { int ret; - WC_RNG* random; + WC_RNG* random = NULL; if (iv == NULL || ivSz == 0) return BAD_FUNC_ARG; @@ -1316,17 +1319,19 @@ int wc_PKCS7_GenerateIV(WC_RNG* rng, byte* iv, word32 ivSz) random = XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); if (random == NULL) return MEMORY_E; + + ret = wc_InitRng(random); + if (ret != 0) + return ret; + } else { random = rng; } - ret = wc_InitRng(random); - if (ret == 0) { - ret = wc_RNG_GenerateBlock(random, iv, ivSz); - wc_FreeRng(random); - } + ret = wc_RNG_GenerateBlock(random, iv, ivSz); if (rng == NULL) { + wc_FreeRng(random); XFREE(random, NULL, DYNAMIC_TYPE_RNG); } @@ -2098,8 +2103,8 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) byte encDataSeq[MAX_SEQ_SZ]; byte ver[MAX_VERSION_SZ]; - byte* plain; - byte* encryptedContent; + byte* plain = NULL; + byte* encryptedContent = NULL; int encContentOctetSz, encContentSeqSz, contentTypeSz; int contentEncAlgoSz, ivOctetStringSz; @@ -2110,6 +2115,14 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) byte ivOctetString[MAX_OCTET_STR_SZ]; byte encContentOctet[MAX_OCTET_STR_SZ]; + byte attribSet[MAX_SET_SZ]; + EncodedAttrib* attribs = NULL; + word32 attribsSz; + word32 attribsCount; + word32 attribsSetSz; + + byte* flatAttribs = NULL; + if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 || pkcs7->encryptOID == 0 || pkcs7->encryptionKey == NULL || pkcs7->encryptionKeySz == 0) @@ -2122,7 +2135,11 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) outerContentTypeSz = wc_SetContentType(ENCRYPTED_DATA, outerContentType); /* version, 2 if unprotectedAttrs present, 0 if absent */ - verSz = SetMyVersion(0, ver, 0); + if (pkcs7->unprotectedAttribsSz > 0) { + verSz = SetMyVersion(2, ver, 0); + } else { + verSz = SetMyVersion(0, ver, 0); + } /* EncryptedContentInfo */ contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType); @@ -2194,9 +2211,49 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) encContentOctetSz + encryptedOutSz, encContentSeq); + /* optional UnprotectedAttributes */ + if (pkcs7->unprotectedAttribsSz != 0) { + + if (pkcs7->unprotectedAttribs == NULL) { + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + return BAD_FUNC_ARG; + } + + attribs = (EncodedAttrib*)XMALLOC( + sizeof(EncodedAttrib) * pkcs7->unprotectedAttribsSz, + pkcs7->heap, DYNAMIC_TYPE_PKCS); + if (attribs == NULL) { + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + + attribsCount = pkcs7->unprotectedAttribsSz; + attribsSz = EncodeAttributes(attribs, pkcs7->unprotectedAttribsSz, + pkcs7->unprotectedAttribs, + pkcs7->unprotectedAttribsSz); + + flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, DYNAMIC_TYPE_PKCS); + if (flatAttribs == NULL) { + XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS); + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + + FlattenAttributes(flatAttribs, attribs, attribsCount); + attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet); + + } else { + attribsSz = 0; + attribsSetSz = 0; + } + /* keep track of sizes for outer wrapper layering */ totalSz = verSz + encContentSeqSz + contentTypeSz + contentEncAlgoSz + - ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz; + ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz + + attribsSz + attribsSetSz;; /* EncryptedData */ encDataSeqSz = SetSequence(totalSz, encDataSeq); @@ -2213,6 +2270,10 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) if (totalSz > (int)outputSz) { WOLFSSL_MSG("PKCS#7 output buffer too small"); + if (pkcs7->unprotectedAttribsSz != 0) { + XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS); + XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS); + } XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); return BUFFER_E; @@ -2243,6 +2304,15 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) XMEMCPY(output + idx, encryptedContent, encryptedOutSz); idx += encryptedOutSz; + if (pkcs7->unprotectedAttribsSz != 0) { + XMEMCPY(output + idx, attribSet, attribsSetSz); + idx += attribsSetSz; + XMEMCPY(output + idx, flatAttribs, attribsSz); + idx += attribsSz; + XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS); + XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS); + } + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -2250,11 +2320,120 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) } -/* unwrap and decrypt PKCS#7/CMS encrypted-data object, returned decoded size */ -int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, - byte* output, word32 outputSz) +void wc_PKCS7_FreeDecodedAttrib(PKCS7DecodedAttrib* attrib, void* heap) { - int ret, version, length; + PKCS7DecodedAttrib* current; + + if (attrib == NULL) { + return; + } + + current = attrib; + while (current != NULL) { + PKCS7DecodedAttrib* next = current->next; + if (current->oid != NULL) { + XFREE(current->oid, heap, DYNAMIC_TYPE_PKCS7); + } + if (current->value != NULL) { + XFREE(current->value, heap, DYNAMIC_TYPE_PKCS7); + } + XFREE(current, heap, DYNAMIC_TYPE_PKCS7); + current = next; + } + + (void)heap; +} + + +/* decode and store unprotected attributes in PKCS7->decodedAttrib. Return + * 0 on success, negative on error. User must call wc_PKCS7_Free(). */ +int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg, + word32 pkiMsgSz, word32* inOutIdx) +{ + int length, attribLen; + word32 oid, savedIdx, idx; + PKCS7DecodedAttrib* attrib = NULL; + + if (pkcs7 == NULL || pkiMsg == NULL || + pkiMsgSz == 0 || inOutIdx == NULL) + return BAD_FUNC_ARG; + + idx = *inOutIdx; + + if (pkiMsg[idx] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) + return ASN_PARSE_E; + idx++; + + if (GetLength(pkiMsg, &idx, &attribLen, pkiMsgSz) < 0) + return ASN_PARSE_E; + + /* loop through attributes */ + while (attribLen > 0) { + + if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) + return ASN_PARSE_E; + + attribLen -= (length + 2); /* TAG + LENGTH + DATA */ + savedIdx = idx; + + attrib = (PKCS7DecodedAttrib*)XMALLOC(sizeof(PKCS7DecodedAttrib), + pkcs7->heap, DYNAMIC_TYPE_PKCS); + if (attrib == NULL) { + return MEMORY_E; + } + XMEMSET(attrib, 0, sizeof(PKCS7DecodedAttrib)); + + /* save attribute OID bytes and size */ + if (GetObjectId(pkiMsg, &idx, &oid, oidIgnoreType, pkiMsgSz) < 0) + return ASN_PARSE_E; + + attrib->oidSz = idx - savedIdx; + attrib->oid = (byte*)XMALLOC(attrib->oidSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS); + if (attrib->oid == NULL) { + XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS); + return MEMORY_E; + } + XMEMCPY(attrib->oid, pkiMsg + savedIdx, attrib->oidSz); + + /* save attribute value bytes and size */ + if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) + return ASN_PARSE_E; + + if ((pkiMsgSz - idx) < (word32)length) + return ASN_PARSE_E; + + attrib->valueSz = (word32)length; + attrib->value = (byte*)XMALLOC(attrib->valueSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS); + if (attrib->value == NULL) { + XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS); + XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS); + return MEMORY_E; + } + XMEMCPY(attrib->value, pkiMsg + idx, attrib->valueSz); + idx += length; + + /* store attribute in linked list */ + if (pkcs7->decodedAttrib != NULL) { + attrib->next = pkcs7->decodedAttrib; + pkcs7->decodedAttrib = attrib; + } else { + pkcs7->decodedAttrib = attrib; + } + } + + *inOutIdx = idx; + + return 0; +} + + +/* unwrap and decrypt PKCS#7/CMS encrypted-data object, returned decoded size */ +int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, + byte* output, word32 outputSz) +{ + int ret, version, length, haveAttribs; word32 idx = 0; word32 contentType, encOID; @@ -2295,14 +2474,11 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; + /* get version, check later */ + haveAttribs = 0; if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0) return ASN_PARSE_E; - if (version != 0) { - WOLFSSL_MSG("PKCS#7 EncryptedData needs to be of version 0"); - return ASN_VERSION_E; - } - /* remove EncryptedContentInfo */ if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -2345,6 +2521,7 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, return MEMORY_E; XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz); + idx += encryptedContentSz; /* decrypt encryptedContent */ ret = wc_PKCS7_DecryptContent(encOID, pkcs7->encryptionKey, @@ -2361,6 +2538,29 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, /* copy plaintext to output */ XMEMCPY(output, encryptedContent, encryptedContentSz - padLen); + /* get implicit[1] unprotected attributes, optional */ + if (idx < pkiMsgSz) { + + haveAttribs = 1; + pkcs7->decodedAttrib = NULL; + + ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg, + pkiMsgSz, &idx); + if (ret != 0) { + printf("DEBUG: DecodeUnprotectedAttributes failed!\n"); + ForceZero(encryptedContent, encryptedContentSz); + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + return ASN_PARSE_E; + } + } + + /* go back and check the version now that attribs have been processed */ + if ((haveAttribs == 0 && version != 0) || + (haveAttribs == 1 && version != 2) ) { + WOLFSSL_MSG("Wrong PKCS#7 EncryptedData version"); + return ASN_VERSION_E; + } + ForceZero(encryptedContent, encryptedContentSz); XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index ae93f5b91..ab444ef2d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9041,14 +9041,16 @@ int compress_test(void) typedef struct { const char* outFileName; - const byte* content; - word32 contentSz; - int contentOID; - int encryptOID; - byte* privateKey; - word32 privateKeySz; - byte* encryptionKey; - word32 encryptionKeySz; + const byte* content; + word32 contentSz; + int contentOID; + int encryptOID; + byte* privateKey; + word32 privateKeySz; + byte* encryptionKey; + word32 encryptionKeySz; + PKCS7Attrib* attribs; + word32 attribsSz; } pkcs7Vector; int pkcs7enveloped_test(void) @@ -9224,6 +9226,9 @@ int pkcs7encrypted_test(void) byte decoded[2048]; FILE* pkcs7File; + PKCS7Attrib* expectedAttrib; + PKCS7DecodedAttrib* decodedAttrib; + const byte data[] = { /* Hello World */ 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f, 0x72,0x6c,0x64 @@ -9248,19 +9253,52 @@ int pkcs7encrypted_test(void) }; byte aes256Key[] = { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, - 0x01,0x02,0x03,0x05,0x05,0x06,0x07,0x08, - 0x01,0x02,0x03,0x05,0x05,0x06,0x07,0x08, - 0x01,0x02,0x03,0x05,0x05,0x06,0x07,0x08 + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08 + }; + + /* Attribute example from RFC 4134, Section 7.2 + * OID = 1.2.5555 + * OCTET STRING = 'This is a test General ASN Attribute, number 1.' */ + static byte genAttrOid[] = { 0x06, 0x03, 0x2a, 0xab, 0x33 }; + static byte genAttr[] = { 0x04, 47, + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x41, + 0x53, 0x4e, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x2c, 0x20, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x20, 0x31, 0x2e }; + + static byte genAttrOid2[] = { 0x06, 0x03, 0x2a, 0xab, 0x34 }; + static byte genAttr2[] = { 0x04, 47, + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x41, + 0x53, 0x4e, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x2c, 0x20, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x20, 0x32, 0x2e }; + + PKCS7Attrib attribs[] = + { + { genAttrOid, sizeof(genAttrOid), genAttr, sizeof(genAttr) } + }; + + PKCS7Attrib multiAttribs[] = + { + { genAttrOid, sizeof(genAttrOid), genAttr, sizeof(genAttr) }, + { genAttrOid2, sizeof(genAttrOid2), genAttr2, sizeof(genAttr2) } }; pkcs7Vector a, b; #ifndef NO_AES - pkcs7Vector c, d, e; - pkcs7Vector test_pkcs7enc[4]; + pkcs7Vector c, d, e, f, g; + pkcs7Vector test_pkcs7enc[7]; #else pkcs7Vector test_pkcs7enc[1]; #endif - int times = sizeof(test_pkcs7enc) / sizeof(pkcs7Vector), i; + int times = sizeof(test_pkcs7enc) / sizeof(pkcs7Vector); + int i, attribIdx; /* set up test vectors */ a.content = data; @@ -9270,6 +9308,8 @@ int pkcs7encrypted_test(void) a.encryptionKey = des3Key; a.encryptionKeySz = sizeof(des3Key); a.outFileName = "pkcs7encryptedDataDES3.der"; + a.attribs = NULL; + a.attribsSz = 0; b.content = data; b.contentSz = (word32)sizeof(data); @@ -9278,6 +9318,8 @@ int pkcs7encrypted_test(void) b.encryptionKey = desKey; b.encryptionKeySz = sizeof(desKey); b.outFileName = "pkcs7encryptedDataDES.der"; + b.attribs = NULL; + b.attribsSz = 0; #ifndef NO_AES c.content = data; @@ -9287,6 +9329,8 @@ int pkcs7encrypted_test(void) c.encryptionKey = aes128Key; c.encryptionKeySz = sizeof(aes128Key); c.outFileName = "pkcs7encryptedDataAES128CBC.der"; + c.attribs = NULL; + c.attribsSz = 0; d.content = data; d.contentSz = (word32)sizeof(data); @@ -9295,6 +9339,8 @@ int pkcs7encrypted_test(void) d.encryptionKey = aes192Key; d.encryptionKeySz = sizeof(aes192Key); d.outFileName = "pkcs7encryptedDataAES192CBC.der"; + d.attribs = NULL; + d.attribsSz = 0; e.content = data; e.contentSz = (word32)sizeof(data); @@ -9303,6 +9349,28 @@ int pkcs7encrypted_test(void) e.encryptionKey = aes256Key; e.encryptionKeySz = sizeof(aes256Key); e.outFileName = "pkcs7encryptedDataAES256CBC.der"; + e.attribs = NULL; + e.attribsSz = 0; + + f.content = data; + f.contentSz = (word32)sizeof(data); + f.contentOID = DATA; + f.encryptOID = AES256CBCb; + f.encryptionKey = aes256Key; + f.encryptionKeySz = sizeof(aes256Key); + f.outFileName = "pkcs7encryptedDataAES256CBC_attribs.der"; + f.attribs = attribs; + f.attribsSz = sizeof(attribs)/sizeof(PKCS7Attrib); + + g.content = data; + g.contentSz = (word32)sizeof(data); + g.contentOID = DATA; + g.encryptOID = AES256CBCb; + g.encryptionKey = aes256Key; + g.encryptionKeySz = sizeof(aes256Key); + g.outFileName = "pkcs7encryptedDataAES256CBC_multi_attribs.der"; + g.attribs = multiAttribs; + g.attribsSz = sizeof(multiAttribs)/sizeof(PKCS7Attrib); #endif test_pkcs7enc[0] = a; @@ -9311,6 +9379,8 @@ int pkcs7encrypted_test(void) test_pkcs7enc[2] = c; test_pkcs7enc[3] = d; test_pkcs7enc[4] = e; + test_pkcs7enc[5] = f; + test_pkcs7enc[6] = g; #endif for (i = 0; i < times; i++) { @@ -9320,6 +9390,8 @@ int pkcs7encrypted_test(void) pkcs7.encryptOID = test_pkcs7enc[i].encryptOID; pkcs7.encryptionKey = test_pkcs7enc[i].encryptionKey; pkcs7.encryptionKeySz = test_pkcs7enc[i].encryptionKeySz; + pkcs7.unprotectedAttribs = test_pkcs7enc[i].attribs; + pkcs7.unprotectedAttribsSz = test_pkcs7enc[i].attribsSz; /* encode encryptedData */ encryptedSz = wc_PKCS7_EncodeEncryptedData(&pkcs7, encrypted, @@ -9337,10 +9409,36 @@ int pkcs7encrypted_test(void) if (XMEMCMP(decoded, data, sizeof(data)) != 0) return -205; + /* verify decoded unprotected attributes */ + if (pkcs7.decodedAttrib != NULL) { + decodedAttrib = pkcs7.decodedAttrib; + attribIdx = 1; + + while (decodedAttrib != NULL) { + + /* expected attribute, stored list is reversed */ + expectedAttrib = &(pkcs7.unprotectedAttribs + [pkcs7.unprotectedAttribsSz - attribIdx]); + + /* verify oid */ + if (XMEMCMP(decodedAttrib->oid, expectedAttrib->oid, + decodedAttrib->oidSz) != 0) + return -206; + + /* verify value */ + if (XMEMCMP(decodedAttrib->value, expectedAttrib->value, + decodedAttrib->valueSz) != 0) + return -207; + + decodedAttrib = decodedAttrib->next; + attribIdx++; + } + } + /* output pkcs7 envelopedData for external testing */ pkcs7File = fopen(test_pkcs7enc[i].outFileName, "wb"); if (!pkcs7File) - return -206; + return -208; ret = (int)fwrite(encrypted, encryptedSz, 1, pkcs7File); fclose(pkcs7File); diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 6fba46a1a..357b24ea7 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -78,6 +78,15 @@ typedef struct PKCS7Attrib { } PKCS7Attrib; +typedef struct PKCS7DecodedAttrib { + byte* oid; + word32 oidSz; + byte* value; + word32 valueSz; + struct PKCS7DecodedAttrib* next; +} PKCS7DecodedAttrib; + + typedef struct PKCS7 { byte* content; /* inner content, not owner */ word32 contentSz; /* content size */ @@ -105,10 +114,11 @@ typedef struct PKCS7 { word32 signedAttribsSz; /* Encrypted-data Content Type */ - byte* encryptionKey; /* block cipher encryption key */ - word32 encryptionKeySz; /* size of key buffer, bytes */ + byte* encryptionKey; /* block cipher encryption key */ + word32 encryptionKeySz; /* size of key buffer, bytes */ PKCS7Attrib* unprotectedAttribs; /* optional */ - word32 unprotectedAttribsSz; + word32 unprotectedAttribsSz; + PKCS7DecodedAttrib* decodedAttrib; /* linked list of decoded attribs */ } PKCS7; @@ -133,6 +143,11 @@ WOLFSSL_LOCAL int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outS word32 blockSz); WOLFSSL_LOCAL int wc_PKCS7_GetOIDBlockSize(int oid); WOLFSSL_LOCAL int wc_PKCS7_GetOIDKeySize(int oid); +WOLFSSL_LOCAL int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, + byte* pkiMsg, word32 pkiMsgSz, + word32* inOutIdx); +WOLFSSL_LOCAL void wc_PKCS7_FreeDecodedAttrib(PKCS7DecodedAttrib* attrib, + void* heap); WOLFSSL_API int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz);