mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 19:54:40 +02:00
Merge pull request #607 from cconlon/pkcs7
add AES content encryption support to PKCS#7 EnvelopedData
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -85,7 +85,10 @@ certreq.der
|
|||||||
certreq.pem
|
certreq.pem
|
||||||
pkcs7cert.der
|
pkcs7cert.der
|
||||||
pkcs7signedData.der
|
pkcs7signedData.der
|
||||||
pkcs7envelopedData.der
|
pkcs7envelopedDataDES3.der
|
||||||
|
pkcs7envelopedDataAES128CBC.der
|
||||||
|
pkcs7envelopedDataAES192CBC.der
|
||||||
|
pkcs7envelopedDataAES256CBC.der
|
||||||
diff
|
diff
|
||||||
sslSniffer/sslSnifferTest/tracefile.txt
|
sslSniffer/sslSnifferTest/tracefile.txt
|
||||||
tracefile.txt
|
tracefile.txt
|
||||||
|
@@ -38,7 +38,10 @@ CLEANFILES+= cert.der \
|
|||||||
othercert.der \
|
othercert.der \
|
||||||
othercert.pem \
|
othercert.pem \
|
||||||
pkcs7cert.der \
|
pkcs7cert.der \
|
||||||
pkcs7envelopedData.der \
|
pkcs7envelopedDataDES3.der \
|
||||||
|
pkcs7envelopedDataAES128CBC.der \
|
||||||
|
pkcs7envelopedDataAES192CBC.der \
|
||||||
|
pkcs7envelopedDataAES256CBC.der \
|
||||||
pkcs7signedData.der
|
pkcs7signedData.der
|
||||||
|
|
||||||
exampledir = $(docdir)/example
|
exampledir = $(docdir)/example
|
||||||
|
@@ -783,6 +783,9 @@ static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
|
|||||||
#endif /* HAVE_ECC */
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
/* blkType */
|
/* blkType */
|
||||||
|
static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
|
||||||
|
static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
|
||||||
|
static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
|
||||||
static const byte blkDesCbcOid[] = {43, 14, 3, 2, 7};
|
static const byte blkDesCbcOid[] = {43, 14, 3, 2, 7};
|
||||||
static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
|
static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
|
||||||
|
|
||||||
@@ -959,6 +962,18 @@ static const byte* OidFromId(word32 id, word32 type, word32* oidSz)
|
|||||||
|
|
||||||
case oidBlkType:
|
case oidBlkType:
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
case AES128CBCb:
|
||||||
|
oid = blkAes128CbcOid;
|
||||||
|
*oidSz = sizeof(blkAes128CbcOid);
|
||||||
|
break;
|
||||||
|
case AES192CBCb:
|
||||||
|
oid = blkAes192CbcOid;
|
||||||
|
*oidSz = sizeof(blkAes192CbcOid);
|
||||||
|
break;
|
||||||
|
case AES256CBCb:
|
||||||
|
oid = blkAes256CbcOid;
|
||||||
|
*oidSz = sizeof(blkAes256CbcOid);
|
||||||
|
break;
|
||||||
case DESb:
|
case DESb:
|
||||||
oid = blkDesCbcOid;
|
oid = blkDesCbcOid;
|
||||||
*oidSz = sizeof(blkDesCbcOid);
|
*oidSz = sizeof(blkDesCbcOid);
|
||||||
|
@@ -1173,6 +1173,125 @@ WOLFSSL_LOCAL int wc_CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,
|
||||||
|
byte* iv, int ivSz, byte* in, int inSz,
|
||||||
|
byte* out)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
#ifndef NO_AES
|
||||||
|
Aes aes;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_DES3
|
||||||
|
Des des;
|
||||||
|
Des3 des3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (key == NULL || iv == NULL || in == NULL || out == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
switch (encryptOID) {
|
||||||
|
#ifndef NO_AES
|
||||||
|
case AES128CBCb:
|
||||||
|
case AES192CBCb:
|
||||||
|
case AES256CBCb:
|
||||||
|
if (ivSz != AES_BLOCK_SIZE)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_AesCbcEncrypt(&aes, out, in, inSz);
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_DES3
|
||||||
|
case DESb:
|
||||||
|
if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
ret = wc_Des_SetKey(&des, key, iv, DES_ENCRYPTION);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Des_CbcEncrypt(&des, out, in, inSz);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DES3b:
|
||||||
|
if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Des3_CbcEncrypt(&des3, out, in, inSz);
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("Unsupported content cipher type");
|
||||||
|
return ALGO_ID_E;
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz,
|
||||||
|
byte* iv, int ivSz, byte* in, int inSz,
|
||||||
|
byte* out)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
#ifndef NO_AES
|
||||||
|
Aes aes;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_DES3
|
||||||
|
Des des;
|
||||||
|
Des3 des3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (key == NULL || iv == NULL || in == NULL || out == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
switch (encryptOID) {
|
||||||
|
#ifndef NO_AES
|
||||||
|
case AES128CBCb:
|
||||||
|
case AES192CBCb:
|
||||||
|
case AES256CBCb:
|
||||||
|
if (ivSz != AES_BLOCK_SIZE)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
ret = wc_AesSetKey(&aes, key, keySz, iv, AES_DECRYPTION);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_AesCbcDecrypt(&aes, out, in, inSz);
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_DES3
|
||||||
|
case DESb:
|
||||||
|
if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Des_CbcDecrypt(&des, out, in, inSz);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case DES3b:
|
||||||
|
if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Des3_CbcDecrypt(&des3, out, in, inSz);
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("Unsupported content cipher type");
|
||||||
|
return ALGO_ID_E;
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* build PKCS#7 envelopedData content type, return enveloped size */
|
/* build PKCS#7 envelopedData content type, return enveloped size */
|
||||||
int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||||
{
|
{
|
||||||
@@ -1189,7 +1308,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
byte ver[MAX_VERSION_SZ];
|
byte ver[MAX_VERSION_SZ];
|
||||||
|
|
||||||
WC_RNG rng;
|
WC_RNG rng;
|
||||||
int contentKeyEncSz, blockKeySz;
|
int contentKeyEncSz, blockSz, blockKeySz;
|
||||||
byte contentKeyPlain[MAX_CONTENT_KEY_LEN];
|
byte contentKeyPlain[MAX_CONTENT_KEY_LEN];
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte* contentKeyEnc;
|
byte* contentKeyEnc;
|
||||||
@@ -1212,7 +1331,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
byte encContentSeq[MAX_SEQ_SZ];
|
byte encContentSeq[MAX_SEQ_SZ];
|
||||||
byte contentType[MAX_ALGO_SZ];
|
byte contentType[MAX_ALGO_SZ];
|
||||||
byte contentEncAlgo[MAX_ALGO_SZ];
|
byte contentEncAlgo[MAX_ALGO_SZ];
|
||||||
byte tmpIv[DES_BLOCK_SIZE];
|
byte tmpIv[MAX_CONTENT_IV_SIZE];
|
||||||
byte ivOctetString[MAX_OCTET_STR_SZ];
|
byte ivOctetString[MAX_OCTET_STR_SZ];
|
||||||
byte encContentOctet[MAX_OCTET_STR_SZ];
|
byte encContentOctet[MAX_OCTET_STR_SZ];
|
||||||
|
|
||||||
@@ -1223,14 +1342,31 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
if (output == NULL || outputSz == 0)
|
if (output == NULL || outputSz == 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* PKCS#7 only supports DES, 3DES for now */
|
/* wolfCrypt PKCS#7 supports AES-128/192/256-CBC, DES, 3DES for now */
|
||||||
switch (pkcs7->encryptOID) {
|
switch (pkcs7->encryptOID) {
|
||||||
|
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;
|
||||||
|
|
||||||
case DESb:
|
case DESb:
|
||||||
blockKeySz = DES_KEYLEN;
|
blockKeySz = DES_KEYLEN;
|
||||||
|
blockSz = DES_BLOCK_SIZE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DES3b:
|
case DES3b:
|
||||||
blockKeySz = DES3_KEYLEN;
|
blockKeySz = DES3_KEYLEN;
|
||||||
|
blockSz = DES_BLOCK_SIZE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1291,7 +1427,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
recipSetSz = SetSet(recipSz, recipSet);
|
recipSetSz = SetSet(recipSz, recipSet);
|
||||||
|
|
||||||
/* generate IV for block cipher */
|
/* generate IV for block cipher */
|
||||||
ret = wc_RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE);
|
ret = wc_RNG_GenerateBlock(&rng, tmpIv, blockSz);
|
||||||
wc_FreeRng(&rng);
|
wc_FreeRng(&rng);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
@@ -1310,7 +1446,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* allocate encrypted content buffer and PKCS#7 padding */
|
/* allocate encrypted content buffer and PKCS#7 padding */
|
||||||
padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE);
|
padSz = blockSz - (pkcs7->contentSz % blockSz);
|
||||||
desOutSz = pkcs7->contentSz + padSz;
|
desOutSz = pkcs7->contentSz + padSz;
|
||||||
|
|
||||||
plain = (byte*)XMALLOC(desOutSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
plain = (byte*)XMALLOC(desOutSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
@@ -1337,12 +1473,12 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* put together IV OCTET STRING */
|
/* put together IV OCTET STRING */
|
||||||
ivOctetStringSz = SetOctetString(DES_BLOCK_SIZE, ivOctetString);
|
ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
|
||||||
|
|
||||||
/* build up our ContentEncryptionAlgorithmIdentifier sequence,
|
/* build up our ContentEncryptionAlgorithmIdentifier sequence,
|
||||||
* adding (ivOctetStringSz + DES_BLOCK_SIZE) for IV OCTET STRING */
|
* adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
|
||||||
contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
|
contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
|
||||||
oidBlkType, ivOctetStringSz + DES_BLOCK_SIZE);
|
oidBlkType, ivOctetStringSz + blockSz);
|
||||||
|
|
||||||
if (contentEncAlgoSz == 0) {
|
if (contentEncAlgoSz == 0) {
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
@@ -1354,51 +1490,28 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* encrypt content */
|
/* encrypt content */
|
||||||
if (pkcs7->encryptOID == DESb) {
|
ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, contentKeyPlain,
|
||||||
Des des;
|
blockKeySz, tmpIv, blockSz, plain, desOutSz, encryptedContent);
|
||||||
|
|
||||||
ret = wc_Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION);
|
if (ret != 0) {
|
||||||
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (ret == 0)
|
XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
wc_Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
|
XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pkcs7->encryptOID == DES3b) {
|
|
||||||
Des3 des3;
|
|
||||||
|
|
||||||
ret = wc_Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION);
|
|
||||||
|
|
||||||
if (ret == 0)
|
|
||||||
ret = wc_Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
|
encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
|
||||||
desOutSz, encContentOctet);
|
desOutSz, encContentOctet);
|
||||||
|
|
||||||
encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
|
encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
|
||||||
ivOctetStringSz + DES_BLOCK_SIZE +
|
ivOctetStringSz + blockSz +
|
||||||
encContentOctetSz + desOutSz, encContentSeq);
|
encContentOctetSz + desOutSz, encContentSeq);
|
||||||
|
|
||||||
/* keep track of sizes for outer wrapper layering */
|
/* keep track of sizes for outer wrapper layering */
|
||||||
totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
|
totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
|
||||||
contentEncAlgoSz + ivOctetStringSz + DES_BLOCK_SIZE +
|
contentEncAlgoSz + ivOctetStringSz + blockSz +
|
||||||
encContentOctetSz + desOutSz;
|
encContentOctetSz + desOutSz;
|
||||||
|
|
||||||
/* EnvelopedData */
|
/* EnvelopedData */
|
||||||
@@ -1446,8 +1559,8 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
idx += contentEncAlgoSz;
|
idx += contentEncAlgoSz;
|
||||||
XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
|
XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
|
||||||
idx += ivOctetStringSz;
|
idx += ivOctetStringSz;
|
||||||
XMEMCPY(output + idx, tmpIv, DES_BLOCK_SIZE);
|
XMEMCPY(output + idx, tmpIv, blockSz);
|
||||||
idx += DES_BLOCK_SIZE;
|
idx += blockSz;
|
||||||
XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
|
XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
|
||||||
idx += encContentOctetSz;
|
idx += encContentOctetSz;
|
||||||
XMEMCPY(output + idx, encryptedContent, desOutSz);
|
XMEMCPY(output + idx, encryptedContent, desOutSz);
|
||||||
@@ -1476,8 +1589,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
word32 contentType, encOID;
|
word32 contentType, encOID;
|
||||||
byte issuerHash[SHA_DIGEST_SIZE];
|
byte issuerHash[SHA_DIGEST_SIZE];
|
||||||
|
|
||||||
int encryptedKeySz, keySz;
|
int encryptedKeySz, keySz, expBlockSz, blockKeySz;
|
||||||
byte tmpIv[DES_BLOCK_SIZE];
|
byte tmpIv[MAX_CONTENT_IV_SIZE];
|
||||||
byte* decryptedKey = NULL;
|
byte* decryptedKey = NULL;
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
@@ -1685,7 +1798,39 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
#endif
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wolfCrypt PKCS#7 supports AES-128-CBC, DES, 3DES for now */
|
||||||
|
switch(encOID) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
/* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
|
/* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
|
||||||
if (pkiMsg[idx++] != ASN_OCTET_STRING) {
|
if (pkiMsg[idx++] != ASN_OCTET_STRING) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
@@ -1701,8 +1846,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length != DES_BLOCK_SIZE) {
|
if (length != expBlockSz) {
|
||||||
WOLFSSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE");
|
WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
#endif
|
#endif
|
||||||
@@ -1743,7 +1888,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (privKey == NULL) {
|
if (privKey == NULL) {
|
||||||
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E;
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1802,43 +1948,15 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* decrypt encryptedContent */
|
/* decrypt encryptedContent */
|
||||||
if (encOID == DESb) {
|
ret = wc_PKCS7_DecryptContent(encOID, decryptedKey, blockKeySz,
|
||||||
Des des;
|
tmpIv, expBlockSz, encryptedContent,
|
||||||
ret = wc_Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
|
encryptedContentSz, encryptedContent);
|
||||||
|
if (ret != 0) {
|
||||||
if (ret == 0)
|
|
||||||
wc_Des_CbcDecrypt(&des, encryptedContent, encryptedContent,
|
|
||||||
encryptedContentSz);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (encOID == DES3b) {
|
|
||||||
Des3 des;
|
|
||||||
ret = wc_Des3_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
|
|
||||||
if (ret == 0)
|
|
||||||
ret = wc_Des3_CbcDecrypt(&des, encryptedContent, encryptedContent,
|
|
||||||
encryptedContentSz);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
WOLFSSL_MSG("Unsupported content encryption OID type");
|
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
#endif
|
#endif
|
||||||
return ALGO_ID_E;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
padLen = encryptedContent[encryptedContentSz-1];
|
padLen = encryptedContent[encryptedContentSz-1];
|
||||||
|
@@ -8520,11 +8520,20 @@ int compress_test(void)
|
|||||||
|
|
||||||
#ifdef HAVE_PKCS7
|
#ifdef HAVE_PKCS7
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* outFileName;
|
||||||
|
const byte* content;
|
||||||
|
word32 contentSz;
|
||||||
|
int contentOID;
|
||||||
|
int encryptOID;
|
||||||
|
byte* privateKey;
|
||||||
|
word32 privateKeySz;
|
||||||
|
} pkcs7EnvelopedVector;
|
||||||
|
|
||||||
int pkcs7enveloped_test(void)
|
int pkcs7enveloped_test(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
int cipher = DES3b;
|
|
||||||
int envelopedSz, decodedSz;
|
int envelopedSz, decodedSz;
|
||||||
PKCS7 pkcs7;
|
PKCS7 pkcs7;
|
||||||
byte* cert;
|
byte* cert;
|
||||||
@@ -8537,13 +8546,16 @@ int pkcs7enveloped_test(void)
|
|||||||
FILE* certFile;
|
FILE* certFile;
|
||||||
FILE* keyFile;
|
FILE* keyFile;
|
||||||
FILE* pkcs7File;
|
FILE* pkcs7File;
|
||||||
const char* pkcs7OutFile = "pkcs7envelopedData.der";
|
|
||||||
|
|
||||||
const byte data[] = { /* Hello World */
|
const byte data[] = { /* Hello World */
|
||||||
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
|
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
|
||||||
0x72,0x6c,0x64
|
0x72,0x6c,0x64
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pkcs7EnvelopedVector a, b, c, d;
|
||||||
|
pkcs7EnvelopedVector test_pkcs7env[4];
|
||||||
|
int times = sizeof(test_pkcs7env) / sizeof(pkcs7EnvelopedVector), 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);
|
||||||
if (cert == NULL)
|
if (cert == NULL)
|
||||||
@@ -8580,49 +8592,91 @@ int pkcs7enveloped_test(void)
|
|||||||
fclose(keyFile);
|
fclose(keyFile);
|
||||||
|
|
||||||
wc_PKCS7_InitWithCert(&pkcs7, cert, (word32)certSz);
|
wc_PKCS7_InitWithCert(&pkcs7, cert, (word32)certSz);
|
||||||
pkcs7.content = (byte*)data;
|
|
||||||
pkcs7.contentSz = (word32)sizeof(data);
|
|
||||||
pkcs7.contentOID = DATA;
|
|
||||||
pkcs7.encryptOID = cipher;
|
|
||||||
pkcs7.privateKey = privKey;
|
|
||||||
pkcs7.privateKeySz = (word32)privKeySz;
|
|
||||||
|
|
||||||
/* encode envelopedData */
|
/* set up test vectors */
|
||||||
envelopedSz = wc_PKCS7_EncodeEnvelopedData(&pkcs7, enveloped,
|
a.content = data;
|
||||||
sizeof(enveloped));
|
a.contentSz = (word32)sizeof(data);
|
||||||
if (envelopedSz <= 0) {
|
a.contentOID = DATA;
|
||||||
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
a.encryptOID = DES3b;
|
||||||
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
a.privateKey = privKey;
|
||||||
return -203;
|
a.privateKeySz = (word32)privKeySz;
|
||||||
|
a.outFileName = "pkcs7envelopedDataDES3.der";
|
||||||
|
|
||||||
|
b.content = data;
|
||||||
|
b.contentSz = (word32)sizeof(data);
|
||||||
|
b.contentOID = DATA;
|
||||||
|
b.encryptOID = AES128CBCb;
|
||||||
|
b.privateKey = privKey;
|
||||||
|
b.privateKeySz = (word32)privKeySz;
|
||||||
|
b.outFileName = "pkcs7envelopedDataAES128CBC.der";
|
||||||
|
|
||||||
|
c.content = data;
|
||||||
|
c.contentSz = (word32)sizeof(data);
|
||||||
|
c.contentOID = DATA;
|
||||||
|
c.encryptOID = AES192CBCb;
|
||||||
|
c.privateKey = privKey;
|
||||||
|
c.privateKeySz = (word32)privKeySz;
|
||||||
|
c.outFileName = "pkcs7envelopedDataAES192CBC.der";
|
||||||
|
|
||||||
|
d.content = data;
|
||||||
|
d.contentSz = (word32)sizeof(data);
|
||||||
|
d.contentOID = DATA;
|
||||||
|
d.encryptOID = AES256CBCb;
|
||||||
|
d.privateKey = privKey;
|
||||||
|
d.privateKeySz = (word32)privKeySz;
|
||||||
|
d.outFileName = "pkcs7envelopedDataAES256CBC.der";
|
||||||
|
|
||||||
|
test_pkcs7env[0] = a;
|
||||||
|
test_pkcs7env[1] = b;
|
||||||
|
test_pkcs7env[2] = c;
|
||||||
|
test_pkcs7env[3] = d;
|
||||||
|
|
||||||
|
for (i = 0; i < times; i++) {
|
||||||
|
pkcs7.content = (byte*)test_pkcs7env[i].content;
|
||||||
|
pkcs7.contentSz = test_pkcs7env[i].contentSz;
|
||||||
|
pkcs7.contentOID = test_pkcs7env[i].contentOID;
|
||||||
|
pkcs7.encryptOID = test_pkcs7env[i].encryptOID;
|
||||||
|
pkcs7.privateKey = test_pkcs7env[i].privateKey;
|
||||||
|
pkcs7.privateKeySz = test_pkcs7env[i].privateKeySz;
|
||||||
|
|
||||||
|
/* encode envelopedData */
|
||||||
|
envelopedSz = wc_PKCS7_EncodeEnvelopedData(&pkcs7, enveloped,
|
||||||
|
sizeof(enveloped));
|
||||||
|
if (envelopedSz <= 0) {
|
||||||
|
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
printf("envelopedSz = %d\n", envelopedSz);
|
||||||
|
return -203;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* decode envelopedData */
|
||||||
|
decodedSz = wc_PKCS7_DecodeEnvelopedData(&pkcs7, enveloped, envelopedSz,
|
||||||
|
decoded, sizeof(decoded));
|
||||||
|
if (decodedSz <= 0) {
|
||||||
|
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return -204;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test decode result */
|
||||||
|
if (XMEMCMP(decoded, data, sizeof(data)) != 0) {
|
||||||
|
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return -205;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* output pkcs7 envelopedData for external testing */
|
||||||
|
pkcs7File = fopen(test_pkcs7env[i].outFileName, "wb");
|
||||||
|
if (!pkcs7File) {
|
||||||
|
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return -206;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (int)fwrite(enveloped, envelopedSz, 1, pkcs7File);
|
||||||
|
fclose(pkcs7File);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decode envelopedData */
|
|
||||||
decodedSz = wc_PKCS7_DecodeEnvelopedData(&pkcs7, enveloped, envelopedSz,
|
|
||||||
decoded, sizeof(decoded));
|
|
||||||
if (decodedSz <= 0) {
|
|
||||||
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
return -204;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* test decode result */
|
|
||||||
if (XMEMCMP(decoded, data, sizeof(data)) != 0) {
|
|
||||||
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
return -205;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* output pkcs7 envelopedData for external testing */
|
|
||||||
pkcs7File = fopen(pkcs7OutFile, "wb");
|
|
||||||
if (!pkcs7File) {
|
|
||||||
XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
return -206;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = (int)fwrite(enveloped, envelopedSz, 1, pkcs7File);
|
|
||||||
fclose(pkcs7File);
|
|
||||||
|
|
||||||
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);
|
||||||
wc_PKCS7_Free(&pkcs7);
|
wc_PKCS7_Free(&pkcs7);
|
||||||
|
@@ -227,8 +227,11 @@ enum Hash_Sum {
|
|||||||
|
|
||||||
|
|
||||||
enum Block_Sum {
|
enum Block_Sum {
|
||||||
DESb = 69,
|
AES128CBCb = 414,
|
||||||
DES3b = 652
|
AES192CBCb = 434,
|
||||||
|
AES256CBCb = 454,
|
||||||
|
DESb = 69,
|
||||||
|
DES3b = 652
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -32,6 +32,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||||
#include <wolfssl/wolfcrypt/random.h>
|
#include <wolfssl/wolfcrypt/random.h>
|
||||||
|
#ifndef NO_AES
|
||||||
|
#include <wolfssl/wolfcrypt/aes.h>
|
||||||
|
#endif
|
||||||
#ifndef NO_DES3
|
#ifndef NO_DES3
|
||||||
#include <wolfssl/wolfcrypt/des3.h>
|
#include <wolfssl/wolfcrypt/des3.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -52,12 +55,14 @@ enum PKCS7_TYPES {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum Pkcs7_Misc {
|
enum Pkcs7_Misc {
|
||||||
PKCS7_NONCE_SZ = 16,
|
PKCS7_NONCE_SZ = 16,
|
||||||
MAX_ENCRYPTED_KEY_SZ = 512, /* max enc. key size, RSA <= 4096 */
|
MAX_ENCRYPTED_KEY_SZ = 512, /* max enc. key size, RSA <= 4096 */
|
||||||
MAX_CONTENT_KEY_LEN = DES3_KEYLEN, /* highest current cipher is 3DES */
|
MAX_CONTENT_KEY_LEN = 32, /* highest current cipher is AES-256-CBC */
|
||||||
MAX_RECIP_SZ = MAX_VERSION_SZ +
|
MAX_CONTENT_IV_SIZE = 16, /* highest current is AES128 */
|
||||||
MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ +
|
MAX_CONTENT_BLOCK_LEN = AES_BLOCK_SIZE,
|
||||||
MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ
|
MAX_RECIP_SZ = MAX_VERSION_SZ +
|
||||||
|
MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ +
|
||||||
|
MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -106,6 +111,12 @@ WOLFSSL_LOCAL int wc_CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||||||
WC_RNG* rng, byte* contentKeyPlain,
|
WC_RNG* rng, byte* contentKeyPlain,
|
||||||
byte* contentKeyEnc, int* keyEncSz,
|
byte* contentKeyEnc, int* keyEncSz,
|
||||||
byte* out, word32 outSz, void* heap);
|
byte* out, word32 outSz, void* heap);
|
||||||
|
WOLFSSL_LOCAL int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,
|
||||||
|
byte* iv, int ivSz, byte* in, int inSz,
|
||||||
|
byte* out);
|
||||||
|
WOLFSSL_LOCAL int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz,
|
||||||
|
byte* iv, int ivSz, byte* in, int inSz,
|
||||||
|
byte* out);
|
||||||
|
|
||||||
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);
|
||||||
|
Reference in New Issue
Block a user