michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * CMS ASN.1 templates michael@0: */ michael@0: michael@0: #include "cmslocal.h" michael@0: michael@0: #include "cert.h" michael@0: #include "key.h" michael@0: #include "secasn1.h" michael@0: #include "secitem.h" michael@0: #include "secoid.h" michael@0: #include "prtime.h" michael@0: #include "secerr.h" michael@0: michael@0: michael@0: extern const SEC_ASN1Template nss_cms_set_of_attribute_template[]; michael@0: michael@0: SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate) michael@0: SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate) michael@0: SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) michael@0: SEC_ASN1_MKSUB(SEC_BitStringTemplate) michael@0: SEC_ASN1_MKSUB(SEC_OctetStringTemplate) michael@0: SEC_ASN1_MKSUB(SEC_PointerToOctetStringTemplate) michael@0: SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate) michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * MESSAGE michael@0: * (uses NSSCMSContentInfo) michael@0: */ michael@0: michael@0: /* forward declaration */ michael@0: static const SEC_ASN1Template * michael@0: nss_cms_choose_content_template(void *src_or_dest, PRBool encoding); michael@0: michael@0: static const SEC_ASN1TemplateChooserPtr nss_cms_chooser michael@0: = nss_cms_choose_content_template; michael@0: michael@0: const SEC_ASN1Template NSSCMSMessageTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, michael@0: 0, NULL, sizeof(NSSCMSMessage) }, michael@0: { SEC_ASN1_OBJECT_ID, michael@0: offsetof(NSSCMSMessage,contentInfo.contentType) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM michael@0: | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, michael@0: offsetof(NSSCMSMessage,contentInfo.content), michael@0: &nss_cms_chooser }, michael@0: { 0 } michael@0: }; michael@0: michael@0: static const SEC_ASN1Template NSS_PointerToCMSMessageTemplate[] = { michael@0: { SEC_ASN1_POINTER, 0, NSSCMSMessageTemplate } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * ENCAPSULATED & ENCRYPTED CONTENTINFO michael@0: * (both use a NSSCMSContentInfo) michael@0: */ michael@0: static const SEC_ASN1Template NSSCMSEncapsulatedContentInfoTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, michael@0: 0, NULL, sizeof(NSSCMSContentInfo) }, michael@0: { SEC_ASN1_OBJECT_ID, michael@0: offsetof(NSSCMSContentInfo,contentType) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_MAY_STREAM | michael@0: SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, michael@0: offsetof(NSSCMSContentInfo,rawContent), michael@0: SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: static const SEC_ASN1Template NSSCMSEncryptedContentInfoTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, michael@0: 0, NULL, sizeof(NSSCMSContentInfo) }, michael@0: { SEC_ASN1_OBJECT_ID, michael@0: offsetof(NSSCMSContentInfo,contentType) }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSContentInfo,contentEncAlg), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM | michael@0: SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, michael@0: offsetof(NSSCMSContentInfo,rawContent), michael@0: SEC_ASN1_SUB(SEC_OctetStringTemplate) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * SIGNED DATA michael@0: */ michael@0: michael@0: const SEC_ASN1Template NSSCMSSignerInfoTemplate[]; michael@0: michael@0: const SEC_ASN1Template NSSCMSSignedDataTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, michael@0: 0, NULL, sizeof(NSSCMSSignedData) }, michael@0: { SEC_ASN1_INTEGER, michael@0: offsetof(NSSCMSSignedData,version) }, michael@0: { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSSignedData,digestAlgorithms), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSSignedData,contentInfo), michael@0: NSSCMSEncapsulatedContentInfoTemplate }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | michael@0: SEC_ASN1_XTRN | 0, michael@0: offsetof(NSSCMSSignedData,rawCerts), michael@0: SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | michael@0: SEC_ASN1_XTRN | 1, michael@0: offsetof(NSSCMSSignedData,crls), michael@0: SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) }, michael@0: { SEC_ASN1_SET_OF, michael@0: offsetof(NSSCMSSignedData,signerInfos), michael@0: NSSCMSSignerInfoTemplate }, michael@0: { 0 } michael@0: }; michael@0: michael@0: const SEC_ASN1Template NSS_PointerToCMSSignedDataTemplate[] = { michael@0: { SEC_ASN1_POINTER, 0, NSSCMSSignedDataTemplate } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * signeridentifier michael@0: */ michael@0: michael@0: static const SEC_ASN1Template NSSCMSSignerIdentifierTemplate[] = { michael@0: { SEC_ASN1_CHOICE, michael@0: offsetof(NSSCMSSignerIdentifier,identifierType), NULL, michael@0: sizeof(NSSCMSSignerIdentifier) }, michael@0: { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, michael@0: offsetof(NSSCMSSignerIdentifier,id.subjectKeyID), michael@0: SEC_ASN1_SUB(SEC_OctetStringTemplate) , michael@0: NSSCMSRecipientID_SubjectKeyID }, michael@0: { SEC_ASN1_POINTER | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSSignerIdentifier,id.issuerAndSN), michael@0: SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), michael@0: NSSCMSRecipientID_IssuerSN }, michael@0: { 0 } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * signerinfo michael@0: */ michael@0: michael@0: const SEC_ASN1Template NSSCMSSignerInfoTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSSignerInfo) }, michael@0: { SEC_ASN1_INTEGER, michael@0: offsetof(NSSCMSSignerInfo,version) }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSSignerInfo,signerIdentifier), michael@0: NSSCMSSignerIdentifierTemplate }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSSignerInfo,digestAlg), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, michael@0: offsetof(NSSCMSSignerInfo,authAttr), michael@0: nss_cms_set_of_attribute_template }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSSignerInfo,digestEncAlg), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSSignerInfo,encDigest) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, michael@0: offsetof(NSSCMSSignerInfo,unAuthAttr), michael@0: nss_cms_set_of_attribute_template }, michael@0: { 0 } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * ENVELOPED DATA michael@0: */ michael@0: michael@0: static const SEC_ASN1Template NSSCMSOriginatorInfoTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSOriginatorInfo) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | michael@0: SEC_ASN1_XTRN | 0, michael@0: offsetof(NSSCMSOriginatorInfo,rawCerts), michael@0: SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | michael@0: SEC_ASN1_XTRN | 1, michael@0: offsetof(NSSCMSOriginatorInfo,crls), michael@0: SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: const SEC_ASN1Template NSSCMSRecipientInfoTemplate[]; michael@0: michael@0: const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, michael@0: 0, NULL, sizeof(NSSCMSEnvelopedData) }, michael@0: { SEC_ASN1_INTEGER, michael@0: offsetof(NSSCMSEnvelopedData,version) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, michael@0: offsetof(NSSCMSEnvelopedData,originatorInfo), michael@0: NSSCMSOriginatorInfoTemplate }, michael@0: { SEC_ASN1_SET_OF, michael@0: offsetof(NSSCMSEnvelopedData,recipientInfos), michael@0: NSSCMSRecipientInfoTemplate }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSEnvelopedData,contentInfo), michael@0: NSSCMSEncryptedContentInfoTemplate }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, michael@0: offsetof(NSSCMSEnvelopedData,unprotectedAttr), michael@0: nss_cms_set_of_attribute_template }, michael@0: { 0 } michael@0: }; michael@0: michael@0: const SEC_ASN1Template NSS_PointerToCMSEnvelopedDataTemplate[] = { michael@0: { SEC_ASN1_POINTER, 0, NSSCMSEnvelopedDataTemplate } michael@0: }; michael@0: michael@0: /* here come the 15 gazillion templates for all the v3 varieties of RecipientInfo */ michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * key transport recipient info michael@0: */ michael@0: michael@0: static const SEC_ASN1Template NSSCMSRecipientIdentifierTemplate[] = { michael@0: { SEC_ASN1_CHOICE, michael@0: offsetof(NSSCMSRecipientIdentifier,identifierType), NULL, michael@0: sizeof(NSSCMSRecipientIdentifier) }, michael@0: { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, michael@0: offsetof(NSSCMSRecipientIdentifier,id.subjectKeyID), michael@0: SEC_ASN1_SUB(SEC_OctetStringTemplate) , michael@0: NSSCMSRecipientID_SubjectKeyID }, michael@0: { SEC_ASN1_POINTER | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSRecipientIdentifier,id.issuerAndSN), michael@0: SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), michael@0: NSSCMSRecipientID_IssuerSN }, michael@0: { 0 } michael@0: }; michael@0: michael@0: michael@0: static const SEC_ASN1Template NSSCMSKeyTransRecipientInfoTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSKeyTransRecipientInfo) }, michael@0: { SEC_ASN1_INTEGER, michael@0: offsetof(NSSCMSKeyTransRecipientInfo,version) }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSKeyTransRecipientInfo,recipientIdentifier), michael@0: NSSCMSRecipientIdentifierTemplate }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSKeyTransRecipientInfo,keyEncAlg), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSKeyTransRecipientInfo,encKey) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * key agreement recipient info michael@0: */ michael@0: michael@0: static const SEC_ASN1Template NSSCMSOriginatorPublicKeyTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSOriginatorPublicKey) }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSOriginatorPublicKey,algorithmIdentifier), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSOriginatorPublicKey,publicKey), michael@0: SEC_ASN1_SUB(SEC_BitStringTemplate) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: michael@0: static const SEC_ASN1Template NSSCMSOriginatorIdentifierOrKeyTemplate[] = { michael@0: { SEC_ASN1_CHOICE, michael@0: offsetof(NSSCMSOriginatorIdentifierOrKey,identifierType), NULL, michael@0: sizeof(NSSCMSOriginatorIdentifierOrKey) }, michael@0: { SEC_ASN1_POINTER | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSOriginatorIdentifierOrKey,id.issuerAndSN), michael@0: SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), michael@0: NSSCMSOriginatorIDOrKey_IssuerSN }, michael@0: { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | michael@0: SEC_ASN1_XTRN | 1, michael@0: offsetof(NSSCMSOriginatorIdentifierOrKey,id.subjectKeyID), michael@0: SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) , michael@0: NSSCMSOriginatorIDOrKey_SubjectKeyID }, michael@0: { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, michael@0: offsetof(NSSCMSOriginatorIdentifierOrKey,id.originatorPublicKey), michael@0: NSSCMSOriginatorPublicKeyTemplate, michael@0: NSSCMSOriginatorIDOrKey_OriginatorPublicKey }, michael@0: { 0 } michael@0: }; michael@0: michael@0: const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) }, michael@0: { SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSRecipientKeyIdentifier,subjectKeyIdentifier) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSRecipientKeyIdentifier,date) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSRecipientKeyIdentifier,other) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: michael@0: static const SEC_ASN1Template NSSCMSKeyAgreeRecipientIdentifierTemplate[] = { michael@0: { SEC_ASN1_CHOICE, michael@0: offsetof(NSSCMSKeyAgreeRecipientIdentifier,identifierType), NULL, michael@0: sizeof(NSSCMSKeyAgreeRecipientIdentifier) }, michael@0: { SEC_ASN1_POINTER | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.issuerAndSN), michael@0: SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), michael@0: NSSCMSKeyAgreeRecipientID_IssuerSN }, michael@0: { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, michael@0: offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.recipientKeyIdentifier), michael@0: NSSCMSRecipientKeyIdentifierTemplate, michael@0: NSSCMSKeyAgreeRecipientID_RKeyID }, michael@0: { 0 } michael@0: }; michael@0: michael@0: static const SEC_ASN1Template NSSCMSRecipientEncryptedKeyTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSRecipientEncryptedKey) }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSRecipientEncryptedKey,recipientIdentifier), michael@0: NSSCMSKeyAgreeRecipientIdentifierTemplate }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSRecipientEncryptedKey,encKey), michael@0: SEC_ASN1_SUB(SEC_BitStringTemplate) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: static const SEC_ASN1Template NSSCMSKeyAgreeRecipientInfoTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSKeyAgreeRecipientInfo) }, michael@0: { SEC_ASN1_INTEGER, michael@0: offsetof(NSSCMSKeyAgreeRecipientInfo,version) }, michael@0: { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, michael@0: offsetof(NSSCMSKeyAgreeRecipientInfo,originatorIdentifierOrKey), michael@0: NSSCMSOriginatorIdentifierOrKeyTemplate }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | michael@0: SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, michael@0: offsetof(NSSCMSKeyAgreeRecipientInfo,ukm), michael@0: SEC_ASN1_SUB(SEC_OctetStringTemplate) }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSKeyAgreeRecipientInfo,keyEncAlg), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_SEQUENCE_OF, michael@0: offsetof(NSSCMSKeyAgreeRecipientInfo,recipientEncryptedKeys), michael@0: NSSCMSRecipientEncryptedKeyTemplate }, michael@0: { 0 } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * KEK recipient info michael@0: */ michael@0: michael@0: static const SEC_ASN1Template NSSCMSKEKIdentifierTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSKEKIdentifier) }, michael@0: { SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSKEKIdentifier,keyIdentifier) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSKEKIdentifier,date) }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSKEKIdentifier,other) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: static const SEC_ASN1Template NSSCMSKEKRecipientInfoTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE, michael@0: 0, NULL, sizeof(NSSCMSKEKRecipientInfo) }, michael@0: { SEC_ASN1_INTEGER, michael@0: offsetof(NSSCMSKEKRecipientInfo,version) }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSKEKRecipientInfo,kekIdentifier), michael@0: NSSCMSKEKIdentifierTemplate }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSKEKRecipientInfo,keyEncAlg), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSKEKRecipientInfo,encKey) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * recipient info michael@0: */ michael@0: const SEC_ASN1Template NSSCMSRecipientInfoTemplate[] = { michael@0: { SEC_ASN1_CHOICE, michael@0: offsetof(NSSCMSRecipientInfo,recipientInfoType), NULL, michael@0: sizeof(NSSCMSRecipientInfo) }, michael@0: { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, michael@0: offsetof(NSSCMSRecipientInfo,ri.keyAgreeRecipientInfo), michael@0: NSSCMSKeyAgreeRecipientInfoTemplate, michael@0: NSSCMSRecipientInfoID_KeyAgree }, michael@0: { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, michael@0: offsetof(NSSCMSRecipientInfo,ri.kekRecipientInfo), michael@0: NSSCMSKEKRecipientInfoTemplate, michael@0: NSSCMSRecipientInfoID_KEK }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSRecipientInfo,ri.keyTransRecipientInfo), michael@0: NSSCMSKeyTransRecipientInfoTemplate, michael@0: NSSCMSRecipientInfoID_KeyTrans }, michael@0: { 0 } michael@0: }; michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * michael@0: */ michael@0: michael@0: const SEC_ASN1Template NSSCMSDigestedDataTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, michael@0: 0, NULL, sizeof(NSSCMSDigestedData) }, michael@0: { SEC_ASN1_INTEGER, michael@0: offsetof(NSSCMSDigestedData,version) }, michael@0: { SEC_ASN1_INLINE | SEC_ASN1_XTRN, michael@0: offsetof(NSSCMSDigestedData,digestAlg), michael@0: SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSDigestedData,contentInfo), michael@0: NSSCMSEncapsulatedContentInfoTemplate }, michael@0: { SEC_ASN1_OCTET_STRING, michael@0: offsetof(NSSCMSDigestedData,digest) }, michael@0: { 0 } michael@0: }; michael@0: michael@0: const SEC_ASN1Template NSS_PointerToCMSDigestedDataTemplate[] = { michael@0: { SEC_ASN1_POINTER, 0, NSSCMSDigestedDataTemplate } michael@0: }; michael@0: michael@0: const SEC_ASN1Template NSSCMSEncryptedDataTemplate[] = { michael@0: { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, michael@0: 0, NULL, sizeof(NSSCMSEncryptedData) }, michael@0: { SEC_ASN1_INTEGER, michael@0: offsetof(NSSCMSEncryptedData,version) }, michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSEncryptedData,contentInfo), michael@0: NSSCMSEncryptedContentInfoTemplate }, michael@0: { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, michael@0: offsetof(NSSCMSEncryptedData,unprotectedAttr), michael@0: nss_cms_set_of_attribute_template }, michael@0: { 0 } michael@0: }; michael@0: michael@0: const SEC_ASN1Template NSS_PointerToCMSEncryptedDataTemplate[] = { michael@0: { SEC_ASN1_POINTER, 0, NSSCMSEncryptedDataTemplate } michael@0: }; michael@0: michael@0: const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[] = { michael@0: { SEC_ASN1_INLINE, michael@0: offsetof(NSSCMSGenericWrapperData,contentInfo), michael@0: NSSCMSEncapsulatedContentInfoTemplate }, michael@0: }; michael@0: michael@0: SEC_ASN1_CHOOSER_IMPLEMENT(NSSCMSGenericWrapperDataTemplate) michael@0: michael@0: const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[] = { michael@0: { SEC_ASN1_POINTER, 0, NSSCMSGenericWrapperDataTemplate } michael@0: }; michael@0: michael@0: SEC_ASN1_CHOOSER_IMPLEMENT(NSS_PointerToCMSGenericWrapperDataTemplate) michael@0: michael@0: /* ----------------------------------------------------------------------------- michael@0: * michael@0: */ michael@0: static const SEC_ASN1Template * michael@0: nss_cms_choose_content_template(void *src_or_dest, PRBool encoding) michael@0: { michael@0: const SEC_ASN1Template *theTemplate; michael@0: NSSCMSContentInfo *cinfo; michael@0: SECOidTag type; michael@0: michael@0: PORT_Assert (src_or_dest != NULL); michael@0: if (src_or_dest == NULL) michael@0: return NULL; michael@0: michael@0: cinfo = (NSSCMSContentInfo *)src_or_dest; michael@0: type = NSS_CMSContentInfo_GetContentTypeTag(cinfo); michael@0: switch (type) { michael@0: default: michael@0: theTemplate = NSS_CMSType_GetTemplate(type); michael@0: break; michael@0: case SEC_OID_PKCS7_DATA: michael@0: theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate); michael@0: break; michael@0: case SEC_OID_PKCS7_SIGNED_DATA: michael@0: theTemplate = NSS_PointerToCMSSignedDataTemplate; michael@0: break; michael@0: case SEC_OID_PKCS7_ENVELOPED_DATA: michael@0: theTemplate = NSS_PointerToCMSEnvelopedDataTemplate; michael@0: break; michael@0: case SEC_OID_PKCS7_DIGESTED_DATA: michael@0: theTemplate = NSS_PointerToCMSDigestedDataTemplate; michael@0: break; michael@0: case SEC_OID_PKCS7_ENCRYPTED_DATA: michael@0: theTemplate = NSS_PointerToCMSEncryptedDataTemplate; michael@0: break; michael@0: } michael@0: return theTemplate; michael@0: }