forked from wolfSSL/wolfssl
Merge pull request #2397 from JacobBarthelmeh/PKCS7
updates to CMS and callback functions
This commit is contained in:
135
tests/api.c
135
tests/api.c
@@ -16649,6 +16649,108 @@ static void test_wc_PKCS7_VerifySignedData(void)
|
|||||||
} /* END test_wc_PKCS7_VerifySignedData() */
|
} /* END test_wc_PKCS7_VerifySignedData() */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_PKCS7) && !defined(NO_AES) && !defined(NO_AES_256)
|
||||||
|
static const byte defKey[] = {
|
||||||
|
0x01,0x02,0x03,0x04,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
|
||||||
|
};
|
||||||
|
static byte aesHandle[32]; /* simulated hardware key handle */
|
||||||
|
|
||||||
|
/* return 0 on success */
|
||||||
|
static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz,
|
||||||
|
byte* aad, word32 aadSz, byte* authTag, word32 authTagSz,
|
||||||
|
byte* in, int inSz, byte* out, void* usrCtx)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Aes aes;
|
||||||
|
|
||||||
|
if (usrCtx == NULL) {
|
||||||
|
/* no simulated handle passed in */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (encryptOID) {
|
||||||
|
case AES256CBCb:
|
||||||
|
if (ivSz != AES_BLOCK_SIZE)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("Unsupported content cipher type for test");
|
||||||
|
return ALGO_ID_E;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* simulate using handle to get key */
|
||||||
|
ret = wc_AesInit(&aes, HEAP_HINT, INVALID_DEVID);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_AesSetKey(&aes, (byte*)usrCtx, 32, iv, AES_DECRYPTION);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_AesCbcDecrypt(&aes, out, in, inSz);
|
||||||
|
wc_AesFree(&aes);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)aad;
|
||||||
|
(void)aadSz;
|
||||||
|
(void)authTag;
|
||||||
|
(void)authTagSz;
|
||||||
|
(void)pkcs7;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* returns key size on success */
|
||||||
|
static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId,
|
||||||
|
word32 keyIdSz, byte* orginKey, word32 orginKeySz,
|
||||||
|
byte* out, word32 outSz, int keyWrapAlgo, int type, int direction)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (out == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (keyId[0] != 0x00) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != (int)PKCS7_KEKRI) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (keyWrapAlgo) {
|
||||||
|
case AES256_WRAP:
|
||||||
|
/* simulate setting a handle for later decryption but use key
|
||||||
|
* as handle in the test case here */
|
||||||
|
ret = wc_AesKeyUnWrap(defKey, sizeof(defKey), cek, cekSz,
|
||||||
|
aesHandle, sizeof(aesHandle), NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = wc_PKCS7_SetDecodeEncryptedCtx(pkcs7, (void*)aesHandle);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* return key size on success */
|
||||||
|
return sizeof(defKey);
|
||||||
|
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("Unsupported key wrap algorithm in example");
|
||||||
|
return BAD_KEYWRAP_ALG_E;
|
||||||
|
};
|
||||||
|
|
||||||
|
(void)cekSz;
|
||||||
|
(void)cek;
|
||||||
|
(void)outSz;
|
||||||
|
(void)keyIdSz;
|
||||||
|
(void)direction;
|
||||||
|
(void)orginKey; /* used with KAKRI */
|
||||||
|
(void)orginKeySz;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_PKCS7 && !NO_AES && !NO_AES_256 */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Testing wc_PKCS7_EncodeEnvelopedData()
|
* Testing wc_PKCS7_EncodeEnvelopedData()
|
||||||
*/
|
*/
|
||||||
@@ -16904,10 +17006,39 @@ static void test_wc_PKCS7_EncodeDecodeEnvelopedData (void)
|
|||||||
AssertIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
|
AssertIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
|
||||||
(word32)sizeof(output), decoded, (word32)sizeof(decoded)), BAD_FUNC_ARG);
|
(word32)sizeof(output), decoded, (word32)sizeof(decoded)), BAD_FUNC_ARG);
|
||||||
pkcs7->privateKey = tmpBytePtr;
|
pkcs7->privateKey = tmpBytePtr;
|
||||||
|
wc_PKCS7_Free(pkcs7);
|
||||||
|
|
||||||
|
#if !defined(NO_AES) && !defined(NO_AES_256)
|
||||||
|
/* test of decrypt callback with KEKRI enveloped data */
|
||||||
|
{
|
||||||
|
int envelopedSz;
|
||||||
|
const byte keyId[] = { 0x00 };
|
||||||
|
|
||||||
|
AssertNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, devId));
|
||||||
|
pkcs7->content = (byte*)input;
|
||||||
|
pkcs7->contentSz = (word32)(sizeof(input)/sizeof(char));
|
||||||
|
pkcs7->contentOID = DATA;
|
||||||
|
pkcs7->encryptOID = AES256CBCb;
|
||||||
|
AssertIntGT(wc_PKCS7_AddRecipient_KEKRI(pkcs7, AES256_WRAP,
|
||||||
|
(byte*)defKey, sizeof(defKey), (byte*)keyId,
|
||||||
|
sizeof(keyId), NULL, NULL, 0, NULL, 0, 0), 0);
|
||||||
|
AssertIntEQ(wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID), 0);
|
||||||
|
AssertIntGT((envelopedSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, output,
|
||||||
|
(word32)sizeof(output))), 0);
|
||||||
|
wc_PKCS7_Free(pkcs7);
|
||||||
|
|
||||||
|
/* decode envelopedData */
|
||||||
|
AssertNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, devId));
|
||||||
|
AssertIntEQ(wc_PKCS7_SetWrapCEKCb(pkcs7, myCEKwrapFunc), 0);
|
||||||
|
AssertIntEQ(wc_PKCS7_SetDecodeEncryptedCb(pkcs7, myDecryptionFunc), 0);
|
||||||
|
AssertIntGT((decodedSz = wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
|
||||||
|
envelopedSz, decoded, sizeof(decoded))), 0);
|
||||||
|
wc_PKCS7_Free(pkcs7);
|
||||||
|
}
|
||||||
|
#endif /* !NO_AES && !NO_AES_256 */
|
||||||
|
|
||||||
|
|
||||||
printf(resultFmt, passed);
|
printf(resultFmt, passed);
|
||||||
|
|
||||||
wc_PKCS7_Free(pkcs7);
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
if (rsaCert) {
|
if (rsaCert) {
|
||||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
@@ -6330,11 +6330,11 @@ static int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* decrypt content using encryptOID algo */
|
/* decrypt content using encryptOID algo
|
||||||
static int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz,
|
* returns 0 on success */
|
||||||
byte* iv, int ivSz, byte* aad, word32 aadSz,
|
static int wc_PKCS7_DecryptContent(PKCS7* pkcs7, int encryptOID, byte* key,
|
||||||
byte* authTag, word32 authTagSz, byte* in,
|
int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag,
|
||||||
int inSz, byte* out)
|
word32 authTagSz, byte* in, int inSz, byte* out)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
#ifndef NO_AES
|
#ifndef NO_AES
|
||||||
@@ -6345,7 +6345,16 @@ static int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz,
|
|||||||
Des3 des3;
|
Des3 des3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (key == NULL || iv == NULL || in == NULL || out == NULL)
|
if (iv == NULL || in == NULL || out == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (pkcs7->decryptionCb != NULL) {
|
||||||
|
return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz,
|
||||||
|
aad, aadSz, authTag, authTagSz, in,
|
||||||
|
inSz, out, pkcs7->decryptionCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
switch (encryptOID) {
|
switch (encryptOID) {
|
||||||
@@ -6852,23 +6861,22 @@ static int wc_PKCS7_PwriKek_KeyUnWrap(PKCS7* pkcs7, const byte* kek,
|
|||||||
tmpIv = lastBlock - blockSz;
|
tmpIv = lastBlock - blockSz;
|
||||||
|
|
||||||
/* decrypt last block */
|
/* decrypt last block */
|
||||||
ret = wc_PKCS7_DecryptContent(algID, (byte*)kek, kekSz, tmpIv, blockSz,
|
ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, tmpIv,
|
||||||
NULL, 0, NULL, 0, lastBlock, blockSz,
|
blockSz, NULL, 0, NULL, 0, lastBlock, blockSz,
|
||||||
outTmp + inSz - blockSz);
|
outTmp + inSz - blockSz);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* using last decrypted block as IV, decrypt [0 ... n-1] blocks */
|
/* using last decrypted block as IV, decrypt [0 ... n-1] blocks */
|
||||||
lastBlock = outTmp + inSz - blockSz;
|
lastBlock = outTmp + inSz - blockSz;
|
||||||
ret = wc_PKCS7_DecryptContent(algID, (byte*)kek, kekSz, lastBlock,
|
ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
|
||||||
blockSz, NULL, 0, NULL, 0, (byte*)in,
|
lastBlock, blockSz, NULL, 0, NULL, 0, (byte*)in, inSz - blockSz,
|
||||||
inSz - blockSz, outTmp);
|
outTmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* decrypt using original kek and iv */
|
/* decrypt using original kek and iv */
|
||||||
ret = wc_PKCS7_DecryptContent(algID, (byte*)kek, kekSz, (byte*)iv,
|
ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
|
||||||
ivSz, NULL, 0, NULL, 0, outTmp, inSz,
|
(byte*)iv, ivSz, NULL, 0, NULL, 0, outTmp, inSz, outTmp);
|
||||||
outTmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@@ -8046,7 +8054,8 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
|
|||||||
byte* pkiMsg, word32 pkiMsgSz, word32* idx)
|
byte* pkiMsg, word32 pkiMsgSz, word32* idx)
|
||||||
{
|
{
|
||||||
int ret, length;
|
int ret, length;
|
||||||
word32 keyOID;
|
word32 keyOID, oidSum = 0;
|
||||||
|
int curve_id = ECC_CURVE_DEF;
|
||||||
|
|
||||||
if (kari == NULL || pkiMsg == NULL || idx == NULL)
|
if (kari == NULL || pkiMsg == NULL || idx == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
@@ -8078,6 +8087,15 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
|
|||||||
if (keyOID != ECDSAk)
|
if (keyOID != ECDSAk)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
/* optional algorithm parameters */
|
||||||
|
ret = GetObjectId(pkiMsg, idx, &oidSum, oidIgnoreType, pkiMsgSz);
|
||||||
|
if (ret == 0) {
|
||||||
|
/* get curve id */
|
||||||
|
curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
|
||||||
|
if (curve_id < 0)
|
||||||
|
return ECC_CURVE_OID_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* remove ECPoint BIT STRING */
|
/* remove ECPoint BIT STRING */
|
||||||
if ((pkiMsgSz > (*idx + 1)) && (pkiMsg[(*idx)++] != ASN_BIT_STRING))
|
if ((pkiMsgSz > (*idx + 1)) && (pkiMsg[(*idx)++] != ASN_BIT_STRING))
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
@@ -8096,7 +8114,8 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
|
|||||||
kari->senderKeyInit = 1;
|
kari->senderKeyInit = 1;
|
||||||
|
|
||||||
/* length-1 for unused bits counter */
|
/* length-1 for unused bits counter */
|
||||||
ret = wc_ecc_import_x963(pkiMsg + (*idx), length - 1, kari->senderKey);
|
ret = wc_ecc_import_x963_ex(pkiMsg + (*idx), length - 1, kari->senderKey,
|
||||||
|
curve_id);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ret = wc_EccPublicKeyDecode(pkiMsg, idx, kari->senderKey, *idx + length - 1);
|
ret = wc_EccPublicKeyDecode(pkiMsg, idx, kari->senderKey, *idx + length - 1);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
@@ -9028,11 +9047,18 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
WOLFSSL_MSG("AES key wrap algorithm unsupported");
|
||||||
|
if (pkcs7->wrapCEKCb) {
|
||||||
|
WOLFSSL_MSG("Direction not set!");
|
||||||
|
break; /* if unwrapping callback is set then do not
|
||||||
|
* force restriction of supported wrap
|
||||||
|
* algorithms */
|
||||||
|
}
|
||||||
|
|
||||||
wc_PKCS7_KariFree(kari);
|
wc_PKCS7_KariFree(kari);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||||
#endif
|
#endif
|
||||||
WOLFSSL_MSG("AES key wrap algorithm unsupported");
|
|
||||||
return BAD_KEYWRAP_ALG_E;
|
return BAD_KEYWRAP_ALG_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9084,6 +9110,14 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
|
|||||||
decryptedKey, *decryptedKeySz,
|
decryptedKey, *decryptedKeySz,
|
||||||
keyWrapOID, (int)PKCS7_KARI, direction);
|
keyWrapOID, (int)PKCS7_KARI, direction);
|
||||||
XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
if (keySz > 0) {
|
||||||
|
/* If unwrapping was successful then consider recipient
|
||||||
|
* found. Checking for NULL singleCert to confirm previous
|
||||||
|
* SID check was not done */
|
||||||
|
if (pkcs7->singleCert == NULL)
|
||||||
|
*recipFound = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* create KEK */
|
/* create KEK */
|
||||||
@@ -9955,10 +9989,9 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* decrypt encryptedContent */
|
/* decrypt encryptedContent */
|
||||||
ret = wc_PKCS7_DecryptContent(encOID, decryptedKey, blockKeySz,
|
ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
|
||||||
tmpIv, expBlockSz, NULL, 0, NULL, 0,
|
blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0,
|
||||||
encryptedContent, encryptedContentSz,
|
encryptedContent, encryptedContentSz, encryptedContent);
|
||||||
encryptedContent);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||||
break;
|
break;
|
||||||
@@ -11038,11 +11071,10 @@ authenv_atrbend:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* decrypt encryptedContent */
|
/* decrypt encryptedContent */
|
||||||
ret = wc_PKCS7_DecryptContent(encOID, decryptedKey, blockKeySz,
|
ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
|
||||||
nonce, nonceSz, encodedAttribs,
|
blockKeySz, nonce, nonceSz, encodedAttribs, encodedAttribSz,
|
||||||
encodedAttribSz, authTag, authTagSz,
|
authTag, authTagSz, encryptedContent, encryptedContentSz,
|
||||||
encryptedContent, encryptedContentSz,
|
encryptedContent);
|
||||||
encryptedContent);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -11699,18 +11731,10 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
|
|||||||
|
|
||||||
/* decrypt encryptedContent */
|
/* decrypt encryptedContent */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (pkcs7->decryptionCb != NULL) {
|
ret = wc_PKCS7_DecryptContent(pkcs7, encOID,
|
||||||
ret = pkcs7->decryptionCb(pkcs7, encOID, tmpIv, expBlockSz,
|
pkcs7->encryptionKey, pkcs7->encryptionKeySz, tmpIv,
|
||||||
NULL, 0, NULL, 0, encryptedContent,
|
expBlockSz, NULL, 0, NULL, 0, encryptedContent,
|
||||||
encryptedContentSz, encryptedContent,
|
encryptedContentSz, encryptedContent);
|
||||||
pkcs7->decryptionCtx);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ret = wc_PKCS7_DecryptContent(encOID, pkcs7->encryptionKey,
|
|
||||||
pkcs7->encryptionKeySz, tmpIv, expBlockSz,
|
|
||||||
NULL, 0, NULL, 0, encryptedContent,
|
|
||||||
encryptedContentSz, encryptedContent);
|
|
||||||
}
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user