add PKCS7/CMS decode support for KARI with IssuerAndSerialNumber
This commit is contained in:
parent
e6f0ee84ec
commit
816b0b058c
@ -3513,27 +3513,18 @@ static int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,
|
||||
}
|
||||
|
||||
|
||||
/* remove ASN.1 RecipientEncryptedKeys, return 0 on success, < 0 on error */
|
||||
static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
|
||||
/* remove ASN.1 SubjectKeyIdentifier, return 0 on success, < 0 on error
|
||||
* if subject key ID matches, recipFound is set to 1 */
|
||||
static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
|
||||
byte* pkiMsg, word32 pkiMsgSz, word32* idx,
|
||||
int* recipFound, byte* encryptedKey,
|
||||
int* encryptedKeySz)
|
||||
int* recipFound)
|
||||
{
|
||||
int length;
|
||||
byte subjKeyId[KEYID_SIZE];
|
||||
|
||||
if (kari == NULL || pkiMsg == NULL || idx == NULL ||
|
||||
recipFound == NULL || encryptedKey == NULL)
|
||||
if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* remove RecipientEncryptedKeys */
|
||||
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* remove RecipientEncryptedKeys */
|
||||
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* remove RecipientKeyIdentifier IMPLICIT [0] */
|
||||
if ( (pkiMsgSz > (*idx + 1)) &&
|
||||
(pkiMsg[(*idx)++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) ) {
|
||||
@ -3564,6 +3555,137 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
|
||||
*recipFound = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* remove ASN.1 IssuerAndSerialNumber, return 0 on success, < 0 on error
|
||||
* if issuer and serial number match, recipFound is set to 1 */
|
||||
static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
|
||||
byte* pkiMsg, word32 pkiMsgSz, word32* idx,
|
||||
int* recipFound)
|
||||
{
|
||||
int length, ret;
|
||||
byte issuerHash[KEYID_SIZE];
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
mp_int* serial;
|
||||
mp_int* recipSerial;
|
||||
#else
|
||||
mp_int stack_serial;
|
||||
mp_int* serial = &stack_serial;
|
||||
|
||||
mp_int stack_recipSerial;
|
||||
mp_int* recipSerial = &stack_recipSerial;
|
||||
#endif
|
||||
|
||||
/* remove IssuerAndSerialNumber */
|
||||
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* if we found correct recipient, issuer hashes will match */
|
||||
if (XMEMCMP(issuerHash, kari->decoded->issuerHash, KEYID_SIZE) == 0) {
|
||||
*recipFound = 1;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
serial = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (serial == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
recipSerial = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (recipSerial == NULL) {
|
||||
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GetInt(serial, pkiMsg, idx, pkiMsgSz) < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(recipSerial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
ret = mp_read_unsigned_bin(recipSerial, kari->decoded->serial,
|
||||
kari->decoded->serialSz);
|
||||
if (ret != MP_OKAY) {
|
||||
mp_clear(serial);
|
||||
WOLFSSL_MSG("Failed to parse CMS recipient serial number");
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(recipSerial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mp_cmp(recipSerial, serial) != MP_EQ) {
|
||||
mp_clear(serial);
|
||||
mp_clear(recipSerial);
|
||||
WOLFSSL_MSG("CMS serial number does not match recipient");
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(recipSerial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return PKCS7_RECIP_E;
|
||||
}
|
||||
|
||||
mp_clear(serial);
|
||||
mp_clear(recipSerial);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(recipSerial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* remove ASN.1 RecipientEncryptedKeys, return 0 on success, < 0 on error */
|
||||
static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
|
||||
byte* pkiMsg, word32 pkiMsgSz, word32* idx,
|
||||
int* recipFound, byte* encryptedKey,
|
||||
int* encryptedKeySz)
|
||||
{
|
||||
int length;
|
||||
int ret = 0;
|
||||
|
||||
if (kari == NULL || pkiMsg == NULL || idx == NULL ||
|
||||
recipFound == NULL || encryptedKey == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* remove RecipientEncryptedKeys */
|
||||
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* remove RecipientEncryptedKeys */
|
||||
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber
|
||||
* or [0] IMMPLICIT RecipientKeyIdentifier */
|
||||
if ( (pkiMsgSz > (*idx + 1)) &&
|
||||
(pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) ) {
|
||||
|
||||
/* try to get RecipientKeyIdentifier */
|
||||
ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,
|
||||
idx, recipFound);
|
||||
} else {
|
||||
/* try to get IssuerAndSerialNumber */
|
||||
ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz,
|
||||
idx, recipFound);
|
||||
}
|
||||
|
||||
/* if we don't have either option, malformed CMS */
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* remove EncryptedKey */
|
||||
if ( (pkiMsgSz > (*idx + 1)) &&
|
||||
(pkiMsg[(*idx)++] != ASN_OCTET_STRING) )
|
||||
|
Loading…
x
Reference in New Issue
Block a user