#ifndef WOLF_CRYPT_PKCS7_H
#define WOLF_CRYPT_PKCS7_H
#include <wolfssl/wolfcrypt/types.h>
#ifdef HAVE_PKCS7
#ifndef NO_ASN
#include <wolfssl/wolfcrypt/asn.h>
#endif
#include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/random.h>
#ifndef NO_AES
#include <wolfssl/wolfcrypt/aes.h>
#endif
#ifndef NO_DES3
#include <wolfssl/wolfcrypt/des3.h>
#endif
#include <wolfssl/wolfcrypt/wc_encrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef MAX_PKCS7_CERTS
#ifdef OPENSSL_ALL
#define MAX_PKCS7_CERTS 15
#else
#define MAX_PKCS7_CERTS 4
#endif
#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
#ifndef MAX_SIGNED_ATTRIBS_SZ
#define MAX_SIGNED_ATTRIBS_SZ 7
#endif
#ifndef MAX_AUTH_ATTRIBS_SZ
#define MAX_AUTH_ATTRIBS_SZ 7
#endif
#ifndef MAX_UNAUTH_ATTRIBS_SZ
#define MAX_UNAUTH_ATTRIBS_SZ 7
#endif
#define WOLFSSL_NO_ATTRIBUTES 0x1
#define WOLFSSL_CONTENT_TYPE_ATTRIBUTE 0x2
#define WOLFSSL_SIGNING_TIME_ATTRIBUTE 0x4
#define WOLFSSL_MESSAGE_DIGEST_ATTRIBUTE 0x8
enum PKCS7_STATE {
WC_PKCS7_START = 0,
WC_PKCS7_STAGE2,
WC_PKCS7_STAGE3,
WC_PKCS7_STAGE4,
WC_PKCS7_STAGE5,
WC_PKCS7_STAGE6,
WC_PKCS7_VERIFY_STAGE2,
WC_PKCS7_VERIFY_STAGE3,
WC_PKCS7_VERIFY_STAGE4,
WC_PKCS7_VERIFY_STAGE5,
WC_PKCS7_VERIFY_STAGE6,
WC_PKCS7_VERIFY_STAGE7,
WC_PKCS7_INFOSET_START,
WC_PKCS7_INFOSET_BER,
WC_PKCS7_INFOSET_STAGE1,
WC_PKCS7_INFOSET_STAGE2,
WC_PKCS7_INFOSET_END,
WC_PKCS7_ENV_2,
WC_PKCS7_ENV_3,
WC_PKCS7_ENV_4,
WC_PKCS7_ENV_5,
WC_PKCS7_AUTHENV_2,
WC_PKCS7_AUTHENV_3,
WC_PKCS7_AUTHENV_4,
WC_PKCS7_AUTHENV_5,
WC_PKCS7_AUTHENV_6,
WC_PKCS7_AUTHENV_ATRB,
WC_PKCS7_AUTHENV_ATRBEND,
WC_PKCS7_AUTHENV_7,
WC_PKCS7_DECRYPT_KTRI,
WC_PKCS7_DECRYPT_KTRI_2,
WC_PKCS7_DECRYPT_KTRI_3,
WC_PKCS7_DECRYPT_KARI,
WC_PKCS7_DECRYPT_KEKRI,
WC_PKCS7_DECRYPT_PWRI,
WC_PKCS7_DECRYPT_ORI,
WC_PKCS7_DECRYPT_DONE
};
enum Pkcs7_Misc {
PKCS7_NONCE_SZ = 16,
MAX_ENCRYPTED_KEY_SZ = 512,
MAX_CONTENT_KEY_LEN = 32,
MAX_CONTENT_IV_SIZE = 16,
#ifndef NO_AES
MAX_CONTENT_BLOCK_LEN = WC_AES_BLOCK_SIZE,
#else
MAX_CONTENT_BLOCK_LEN = DES_BLOCK_SIZE,
#endif
MAX_RECIP_SZ = MAX_VERSION_SZ +
MAX_SEQ_SZ + WC_ASN_NAME_MAX + MAX_SN_SZ +
MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ,
WOLF_ENUM_DUMMY_LAST_ELEMENT(Pkcs7_Misc)
};
enum Cms_Options {
CMS_SKID = 1,
CMS_ISSUER_AND_SERIAL_NUMBER = 2
};
#define DEGENERATE_SID 3
enum Pkcs7_RecipientInfo_Types {
PKCS7_KTRI = 0,
PKCS7_KARI = 1,
PKCS7_KEKRI = 2,
PKCS7_PWRI = 3,
PKCS7_ORI = 4
};
typedef struct PKCS7Attrib {
const byte* oid;
word32 oidSz;
const byte* value;
word32 valueSz;
} PKCS7Attrib;
typedef struct PKCS7DecodedAttrib {
struct PKCS7DecodedAttrib* next;
byte* oid;
word32 oidSz;
byte* value;
word32 valueSz;
} PKCS7DecodedAttrib;
typedef struct PKCS7State PKCS7State;
typedef struct Pkcs7Cert Pkcs7Cert;
typedef struct Pkcs7EncodedRecip Pkcs7EncodedRecip;
typedef struct PKCS7SignerInfo PKCS7SignerInfo;
typedef struct wc_PKCS7 wc_PKCS7;
typedef struct wc_PKCS7 wc_PKCS7_SIGNED;
#ifndef OPENSSL_COEXIST
#define PKCS7 wc_PKCS7
#define PKCS7_SIGNED wc_PKCS7_SIGNED
#endif
typedef int (*CallbackOriDecrypt)(wc_PKCS7* pkcs7, byte* oriType, word32 oriTypeSz,
byte* oriValue, word32 oriValueSz,
byte* decryptedKey, word32* decryptedKeySz,
void* ctx);
typedef int (*CallbackOriEncrypt)(wc_PKCS7* pkcs7, byte* cek, word32 cekSz,
byte* oriType, word32* oriTypeSz,
byte* oriValue, word32* oriValueSz,
void* ctx);
typedef int (*CallbackDecryptContent)(wc_PKCS7* pkcs7, int encryptOID,
byte* iv, int ivSz, byte* aad, word32 aadSz,
byte* authTag, word32 authTagSz, byte* in,
int inSz, byte* out, void* ctx);
typedef int (*CallbackWrapCEK)(wc_PKCS7* pkcs7, byte* cek, word32 cekSz,
byte* keyId, word32 keyIdSz,
byte* originKey, word32 originKeySz,
byte* out, word32 outSz,
int keyWrapAlgo, int type, int dir);
typedef int (*CallbackAESKeyWrapUnwrap)(const byte* key, word32 keySz,
const byte* in, word32 inSz, int wrap, byte* out, word32 outSz);
typedef int (*CallbackGetContent)(wc_PKCS7* pkcs7, byte** content, void* ctx);
typedef int (*CallbackStreamOut)(wc_PKCS7* pkcs7, const byte* output,
word32 outputSz, void* ctx);
#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
typedef int (*CallbackRsaSignRawDigest)(wc_PKCS7* pkcs7, byte* digest,
word32 digestSz, byte* out, word32 outSz,
byte* privateKey, word32 privateKeySz,
int devId, int hashOID);
#endif
#if defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK) && defined(HAVE_ECC)
typedef int (*CallbackEccSignRawDigest)(wc_PKCS7* pkcs7, byte* digest,
word32 digestSz, byte* out, word32 outSz,
byte* privateKey, word32 privateKeySz,
int devId, int hashOID);
#endif
struct wc_PKCS7 {
WC_RNG* rng;
PKCS7Attrib* signedAttribs;
byte* content;
byte* contentDynamic;
byte* singleCert;
const byte* issuer;
byte* privateKey;
void* heap;
#ifdef ASN_BER_TO_DER
byte* der;
word32 derSz;
byte indefDepth;
CallbackGetContent getContentCb;
CallbackStreamOut streamOutCb;
void* streamCtx;
#endif
WC_BITFIELD encodeStream:1;
WC_BITFIELD noCerts:1;
byte* cert[MAX_PKCS7_CERTS];
byte* verifyCert;
word32 verifyCertSz;
byte* encryptionKey;
PKCS7Attrib* unprotectedAttribs;
PKCS7DecodedAttrib* decodedAttrib;
byte* ukm;
word32 ukmSz;
word32 encryptionKeySz;
word32 unprotectedAttribsSz;
word32 contentSz;
word32 singleCertSz;
word32 issuerSz;
word32 issuerSnSz;
word32 publicKeySz;
word32 publicKeyOID;
word32 privateKeySz;
word32 signedAttribsSz;
int contentOID;
int hashOID;
int encryptOID;
int keyWrapOID;
int keyAgreeOID;
int devId;
byte issuerHash[KEYID_SIZE];
byte issuerSn[MAX_SN_SZ];
byte publicKey[MAX_RSA_INT_SZ + MAX_RSA_E_SZ];
word32 certSz[MAX_PKCS7_CERTS];
WC_BITFIELD isDynamic:1;
WC_BITFIELD noDegenerate:1;
WC_BITFIELD detached:1;
byte contentType[MAX_OID_SZ];
word32 contentTypeSz;
int sidType;
byte issuerSubjKeyId[KEYID_SIZE];
Pkcs7Cert* certList;
Pkcs7EncodedRecip* recipList;
byte* cek;
word32 cekSz;
byte* pass;
word32 passSz;
int kekEncryptOID;
CallbackOriEncrypt oriEncryptCb;
CallbackOriDecrypt oriDecryptCb;
void* oriEncryptCtx;
void* oriDecryptCtx;
PKCS7Attrib* authAttribs;
word32 authAttribsSz;
PKCS7Attrib* unauthAttribs;
word32 unauthAttribsSz;
#ifndef NO_PKCS7_STREAM
PKCS7State* stream;
#endif
word32 state;
word16 defaultSignedAttribs;
byte version;
PKCS7SignerInfo* signerInfo;
CallbackDecryptContent decryptionCb;
CallbackWrapCEK wrapCEKCb;
void* decryptionCtx;
byte* signature;
byte* plainDigest;
byte* pkcs7Digest;
word32 signatureSz;
word32 plainDigestSz;
word32 pkcs7DigestSz;
#ifdef WC_ASN_UNKNOWN_EXT_CB
wc_UnknownExtCallback unknownExtCallback;
#endif
#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
CallbackRsaSignRawDigest rsaSignRawDigestCb;
#endif
byte* cachedEncryptedContent;
word32 cachedEncryptedContentSz;
word32 totalEncryptedContentSz;
WC_BITFIELD contentCRLF:1;
WC_BITFIELD contentIsPkcs7Type:1;
WC_BITFIELD hashParamsAbsent:1;
byte* customSKID;
word16 customSKIDSz;
#if !defined(NO_DES3) || !defined(NO_AES)
union {
#ifndef NO_AES
Aes* aes;
#endif
#ifndef NO_DES3
Des* des;
Des3* des3;
#endif
} decryptKey;
#endif
CallbackAESKeyWrapUnwrap aesKeyWrapUnwrapCb;
#if defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK) && defined(HAVE_ECC)
CallbackEccSignRawDigest eccSignRawDigestCb;
#endif
#if defined(WC_RSA_PSS) && !defined(NO_RSA)
int pssSaltLen;
int pssHashType;
int pssMgf;
byte pssParamsPresent;
#endif
};
WOLFSSL_API wc_PKCS7* wc_PKCS7_New(void* heap, int devId);
#ifdef WC_ASN_UNKNOWN_EXT_CB
WOLFSSL_API void wc_PKCS7_SetUnknownExtCallback(wc_PKCS7* pkcs7,
wc_UnknownExtCallback cb);
#endif
WOLFSSL_API int wc_PKCS7_Init(wc_PKCS7* pkcs7, void* heap, int devId);
WOLFSSL_API int wc_PKCS7_InitWithCert(wc_PKCS7* pkcs7, byte* der, word32 derSz);
WOLFSSL_API int wc_PKCS7_AddCertificate(wc_PKCS7* pkcs7, byte* der, word32 derSz);
WOLFSSL_API void wc_PKCS7_Free(wc_PKCS7* pkcs7);
WOLFSSL_API int wc_PKCS7_GetAttributeValue(wc_PKCS7* pkcs7, const byte* oid,
word32 oidSz, byte* out, word32* outSz);
WOLFSSL_API int wc_PKCS7_SetSignerIdentifierType(wc_PKCS7* pkcs7, int type);
WOLFSSL_API int wc_PKCS7_SetContentType(wc_PKCS7* pkcs7, byte* contentType,
word32 sz);
WOLFSSL_API int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz);
WOLFSSL_API int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
word32 blockSz);
WOLFSSL_API int wc_PKCS7_EncodeData(wc_PKCS7* pkcs7, byte* output,
word32 outputSz);
WOLFSSL_API int wc_PKCS7_SetCustomSKID(wc_PKCS7* pkcs7, const byte* in,
word16 inSz);
WOLFSSL_API int wc_PKCS7_SetDetached(wc_PKCS7* pkcs7, word16 flag);
WOLFSSL_API int wc_PKCS7_NoDefaultSignedAttribs(wc_PKCS7* pkcs7);
WOLFSSL_API int wc_PKCS7_SetDefaultSignedAttribs(wc_PKCS7* pkcs7, word16 flag);
WOLFSSL_API int wc_PKCS7_EncodeSignedData(wc_PKCS7* pkcs7,
byte* output, word32 outputSz);
WOLFSSL_API int wc_PKCS7_EncodeSignedData_ex(wc_PKCS7* pkcs7, const byte* hashBuf,
word32 hashSz, byte* outputHead,
word32* outputHeadSz,
byte* outputFoot,
word32* outputFootSz);
WOLFSSL_API void wc_PKCS7_AllowDegenerate(wc_PKCS7* pkcs7, word16 flag);
WOLFSSL_API int wc_PKCS7_VerifySignedData(wc_PKCS7* pkcs7,
byte* pkiMsg, word32 pkiMsgSz);
WOLFSSL_API int wc_PKCS7_VerifySignedData_ex(wc_PKCS7* pkcs7, const byte* hashBuf,
word32 hashSz, byte* pkiMsgHead,
word32 pkiMsgHeadSz, byte* pkiMsgFoot,
word32 pkiMsgFootSz);
WOLFSSL_API int wc_PKCS7_GetSignerSID(wc_PKCS7* pkcs7, byte* out, word32* outSz);
WOLFSSL_API int wc_PKCS7_EncodeSignedFPD(wc_PKCS7* pkcs7, byte* privateKey,
word32 privateKeySz, int signOID,
int hashOID, byte* content,
word32 contentSz,
PKCS7Attrib* signedAttribs,
word32 signedAttribsSz, byte* output,
word32 outputSz);
#ifndef NO_PKCS7_ENCRYPTED_DATA
WOLFSSL_API int wc_PKCS7_EncodeSignedEncryptedFPD(wc_PKCS7* pkcs7,
byte* encryptKey, word32 encryptKeySz,
byte* privateKey, word32 privateKeySz,
int encryptOID, int signOID,
int hashOID, byte* content,
word32 contentSz,
PKCS7Attrib* unprotectedAttribs,
word32 unprotectedAttribsSz,
PKCS7Attrib* signedAttribs,
word32 signedAttribsSz,
byte* output, word32 outputSz);
#endif
#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
WOLFSSL_API int wc_PKCS7_EncodeSignedCompressedFPD(wc_PKCS7* pkcs7,
byte* privateKey, word32 privateKeySz,
int signOID, int hashOID,
byte* content, word32 contentSz,
PKCS7Attrib* signedAttribs,
word32 signedAttribsSz, byte* output,
word32 outputSz);
#ifndef NO_PKCS7_ENCRYPTED_DATA
WOLFSSL_API int wc_PKCS7_EncodeSignedEncryptedCompressedFPD(wc_PKCS7* pkcs7,
byte* encryptKey, word32 encryptKeySz,
byte* privateKey, word32 privateKeySz,
int encryptOID, int signOID,
int hashOID, byte* content,
word32 contentSz,
PKCS7Attrib* unprotectedAttribs,
word32 unprotectedAttribsSz,
PKCS7Attrib* signedAttribs,
word32 signedAttribsSz,
byte* output, word32 outputSz);
#endif
#endif
WOLFSSL_API int wc_PKCS7_AddRecipient_KTRI(wc_PKCS7* pkcs7, const byte* cert,
word32 certSz, int options);
WOLFSSL_API int wc_PKCS7_AddRecipient_KARI(wc_PKCS7* pkcs7, const byte* cert,
word32 certSz, int keyWrapOID,
int keyAgreeOID, byte* ukm,
word32 ukmSz, int options);
WOLFSSL_API int wc_PKCS7_SetKey(wc_PKCS7* pkcs7, byte* key, word32 keySz);
WOLFSSL_API int wc_PKCS7_AddRecipient_KEKRI(wc_PKCS7* pkcs7, int keyWrapOID,
byte* kek, word32 kekSz,
byte* keyID, word32 keyIdSz,
void* timePtr, byte* otherOID,
word32 otherOIDSz, byte* other,
word32 otherSz, int options);
WOLFSSL_API int wc_PKCS7_SetPassword(wc_PKCS7* pkcs7, byte* passwd, word32 pLen);
WOLFSSL_API int wc_PKCS7_AddRecipient_PWRI(wc_PKCS7* pkcs7, byte* passwd,
word32 pLen, byte* salt,
word32 saltSz, int kdfOID,
int prfOID, int iterations,
int kekEncryptOID, int options);
WOLFSSL_API int wc_PKCS7_SetOriEncryptCtx(wc_PKCS7* pkcs7, void* ctx);
WOLFSSL_API int wc_PKCS7_SetOriDecryptCtx(wc_PKCS7* pkcs7, void* ctx);
WOLFSSL_API int wc_PKCS7_SetOriDecryptCb(wc_PKCS7* pkcs7, CallbackOriDecrypt cb);
WOLFSSL_API int wc_PKCS7_AddRecipient_ORI(wc_PKCS7* pkcs7, CallbackOriEncrypt cb,
int options);
WOLFSSL_API int wc_PKCS7_SetWrapCEKCb(wc_PKCS7* pkcs7,
CallbackWrapCEK wrapCEKCb);
WOLFSSL_API int wc_PKCS7_SetAESKeyWrapUnwrapCb(wc_PKCS7* pkcs7,
CallbackAESKeyWrapUnwrap aesKeyWrapUnwrapCb);
#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
WOLFSSL_API int wc_PKCS7_SetRsaSignRawDigestCb(wc_PKCS7* pkcs7,
CallbackRsaSignRawDigest cb);
#endif
#if defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK) && defined(HAVE_ECC)
WOLFSSL_API int wc_PKCS7_SetEccSignRawDigestCb(wc_PKCS7* pkcs7,
CallbackEccSignRawDigest cb);
#endif
WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(wc_PKCS7* pkcs7,
byte* output, word32 outputSz);
WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* pkiMsg,
word32 pkiMsgSz, byte* output,
word32 outputSz);
WOLFSSL_API int wc_PKCS7_GetEnvelopedDataKariRid(const byte * in, word32 inSz,
byte * out, word32 * outSz);
WOLFSSL_API int wc_PKCS7_EncodeAuthEnvelopedData(wc_PKCS7* pkcs7,
byte* output, word32 outputSz);
WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* pkiMsg,
word32 pkiMsgSz, byte* output,
word32 outputSz);
#ifndef NO_PKCS7_ENCRYPTED_DATA
WOLFSSL_API int wc_PKCS7_EncodeEncryptedData(wc_PKCS7* pkcs7,
byte* output, word32 outputSz);
WOLFSSL_API int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* pkiMsg,
word32 pkiMsgSz, byte* output,
word32 outputSz);
WOLFSSL_API int wc_PKCS7_SetDecodeEncryptedCb(wc_PKCS7* pkcs7,
CallbackDecryptContent decryptionCb);
WOLFSSL_API int wc_PKCS7_SetDecodeEncryptedCtx(wc_PKCS7* pkcs7, void* ctx);
#endif
WOLFSSL_API int wc_PKCS7_DecodeEncryptedKeyPackage(wc_PKCS7 * pkcs7,
byte * pkiMsg, word32 pkiMsgSz, byte * output, word32 outputSz);
WOLFSSL_LOCAL int wc_PKCS7_WriteOut(wc_PKCS7* pkcs7, byte* output,
const byte* input, word32 inputSz);
WOLFSSL_API int wc_PKCS7_SetStreamMode(wc_PKCS7* pkcs7, byte flag,
CallbackGetContent getContentCb, CallbackStreamOut streamOutCb, void* ctx);
WOLFSSL_API int wc_PKCS7_GetStreamMode(wc_PKCS7* pkcs7);
WOLFSSL_API int wc_PKCS7_SetNoCerts(wc_PKCS7* pkcs7, byte flag);
WOLFSSL_API int wc_PKCS7_GetNoCerts(wc_PKCS7* pkcs7);
#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
WOLFSSL_API int wc_PKCS7_EncodeCompressedData(wc_PKCS7* pkcs7, byte* output,
word32 outputSz);
WOLFSSL_API int wc_PKCS7_DecodeCompressedData(wc_PKCS7* pkcs7, byte* pkiMsg,
word32 pkiMsgSz, byte* output,
word32 outputSz);
#endif
WOLFSSL_API int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(const byte * skp,
word32 skpSz, size_t index, const byte ** attr, word32 * attrSz);
WOLFSSL_API int wc_PKCS7_DecodeSymmetricKeyPackageKey(const byte * skp,
word32 skpSz, size_t index, const byte ** key, word32 * keySz);
WOLFSSL_API int wc_PKCS7_DecodeOneSymmetricKeyAttribute(const byte * osk,
word32 oskSz, size_t index, const byte ** attr, word32 * attrSz);
WOLFSSL_API int wc_PKCS7_DecodeOneSymmetricKeyKey(const byte * osk,
word32 oskSz, const byte ** key, word32 * keySz);
#ifdef __cplusplus
}
#endif
#endif
#endif