save rid for kari callback

This commit is contained in:
Jacob Barthelmeh
2019-06-03 22:36:02 +07:00
parent 60fc9b3a1d
commit a25d04044a
3 changed files with 124 additions and 53 deletions

View File

@@ -1155,11 +1155,6 @@ void wc_PKCS7_Free(PKCS7* pkcs7)
pkcs7->contentTypeSz = 0; pkcs7->contentTypeSz = 0;
if (pkcs7->isDynamic) {
pkcs7->isDynamic = 0;
XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
}
if (pkcs7->signature) { if (pkcs7->signature) {
XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGANTURE); XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGANTURE);
pkcs7->signature = NULL; pkcs7->signature = NULL;
@@ -1175,6 +1170,11 @@ void wc_PKCS7_Free(PKCS7* pkcs7)
pkcs7->pkcs7Digest = NULL; pkcs7->pkcs7Digest = NULL;
pkcs7->pkcs7DigestSz = 0; pkcs7->pkcs7DigestSz = 0;
} }
if (pkcs7->isDynamic) {
pkcs7->isDynamic = 0;
XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
}
} }
@@ -7911,10 +7911,14 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
/* 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(pkiMsg + (*idx), length - 1, kari->senderKey);
if (ret != 0) {
ret = wc_EccPublicKeyDecode(pkiMsg, idx, kari->senderKey, *idx + length - 1);
if (ret != 0) if (ret != 0)
return ret; return ret;
}
else {
(*idx) += length - 1; (*idx) += length - 1;
}
return 0; return 0;
} }
@@ -7979,15 +7983,26 @@ static int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,
byte* pkiMsg, word32 pkiMsgSz, word32* idx, byte* pkiMsg, word32 pkiMsgSz, word32* idx,
word32* keyAgreeOID, word32* keyWrapOID) word32* keyAgreeOID, word32* keyWrapOID)
{ {
int length = 0;
word32 localIdx = *idx;
if (kari == NULL || pkiMsg == NULL || idx == NULL || if (kari == NULL || pkiMsg == NULL || idx == NULL ||
keyAgreeOID == NULL || keyWrapOID == NULL) keyAgreeOID == NULL || keyWrapOID == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* remove KeyEncryptionAlgorithmIdentifier */ /* remove KeyEncryptionAlgorithmIdentifier */
if (GetAlgoId(pkiMsg, idx, keyAgreeOID, oidCmsKeyAgreeType, if (GetSequence(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
pkiMsgSz) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
localIdx = *idx;
if (GetAlgoId(pkiMsg, &localIdx, keyAgreeOID, oidCmsKeyAgreeType,
pkiMsgSz) < 0) {
return ASN_PARSE_E;
}
if (localIdx < *idx + length) {
*idx = localIdx;
}
/* remove KeyWrapAlgorithm, stored in parameter of KeyEncAlgoId */ /* remove KeyWrapAlgorithm, stored in parameter of KeyEncAlgoId */
if (GetAlgoId(pkiMsg, idx, keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0) if (GetAlgoId(pkiMsg, idx, keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
@@ -8000,12 +8015,12 @@ static int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,
* if subject key ID matches, recipFound is set to 1 */ * if subject key ID matches, recipFound is set to 1 */
static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari, static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
byte* pkiMsg, word32 pkiMsgSz, word32* idx, byte* pkiMsg, word32 pkiMsgSz, word32* idx,
int* recipFound) int* recipFound, byte* rid)
{ {
int length; int length;
byte subjKeyId[KEYID_SIZE];
if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL) if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL ||
rid == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* remove RecipientKeyIdentifier IMPLICIT [0] */ /* remove RecipientKeyIdentifier IMPLICIT [0] */
@@ -8030,11 +8045,11 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
if (length != KEYID_SIZE) if (length != KEYID_SIZE)
return ASN_PARSE_E; return ASN_PARSE_E;
XMEMCPY(subjKeyId, pkiMsg + (*idx), KEYID_SIZE); XMEMCPY(rid, pkiMsg + (*idx), KEYID_SIZE);
(*idx) += length; (*idx) += length;
/* subject key id should match if recipient found */ /* subject key id should match if recipient found */
if (XMEMCMP(subjKeyId, kari->decoded->extSubjKeyId, KEYID_SIZE) == 0) { if (XMEMCMP(rid, kari->decoded->extSubjKeyId, KEYID_SIZE) == 0) {
*recipFound = 1; *recipFound = 1;
} }
@@ -8046,10 +8061,9 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
* if issuer and serial number match, recipFound is set to 1 */ * if issuer and serial number match, recipFound is set to 1 */
static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari, static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
byte* pkiMsg, word32 pkiMsgSz, word32* idx, byte* pkiMsg, word32 pkiMsgSz, word32* idx,
int* recipFound) int* recipFound, byte* rid)
{ {
int length, ret; int length, ret;
byte issuerHash[KEYID_SIZE];
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
mp_int* serial; mp_int* serial;
mp_int* recipSerial; mp_int* recipSerial;
@@ -8058,15 +8072,19 @@ static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
mp_int recipSerial[1]; mp_int recipSerial[1];
#endif #endif
if (rid == NULL) {
return BAD_FUNC_ARG;
}
/* remove IssuerAndSerialNumber */ /* remove IssuerAndSerialNumber */
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0) if (GetNameHash(pkiMsg, idx, rid, pkiMsgSz) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
/* if we found correct recipient, issuer hashes will match */ /* if we found correct recipient, issuer hashes will match */
if (XMEMCMP(issuerHash, kari->decoded->issuerHash, KEYID_SIZE) == 0) { if (XMEMCMP(rid, kari->decoded->issuerHash, KEYID_SIZE) == 0) {
*recipFound = 1; *recipFound = 1;
} }
@@ -8131,7 +8149,7 @@ static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari, static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
byte* pkiMsg, word32 pkiMsgSz, word32* idx, byte* pkiMsg, word32 pkiMsgSz, word32* idx,
int* recipFound, byte* encryptedKey, int* recipFound, byte* encryptedKey,
int* encryptedKeySz) int* encryptedKeySz, byte* rid)
{ {
int length; int length;
int ret = 0; int ret = 0;
@@ -8155,11 +8173,11 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
/* try to get RecipientKeyIdentifier */ /* try to get RecipientKeyIdentifier */
ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz, ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,
idx, recipFound); idx, recipFound, rid);
} else { } else {
/* try to get IssuerAndSerialNumber */ /* try to get IssuerAndSerialNumber */
ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz, ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz,
idx, recipFound); idx, recipFound, rid);
} }
/* if we don't have either option, malformed CMS */ /* if we don't have either option, malformed CMS */
@@ -8653,8 +8671,9 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
/* decrypt CEK with KEK */ /* decrypt CEK with KEK */
if (pkcs7->wrapCEKCb) { if (pkcs7->wrapCEKCb) {
keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, length, keyId, keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, length, keyId,
keyIdSz, decryptedKey, *decryptedKeySz, keyIdSz, NULL, 0, decryptedKey,
keyWrapOID, direction); *decryptedKeySz, keyWrapOID,
(int)PKCS7_KEKRI, direction);
} }
else { else {
keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, length, pkcs7->privateKey, keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, length, pkcs7->privateKey,
@@ -8700,6 +8719,7 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
int encryptedKeySz; int encryptedKeySz;
int direction = 0; int direction = 0;
word32 keyAgreeOID, keyWrapOID; word32 keyAgreeOID, keyWrapOID;
byte rid[KEYID_SIZE];
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
byte* encryptedKey; byte* encryptedKey;
@@ -8715,8 +8735,9 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
#endif #endif
WOLFSSL_ENTER("wc_PKCS7_DecryptKari"); WOLFSSL_ENTER("wc_PKCS7_DecryptKari");
if (pkcs7 == NULL || pkcs7->singleCert == NULL || if (pkcs7 == NULL || pkiMsg == NULL ||
pkcs7->singleCertSz == 0 || pkiMsg == NULL || ((pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) &&
pkcs7->wrapCEKCb == NULL) ||
idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) { idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@@ -8756,6 +8777,7 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
encryptedKeySz = MAX_ENCRYPTED_KEY_SZ; encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
/* parse cert and key */ /* parse cert and key */
if (pkcs7->singleCert != NULL) {
ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert, ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,
pkcs7->singleCertSz, pkcs7->privateKey, pkcs7->singleCertSz, pkcs7->privateKey,
pkcs7->privateKeySz); pkcs7->privateKeySz);
@@ -8766,6 +8788,7 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
#endif #endif
return ret; return ret;
} }
}
/* remove OriginatorIdentifierOrKey */ /* remove OriginatorIdentifierOrKey */
ret = wc_PKCS7_KariGetOriginatorIdentifierOrKey(kari, pkiMsg, ret = wc_PKCS7_KariGetOriginatorIdentifierOrKey(kari, pkiMsg,
@@ -8789,9 +8812,8 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
} }
/* remove KeyEncryptionAlgorithmIdentifier */ /* remove KeyEncryptionAlgorithmIdentifier */
ret = wc_PKCS7_KariGetKeyEncryptionAlgorithmId(kari, pkiMsg, pkiMsgSz, ret = wc_PKCS7_KariGetKeyEncryptionAlgorithmId(kari, pkiMsg,
idx, &keyAgreeOID, pkiMsgSz, idx, &keyAgreeOID, &keyWrapOID);
&keyWrapOID);
if (ret != 0) { if (ret != 0) {
wc_PKCS7_KariFree(kari); wc_PKCS7_KariFree(kari);
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
@@ -8830,7 +8852,7 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
/* remove RecipientEncryptedKeys */ /* remove RecipientEncryptedKeys */
ret = wc_PKCS7_KariGetRecipientEncryptedKeys(kari, pkiMsg, pkiMsgSz, ret = wc_PKCS7_KariGetRecipientEncryptedKeys(kari, pkiMsg, pkiMsgSz,
idx, recipFound, encryptedKey, &encryptedKeySz); idx, recipFound, encryptedKey, &encryptedKeySz, rid);
if (ret != 0) { if (ret != 0) {
wc_PKCS7_KariFree(kari); wc_PKCS7_KariFree(kari);
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
@@ -8839,6 +8861,45 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
return ret; return ret;
} }
/* decrypt CEK with KEK */
if (pkcs7->wrapCEKCb) {
word32 tmpKeySz = 0;
byte* tmpKeyDer = NULL;
ret = wc_ecc_export_x963(kari->senderKey, NULL, &tmpKeySz);
if (ret != LENGTH_ONLY_E) {
return ret;
}
/* buffer space for algorithm/curve */
tmpKeySz += MAX_SEQ_SZ;
tmpKeySz += 2 * MAX_ALGO_SZ;
/* buffer space for public key sequence */
tmpKeySz += MAX_SEQ_SZ;
tmpKeySz += TRAILING_ZERO;
tmpKeyDer = (byte*)XMALLOC(tmpKeySz, pkcs7->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (tmpKeyDer == NULL) {
return MEMORY_E;
}
ret = wc_EccPublicKeyToDer(kari->senderKey, tmpKeyDer,
tmpKeySz, 1);
if (ret < 0) {
XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
tmpKeySz = (word32)ret;
keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, encryptedKeySz,
rid, KEYID_SIZE, tmpKeyDer, tmpKeySz,
decryptedKey, *decryptedKeySz,
keyWrapOID, (int)PKCS7_KARI, direction);
XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
else {
/* create KEK */ /* create KEK */
ret = wc_PKCS7_KariGenerateKEK(kari, keyWrapOID, pkcs7->keyAgreeOID); ret = wc_PKCS7_KariGenerateKEK(kari, keyWrapOID, pkcs7->keyAgreeOID);
if (ret != 0) { if (ret != 0) {
@@ -8853,6 +8914,7 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
keySz = wc_PKCS7_KeyWrap(encryptedKey, encryptedKeySz, kari->kek, keySz = wc_PKCS7_KeyWrap(encryptedKey, encryptedKeySz, kari->kek,
kari->kekSz, decryptedKey, *decryptedKeySz, kari->kekSz, decryptedKey, *decryptedKeySz,
keyWrapOID, direction); keyWrapOID, direction);
}
if (keySz <= 0) { if (keySz <= 0) {
wc_PKCS7_KariFree(kari); wc_PKCS7_KariFree(kari);
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK

View File

@@ -22025,7 +22025,8 @@ static const byte altKey[] = {
}; };
static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId, static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId,
word32 keyIdSz, byte* out, word32 outSz, int keyWrapAlgo, int direction) word32 keyIdSz, byte* orginKey, word32 orginKeySz,
byte* out, word32 outSz, int keyWrapAlgo, int type, int direction)
{ {
int ret; int ret;
@@ -22041,6 +22042,10 @@ static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId,
return -1; return -1;
} }
if (type != (int)PKCS7_KEKRI) {
return -1;
}
switch (keyWrapAlgo) { switch (keyWrapAlgo) {
case AES256_WRAP: case AES256_WRAP:
ret = wc_AesKeyUnWrap(defKey, sizeof(defKey), cek, cekSz, ret = wc_AesKeyUnWrap(defKey, sizeof(defKey), cek, cekSz,
@@ -22056,6 +22061,8 @@ static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId,
(void)pkcs7; (void)pkcs7;
(void)direction; (void)direction;
(void)orginKey; /* used with KAKRI */
(void)orginKeySz;
return ret; return ret;
} }

View File

@@ -214,8 +214,10 @@ typedef int (*CallbackDecryptContent)(PKCS7* pkcs7, int encryptOID,
byte* authTag, word32 authTagSz, byte* in, byte* authTag, word32 authTagSz, byte* in,
int inSz, byte* out, void* ctx); int inSz, byte* out, void* ctx);
typedef int (*CallbackWrapCEK)(PKCS7* pkcs7, byte* cek, word32 cekSz, typedef int (*CallbackWrapCEK)(PKCS7* pkcs7, byte* cek, word32 cekSz,
byte* keyId, word32 keyIdSz, byte* out, byte* keyId, word32 keyIdSz,
word32 outSz, int keyWrapAlgo, int dir); byte* originKey, word32 originKeySz,
byte* out, word32 outSz,
int keyWrapAlgo, int type, int dir);
/* Public Structure Warning: /* Public Structure Warning:
* Existing members must not be changed to maintain backwards compatibility! * Existing members must not be changed to maintain backwards compatibility!