PKCS#7: add support for optional unprotectedAttributes with EncryptedData

This commit is contained in:
Chris Conlon
2016-11-23 15:38:27 -07:00
parent abf18858a8
commit 5006306bb8
3 changed files with 351 additions and 38 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);