diff --git a/.gitignore b/.gitignore index e997bb8e4..477bcf0c9 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ pkcs7envelopedDataAES128CBC.der pkcs7envelopedDataAES128CBC_ECDH_SHA1KDF.der pkcs7envelopedDataAES128CBC_KEKRI.der pkcs7envelopedDataAES128CBC_PWRI.der +pkcs7envelopedDataAES128CBC_ORI.der pkcs7envelopedDataAES192CBC.der pkcs7envelopedDataAES256CBC.der pkcs7envelopedDataAES256CBC_ECDH_SHA256KDF.der diff --git a/Makefile.am b/Makefile.am index 2b7864979..8f01ce5aa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,6 +58,7 @@ CLEANFILES+= cert.der \ pkcs7envelopedDataAES128CBC.der \ pkcs7envelopedDataAES128CBC_KEKRI.der \ pkcs7envelopedDataAES128CBC_PWRI.der \ + pkcs7envelopedDataAES128CBC_ORI.der \ pkcs7envelopedDataAES192CBC.der \ pkcs7envelopedDataAES256CBC.der \ pkcs7signedData_RSA_SHA.der \ diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 78e36c0b8..fbd9dbae8 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -336,6 +336,7 @@ typedef struct Pkcs7Cert { typedef struct Pkcs7EncodedRecip { byte recip[MAX_RECIP_SZ]; word32 recipSz; + int recipType; Pkcs7EncodedRecip* next; } Pkcs7EncodedRecip; @@ -3713,6 +3714,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, /* store recipient size */ recip->recipSz = idx; + recip->recipType = PKCS7_KARI; /* add recipient to recip list */ if (pkcs7->recipList == NULL) { @@ -4047,6 +4049,7 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz) /* store recipient size */ recip->recipSz = idx; + recip->recipType = PKCS7_KTRI; /* add recipient to recip list */ if (pkcs7->recipList == NULL) { @@ -4342,6 +4345,97 @@ int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz, } +/* Encode and add CMS EnvelopedData ORI (OtherRecipientInfo) RecipientInfo + * to CMS/PKCS#7 EnvelopedData structure. + * + * Return 0 on success, negative upon error */ +int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb) +{ + int oriTypeLenSz, blockKeySz, ret; + word32 idx, recipSeqSz; + + Pkcs7EncodedRecip* recip = NULL; + Pkcs7EncodedRecip* lastRecip = NULL; + + byte recipSeq[MAX_SEQ_SZ]; + byte oriTypeLen[MAX_LENGTH_SZ]; + + byte oriType[MAX_ORI_TYPE_SZ]; + byte oriValue[MAX_ORI_VALUE_SZ]; + word32 oriTypeSz = MAX_ORI_TYPE_SZ; + word32 oriValueSz = MAX_ORI_VALUE_SZ; + + if (pkcs7 == NULL || oriEncryptCb == NULL) { + return BAD_FUNC_ARG; + } + + /* allocate memory for RecipientInfo, KEK, encrypted key */ + recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), + pkcs7->heap, DYNAMIC_TYPE_PKCS7); + if (recip == NULL) + return MEMORY_E; + + /* get key size for content-encryption key based on algorithm */ + blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID); + if (blockKeySz < 0) { + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return blockKeySz; + } + + /* generate random content encryption key, if needed */ + ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz); + if (ret < 0) { + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ret; + } + + /* call user callback to encrypt CEK and get oriType and oriValue + values back */ + ret = oriEncryptCb(pkcs7, pkcs7->cek, pkcs7->cekSz, oriType, &oriTypeSz, + oriValue, &oriValueSz, pkcs7->oriEncryptCtx); + if (ret != 0) { + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ret; + } + + oriTypeLenSz = SetLength(oriTypeSz, oriTypeLen); + + recipSeqSz = SetImplicit(ASN_SEQUENCE, 4, 1 + oriTypeLenSz + oriTypeSz + + oriValueSz, recipSeq); + + idx = 0; + XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz); + idx += recipSeqSz; + /* oriType */ + recip->recip[idx] = ASN_OBJECT_ID; + idx += 1; + XMEMCPY(recip->recip + idx, oriTypeLen, oriTypeLenSz); + idx += oriTypeLenSz; + XMEMCPY(recip->recip + idx, oriType, oriTypeSz); + idx += oriTypeSz; + /* oriValue, input MUST already be ASN.1 encoded */ + XMEMCPY(recip->recip + idx, oriValue, oriValueSz); + idx += oriValueSz; + + /* store recipient size */ + recip->recipSz = idx; + recip->recipType = PKCS7_ORI; + + /* add recipient to recip list */ + if (pkcs7->recipList == NULL) { + pkcs7->recipList = recip; + } else { + lastRecip = pkcs7->recipList; + while (lastRecip->next != NULL) { + lastRecip = lastRecip->next; + } + lastRecip->next = recip; + } + + return idx; +} + + #ifndef NO_PWDBASED @@ -4780,6 +4874,7 @@ int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen, /* store recipient size */ recip->recipSz = idx; + recip->recipType = PKCS7_PWRI; /* add recipient to recip list */ if (pkcs7->recipList == NULL) { @@ -4984,6 +5079,7 @@ int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek, /* store recipient size */ recip->recipSz = idx; + recip->recipType = PKCS7_KEKRI; /* add recipient to recip list */ if (pkcs7->recipList == NULL) { @@ -5757,6 +5853,108 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari, #endif /* HAVE_ECC */ +int wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx) +{ + if (pkcs7 == NULL) + return BAD_FUNC_ARG; + + pkcs7->oriEncryptCtx = ctx; + + return 0; +} + + +int wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx) +{ + + if (pkcs7 == NULL) + return BAD_FUNC_ARG; + + pkcs7->oriDecryptCtx = ctx; + + return 0; +} + + +int wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb) +{ + if (pkcs7 == NULL) + return BAD_FUNC_ARG; + + pkcs7->oriDecryptCb = cb; + + return 0; +} + + +/* Decrypt ASN.1 OtherRecipientInfo (ori), as defined by: + * + * OtherRecipientInfo ::= SEQUENCE { + * oriType OBJECT IDENTIFIER, + * oriValue ANY DEFINED BY oriType } + * + * pkcs7 - pointer to initialized PKCS7 structure + * pkiMsg - pointer to encoded CMS bundle + * pkiMsgSz - size of pkiMsg, bytes + * idx - [IN/OUT] pointer to index into pkiMsg + * decryptedKey - [OUT] output buf for decrypted content encryption key + * decryptedKeySz - [IN/OUT] size of buffer, size of decrypted key + * recipFound - [OUT] 1 if recipient has been found, 0 if not + * + * Return 0 on success, negative upon error. + */ +static int wc_PKCS7_DecryptOri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, + word32* idx, byte* decryptedKey, + word32* decryptedKeySz, int* recipFound) +{ + int ret, seqSz, oriOIDSz; + word32 oriValueSz, tmpIdx; + + byte* oriValue; + byte oriOID[MAX_OID_SZ]; + + if (pkcs7->oriDecryptCb == NULL) { + WOLFSSL_MSG("You must register an ORI Decrypt callback"); + return BAD_FUNC_ARG; + } + + /* get OtherRecipientInfo sequence length */ + if (GetLength(pkiMsg, idx, &seqSz, pkiMsgSz) < 0) + return ASN_PARSE_E; + + tmpIdx = *idx; + + /* remove and store oriType OBJECT IDENTIFIER */ + if (GetASNObjectId(pkiMsg, idx, &oriOIDSz, pkiMsgSz) != 0) + return ASN_PARSE_E; + + XMEMCPY(oriOID, pkiMsg + *idx, oriOIDSz); + *idx += oriOIDSz; + + /* get oriValue, increment idx */ + oriValue = pkiMsg + *idx; + oriValueSz = seqSz - (*idx - tmpIdx); + *idx += oriValueSz; + + /* pass oriOID and oriValue to user callback, expect back + decryptedKey and size */ + ret = pkcs7->oriDecryptCb(pkcs7, oriOID, (word32)oriOIDSz, oriValue, + oriValueSz, decryptedKey, decryptedKeySz, + pkcs7->oriDecryptCtx); + + if (ret != 0 || decryptedKey == NULL || *decryptedKeySz == 0) { + /* decrypt operation failed */ + *recipFound = 0; + return PKCS7_RECIP_E; + } + + /* mark recipFound, since we only support one RecipientInfo for now */ + *recipFound = 1; + + return 0; +} + + /* decode ASN.1 PasswordRecipientInfo (pwri), return 0 on success, * < 0 on error */ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, @@ -6287,6 +6485,18 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* pkiMsg, if (ret != 0) return ret; + /* ori is IMPLICIT[4] */ + } else if (pkiMsg[*idx] == (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 4)) { + (*idx)++; + + /* found ori */ + ret = wc_PKCS7_DecryptOri(pkcs7, pkiMsg, pkiMsgSz, idx, + decryptedKey, decryptedKeySz, + recipFound); + if (ret != 0) + return ret; + } else { /* failed to find RecipientInfo, restore idx and continue */ *idx = savedIdx; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 23983ecd8..af17794fe 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -18963,10 +18963,89 @@ typedef struct { int hashOID; int kdfIterations; + /* ORI specific */ + int isOri; + const char* outFileName; } pkcs7EnvelopedVector; +static const byte asnDataOid[] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 +}; + +/* ORI encrypt callback, responsible for encrypting content-encryption key (CEK) + * and giving wolfCrypt the value for oriOID and oriValue to place in + * OtherRecipientInfo. + * + * Returns 0 on success, negative upon error. */ +static int myOriEncryptCb(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* oriType, + word32* oriTypeSz, byte* oriValue, word32* oriValueSz, + void* ctx) +{ + int i; + + /* make sure buffers are large enough */ + if ((*oriValueSz < (2 + cekSz)) || (*oriTypeSz < sizeof(oriType))) + return -1; + + /* our simple encryption algorithm will be take the bitwise complement */ + oriValue[0] = 0x04; /*ASN OCTET STRING */ + oriValue[1] = (byte)cekSz; /* length */ + for (i = 0; i < (int)cekSz; i++) { + oriValue[2 + i] = ~cek[i]; + } + *oriValueSz = 2 + cekSz; + + /* set oriType to ASN.1 encoded data OID */ + XMEMCPY(oriType, asnDataOid, sizeof(asnDataOid)); + *oriTypeSz = sizeof(asnDataOid); + + (void)pkcs7; + (void)ctx; + + return 0; +} + + +/* ORI decrypt callback, responsible for providing a decrypted content + * encryption key (CEK) placed into decryptedKey and size placed into + * decryptedKeySz. oriOID and oriValue are given to the callback to help + * in decrypting the encrypted CEK. + * + * Returns 0 on success, negative upon error. */ +static int myOriDecryptCb(PKCS7* pkcs7, byte* oriType, word32 oriTypeSz, + byte* oriValue, word32 oriValueSz, byte* decryptedKey, + word32* decryptedKeySz, void* ctx) +{ + int i; + + /* make sure oriType matches what we expect */ + if (oriTypeSz != sizeof(asnDataOid)) + return -1; + + if (XMEMCMP(oriType, asnDataOid, sizeof(asnDataOid)) != 0) + return -1; + + /* make sure decrypted buffer is large enough */ + if (*decryptedKeySz < oriValueSz) + return -1; + + /* decrypt encrypted CEK using simple bitwise complement, + only for example */ + for (i = 0; i < (int)oriValueSz - 2; i++) { + decryptedKey[i] = ~oriValue[2 + i]; + } + + *decryptedKeySz = oriValueSz - 2; + + (void)pkcs7; + (void)ctx; + + return 0; +} + + static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, byte* rsaPrivKey, word32 rsaPrivKeySz, byte* eccCert, word32 eccCertSz, @@ -19022,24 +19101,28 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #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, "pkcs7envelopedDataDES3.der"}, + NULL, 0, NULL, 0, NULL, 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, "pkcs7envelopedDataAES128CBC.der"}, + NULL, 0, NULL, 0, NULL, 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, "pkcs7envelopedDataAES192CBC.der"}, + NULL, 0, NULL, 0, NULL, 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, "pkcs7envelopedDataAES256CBC.der"}, + NULL, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, + "pkcs7envelopedDataAES256CBC.der"}, #endif #endif /* NO_AES */ #endif @@ -19051,7 +19134,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, {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, + NULL, 0, NULL, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES128CBC_ECDH_SHA1KDF.der"}, #endif @@ -19059,7 +19142,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, {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, + NULL, 0, NULL, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES256CBC_ECDH_SHA256KDF.der"}, #endif /* NO_SHA256 && WOLFSSL_AES_256 */ @@ -19067,14 +19150,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, {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, + NULL, 0, NULL, 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, + NULL, 0, NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0, 0, 0, 0, 0, "pkcs7envelopedDataAES256CBC_ECDH_SHA512KDF_ukm.der"}, #endif /* WOLFSSL_SHA512 && WOLFSSL_AES_256 */ #endif /* NO_AES */ @@ -19086,7 +19169,8 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, {data, (word32)sizeof(data), DATA, AES128CBCb, AES128_WRAP, 0, NULL, 0, NULL, 0, NULL, 0, secretKey, sizeof(secretKey), secretKeyId, sizeof(secretKeyId), NULL, NULL, 0, NULL, 0, - NULL, 0, NULL, 0, 0, 0, 0, "pkcs7envelopedDataAES128CBC_KEKRI.der"}, + NULL, 0, NULL, 0, 0, 0, 0, 0, + "pkcs7envelopedDataAES128CBC_KEKRI.der"}, #endif #endif @@ -19096,10 +19180,15 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, {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, + salt, sizeof(salt), PBKDF2_OID, WC_SHA, 5, 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"}, }; testSz = sizeof(testVectors) / sizeof(pkcs7EnvelopedVector); @@ -19187,6 +19276,33 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, return -9220; } + } else if (testVectors[i].isOri == 1) { + /* ORI recipient type */ + + ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); + if (ret != 0) { + return -9221; + } + + pkcs7->content = (byte*)testVectors[i].content; + pkcs7->contentSz = testVectors[i].contentSz; + pkcs7->contentOID = testVectors[i].contentOID; + pkcs7->encryptOID = testVectors[i].encryptOID; + + ret = wc_PKCS7_AddRecipient_ORI(pkcs7, myOriEncryptCb); + + if (ret < 0) { + wc_PKCS7_Free(pkcs7); + return -9222; + } + + /* set decrypt callback for decryption */ + ret = wc_PKCS7_SetOriDecryptCb(pkcs7, myOriDecryptCb); + + if (ret < 0) { + wc_PKCS7_Free(pkcs7); + return -9223; + } } else { /* KTRI or KARI recipient types */ @@ -19195,7 +19311,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, (word32)testVectors[i].certSz); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9221; + return -9224; } pkcs7->keyWrapOID = testVectors[i].keyWrapOID; @@ -19215,7 +19331,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, sizeof(enveloped)); if (envelopedSz <= 0) { wc_PKCS7_Free(pkcs7); - return -9222; + return -9225; } /* decode envelopedData */ @@ -19223,13 +19339,13 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, decoded, sizeof(decoded)); if (decodedSz <= 0) { wc_PKCS7_Free(pkcs7); - return -9223; + return -9226; } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0){ wc_PKCS7_Free(pkcs7); - return -9224; + return -9227; } #ifdef PKCS7_OUTPUT_TEST_BUNDLES @@ -19237,14 +19353,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, pkcs7File = fopen(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - return -9225; + return -9228; } ret = (int)fwrite(enveloped, 1, envelopedSz, pkcs7File); fclose(pkcs7File); if (ret != envelopedSz) { wc_PKCS7_Free(pkcs7); - return -9226; + return -9229; } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index ee1ea015d..0adeb08cc 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -51,6 +51,13 @@ #define MAX_PKCS7_CERTS 4 #endif +#ifndef MAX_ORI_TYPE_SZ + #define MAX_ORI_TYPE_SZ MAX_OID_SZ +#endif +#ifndef MAX_ORI_VALUE_SZ + #define MAX_ORI_VALUE_SZ 512 +#endif + /* PKCS#7 content types, ref RFC 2315 (Section 14) */ enum PKCS7_TYPES { PKCS7_MSG = 650, /* 1.2.840.113549.1.7 */ @@ -113,6 +120,17 @@ typedef struct PKCS7DecodedAttrib { typedef struct Pkcs7Cert Pkcs7Cert; typedef struct Pkcs7EncodedRecip Pkcs7EncodedRecip; +typedef struct PKCS7 PKCS7; + +/* OtherRecipientInfo decrypt callback prototype */ +typedef int (*CallbackOriDecrypt)(PKCS7* pkcs7, byte* oriType, word32 oriTypeSz, + byte* oriValue, word32 oriValueSz, + byte* decryptedKey, word32* decryptedKeySz, + void* ctx); +typedef int (*CallbackOriEncrypt)(PKCS7* pkcs7, byte* cek, word32 cekSz, + byte* oriType, word32* oriTypeSz, + byte* oriValue, word32* oriValueSz, + void* ctx); /* Public Structure Warning: * Existing members must not be changed to maintain backwards compatibility! @@ -180,6 +198,11 @@ typedef struct PKCS7 { byte* pass; /* password, for PWRI decryption */ word32 passSz; /* size of pass, bytes */ + CallbackOriEncrypt oriEncryptCb; /* ORI encrypt callback */ + CallbackOriDecrypt oriDecryptCb; /* ORI decrypt callback */ + void* oriEncryptCtx; /* ORI encrypt user context ptr */ + void* oriDecryptCtx; /* ORI decrypt user context ptr */ + /* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */ } PKCS7; @@ -224,21 +247,28 @@ WOLFSSL_API int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, int keyWrapOID, int keyAgreeOID, byte* ukm, word32 ukmSz); + +WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz); WOLFSSL_API 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); + +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); +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_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz); -WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz); -WOLFSSL_API int wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen); WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, byte* output, word32 outputSz);