| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| /* |
| * Header for CMS types. |
| */ |
| |
| #ifndef _CMST_H_ |
| #define _CMST_H_ |
| |
| #include "seccomon.h" |
| #include "secoidt.h" |
| #include "certt.h" |
| #include "secmodt.h" |
| #include "secmodt.h" |
| |
| #include "plarena.h" |
| |
| /* Non-opaque objects. NOTE, though: I want them to be treated as |
| * opaque as much as possible. If I could hide them completely, |
| * I would. (I tried, but ran into trouble that was taking me too |
| * much time to get out of.) I still intend to try to do so. |
| * In fact, the only type that "outsiders" should even *name* is |
| * NSSCMSMessage, and they should not reference its fields. |
| */ |
| /* rjr: PKCS #11 cert handling (pk11cert.c) does use NSSCMSRecipientInfo's. |
| * This is because when we search the recipient list for the cert and key we |
| * want, we need to invert the order of the loops we used to have. The old |
| * loops were: |
| * |
| * For each recipient { |
| * find_cert = PK11_Find_AllCert(recipient->issuerSN); |
| * [which unrolls to... ] |
| * For each slot { |
| * Log into slot; |
| * search slot for cert; |
| * } |
| * } |
| * |
| * the new loop searchs all the recipients at once on a slot. this allows |
| * PKCS #11 to order slots in such a way that logout slots don't get checked |
| * if we can find the cert on a logged in slot. This eliminates lots of |
| * spurious password prompts when smart cards are installed... so why this |
| * comment? If you make NSSCMSRecipientInfo completely opaque, you need |
| * to provide a non-opaque list of issuerSN's (the only field PKCS#11 needs |
| * and fix up pk11cert.c first. NOTE: Only S/MIME calls this special PKCS #11 |
| * function. |
| */ |
| |
| typedef struct NSSCMSMessageStr NSSCMSMessage; |
| |
| typedef union NSSCMSContentUnion NSSCMSContent; |
| typedef struct NSSCMSContentInfoStr NSSCMSContentInfo; |
| |
| typedef struct NSSCMSSignedDataStr NSSCMSSignedData; |
| typedef struct NSSCMSSignerInfoStr NSSCMSSignerInfo; |
| typedef struct NSSCMSSignerIdentifierStr NSSCMSSignerIdentifier; |
| |
| typedef struct NSSCMSEnvelopedDataStr NSSCMSEnvelopedData; |
| typedef struct NSSCMSOriginatorInfoStr NSSCMSOriginatorInfo; |
| typedef struct NSSCMSRecipientInfoStr NSSCMSRecipientInfo; |
| |
| typedef struct NSSCMSDigestedDataStr NSSCMSDigestedData; |
| typedef struct NSSCMSEncryptedDataStr NSSCMSEncryptedData; |
| |
| typedef struct NSSCMSGenericWrapperDataStr NSSCMSGenericWrapperData; |
| |
| typedef struct NSSCMSAttributeStr NSSCMSAttribute; |
| |
| typedef struct NSSCMSDecoderContextStr NSSCMSDecoderContext; |
| typedef struct NSSCMSEncoderContextStr NSSCMSEncoderContext; |
| |
| typedef struct NSSCMSCipherContextStr NSSCMSCipherContext; |
| typedef struct NSSCMSDigestContextStr NSSCMSDigestContext; |
| |
| typedef struct NSSCMSContentInfoPrivateStr NSSCMSContentInfoPrivate; |
| |
| typedef SECStatus (*NSSCMSGenericWrapperDataCallback)(NSSCMSGenericWrapperData *); |
| typedef void (*NSSCMSGenericWrapperDataDestroy)(NSSCMSGenericWrapperData *); |
| |
| extern const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[]; |
| extern const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[]; |
| |
| SEC_ASN1_CHOOSER_DECLARE(NSS_PointerToCMSGenericWrapperDataTemplate) |
| SEC_ASN1_CHOOSER_DECLARE(NSSCMSGenericWrapperDataTemplate) |
| |
| /* |
| * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart. |
| * If specified, this is where the content bytes (only) will be "sent" |
| * as they are recovered during the decoding. |
| * And: |
| * Type of function passed to NSSCMSEncode or NSSCMSEncoderStart. |
| * This is where the DER-encoded bytes will be "sent". |
| * |
| * XXX Should just combine this with NSSCMSEncoderContentCallback type |
| * and use a simpler, common name. |
| */ |
| typedef void (*NSSCMSContentCallback)(void *arg, const char *buf, unsigned long len); |
| |
| /* |
| * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart |
| * to retrieve the decryption key. This function is intended to be |
| * used for EncryptedData content info's which do not have a key available |
| * in a certificate, etc. |
| */ |
| typedef PK11SymKey *(*NSSCMSGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid); |
| |
| /* ============================================================================= |
| * ENCAPSULATED CONTENTINFO & CONTENTINFO |
| */ |
| |
| union NSSCMSContentUnion { |
| /* either unstructured */ |
| SECItem *data; |
| /* or structured data */ |
| NSSCMSDigestedData *digestedData; |
| NSSCMSEncryptedData *encryptedData; |
| NSSCMSEnvelopedData *envelopedData; |
| NSSCMSSignedData *signedData; |
| NSSCMSGenericWrapperData *genericData; |
| /* or anonymous pointer to something */ |
| void *pointer; |
| }; |
| |
| struct NSSCMSContentInfoStr { |
| SECItem contentType; |
| NSSCMSContent content; |
| /* --------- local; not part of encoding --------- */ |
| SECOidData *contentTypeTag; |
| |
| /* additional info for encryptedData and envelopedData */ |
| /* we waste this space for signedData and digestedData. sue me. */ |
| |
| SECAlgorithmID contentEncAlg; |
| SECItem *rawContent; /* encrypted DER, optional */ |
| /* XXXX bytes not encrypted, but encoded? */ |
| /* --------- local; not part of encoding --------- */ |
| PK11SymKey *bulkkey; /* bulk encryption key */ |
| int keysize; /* size of bulk encryption key |
| * (only used by creation code) */ |
| SECOidTag contentEncAlgTag; /* oid tag of encryption algorithm |
| * (only used by creation code) */ |
| NSSCMSContentInfoPrivate *privateInfo; /* place for NSS private info */ |
| void *reserved; /* keep binary compatibility */ |
| }; |
| |
| /* ============================================================================= |
| * MESSAGE |
| */ |
| |
| struct NSSCMSMessageStr { |
| NSSCMSContentInfo contentInfo; /* "outer" cinfo */ |
| /* --------- local; not part of encoding --------- */ |
| PLArenaPool *poolp; |
| PRBool poolp_is_ours; |
| int refCount; |
| /* properties of the "inner" data */ |
| SECAlgorithmID **detached_digestalgs; |
| SECItem **detached_digests; |
| void *pwfn_arg; |
| NSSCMSGetDecryptKeyCallback decrypt_key_cb; |
| void *decrypt_key_cb_arg; |
| }; |
| |
| /* ============================================================================ |
| * GENERIC WRAPPER |
| * |
| * used for user defined types. |
| */ |
| struct NSSCMSGenericWrapperDataStr { |
| NSSCMSContentInfo contentInfo; |
| /* ---- local; not part of encoding ------ */ |
| NSSCMSMessage *cmsg; |
| /* wrapperspecific data starts here */ |
| }; |
| |
| /* ============================================================================= |
| * SIGNEDDATA |
| */ |
| |
| struct NSSCMSSignedDataStr { |
| SECItem version; |
| SECAlgorithmID **digestAlgorithms; |
| NSSCMSContentInfo contentInfo; |
| SECItem **rawCerts; |
| CERTSignedCrl **crls; |
| NSSCMSSignerInfo **signerInfos; |
| /* --------- local; not part of encoding --------- */ |
| NSSCMSMessage *cmsg; /* back pointer to message */ |
| SECItem **digests; |
| CERTCertificate **certs; |
| CERTCertificateList **certLists; |
| CERTCertificate **tempCerts; /* temporary certs, needed |
| * for example for signature |
| * verification */ |
| }; |
| #define NSS_CMS_SIGNED_DATA_VERSION_BASIC 1 /* what we *create* */ |
| #define NSS_CMS_SIGNED_DATA_VERSION_EXT 3 /* what we *create* */ |
| |
| typedef enum { |
| NSSCMSVS_Unverified = 0, |
| NSSCMSVS_GoodSignature = 1, |
| NSSCMSVS_BadSignature = 2, |
| NSSCMSVS_DigestMismatch = 3, |
| NSSCMSVS_SigningCertNotFound = 4, |
| NSSCMSVS_SigningCertNotTrusted = 5, |
| NSSCMSVS_SignatureAlgorithmUnknown = 6, |
| NSSCMSVS_SignatureAlgorithmUnsupported = 7, |
| NSSCMSVS_MalformedSignature = 8, |
| NSSCMSVS_ProcessingError = 9 |
| } NSSCMSVerificationStatus; |
| |
| typedef enum { |
| NSSCMSSignerID_IssuerSN = 0, |
| NSSCMSSignerID_SubjectKeyID = 1 |
| } NSSCMSSignerIDSelector; |
| |
| struct NSSCMSSignerIdentifierStr { |
| NSSCMSSignerIDSelector identifierType; |
| union { |
| CERTIssuerAndSN *issuerAndSN; |
| SECItem *subjectKeyID; |
| } id; |
| }; |
| |
| struct NSSCMSSignerInfoStr { |
| SECItem version; |
| NSSCMSSignerIdentifier signerIdentifier; |
| SECAlgorithmID digestAlg; |
| NSSCMSAttribute **authAttr; |
| SECAlgorithmID digestEncAlg; |
| SECItem encDigest; |
| NSSCMSAttribute **unAuthAttr; |
| /* --------- local; not part of encoding --------- */ |
| NSSCMSMessage *cmsg; /* back pointer to message */ |
| CERTCertificate *cert; |
| CERTCertificateList *certList; |
| PRTime signingTime; |
| NSSCMSVerificationStatus verificationStatus; |
| SECKEYPrivateKey *signingKey; /* Used if we're using subjKeyID*/ |
| SECKEYPublicKey *pubKey; |
| }; |
| #define NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */ |
| #define NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */ |
| |
| typedef enum { |
| NSSCMSCM_None = 0, |
| NSSCMSCM_CertOnly = 1, |
| NSSCMSCM_CertChain = 2, |
| NSSCMSCM_CertChainWithRoot = 3 |
| } NSSCMSCertChainMode; |
| |
| /* ============================================================================= |
| * ENVELOPED DATA |
| */ |
| struct NSSCMSEnvelopedDataStr { |
| SECItem version; |
| NSSCMSOriginatorInfo *originatorInfo; /* optional */ |
| NSSCMSRecipientInfo **recipientInfos; |
| NSSCMSContentInfo contentInfo; |
| NSSCMSAttribute **unprotectedAttr; |
| /* --------- local; not part of encoding --------- */ |
| NSSCMSMessage *cmsg; /* back pointer to message */ |
| }; |
| #define NSS_CMS_ENVELOPED_DATA_VERSION_REG 0 /* what we *create* */ |
| #define NSS_CMS_ENVELOPED_DATA_VERSION_ADV 2 /* what we *create* */ |
| |
| struct NSSCMSOriginatorInfoStr { |
| SECItem **rawCerts; |
| CERTSignedCrl **crls; |
| /* --------- local; not part of encoding --------- */ |
| CERTCertificate **certs; |
| }; |
| |
| /* ----------------------------------------------------------------------------- |
| * key transport recipient info |
| */ |
| typedef enum { |
| NSSCMSRecipientID_IssuerSN = 0, |
| NSSCMSRecipientID_SubjectKeyID = 1, |
| NSSCMSRecipientID_BrandNew = 2 |
| } NSSCMSRecipientIDSelector; |
| |
| struct NSSCMSRecipientIdentifierStr { |
| NSSCMSRecipientIDSelector identifierType; |
| union { |
| CERTIssuerAndSN *issuerAndSN; |
| SECItem *subjectKeyID; |
| } id; |
| }; |
| typedef struct NSSCMSRecipientIdentifierStr NSSCMSRecipientIdentifier; |
| |
| struct NSSCMSKeyTransRecipientInfoStr { |
| SECItem version; |
| NSSCMSRecipientIdentifier recipientIdentifier; |
| SECAlgorithmID keyEncAlg; |
| SECItem encKey; |
| }; |
| typedef struct NSSCMSKeyTransRecipientInfoStr NSSCMSKeyTransRecipientInfo; |
| |
| /* |
| * View comments before NSSCMSRecipientInfoStr for purpose of this |
| * structure. |
| */ |
| struct NSSCMSKeyTransRecipientInfoExStr { |
| NSSCMSKeyTransRecipientInfo recipientInfo; |
| int version; /* version of this structure (0) */ |
| SECKEYPublicKey *pubKey; |
| }; |
| |
| typedef struct NSSCMSKeyTransRecipientInfoExStr NSSCMSKeyTransRecipientInfoEx; |
| |
| #define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN 0 /* what we *create* */ |
| #define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY 2 /* what we *create* */ |
| |
| /* ----------------------------------------------------------------------------- |
| * key agreement recipient info |
| */ |
| struct NSSCMSOriginatorPublicKeyStr { |
| SECAlgorithmID algorithmIdentifier; |
| SECItem publicKey; /* bit string! */ |
| }; |
| typedef struct NSSCMSOriginatorPublicKeyStr NSSCMSOriginatorPublicKey; |
| |
| typedef enum { |
| NSSCMSOriginatorIDOrKey_IssuerSN = 0, |
| NSSCMSOriginatorIDOrKey_SubjectKeyID = 1, |
| NSSCMSOriginatorIDOrKey_OriginatorPublicKey = 2 |
| } NSSCMSOriginatorIDOrKeySelector; |
| |
| struct NSSCMSOriginatorIdentifierOrKeyStr { |
| NSSCMSOriginatorIDOrKeySelector identifierType; |
| union { |
| CERTIssuerAndSN *issuerAndSN; /* static-static */ |
| SECItem *subjectKeyID; /* static-static */ |
| NSSCMSOriginatorPublicKey originatorPublicKey; /* ephemeral-static */ |
| } id; |
| }; |
| typedef struct NSSCMSOriginatorIdentifierOrKeyStr NSSCMSOriginatorIdentifierOrKey; |
| |
| struct NSSCMSRecipientKeyIdentifierStr { |
| SECItem *subjectKeyIdentifier; |
| SECItem *date; /* optional */ |
| SECItem *other; /* optional */ |
| }; |
| typedef struct NSSCMSRecipientKeyIdentifierStr NSSCMSRecipientKeyIdentifier; |
| |
| typedef enum { |
| NSSCMSKeyAgreeRecipientID_IssuerSN = 0, |
| NSSCMSKeyAgreeRecipientID_RKeyID = 1 |
| } NSSCMSKeyAgreeRecipientIDSelector; |
| |
| struct NSSCMSKeyAgreeRecipientIdentifierStr { |
| NSSCMSKeyAgreeRecipientIDSelector identifierType; |
| union { |
| CERTIssuerAndSN *issuerAndSN; |
| NSSCMSRecipientKeyIdentifier recipientKeyIdentifier; |
| } id; |
| }; |
| typedef struct NSSCMSKeyAgreeRecipientIdentifierStr NSSCMSKeyAgreeRecipientIdentifier; |
| |
| struct NSSCMSRecipientEncryptedKeyStr { |
| NSSCMSKeyAgreeRecipientIdentifier recipientIdentifier; |
| SECItem encKey; |
| }; |
| typedef struct NSSCMSRecipientEncryptedKeyStr NSSCMSRecipientEncryptedKey; |
| |
| struct NSSCMSKeyAgreeRecipientInfoStr { |
| SECItem version; |
| NSSCMSOriginatorIdentifierOrKey originatorIdentifierOrKey; |
| SECItem *ukm; /* optional */ |
| SECAlgorithmID keyEncAlg; |
| NSSCMSRecipientEncryptedKey **recipientEncryptedKeys; |
| }; |
| typedef struct NSSCMSKeyAgreeRecipientInfoStr NSSCMSKeyAgreeRecipientInfo; |
| |
| #define NSS_CMS_KEYAGREE_RECIPIENT_INFO_VERSION 3 /* what we *create* */ |
| |
| /* ----------------------------------------------------------------------------- |
| * KEK recipient info |
| */ |
| struct NSSCMSKEKIdentifierStr { |
| SECItem keyIdentifier; |
| SECItem *date; /* optional */ |
| SECItem *other; /* optional */ |
| }; |
| typedef struct NSSCMSKEKIdentifierStr NSSCMSKEKIdentifier; |
| |
| struct NSSCMSKEKRecipientInfoStr { |
| SECItem version; |
| NSSCMSKEKIdentifier kekIdentifier; |
| SECAlgorithmID keyEncAlg; |
| SECItem encKey; |
| }; |
| typedef struct NSSCMSKEKRecipientInfoStr NSSCMSKEKRecipientInfo; |
| |
| #define NSS_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */ |
| |
| /* ----------------------------------------------------------------------------- |
| * recipient info |
| */ |
| |
| typedef enum { |
| NSSCMSRecipientInfoID_KeyTrans = 0, |
| NSSCMSRecipientInfoID_KeyAgree = 1, |
| NSSCMSRecipientInfoID_KEK = 2 |
| } NSSCMSRecipientInfoIDSelector; |
| |
| /* |
| * In order to preserve backwards binary compatibility when implementing |
| * creation of Recipient Info's that uses subjectKeyID in the |
| * keyTransRecipientInfo we need to stash a public key pointer in this |
| * structure somewhere. We figured out that NSSCMSKeyTransRecipientInfo |
| * is the smallest member of the ri union. We're in luck since that's |
| * the very structure that would need to use the public key. So we created |
| * a new structure NSSCMSKeyTransRecipientInfoEx which has a member |
| * NSSCMSKeyTransRecipientInfo as the first member followed by a version |
| * and a public key pointer. This way we can keep backwards compatibility |
| * without changing the size of this structure. |
| * |
| * BTW, size of structure: |
| * NSSCMSKeyTransRecipientInfo: 9 ints, 4 pointers |
| * NSSCMSKeyAgreeRecipientInfo: 12 ints, 8 pointers |
| * NSSCMSKEKRecipientInfo: 10 ints, 7 pointers |
| * |
| * The new structure: |
| * NSSCMSKeyTransRecipientInfoEx: sizeof(NSSCMSKeyTransRecipientInfo) + |
| * 1 int, 1 pointer |
| */ |
| |
| struct NSSCMSRecipientInfoStr { |
| NSSCMSRecipientInfoIDSelector recipientInfoType; |
| union { |
| NSSCMSKeyTransRecipientInfo keyTransRecipientInfo; |
| NSSCMSKeyAgreeRecipientInfo keyAgreeRecipientInfo; |
| NSSCMSKEKRecipientInfo kekRecipientInfo; |
| NSSCMSKeyTransRecipientInfoEx keyTransRecipientInfoEx; |
| } ri; |
| /* --------- local; not part of encoding --------- */ |
| NSSCMSMessage *cmsg; /* back pointer to message */ |
| CERTCertificate *cert; /* recipient's certificate */ |
| }; |
| |
| /* ============================================================================= |
| * DIGESTED DATA |
| */ |
| struct NSSCMSDigestedDataStr { |
| SECItem version; |
| SECAlgorithmID digestAlg; |
| NSSCMSContentInfo contentInfo; |
| SECItem digest; |
| /* --------- local; not part of encoding --------- */ |
| NSSCMSMessage *cmsg; /* back pointer */ |
| SECItem cdigest; /* calculated digest */ |
| }; |
| #define NSS_CMS_DIGESTED_DATA_VERSION_DATA 0 /* what we *create* */ |
| #define NSS_CMS_DIGESTED_DATA_VERSION_ENCAP 2 /* what we *create* */ |
| |
| /* ============================================================================= |
| * ENCRYPTED DATA |
| */ |
| struct NSSCMSEncryptedDataStr { |
| SECItem version; |
| NSSCMSContentInfo contentInfo; |
| NSSCMSAttribute **unprotectedAttr; /* optional */ |
| /* --------- local; not part of encoding --------- */ |
| NSSCMSMessage *cmsg; /* back pointer */ |
| }; |
| #define NSS_CMS_ENCRYPTED_DATA_VERSION 0 /* what we *create* */ |
| #define NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */ |
| |
| /* |
| * ***************************************************************************** |
| * ***************************************************************************** |
| * ***************************************************************************** |
| */ |
| |
| /* |
| * See comment above about this type not really belonging to CMS. |
| */ |
| struct NSSCMSAttributeStr { |
| /* The following fields make up an encoded Attribute: */ |
| SECItem type; |
| SECItem **values; /* data may or may not be encoded */ |
| /* The following fields are not part of an encoded Attribute: */ |
| SECOidData *typeTag; |
| PRBool encoded; /* when true, values are encoded */ |
| }; |
| |
| #endif /* _CMST_H_ */ |