forked from wolfSSL/wolfssl
PKCS#7: add support for optional unprotectedAttributes with EncryptedData
This commit is contained in:
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user