From 75349bbba5e6dce290ec61301a5927067415b4c7 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Tue, 18 Sep 2018 10:12:28 -0600 Subject: [PATCH] add support for SubjectKeyIdentifier to KTRI CMS RecipientInfo types --- .gitignore | 2 + Makefile.am | 2 + wolfcrypt/src/pkcs7.c | 295 +++++++++++++++++++++++++------------- wolfcrypt/test/test.c | 102 ++++++++----- wolfssl/wolfcrypt/pkcs7.h | 17 +-- 5 files changed, 277 insertions(+), 141 deletions(-) diff --git a/.gitignore b/.gitignore index 477bcf0c9..570a4406c 100644 --- a/.gitignore +++ b/.gitignore @@ -118,6 +118,8 @@ pkcs7envelopedDataAES128CBC_PWRI.der pkcs7envelopedDataAES128CBC_ORI.der pkcs7envelopedDataAES192CBC.der pkcs7envelopedDataAES256CBC.der +pkcs7envelopedDataAES256CBC_IANDS.der +pkcs7envelopedDataAES256CBC_SKID.der pkcs7envelopedDataAES256CBC_ECDH_SHA256KDF.der pkcs7envelopedDataAES256CBC_ECDH_SHA512KDF.der pkcs7envelopedDataAES256CBC_ECDH_SHA512KDF_ukm.der diff --git a/Makefile.am b/Makefile.am index 8f01ce5aa..08a60d8b8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -61,6 +61,8 @@ CLEANFILES+= cert.der \ pkcs7envelopedDataAES128CBC_ORI.der \ pkcs7envelopedDataAES192CBC.der \ pkcs7envelopedDataAES256CBC.der \ + pkcs7envelopedDataAES256CBC_IANDS.der \ + pkcs7envelopedDataAES256CBC_SKID.der \ pkcs7signedData_RSA_SHA.der \ pkcs7signedData_RSA_SHA_noattr.der \ pkcs7signedData_RSA_SHA224.der \ diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index fbd9dbae8..808e2c0b2 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -487,7 +487,7 @@ int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz) XMEMCPY(pkcs7->issuerSubjKeyId, dCert->extSubjKeyId, KEYID_SIZE); /* default to IssuerAndSerialNumber for SignerIdentifier */ - pkcs7->sidType = SID_ISSUER_AND_SERIAL_NUMBER; + pkcs7->sidType = CMS_ISSUER_AND_SERIAL_NUMBER; /* free existing recipient list if existing */ wc_PKCS7_FreeEncodedRecipientSet(pkcs7); @@ -1373,7 +1373,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->contentInfoSeq); /* SignerIdentifier */ - if (pkcs7->sidType == SID_ISSUER_AND_SERIAL_NUMBER) { + if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { /* IssuerAndSerialNumber */ esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, esd->issuerSn, MAX_SN_SZ); @@ -1386,7 +1386,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, /* version MUST be 1 */ esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0); - } else if (pkcs7->sidType == SID_SUBJECT_KEY_IDENTIFIER) { + } else if (pkcs7->sidType == CMS_SKID) { /* SubjectKeyIdentifier */ esd->issuerSKIDSz = SetOctetString(KEYID_SIZE, esd->issuerSKID); esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + KEYID_SIZE, @@ -1560,7 +1560,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(output2 + idx, esd->signerVersion, esd->signerVersionSz); idx += esd->signerVersionSz; /* SignerIdentifier */ - if (pkcs7->sidType == SID_ISSUER_AND_SERIAL_NUMBER) { + if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { /* IssuerAndSerialNumber */ XMEMCPY(output2 + idx, esd->issuerSnSeq, esd->issuerSnSeqSz); idx += esd->issuerSnSeqSz; @@ -1570,7 +1570,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, idx += pkcs7->issuerSz; XMEMCPY(output2 + idx, esd->issuerSn, esd->issuerSnSz); idx += esd->issuerSnSz; - } else if (pkcs7->sidType == SID_SUBJECT_KEY_IDENTIFIER) { + } else if (pkcs7->sidType == CMS_SKID) { /* SubjectKeyIdentifier */ XMEMCPY(output2 + idx, esd->issuerSKIDSeq, esd->issuerSKIDSeqSz); idx += esd->issuerSKIDSeqSz; @@ -3400,7 +3400,7 @@ static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, * Returns 0 on success, negative upon error */ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, int keyWrapOID, int keyAgreeOID, byte* ukm, - word32 ukmSz) + word32 ukmSz, int options) { Pkcs7EncodedRecip* recip = NULL; Pkcs7EncodedRecip* lastRecip = NULL; @@ -3727,6 +3727,8 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, lastRecip->next = recip; } + (void)options; + return idx; } @@ -3738,7 +3740,8 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, * to CMS/PKCS#7 EnvelopedData structure. * * Returns 0 on success, negative upon error */ -int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz) +int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz, + int options) { Pkcs7EncodedRecip* recip = NULL; Pkcs7EncodedRecip* lastRecip = NULL; @@ -3748,9 +3751,10 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz) word32 encryptedKeySz = 0; int ret = 0, blockKeySz; - int verSz, issuerSz, snSz, keyEncAlgSz; - int issuerSeqSz, recipSeqSz, issuerSerialSeqSz; + int verSz = 0, issuerSz = 0, snSz = 0, keyEncAlgSz = 0; + int issuerSeqSz = 0, recipSeqSz = 0, issuerSerialSeqSz = 0; int encKeyOctetStrSz; + int sidType; byte ver[MAX_VERSION_SZ]; byte issuerSerialSeq[MAX_SEQ_SZ]; @@ -3758,6 +3762,10 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz) byte issuerSeq[MAX_SEQ_SZ]; byte encKeyOctetStr[MAX_OCTET_STR_SZ]; + byte issuerSKIDSeq[MAX_SEQ_SZ]; + byte issuerSKID[MAX_OCTET_STR_SZ]; + word32 issuerSKIDSeqSz = 0, issuerSKIDSz = 0; + #ifdef WOLFSSL_SMALL_STACK byte* serial; byte* keyAlgArray; @@ -3797,6 +3805,14 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz) encryptedKeySz = MAX_ENCRYPTED_KEY_SZ; XMEMSET(encryptedKey, 0, encryptedKeySz); + /* allow options to override SubjectIdentifier type if set */ + sidType = pkcs7->sidType; + if (options & CMS_SKID) { + sidType = CMS_SKID; + } else if (options & CMS_ISSUER_AND_SERIAL_NUMBER) { + sidType = CMS_ISSUER_AND_SERIAL_NUMBER; + } + /* allocate recipient struct */ recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap, DYNAMIC_TYPE_PKCS7); @@ -3851,42 +3867,56 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz) return ret; } - /* version */ - verSz = SetMyVersion(0, ver, 0); + if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { - /* IssuerAndSerialNumber */ - if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) { - WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length"); - FreeDecodedCert(decoded); + /* version, must be 0 for IssuerAndSerialNumber */ + verSz = SetMyVersion(0, ver, 0); + + /* IssuerAndSerialNumber */ + if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) { + WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length"); + FreeDecodedCert(decoded); #ifdef WOLFSSL_SMALL_STACK - XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif - XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - return -1; - } - issuerSz = decoded->issuerRawLen; - issuerSeqSz = SetSequence(issuerSz, issuerSeq); + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return -1; + } + issuerSz = decoded->issuerRawLen; + issuerSeqSz = SetSequence(issuerSz, issuerSeq); - if (decoded->serialSz == 0) { - WOLFSSL_MSG("DecodedCert missing serial number"); - FreeDecodedCert(decoded); + if (decoded->serialSz == 0) { + WOLFSSL_MSG("DecodedCert missing serial number"); + FreeDecodedCert(decoded); #ifdef WOLFSSL_SMALL_STACK - XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif - XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - return -1; - } - snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial, - MAX_SN_SZ); + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return -1; + } + snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial, + MAX_SN_SZ); - issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz, - issuerSerialSeq); + issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz, + issuerSerialSeq); + + } else if (sidType == CMS_SKID) { + + /* version, must be 2 for SubjectKeyIdentifier */ + verSz = SetMyVersion(2, ver, 0); + + issuerSKIDSz = SetOctetString(KEYID_SIZE, issuerSKID); + issuerSKIDSeqSz = SetExplicit(0, issuerSKIDSz + KEYID_SIZE, + issuerSKIDSeq); + } else { + return PKCS7_RECIP_E; + } /* KeyEncryptionAlgorithmIdentifier, only support RSA now */ if (pkcs7->publicKeyOID != RSAk) { @@ -4000,22 +4030,43 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz) encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr); /* RecipientInfo */ - recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz + - issuerSz + snSz + keyEncAlgSz + encKeyOctetStrSz + - encryptedKeySz, recipSeq); + if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { + recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz + + issuerSz + snSz + keyEncAlgSz + + encKeyOctetStrSz + encryptedKeySz, recipSeq); - if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz + - keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) { - WOLFSSL_MSG("RecipientInfo output buffer too small"); - FreeDecodedCert(decoded); + if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz + + keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) { + WOLFSSL_MSG("RecipientInfo output buffer too small"); + FreeDecodedCert(decoded); #ifdef WOLFSSL_SMALL_STACK - XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif - XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - return BUFFER_E; + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return BUFFER_E; + } + + } else { + recipSeqSz = SetSequence(verSz + issuerSKIDSeqSz + issuerSKIDSz + + KEYID_SIZE + keyEncAlgSz + encKeyOctetStrSz + + encryptedKeySz, recipSeq); + + if (recipSeqSz + verSz + issuerSKIDSeqSz + issuerSKIDSz + KEYID_SIZE + + keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) { + WOLFSSL_MSG("RecipientInfo output buffer too small"); + FreeDecodedCert(decoded); +#ifdef WOLFSSL_SMALL_STACK + XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return BUFFER_E; + } } idx = 0; @@ -4023,14 +4074,23 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz) idx += recipSeqSz; XMEMCPY(recip->recip + idx, ver, verSz); idx += verSz; - XMEMCPY(recip->recip + idx, issuerSerialSeq, issuerSerialSeqSz); - idx += issuerSerialSeqSz; - XMEMCPY(recip->recip + idx, issuerSeq, issuerSeqSz); - idx += issuerSeqSz; - XMEMCPY(recip->recip + idx, decoded->issuerRaw, issuerSz); - idx += issuerSz; - XMEMCPY(recip->recip + idx, serial, snSz); - idx += snSz; + if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { + XMEMCPY(recip->recip + idx, issuerSerialSeq, issuerSerialSeqSz); + idx += issuerSerialSeqSz; + XMEMCPY(recip->recip + idx, issuerSeq, issuerSeqSz); + idx += issuerSeqSz; + XMEMCPY(recip->recip + idx, decoded->issuerRaw, issuerSz); + idx += issuerSz; + XMEMCPY(recip->recip + idx, serial, snSz); + idx += snSz; + } else { + XMEMCPY(recip->recip + idx, issuerSKIDSeq, issuerSKIDSeqSz); + idx += issuerSKIDSeqSz; + XMEMCPY(recip->recip + idx, issuerSKID, issuerSKIDSz); + idx += issuerSKIDSz; + XMEMCPY(recip->recip + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE); + idx += KEYID_SIZE; + } XMEMCPY(recip->recip + idx, keyAlgArray, keyEncAlgSz); idx += keyEncAlgSz; XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz); @@ -4257,12 +4317,13 @@ static int wc_PKCS7_GenerateIV(PKCS7* pkcs7, WC_RNG* rng, byte* iv, word32 ivSz) } -/* Set SignerIdentifier type to be used in SignedData encoding. Is either - * IssuerAndSerialNumber or SubjectKeyIdentifier. SignedData encoding - * defaults to using IssuerAndSerialNumber unless set with this function. +/* Set default SignerIdentifier type to be used. Is either + * IssuerAndSerialNumber or SubjectKeyIdentifier. Encoding defaults to using + * IssuerAndSerialNumber unless set with this function or explicitly + * overriden via options when adding RecipientInfo type. * * pkcs7 - pointer to initialized PKCS7 structure - * type - either SID_ISSUER_AND_SERIAL_NUMBER or SID_SUBJECT_KEY_IDENTIFIER + * type - either CMS_ISSUER_AND_SERIAL_NUMBER or CMS_SKID * * return 0 on success, negative upon error */ int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type) @@ -4270,8 +4331,8 @@ int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type) if (pkcs7 == NULL) return BAD_FUNC_ARG; - if (type != SID_ISSUER_AND_SERIAL_NUMBER && - type != SID_SUBJECT_KEY_IDENTIFIER) { + if (type != CMS_ISSUER_AND_SERIAL_NUMBER && + type != CMS_SKID) { return BAD_FUNC_ARG; } @@ -4349,7 +4410,8 @@ int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz, * to CMS/PKCS#7 EnvelopedData structure. * * Return 0 on success, negative upon error */ -int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb) +int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb, + int options) { int oriTypeLenSz, blockKeySz, ret; word32 idx, recipSeqSz; @@ -4432,6 +4494,8 @@ int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb) lastRecip->next = recip; } + (void)options; + return idx; } @@ -4650,7 +4714,8 @@ static int wc_PKCS7_PwriKek_KeyUnWrap(PKCS7* pkcs7, const byte* kek, * Return 0 on success, negative upon error */ int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen, byte* salt, word32 saltSz, int kdfOID, - int hashOID, int iterations, int encryptOID) + int hashOID, int iterations, int encryptOID, + int options) { Pkcs7EncodedRecip* recip = NULL; Pkcs7EncodedRecip* lastRecip = NULL; @@ -4887,6 +4952,8 @@ int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen, lastRecip->next = recip; } + (void)options; + return idx; } @@ -4927,7 +4994,8 @@ int wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen) int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek, word32 kekSz, byte* keyId, word32 keyIdSz, void* timePtr, byte* otherOID, - word32 otherOIDSz, byte* other, word32 otherSz) + word32 otherOIDSz, byte* other, word32 otherSz, + int options) { Pkcs7EncodedRecip* recip = NULL; Pkcs7EncodedRecip* lastRecip = NULL; @@ -5092,6 +5160,8 @@ int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek, lastRecip->next = recip; } + (void)options; + return idx; } @@ -5173,7 +5243,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) #ifndef NO_RSA case RSAk: ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert, - pkcs7->singleCertSz); + pkcs7->singleCertSz, 0); break; #endif #ifdef HAVE_ECC @@ -5182,7 +5252,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) pkcs7->singleCertSz, pkcs7->keyWrapOID, pkcs7->keyAgreeOID, pkcs7->ukm, - pkcs7->ukmSz); + pkcs7->ukmSz, 0); break; #endif @@ -5356,7 +5426,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, word32* decryptedKeySz, int* recipFound) { int length, encryptedKeySz, ret; - int keySz; + int keySz, version, sidType; word32 encOID; word32 keyIdx; byte issuerHash[KEYID_SIZE]; @@ -5376,38 +5446,73 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, RsaKey privKey[1]; #endif - /* remove IssuerAndSerialNumber */ - if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) + if (GetMyVersion(pkiMsg, idx, &version, 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, pkcs7->issuerHash, KEYID_SIZE) == 0) { - *recipFound = 1; + if (version == 0) { + sidType = CMS_ISSUER_AND_SERIAL_NUMBER; + } else if (version == 2) { + sidType = CMS_SKID; + } else { + return ASN_VERSION_E; } + if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { + + /* 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, pkcs7->issuerHash, KEYID_SIZE) == 0) { + *recipFound = 1; + } + #ifdef WOLFSSL_SMALL_STACK - serialNum = (mp_int*)XMALLOC(sizeof(mp_int), pkcs7->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (serialNum == NULL) - return MEMORY_E; + serialNum = (mp_int*)XMALLOC(sizeof(mp_int), pkcs7->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (serialNum == NULL) + return MEMORY_E; #endif - if (GetInt(serialNum, pkiMsg, idx, pkiMsgSz) < 0) { + if (GetInt(serialNum, pkiMsg, idx, pkiMsgSz) < 0) { +#ifdef WOLFSSL_SMALL_STACK + XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ASN_PARSE_E; + } + + mp_clear(serialNum); + #ifdef WOLFSSL_SMALL_STACK XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif - return ASN_PARSE_E; + + } else { + + /* remove SubjectKeyIdentifier */ + if (pkiMsg[(*idx)++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) + return ASN_PARSE_E; + + if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) + return ASN_PARSE_E; + + if (pkiMsg[(*idx)++] != ASN_OCTET_STRING) + return ASN_PARSE_E; + + if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) + return ASN_PARSE_E; + + /* if we found correct recipient, SKID will match */ + if (XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId, KEYID_SIZE) == 0) { + *recipFound = 1; + } + (*idx) += KEYID_SIZE; } - mp_clear(serialNum); - -#ifdef WOLFSSL_SMALL_STACK - XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); -#endif - if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -6395,14 +6500,6 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* pkiMsg, * last good saved one */ if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) > 0) { - if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) { - *idx = savedIdx; - break; - } - - if (version != 0) - return ASN_VERSION_E; - #ifndef NO_RSA /* found ktri */ ret = wc_PKCS7_DecryptKtri(pkcs7, pkiMsg, pkiMsgSz, idx, diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index af17794fe..2fcee72d3 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -18942,6 +18942,8 @@ typedef struct { word32 privateKeySz; byte* optionalUkm; word32 optionalUkmSz; + int ktriOptions; /* KTRI options flags */ + int kariOptions; /* KARI options flags */ /* KEKRI specific */ byte* secretKey; /* key, only for kekri RecipientInfo types */ @@ -18953,6 +18955,7 @@ typedef struct { word32 otherAttrOIDSz; /* size of otherAttrOID, bytes */ byte* otherAttr; /* OPTIONAL, other attribute, ASN.1 encoded */ word32 otherAttrSz; /* size of otherAttr, bytes */ + int kekriOptions; /* KEKRI options flags */ /* PWRI specific */ char* password; @@ -18962,9 +18965,11 @@ typedef struct { int kdfOID; int hashOID; int kdfIterations; + int pwriOptions; /* PWRI options flags */ /* ORI specific */ int isOri; + int oriOptions; /* ORI options flags */ const char* outFileName; } pkcs7EnvelopedVector; @@ -19100,29 +19105,41 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #ifndef NO_RSA #ifndef NO_DES3 {data, (word32)sizeof(data), DATA, DES3b, 0, 0, rsaCert, rsaCertSz, - rsaPrivKey, rsaPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, + rsaPrivKey, rsaPrivKeySz, NULL, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, + 0, NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataDES3.der"}, #endif #ifndef NO_AES #ifdef WOLFSSL_AES_128 {data, (word32)sizeof(data), DATA, AES128CBCb, 0, 0, rsaCert, rsaCertSz, - rsaPrivKey, rsaPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, + rsaPrivKey, rsaPrivKeySz, NULL, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, + 0, NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES128CBC.der"}, #endif #ifdef WOLFSSL_AES_192 {data, (word32)sizeof(data), DATA, AES192CBCb, 0, 0, rsaCert, rsaCertSz, - rsaPrivKey, rsaPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, + rsaPrivKey, rsaPrivKeySz, NULL, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, + 0, NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES192CBC.der"}, #endif #ifdef WOLFSSL_AES_256 {data, (word32)sizeof(data), DATA, AES256CBCb, 0, 0, rsaCert, rsaCertSz, - rsaPrivKey, rsaPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, + rsaPrivKey, rsaPrivKeySz, NULL, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, + 0, NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES256CBC.der"}, + + /* explicitly using SKID for SubjectKeyIdentifier */ + {data, (word32)sizeof(data), DATA, AES256CBCb, 0, 0, rsaCert, rsaCertSz, + rsaPrivKey, rsaPrivKeySz, NULL, 0, CMS_SKID, 0, NULL, 0, NULL, 0, NULL, + NULL, 0, NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, + "pkcs7envelopedDataAES256CBC_SKID.der"}, + + /* explicitly using IssuerAndSerialNumber for SubjectKeyIdentifier */ + {data, (word32)sizeof(data), DATA, AES256CBCb, 0, 0, rsaCert, rsaCertSz, + rsaPrivKey, rsaPrivKeySz, NULL, 0, CMS_ISSUER_AND_SERIAL_NUMBER, 0, + NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, + 0, 0, 0, 0, "pkcs7envelopedDataAES256CBC_IANDS.der"}, #endif #endif /* NO_AES */ #endif @@ -19133,31 +19150,31 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #if !defined(NO_SHA) && defined(WOLFSSL_AES_128) {data, (word32)sizeof(data), DATA, AES128CBCb, AES128_WRAP, dhSinglePass_stdDH_sha1kdf_scheme, eccCert, eccCertSz, eccPrivKey, - eccPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, - NULL, 0, NULL, 0, 0, 0, 0, 0, + eccPrivKeySz, NULL, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, + 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES128CBC_ECDH_SHA1KDF.der"}, #endif #if !defined(NO_SHA256) && defined(WOLFSSL_AES_256) {data, (word32)sizeof(data), DATA, AES256CBCb, AES256_WRAP, dhSinglePass_stdDH_sha256kdf_scheme, eccCert, eccCertSz, eccPrivKey, - eccPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, - NULL, 0, NULL, 0, 0, 0, 0, 0, + eccPrivKeySz, NULL, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, + 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES256CBC_ECDH_SHA256KDF.der"}, #endif /* NO_SHA256 && WOLFSSL_AES_256 */ #if defined(WOLFSSL_SHA512) && defined(WOLFSSL_AES_256) {data, (word32)sizeof(data), DATA, AES256CBCb, AES256_WRAP, dhSinglePass_stdDH_sha512kdf_scheme, eccCert, eccCertSz, eccPrivKey, - eccPrivKeySz, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, - NULL, 0, NULL, 0, 0, 0, 0, 0, + eccPrivKeySz, NULL, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, + 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES256CBC_ECDH_SHA512KDF.der"}, /* with optional user keying material (ukm) */ {data, (word32)sizeof(data), DATA, AES256CBCb, AES256_WRAP, dhSinglePass_stdDH_sha512kdf_scheme, eccCert, eccCertSz, eccPrivKey, - eccPrivKeySz, optionalUkm, sizeof(optionalUkm), NULL, 0, - NULL, 0, NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, + eccPrivKeySz, optionalUkm, sizeof(optionalUkm), 0, 0, NULL, 0, + NULL, 0, NULL, NULL, 0, NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES256CBC_ECDH_SHA512KDF_ukm.der"}, #endif /* WOLFSSL_SHA512 && WOLFSSL_AES_256 */ #endif /* NO_AES */ @@ -19167,9 +19184,9 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #ifndef NO_AES #if !defined(NO_SHA) && defined(WOLFSSL_AES_128) {data, (word32)sizeof(data), DATA, AES128CBCb, AES128_WRAP, 0, - NULL, 0, NULL, 0, NULL, 0, secretKey, sizeof(secretKey), + NULL, 0, NULL, 0, NULL, 0, 0, 0, secretKey, sizeof(secretKey), secretKeyId, sizeof(secretKeyId), NULL, NULL, 0, NULL, 0, - NULL, 0, NULL, 0, 0, 0, 0, 0, + 0, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES128CBC_KEKRI.der"}, #endif #endif @@ -19178,17 +19195,17 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #if !defined(NO_PWDBASED) && !defined(NO_AES) #if !defined(NO_SHA) && defined(WOLFSSL_AES_128) {data, (word32)sizeof(data), DATA, AES128CBCb, 0, 0, - NULL, 0, NULL, 0, NULL, 0, NULL, 0, - NULL, 0, NULL, NULL, 0, NULL, 0, password, (word32)XSTRLEN(password), - salt, sizeof(salt), PBKDF2_OID, WC_SHA, 5, 0, - "pkcs7envelopedDataAES128CBC_PWRI.der"}, + NULL, 0, NULL, 0, NULL, 0, 0, 0, NULL, 0, + NULL, 0, NULL, NULL, 0, NULL, 0, 0, password, + (word32)XSTRLEN(password), salt, sizeof(salt), PBKDF2_OID, WC_SHA, 5, + 0, 0, 0, "pkcs7envelopedDataAES128CBC_PWRI.der"}, #endif #endif /* ori (OtherRecipientInfo) recipient types */ {data, (word32)sizeof(data), DATA, AES128CBCb, 0, 0, NULL, 0, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, NULL, 0, NULL, - 0, 0, 0, 0, 1, "pkcs7envelopedDataAES128CBC_ORI.der"}, + NULL, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, 0, NULL, 0, 0, NULL, 0, + NULL, 0, 0, 0, 0, 0, 1, 0, "pkcs7envelopedDataAES128CBC_ORI.der"}, }; testSz = sizeof(testVectors) / sizeof(pkcs7EnvelopedVector); @@ -19224,7 +19241,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, testVectors[i].secretKeyId, testVectors[i].secretKeyIdSz, testVectors[i].timePtr, testVectors[i].otherAttrOID, testVectors[i].otherAttrOIDSz, testVectors[i].otherAttr, - testVectors[i].otherAttrSz); + testVectors[i].otherAttrSz, testVectors[i].kekriOptions); if (ret < 0) { wc_PKCS7_Free(pkcs7); @@ -19260,7 +19277,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, testVectors[i].passwordSz, testVectors[i].salt, testVectors[i].saltSz, testVectors[i].kdfOID, testVectors[i].hashOID, testVectors[i].kdfIterations, - testVectors[i].encryptOID); + testVectors[i].encryptOID, testVectors[i].pwriOptions); if (ret < 0) { wc_PKCS7_Free(pkcs7); @@ -19289,7 +19306,8 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, pkcs7->contentOID = testVectors[i].contentOID; pkcs7->encryptOID = testVectors[i].encryptOID; - ret = wc_PKCS7_AddRecipient_ORI(pkcs7, myOriEncryptCb); + ret = wc_PKCS7_AddRecipient_ORI(pkcs7, myOriEncryptCb, + testVectors[i].oriOptions); if (ret < 0) { wc_PKCS7_Free(pkcs7); @@ -19324,6 +19342,25 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, pkcs7->encryptOID = testVectors[i].encryptOID; pkcs7->ukm = testVectors[i].optionalUkm; pkcs7->ukmSz = testVectors[i].optionalUkmSz; + + /* set SubjectIdentifier type for KTRI types */ + if (testVectors[i].ktriOptions & CMS_SKID) { + + ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID); + if (ret != 0) { + wc_PKCS7_Free(pkcs7); + return -9225; + } + } else if (testVectors[i].ktriOptions & + CMS_ISSUER_AND_SERIAL_NUMBER) { + + ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, + CMS_ISSUER_AND_SERIAL_NUMBER); + if (ret != 0) { + wc_PKCS7_Free(pkcs7); + return -9225; + } + } } /* encode envelopedData */ @@ -19923,8 +19960,7 @@ static int pkcs7signed_run_vectors( {data, (word32)sizeof(data), SHA256h, RSAk, rsaClientPrivKeyBuf, rsaClientPrivKeyBufSz, rsaClientCertBuf, rsaClientCertBufSz, NULL, 0, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_RSA_SHA256_SKID.der", 0, NULL, 0, - SID_SUBJECT_KEY_IDENTIFIER}, + "pkcs7signedData_RSA_SHA256_SKID.der", 0, NULL, 0, CMS_SKID}, /* RSA with SHA256 and custom contentType */ {data, (word32)sizeof(data), SHA256h, RSAk, rsaClientPrivKeyBuf, @@ -19995,8 +20031,7 @@ static int pkcs7signed_run_vectors( {data, (word32)sizeof(data), SHA256h, ECDSAk, eccClientPrivKeyBuf, eccClientPrivKeyBufSz, eccClientCertBuf, eccClientCertBufSz, NULL, 0, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_ECDSA_SHA256_SKID.der", 0, NULL, 0, - SID_SUBJECT_KEY_IDENTIFIER}, + "pkcs7signedData_ECDSA_SHA256_SKID.der", 0, NULL, 0, CMS_SKID}, /* ECDSA with SHA256 and custom contentType */ {data, (word32)sizeof(data), SHA256h, ECDSAk, eccClientPrivKeyBuf, @@ -20106,9 +20141,8 @@ static int pkcs7signed_run_vectors( /* set SignerIdentifier to use SubjectKeyIdentifier if desired, default is IssuerAndSerialNumber */ - if (testVectors[i].sidType == SID_SUBJECT_KEY_IDENTIFIER) { - ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, - SID_SUBJECT_KEY_IDENTIFIER); + if (testVectors[i].sidType == CMS_SKID) { + ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID); if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 0adeb08cc..6d1cbe472 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -88,9 +88,9 @@ enum Pkcs7_Misc { MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ }; -enum Pkcs7_SignerIdentifier_Types { - SID_ISSUER_AND_SERIAL_NUMBER = 0, - SID_SUBJECT_KEY_IDENTIFIER = 1 +enum Cms_Options { + CMS_SKID = 1, + CMS_ISSUER_AND_SERIAL_NUMBER = 2, }; /* CMS/PKCS#7 RecipientInfo types, RFC 5652, Section 6.2 */ @@ -242,11 +242,11 @@ WOLFSSL_API int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf, /* CMS/PKCS#7 EnvelopedData */ WOLFSSL_API int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, - word32 certSz); + word32 certSz, int options); WOLFSSL_API int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, int keyWrapOID, int keyAgreeOID, byte* ukm, - word32 ukmSz); + word32 ukmSz, int options); WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz); WOLFSSL_API int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, @@ -254,18 +254,19 @@ WOLFSSL_API int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* keyID, word32 keyIdSz, void* timePtr, byte* otherOID, word32 otherOIDSz, byte* other, - word32 otherSz); + word32 otherSz, int options); WOLFSSL_API int wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen); WOLFSSL_API int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen, byte* salt, word32 saltSz, int kdfOID, int prfOID, int iterations, - int encryptOID); + int encryptOID, int options); WOLFSSL_API int wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx); WOLFSSL_API int wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx); WOLFSSL_API int wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb); -WOLFSSL_API int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt cb); +WOLFSSL_API int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt cb, + int options); WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz);