forked from wolfSSL/wolfssl
add PKCS#7/CMS EncryptedContent support
This commit is contained in:
@ -1982,6 +1982,362 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* build PKCS#7 encryptedData content type, return encrypted size */
|
||||||
|
int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||||
|
{
|
||||||
|
int i, ret, idx = 0;
|
||||||
|
int totalSz, padSz, desOutSz;
|
||||||
|
|
||||||
|
int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
|
||||||
|
byte contentInfoSeq[MAX_SEQ_SZ];
|
||||||
|
byte outerContentType[MAX_ALGO_SZ];
|
||||||
|
byte outerContent[MAX_SEQ_SZ];
|
||||||
|
|
||||||
|
int encDataSeqSz, verSz;
|
||||||
|
byte encDataSeq[MAX_SEQ_SZ];
|
||||||
|
byte ver[MAX_VERSION_SZ];
|
||||||
|
|
||||||
|
WC_RNG rng;
|
||||||
|
word32 blockSz, blockKeySz;
|
||||||
|
|
||||||
|
byte* plain;
|
||||||
|
byte* encryptedContent;
|
||||||
|
|
||||||
|
int encContentOctetSz, encContentSeqSz, contentTypeSz;
|
||||||
|
int contentEncAlgoSz, ivOctetStringSz;
|
||||||
|
byte encContentSeq[MAX_SEQ_SZ];
|
||||||
|
byte contentType[MAX_ALGO_SZ];
|
||||||
|
byte contentEncAlgo[MAX_ALGO_SZ];
|
||||||
|
byte tmpIv[MAX_CONTENT_IV_SIZE];
|
||||||
|
byte ivOctetString[MAX_OCTET_STR_SZ];
|
||||||
|
byte encContentOctet[MAX_OCTET_STR_SZ];
|
||||||
|
|
||||||
|
if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
|
||||||
|
pkcs7->encryptOID == 0 || pkcs7->encryptionKey == NULL ||
|
||||||
|
pkcs7->encryptionKeySz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (output == NULL || outputSz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
/* wolfCrypt EncryptedData supports AES-128/192/256-CBC, DES 3DES for now */
|
||||||
|
switch (pkcs7->encryptOID) {
|
||||||
|
#ifndef NO_AES
|
||||||
|
case AES128CBCb:
|
||||||
|
blockKeySz = 16;
|
||||||
|
blockSz = AES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AES192CBCb:
|
||||||
|
blockKeySz = 24;
|
||||||
|
blockSz = AES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AES256CBCb:
|
||||||
|
blockKeySz = 32;
|
||||||
|
blockSz = AES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case DESb:
|
||||||
|
blockKeySz = DES_KEYLEN;
|
||||||
|
blockSz = DES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DES3b:
|
||||||
|
blockKeySz = DES3_KEYLEN;
|
||||||
|
blockSz = DES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("Unsupported content cipher type");
|
||||||
|
return ALGO_ID_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkcs7->encryptionKeySz != blockKeySz) {
|
||||||
|
WOLFSSL_MSG("Encryption key wrong size for block cipher being used");
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* outer content type */
|
||||||
|
outerContentTypeSz = wc_SetContentType(ENCRYPTED_DATA, outerContentType);
|
||||||
|
|
||||||
|
/* version, 2 if unprotectedAttrs present, 0 if absent */
|
||||||
|
verSz = SetMyVersion(0, ver, 0);
|
||||||
|
|
||||||
|
/* generate IV for block cipher */
|
||||||
|
ret = wc_InitRng(&rng);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = wc_RNG_GenerateBlock(&rng, tmpIv, blockSz);
|
||||||
|
wc_FreeRng(&rng);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* EncryptedContentInfo */
|
||||||
|
contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType);
|
||||||
|
if (contentTypeSz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
/* allocate encrypted content buffer and PKCS#7 padding */
|
||||||
|
padSz = blockSz - (pkcs7->contentSz % blockSz);
|
||||||
|
desOutSz = pkcs7->contentSz + padSz;
|
||||||
|
|
||||||
|
plain = (byte*)XMALLOC(desOutSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (plain == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
XMEMCPY(plain, pkcs7->content, pkcs7->contentSz);
|
||||||
|
|
||||||
|
for (i = 0; i < padSz; i++) {
|
||||||
|
plain[pkcs7->contentSz + i] = (byte)padSz;
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedContent = (byte*)XMALLOC(desOutSz, pkcs7->heap,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (encryptedContent == NULL) {
|
||||||
|
XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put together IV OCTET STRING */
|
||||||
|
ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
|
||||||
|
|
||||||
|
/* build up ContentEncryptionAlgorithmIdentifier sequence,
|
||||||
|
adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
|
||||||
|
contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
|
||||||
|
oidBlkType, ivOctetStringSz + blockSz);
|
||||||
|
if (contentEncAlgoSz == 0) {
|
||||||
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encrypt content */
|
||||||
|
ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->encryptionKey,
|
||||||
|
pkcs7->encryptionKeySz, tmpIv, blockSz, plain, desOutSz,
|
||||||
|
encryptedContent);
|
||||||
|
if (ret != 0) {
|
||||||
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
|
||||||
|
desOutSz, encContentOctet);
|
||||||
|
|
||||||
|
encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
|
||||||
|
ivOctetStringSz + blockSz +
|
||||||
|
encContentOctetSz + desOutSz, encContentSeq);
|
||||||
|
|
||||||
|
/* keep track of sizes for outer wrapper layering */
|
||||||
|
totalSz = verSz + encContentSeqSz + contentTypeSz + contentEncAlgoSz +
|
||||||
|
ivOctetStringSz + blockSz + encContentOctetSz + desOutSz;
|
||||||
|
|
||||||
|
/* EncryptedData */
|
||||||
|
encDataSeqSz = SetSequence(totalSz, encDataSeq);
|
||||||
|
totalSz += encDataSeqSz;
|
||||||
|
|
||||||
|
/* outer content */
|
||||||
|
outerContentSz = SetExplicit(0, totalSz, outerContent);
|
||||||
|
totalSz += outerContentTypeSz;
|
||||||
|
totalSz += outerContentSz;
|
||||||
|
|
||||||
|
/* ContentInfo */
|
||||||
|
contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
|
||||||
|
totalSz += contentInfoSeqSz;
|
||||||
|
|
||||||
|
if (totalSz > (int)outputSz) {
|
||||||
|
WOLFSSL_MSG("PKCS#7 output buffer too small");
|
||||||
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
|
||||||
|
idx += contentInfoSeqSz;
|
||||||
|
XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
|
||||||
|
idx += outerContentTypeSz;
|
||||||
|
XMEMCPY(output + idx, outerContent, outerContentSz);
|
||||||
|
idx += outerContentSz;
|
||||||
|
XMEMCPY(output + idx, encDataSeq, encDataSeqSz);
|
||||||
|
idx += encDataSeqSz;
|
||||||
|
XMEMCPY(output + idx, ver, verSz);
|
||||||
|
idx += verSz;
|
||||||
|
XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
|
||||||
|
idx += encContentSeqSz;
|
||||||
|
XMEMCPY(output + idx, contentType, contentTypeSz);
|
||||||
|
idx += contentTypeSz;
|
||||||
|
XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
|
||||||
|
idx += contentEncAlgoSz;
|
||||||
|
XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
|
||||||
|
idx += ivOctetStringSz;
|
||||||
|
XMEMCPY(output + idx, tmpIv, blockSz);
|
||||||
|
idx += blockSz;
|
||||||
|
XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
|
||||||
|
idx += encContentOctetSz;
|
||||||
|
XMEMCPY(output + idx, encryptedContent, desOutSz);
|
||||||
|
idx += desOutSz;
|
||||||
|
|
||||||
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
word32 idx = 0;
|
||||||
|
word32 contentType, encOID;
|
||||||
|
|
||||||
|
int expBlockSz;
|
||||||
|
word32 blockKeySz;
|
||||||
|
byte tmpIv[MAX_CONTENT_IV_SIZE];
|
||||||
|
|
||||||
|
int encryptedContentSz;
|
||||||
|
byte padLen;
|
||||||
|
byte* encryptedContent = NULL;
|
||||||
|
|
||||||
|
if (pkcs7 == NULL || pkcs7->encryptionKey == NULL ||
|
||||||
|
pkcs7->encryptionKeySz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (pkiMsg == NULL || pkiMsgSz == 0 ||
|
||||||
|
output == NULL || outputSz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
/* read past ContentInfo, verify type is encrypted-data */
|
||||||
|
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (contentType != ENCRYPTED_DATA) {
|
||||||
|
WOLFSSL_MSG("PKCS#7 input not of type EncryptedData");
|
||||||
|
return PKCS7_OID_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
/* remove EncryptedData and version */
|
||||||
|
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType, pkiMsgSz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
/* wolfCrypt PKCS#7/CMS supports AES-128/192/256-CBC, DES, 3DES for now */
|
||||||
|
switch (encOID) {
|
||||||
|
#ifndef NO_AES
|
||||||
|
case AES128CBCb:
|
||||||
|
blockKeySz = 16;
|
||||||
|
expBlockSz = AES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AES192CBCb:
|
||||||
|
blockKeySz = 24;
|
||||||
|
expBlockSz = AES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AES256CBCb:
|
||||||
|
blockKeySz = 32;
|
||||||
|
expBlockSz = AES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case DESb:
|
||||||
|
blockKeySz = DES_KEYLEN;
|
||||||
|
expBlockSz = DES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DES3b:
|
||||||
|
blockKeySz = DES3_KEYLEN;
|
||||||
|
expBlockSz = DES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("Unsupported content cipher type");
|
||||||
|
return ALGO_ID_E;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pkcs7->encryptionKeySz != blockKeySz) {
|
||||||
|
WOLFSSL_MSG("Encryption key wrong size for block cipher being used");
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
|
||||||
|
if (pkiMsg[idx++] != ASN_OCTET_STRING)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (length != expBlockSz) {
|
||||||
|
WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(tmpIv, &pkiMsg[idx], length);
|
||||||
|
idx += length;
|
||||||
|
|
||||||
|
/* read encryptedContent, cont[0] */
|
||||||
|
if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0))
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (encryptedContent == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
|
||||||
|
|
||||||
|
/* decrypt encryptedContent */
|
||||||
|
ret = wc_PKCS7_DecryptContent(encOID, pkcs7->encryptionKey,
|
||||||
|
pkcs7->encryptionKeySz, tmpIv, expBlockSz,
|
||||||
|
encryptedContent, encryptedContentSz,
|
||||||
|
encryptedContent);
|
||||||
|
if (ret != 0) {
|
||||||
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
padLen = encryptedContent[encryptedContentSz-1];
|
||||||
|
|
||||||
|
/* copy plaintext to output */
|
||||||
|
XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
|
||||||
|
|
||||||
|
ForceZero(encryptedContent, encryptedContentSz);
|
||||||
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
return encryptedContentSz - padLen;
|
||||||
|
}
|
||||||
|
|
||||||
#else /* HAVE_PKCS7 */
|
#else /* HAVE_PKCS7 */
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,6 +238,7 @@ int pbkdf2_test(void);
|
|||||||
#ifdef HAVE_PKCS7
|
#ifdef HAVE_PKCS7
|
||||||
int pkcs7enveloped_test(void);
|
int pkcs7enveloped_test(void);
|
||||||
int pkcs7signed_test(void);
|
int pkcs7signed_test(void);
|
||||||
|
int pkcs7encrypted_test(void);
|
||||||
#endif
|
#endif
|
||||||
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT)
|
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT)
|
||||||
int certext_test(void);
|
int certext_test(void);
|
||||||
@ -707,6 +708,11 @@ int wolfcrypt_test(void* args)
|
|||||||
return err_sys("PKCS7signed test failed!\n", ret);
|
return err_sys("PKCS7signed test failed!\n", ret);
|
||||||
else
|
else
|
||||||
printf( "PKCS7signed test passed!\n");
|
printf( "PKCS7signed test passed!\n");
|
||||||
|
|
||||||
|
if ( (ret = pkcs7encrypted_test()) != 0)
|
||||||
|
return err_sys("PKCS7encrypted test failed!\n", ret);
|
||||||
|
else
|
||||||
|
printf( "PKCS7encrypted test passed!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY)
|
#if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY)
|
||||||
@ -9041,7 +9047,9 @@ typedef struct {
|
|||||||
int encryptOID;
|
int encryptOID;
|
||||||
byte* privateKey;
|
byte* privateKey;
|
||||||
word32 privateKeySz;
|
word32 privateKeySz;
|
||||||
} pkcs7EnvelopedVector;
|
byte* encryptionKey;
|
||||||
|
word32 encryptionKeySz;
|
||||||
|
} pkcs7Vector;
|
||||||
|
|
||||||
int pkcs7enveloped_test(void)
|
int pkcs7enveloped_test(void)
|
||||||
{
|
{
|
||||||
@ -9065,14 +9073,14 @@ int pkcs7enveloped_test(void)
|
|||||||
0x72,0x6c,0x64
|
0x72,0x6c,0x64
|
||||||
};
|
};
|
||||||
|
|
||||||
pkcs7EnvelopedVector a;
|
pkcs7Vector a;
|
||||||
#ifndef NO_AES
|
#ifndef NO_AES
|
||||||
pkcs7EnvelopedVector b, c, d;
|
pkcs7Vector b, c, d;
|
||||||
pkcs7EnvelopedVector test_pkcs7env[4];
|
pkcs7Vector test_pkcs7env[4];
|
||||||
#else
|
#else
|
||||||
pkcs7EnvelopedVector test_pkcs7env[1];
|
pkcs7Vector test_pkcs7env[1];
|
||||||
#endif
|
#endif
|
||||||
int times = sizeof(test_pkcs7env) / sizeof(pkcs7EnvelopedVector), i;
|
int times = sizeof(test_pkcs7env) / sizeof(pkcs7Vector), i;
|
||||||
|
|
||||||
/* read client cert and key in DER format */
|
/* read client cert and key in DER format */
|
||||||
cert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
cert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
@ -9167,7 +9175,6 @@ int pkcs7enveloped_test(void)
|
|||||||
if (envelopedSz <= 0) {
|
if (envelopedSz <= 0) {
|
||||||
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
printf("envelopedSz = %d\n", envelopedSz);
|
|
||||||
return -203;
|
return -203;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9209,6 +9216,144 @@ int pkcs7enveloped_test(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pkcs7encrypted_test(void)
|
||||||
|
{
|
||||||
|
int ret, encryptedSz, decodedSz;
|
||||||
|
PKCS7 pkcs7;
|
||||||
|
byte encrypted[2048];
|
||||||
|
byte decoded[2048];
|
||||||
|
FILE* pkcs7File;
|
||||||
|
|
||||||
|
const byte data[] = { /* Hello World */
|
||||||
|
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
|
||||||
|
0x72,0x6c,0x64
|
||||||
|
};
|
||||||
|
|
||||||
|
byte desKey[] = {
|
||||||
|
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
|
||||||
|
};
|
||||||
|
byte des3Key[] = {
|
||||||
|
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
|
||||||
|
0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
|
||||||
|
0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
|
||||||
|
};
|
||||||
|
byte aes128Key[] = {
|
||||||
|
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||||
|
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
|
||||||
|
};
|
||||||
|
byte aes192Key[] = {
|
||||||
|
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||||
|
0x01,0x02,0x03,0x05,0x05,0x06,0x07,0x08,
|
||||||
|
0x01,0x02,0x03,0x05,0x05,0x06,0x07,0x08
|
||||||
|
};
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
pkcs7Vector a, b;
|
||||||
|
#ifndef NO_AES
|
||||||
|
pkcs7Vector c, d, e;
|
||||||
|
pkcs7Vector test_pkcs7enc[4];
|
||||||
|
#else
|
||||||
|
pkcs7Vector test_pkcs7enc[1];
|
||||||
|
#endif
|
||||||
|
int times = sizeof(test_pkcs7enc) / sizeof(pkcs7Vector), i;
|
||||||
|
|
||||||
|
/* set up test vectors */
|
||||||
|
a.content = data;
|
||||||
|
a.contentSz = (word32)sizeof(data);
|
||||||
|
a.contentOID = DATA;
|
||||||
|
a.encryptOID = DES3b;
|
||||||
|
a.encryptionKey = des3Key;
|
||||||
|
a.encryptionKeySz = sizeof(des3Key);
|
||||||
|
a.outFileName = "pkcs7encryptedDataDES3.der";
|
||||||
|
|
||||||
|
b.content = data;
|
||||||
|
b.contentSz = (word32)sizeof(data);
|
||||||
|
b.contentOID = DATA;
|
||||||
|
b.encryptOID = DESb;
|
||||||
|
b.encryptionKey = desKey;
|
||||||
|
b.encryptionKeySz = sizeof(desKey);
|
||||||
|
b.outFileName = "pkcs7encryptedDataDES.der";
|
||||||
|
|
||||||
|
#ifndef NO_AES
|
||||||
|
c.content = data;
|
||||||
|
c.contentSz = (word32)sizeof(data);
|
||||||
|
c.contentOID = DATA;
|
||||||
|
c.encryptOID = AES128CBCb;
|
||||||
|
c.encryptionKey = aes128Key;
|
||||||
|
c.encryptionKeySz = sizeof(aes128Key);
|
||||||
|
c.outFileName = "pkcs7encryptedDataAES128CBC.der";
|
||||||
|
|
||||||
|
d.content = data;
|
||||||
|
d.contentSz = (word32)sizeof(data);
|
||||||
|
d.contentOID = DATA;
|
||||||
|
d.encryptOID = AES192CBCb;
|
||||||
|
d.encryptionKey = aes192Key;
|
||||||
|
d.encryptionKeySz = sizeof(aes192Key);
|
||||||
|
d.outFileName = "pkcs7encryptedDataAES192CBC.der";
|
||||||
|
|
||||||
|
e.content = data;
|
||||||
|
e.contentSz = (word32)sizeof(data);
|
||||||
|
e.contentOID = DATA;
|
||||||
|
e.encryptOID = AES256CBCb;
|
||||||
|
e.encryptionKey = aes256Key;
|
||||||
|
e.encryptionKeySz = sizeof(aes256Key);
|
||||||
|
e.outFileName = "pkcs7encryptedDataAES256CBC.der";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
test_pkcs7enc[0] = a;
|
||||||
|
test_pkcs7enc[1] = b;
|
||||||
|
#ifndef NO_AES
|
||||||
|
test_pkcs7enc[2] = c;
|
||||||
|
test_pkcs7enc[3] = d;
|
||||||
|
test_pkcs7enc[4] = e;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < times; i++) {
|
||||||
|
pkcs7.content = (byte*)test_pkcs7enc[i].content;
|
||||||
|
pkcs7.contentSz = test_pkcs7enc[i].contentSz;
|
||||||
|
pkcs7.contentOID = test_pkcs7enc[i].contentOID;
|
||||||
|
pkcs7.encryptOID = test_pkcs7enc[i].encryptOID;
|
||||||
|
pkcs7.encryptionKey = test_pkcs7enc[i].encryptionKey;
|
||||||
|
pkcs7.encryptionKeySz = test_pkcs7enc[i].encryptionKeySz;
|
||||||
|
|
||||||
|
/* encode encryptedData */
|
||||||
|
encryptedSz = wc_PKCS7_EncodeEncryptedData(&pkcs7, encrypted,
|
||||||
|
sizeof(encrypted));
|
||||||
|
if (encryptedSz <= 0)
|
||||||
|
return -203;
|
||||||
|
|
||||||
|
/* decode encryptedData */
|
||||||
|
decodedSz = wc_PKCS7_DecodeEncryptedData(&pkcs7, encrypted, encryptedSz,
|
||||||
|
decoded, sizeof(decoded));
|
||||||
|
if (decodedSz <= 0)
|
||||||
|
return -204;
|
||||||
|
|
||||||
|
/* test decode result */
|
||||||
|
if (XMEMCMP(decoded, data, sizeof(data)) != 0)
|
||||||
|
return -205;
|
||||||
|
|
||||||
|
/* output pkcs7 envelopedData for external testing */
|
||||||
|
pkcs7File = fopen(test_pkcs7enc[i].outFileName, "wb");
|
||||||
|
if (!pkcs7File)
|
||||||
|
return -206;
|
||||||
|
|
||||||
|
ret = (int)fwrite(encrypted, encryptedSz, 1, pkcs7File);
|
||||||
|
fclose(pkcs7File);
|
||||||
|
}
|
||||||
|
|
||||||
|
wc_PKCS7_Free(&pkcs7);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int pkcs7signed_test(void)
|
int pkcs7signed_test(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -103,6 +103,12 @@ typedef struct PKCS7 {
|
|||||||
|
|
||||||
PKCS7Attrib* signedAttribs;
|
PKCS7Attrib* signedAttribs;
|
||||||
word32 signedAttribsSz;
|
word32 signedAttribsSz;
|
||||||
|
|
||||||
|
/* Encrypted-data Content Type */
|
||||||
|
byte* encryptionKey; /* block cipher encryption key */
|
||||||
|
word32 encryptionKeySz; /* size of key buffer, bytes */
|
||||||
|
PKCS7Attrib* unprotectedAttribs; /* optional */
|
||||||
|
word32 unprotectedAttribsSz;
|
||||||
} PKCS7;
|
} PKCS7;
|
||||||
|
|
||||||
|
|
||||||
@ -124,7 +130,8 @@ WOLFSSL_LOCAL int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz,
|
|||||||
|
|
||||||
WOLFSSL_API int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz);
|
WOLFSSL_API int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz);
|
||||||
WOLFSSL_API void wc_PKCS7_Free(PKCS7* pkcs7);
|
WOLFSSL_API void wc_PKCS7_Free(PKCS7* pkcs7);
|
||||||
WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz);
|
WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
|
||||||
|
word32 outputSz);
|
||||||
WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
||||||
byte* output, word32 outputSz);
|
byte* output, word32 outputSz);
|
||||||
WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
|
WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
|
||||||
@ -134,7 +141,11 @@ WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
|
|||||||
WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
||||||
word32 pkiMsgSz, byte* output,
|
word32 pkiMsgSz, byte* output,
|
||||||
word32 outputSz);
|
word32 outputSz);
|
||||||
|
WOLFSSL_API int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7,
|
||||||
|
byte* output, word32 outputSz);
|
||||||
|
WOLFSSL_API int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg,
|
||||||
|
word32 pkiMsgSz, byte* output,
|
||||||
|
word32 outputSz);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user