tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cmsasn1.c (18771B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /*
      6 * CMS ASN.1 templates
      7 */
      8 
      9 #include "cmslocal.h"
     10 
     11 #include "cert.h"
     12 #include "keyhi.h"
     13 #include "secasn1.h"
     14 #include "secitem.h"
     15 #include "secoid.h"
     16 #include "prtime.h"
     17 #include "secerr.h"
     18 
     19 extern const SEC_ASN1Template nss_cms_set_of_attribute_template[];
     20 
     21 SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
     22 SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
     23 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
     24 SEC_ASN1_MKSUB(SEC_BitStringTemplate)
     25 SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
     26 SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
     27 SEC_ASN1_MKSUB(SEC_PointerToOctetStringTemplate)
     28 SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
     29 
     30 /* -----------------------------------------------------------------------------
     31 * MESSAGE
     32 * (uses NSSCMSContentInfo)
     33 */
     34 
     35 /* forward declaration */
     36 static const SEC_ASN1Template *
     37 nss_cms_choose_content_template(void *src_or_dest, PRBool encoding);
     38 
     39 static const SEC_ASN1TemplateChooserPtr nss_cms_chooser = nss_cms_choose_content_template;
     40 
     41 const SEC_ASN1Template NSSCMSMessageTemplate[] = {
     42    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
     43      0, NULL, sizeof(NSSCMSMessage) },
     44    { SEC_ASN1_OBJECT_ID,
     45      offsetof(NSSCMSMessage, contentInfo.contentType) },
     46    { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM |
     47          SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
     48      offsetof(NSSCMSMessage, contentInfo.content),
     49      &nss_cms_chooser },
     50    { 0 }
     51 };
     52 
     53 /* -----------------------------------------------------------------------------
     54 * ENCAPSULATED & ENCRYPTED CONTENTINFO
     55 * (both use a NSSCMSContentInfo)
     56 */
     57 static const SEC_ASN1Template NSSCMSEncapsulatedContentInfoTemplate[] = {
     58    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
     59      0, NULL, sizeof(NSSCMSContentInfo) },
     60    { SEC_ASN1_OBJECT_ID,
     61      offsetof(NSSCMSContentInfo, contentType) },
     62    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_MAY_STREAM |
     63          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
     64      offsetof(NSSCMSContentInfo, rawContent),
     65      SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) },
     66    { 0 }
     67 };
     68 
     69 static const SEC_ASN1Template NSSCMSEncryptedContentInfoTemplate[] = {
     70    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
     71      0, NULL, sizeof(NSSCMSContentInfo) },
     72    { SEC_ASN1_OBJECT_ID,
     73      offsetof(NSSCMSContentInfo, contentType) },
     74    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
     75      offsetof(NSSCMSContentInfo, contentEncAlg),
     76      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
     77    { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM |
     78          SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
     79      offsetof(NSSCMSContentInfo, rawContent),
     80      SEC_ASN1_SUB(SEC_OctetStringTemplate) },
     81    { 0 }
     82 };
     83 
     84 /* -----------------------------------------------------------------------------
     85 * SIGNED DATA
     86 */
     87 
     88 const SEC_ASN1Template NSSCMSSignerInfoTemplate[];
     89 
     90 const SEC_ASN1Template NSSCMSSignedDataTemplate[] = {
     91    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
     92      0, NULL, sizeof(NSSCMSSignedData) },
     93    { SEC_ASN1_INTEGER,
     94      offsetof(NSSCMSSignedData, version) },
     95    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
     96      offsetof(NSSCMSSignedData, digestAlgorithms),
     97      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
     98    { SEC_ASN1_INLINE,
     99      offsetof(NSSCMSSignedData, contentInfo),
    100      NSSCMSEncapsulatedContentInfoTemplate },
    101    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
    102          SEC_ASN1_XTRN | 0,
    103      offsetof(NSSCMSSignedData, rawCerts),
    104      SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
    105    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
    106          SEC_ASN1_XTRN | 1,
    107      offsetof(NSSCMSSignedData, crls),
    108      SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
    109    { SEC_ASN1_SET_OF,
    110      offsetof(NSSCMSSignedData, signerInfos),
    111      NSSCMSSignerInfoTemplate },
    112    { 0 }
    113 };
    114 
    115 const SEC_ASN1Template NSS_PointerToCMSSignedDataTemplate[] = {
    116    { SEC_ASN1_POINTER, 0, NSSCMSSignedDataTemplate }
    117 };
    118 
    119 /* -----------------------------------------------------------------------------
    120 * signeridentifier
    121 */
    122 
    123 static const SEC_ASN1Template NSSCMSSignerIdentifierTemplate[] = {
    124    { SEC_ASN1_CHOICE,
    125      offsetof(NSSCMSSignerIdentifier, identifierType), NULL,
    126      sizeof(NSSCMSSignerIdentifier) },
    127    { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
    128      offsetof(NSSCMSSignerIdentifier, id.subjectKeyID),
    129      SEC_ASN1_SUB(SEC_OctetStringTemplate),
    130      NSSCMSRecipientID_SubjectKeyID },
    131    { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    132      offsetof(NSSCMSSignerIdentifier, id.issuerAndSN),
    133      SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
    134      NSSCMSRecipientID_IssuerSN },
    135    { 0 }
    136 };
    137 
    138 /* -----------------------------------------------------------------------------
    139 * signerinfo
    140 */
    141 
    142 const SEC_ASN1Template NSSCMSSignerInfoTemplate[] = {
    143    { SEC_ASN1_SEQUENCE,
    144      0, NULL, sizeof(NSSCMSSignerInfo) },
    145    { SEC_ASN1_INTEGER,
    146      offsetof(NSSCMSSignerInfo, version) },
    147    { SEC_ASN1_INLINE,
    148      offsetof(NSSCMSSignerInfo, signerIdentifier),
    149      NSSCMSSignerIdentifierTemplate },
    150    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    151      offsetof(NSSCMSSignerInfo, digestAlg),
    152      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    153    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
    154      offsetof(NSSCMSSignerInfo, authAttr),
    155      nss_cms_set_of_attribute_template },
    156    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    157      offsetof(NSSCMSSignerInfo, digestEncAlg),
    158      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    159    { SEC_ASN1_OCTET_STRING,
    160      offsetof(NSSCMSSignerInfo, encDigest) },
    161    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
    162      offsetof(NSSCMSSignerInfo, unAuthAttr),
    163      nss_cms_set_of_attribute_template },
    164    { 0 }
    165 };
    166 
    167 /* -----------------------------------------------------------------------------
    168 * ENVELOPED DATA
    169 */
    170 
    171 static const SEC_ASN1Template NSSCMSOriginatorInfoTemplate[] = {
    172    { SEC_ASN1_SEQUENCE,
    173      0, NULL, sizeof(NSSCMSOriginatorInfo) },
    174    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
    175          SEC_ASN1_XTRN | 0,
    176      offsetof(NSSCMSOriginatorInfo, rawCerts),
    177      SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
    178    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
    179          SEC_ASN1_XTRN | 1,
    180      offsetof(NSSCMSOriginatorInfo, crls),
    181      SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
    182    { 0 }
    183 };
    184 
    185 const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
    186 
    187 const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[] = {
    188    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
    189      0, NULL, sizeof(NSSCMSEnvelopedData) },
    190    { SEC_ASN1_INTEGER,
    191      offsetof(NSSCMSEnvelopedData, version) },
    192    { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED |
    193          SEC_ASN1_CONTEXT_SPECIFIC | 0,
    194      offsetof(NSSCMSEnvelopedData, originatorInfo),
    195      NSSCMSOriginatorInfoTemplate },
    196    { SEC_ASN1_SET_OF,
    197      offsetof(NSSCMSEnvelopedData, recipientInfos),
    198      NSSCMSRecipientInfoTemplate },
    199    { SEC_ASN1_INLINE,
    200      offsetof(NSSCMSEnvelopedData, contentInfo),
    201      NSSCMSEncryptedContentInfoTemplate },
    202    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
    203      offsetof(NSSCMSEnvelopedData, unprotectedAttr),
    204      nss_cms_set_of_attribute_template },
    205    { 0 }
    206 };
    207 
    208 const SEC_ASN1Template NSS_PointerToCMSEnvelopedDataTemplate[] = {
    209    { SEC_ASN1_POINTER, 0, NSSCMSEnvelopedDataTemplate }
    210 };
    211 
    212 /* here come the 15 gazillion templates for all the v3 varieties of RecipientInfo */
    213 
    214 /* -----------------------------------------------------------------------------
    215 * key transport recipient info
    216 */
    217 
    218 static const SEC_ASN1Template NSSCMSRecipientIdentifierTemplate[] = {
    219    { SEC_ASN1_CHOICE,
    220      offsetof(NSSCMSRecipientIdentifier, identifierType), NULL,
    221      sizeof(NSSCMSRecipientIdentifier) },
    222    { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
    223      offsetof(NSSCMSRecipientIdentifier, id.subjectKeyID),
    224      SEC_ASN1_SUB(SEC_OctetStringTemplate),
    225      NSSCMSRecipientID_SubjectKeyID },
    226    { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    227      offsetof(NSSCMSRecipientIdentifier, id.issuerAndSN),
    228      SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
    229      NSSCMSRecipientID_IssuerSN },
    230    { 0 }
    231 };
    232 
    233 static const SEC_ASN1Template NSSCMSKeyTransRecipientInfoTemplate[] = {
    234    { SEC_ASN1_SEQUENCE,
    235      0, NULL, sizeof(NSSCMSKeyTransRecipientInfo) },
    236    { SEC_ASN1_INTEGER,
    237      offsetof(NSSCMSKeyTransRecipientInfo, version) },
    238    { SEC_ASN1_INLINE,
    239      offsetof(NSSCMSKeyTransRecipientInfo, recipientIdentifier),
    240      NSSCMSRecipientIdentifierTemplate },
    241    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    242      offsetof(NSSCMSKeyTransRecipientInfo, keyEncAlg),
    243      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    244    { SEC_ASN1_OCTET_STRING,
    245      offsetof(NSSCMSKeyTransRecipientInfo, encKey) },
    246    { 0 }
    247 };
    248 
    249 /* -----------------------------------------------------------------------------
    250 * key agreement recipient info
    251 */
    252 
    253 static const SEC_ASN1Template NSSCMSOriginatorPublicKeyTemplate[] = {
    254    { SEC_ASN1_SEQUENCE,
    255      0, NULL, sizeof(NSSCMSOriginatorPublicKey) },
    256    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    257      offsetof(NSSCMSOriginatorPublicKey, algorithmIdentifier),
    258      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    259    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    260      offsetof(NSSCMSOriginatorPublicKey, publicKey),
    261      SEC_ASN1_SUB(SEC_BitStringTemplate) },
    262    { 0 }
    263 };
    264 
    265 static const SEC_ASN1Template NSSCMSOriginatorIdentifierOrKeyTemplate[] = {
    266    { SEC_ASN1_CHOICE,
    267      offsetof(NSSCMSOriginatorIdentifierOrKey, identifierType), NULL,
    268      sizeof(NSSCMSOriginatorIdentifierOrKey) },
    269    { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    270      offsetof(NSSCMSOriginatorIdentifierOrKey, id.issuerAndSN),
    271      SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
    272      NSSCMSOriginatorIDOrKey_IssuerSN },
    273    { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
    274      offsetof(NSSCMSOriginatorIdentifierOrKey, id.subjectKeyID),
    275      SEC_ASN1_SUB(SEC_OctetStringTemplate),
    276      NSSCMSOriginatorIDOrKey_SubjectKeyID },
    277    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
    278      offsetof(NSSCMSOriginatorIdentifierOrKey, id.originatorPublicKey),
    279      NSSCMSOriginatorPublicKeyTemplate,
    280      NSSCMSOriginatorIDOrKey_OriginatorPublicKey },
    281    { 0 }
    282 };
    283 
    284 const SEC_ASN1Template NSSCMSOtherKeyAttributeTemplate[] = {
    285    { SEC_ASN1_SEQUENCE,
    286      0, NULL, sizeof(NSSCMSOtherKeyAttribute) },
    287    {
    288        SEC_ASN1_OBJECT_ID,
    289        offsetof(NSSCMSOtherKeyAttribute, keyAttrId),
    290    },
    291    {
    292        SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
    293        offsetof(NSSCMSOtherKeyAttribute, keyAttr),
    294    },
    295    {
    296        0,
    297    }
    298 };
    299 
    300 const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = {
    301    { SEC_ASN1_SEQUENCE,
    302      0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) },
    303    { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    304      offsetof(NSSCMSRecipientKeyIdentifier, subjectKeyIdentifier),
    305      SEC_ASN1_SUB(SEC_OctetStringTemplate) },
    306    { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    307      offsetof(NSSCMSRecipientKeyIdentifier, date),
    308      SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
    309    { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    310      offsetof(NSSCMSRecipientKeyIdentifier, other),
    311      NSSCMSOtherKeyAttributeTemplate },
    312    { 0 }
    313 };
    314 
    315 static const SEC_ASN1Template NSSCMSKeyAgreeRecipientIdentifierTemplate[] = {
    316    { SEC_ASN1_CHOICE,
    317      offsetof(NSSCMSKeyAgreeRecipientIdentifier, identifierType), NULL,
    318      sizeof(NSSCMSKeyAgreeRecipientIdentifier) },
    319    { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    320      offsetof(NSSCMSKeyAgreeRecipientIdentifier, id.issuerAndSN),
    321      SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
    322      NSSCMSKeyAgreeRecipientID_IssuerSN },
    323    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
    324      offsetof(NSSCMSKeyAgreeRecipientIdentifier, id.recipientKeyIdentifier),
    325      NSSCMSRecipientKeyIdentifierTemplate,
    326      NSSCMSKeyAgreeRecipientID_RKeyID },
    327    { 0 }
    328 };
    329 
    330 static const SEC_ASN1Template NSSCMSRecipientEncryptedKeyTemplate[] = {
    331    { SEC_ASN1_SEQUENCE,
    332      0, NULL, sizeof(NSSCMSRecipientEncryptedKey) },
    333    { SEC_ASN1_INLINE,
    334      offsetof(NSSCMSRecipientEncryptedKey, recipientIdentifier),
    335      NSSCMSKeyAgreeRecipientIdentifierTemplate },
    336    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    337      offsetof(NSSCMSRecipientEncryptedKey, encKey),
    338      SEC_ASN1_SUB(SEC_OctetStringTemplate) },
    339    { 0 }
    340 };
    341 
    342 static const SEC_ASN1Template NSSCMSKeyAgreeRecipientInfoTemplate[] = {
    343    { SEC_ASN1_SEQUENCE,
    344      0, NULL, sizeof(NSSCMSKeyAgreeRecipientInfo) },
    345    { SEC_ASN1_INTEGER,
    346      offsetof(NSSCMSKeyAgreeRecipientInfo, version) },
    347    { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
    348      offsetof(NSSCMSKeyAgreeRecipientInfo, originatorIdentifierOrKey),
    349      NSSCMSOriginatorIdentifierOrKeyTemplate },
    350    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
    351          SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
    352      offsetof(NSSCMSKeyAgreeRecipientInfo, ukm),
    353      SEC_ASN1_SUB(SEC_OctetStringTemplate) },
    354    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    355      offsetof(NSSCMSKeyAgreeRecipientInfo, keyEncAlg),
    356      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    357    { SEC_ASN1_SEQUENCE_OF,
    358      offsetof(NSSCMSKeyAgreeRecipientInfo, recipientEncryptedKeys),
    359      NSSCMSRecipientEncryptedKeyTemplate },
    360    { 0 }
    361 };
    362 
    363 /* -----------------------------------------------------------------------------
    364 * KEK recipient info
    365 */
    366 
    367 static const SEC_ASN1Template NSSCMSKEKIdentifierTemplate[] = {
    368    { SEC_ASN1_SEQUENCE,
    369      0, NULL, sizeof(NSSCMSKEKIdentifier) },
    370    { SEC_ASN1_OCTET_STRING,
    371      offsetof(NSSCMSKEKIdentifier, keyIdentifier) },
    372    { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    373      offsetof(NSSCMSKEKIdentifier, date),
    374      SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
    375    { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_XTRN,
    376      offsetof(NSSCMSKEKIdentifier, other),
    377      NSSCMSOtherKeyAttributeTemplate },
    378    { 0 }
    379 };
    380 
    381 static const SEC_ASN1Template NSSCMSKEKRecipientInfoTemplate[] = {
    382    { SEC_ASN1_SEQUENCE,
    383      0, NULL, sizeof(NSSCMSKEKRecipientInfo) },
    384    { SEC_ASN1_INTEGER,
    385      offsetof(NSSCMSKEKRecipientInfo, version) },
    386    { SEC_ASN1_INLINE,
    387      offsetof(NSSCMSKEKRecipientInfo, kekIdentifier),
    388      NSSCMSKEKIdentifierTemplate },
    389    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    390      offsetof(NSSCMSKEKRecipientInfo, keyEncAlg),
    391      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    392    { SEC_ASN1_OCTET_STRING,
    393      offsetof(NSSCMSKEKRecipientInfo, encKey) },
    394    { 0 }
    395 };
    396 
    397 /* -----------------------------------------------------------------------------
    398 * recipient info
    399 */
    400 const SEC_ASN1Template NSSCMSRecipientInfoTemplate[] = {
    401    { SEC_ASN1_CHOICE,
    402      offsetof(NSSCMSRecipientInfo, recipientInfoType), NULL,
    403      sizeof(NSSCMSRecipientInfo) },
    404    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
    405      offsetof(NSSCMSRecipientInfo, ri.keyAgreeRecipientInfo),
    406      NSSCMSKeyAgreeRecipientInfoTemplate,
    407      NSSCMSRecipientInfoID_KeyAgree },
    408    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
    409      offsetof(NSSCMSRecipientInfo, ri.kekRecipientInfo),
    410      NSSCMSKEKRecipientInfoTemplate,
    411      NSSCMSRecipientInfoID_KEK },
    412    { SEC_ASN1_INLINE,
    413      offsetof(NSSCMSRecipientInfo, ri.keyTransRecipientInfo),
    414      NSSCMSKeyTransRecipientInfoTemplate,
    415      NSSCMSRecipientInfoID_KeyTrans },
    416    { 0 }
    417 };
    418 
    419 /* -----------------------------------------------------------------------------
    420 *
    421 */
    422 
    423 const SEC_ASN1Template NSSCMSDigestedDataTemplate[] = {
    424    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
    425      0, NULL, sizeof(NSSCMSDigestedData) },
    426    { SEC_ASN1_INTEGER,
    427      offsetof(NSSCMSDigestedData, version) },
    428    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
    429      offsetof(NSSCMSDigestedData, digestAlg),
    430      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    431    { SEC_ASN1_INLINE,
    432      offsetof(NSSCMSDigestedData, contentInfo),
    433      NSSCMSEncapsulatedContentInfoTemplate },
    434    { SEC_ASN1_OCTET_STRING,
    435      offsetof(NSSCMSDigestedData, digest) },
    436    { 0 }
    437 };
    438 
    439 const SEC_ASN1Template NSS_PointerToCMSDigestedDataTemplate[] = {
    440    { SEC_ASN1_POINTER, 0, NSSCMSDigestedDataTemplate }
    441 };
    442 
    443 const SEC_ASN1Template NSSCMSEncryptedDataTemplate[] = {
    444    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
    445      0, NULL, sizeof(NSSCMSEncryptedData) },
    446    { SEC_ASN1_INTEGER,
    447      offsetof(NSSCMSEncryptedData, version) },
    448    { SEC_ASN1_INLINE,
    449      offsetof(NSSCMSEncryptedData, contentInfo),
    450      NSSCMSEncryptedContentInfoTemplate },
    451    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
    452      offsetof(NSSCMSEncryptedData, unprotectedAttr),
    453      nss_cms_set_of_attribute_template },
    454    { 0 }
    455 };
    456 
    457 const SEC_ASN1Template NSS_PointerToCMSEncryptedDataTemplate[] = {
    458    { SEC_ASN1_POINTER, 0, NSSCMSEncryptedDataTemplate }
    459 };
    460 
    461 const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[] = {
    462    { SEC_ASN1_INLINE,
    463      offsetof(NSSCMSGenericWrapperData, contentInfo),
    464      NSSCMSEncapsulatedContentInfoTemplate },
    465 };
    466 
    467 SEC_ASN1_CHOOSER_IMPLEMENT(NSSCMSGenericWrapperDataTemplate)
    468 
    469 const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[] = {
    470    { SEC_ASN1_POINTER, 0, NSSCMSGenericWrapperDataTemplate }
    471 };
    472 
    473 SEC_ASN1_CHOOSER_IMPLEMENT(NSS_PointerToCMSGenericWrapperDataTemplate)
    474 
    475 /* -----------------------------------------------------------------------------
    476 *
    477 */
    478 static const SEC_ASN1Template *
    479 nss_cms_choose_content_template(void *src_or_dest, PRBool encoding)
    480 {
    481    const SEC_ASN1Template *theTemplate;
    482    NSSCMSContentInfo *cinfo;
    483    SECOidTag type;
    484 
    485    PORT_Assert(src_or_dest != NULL);
    486    if (src_or_dest == NULL)
    487        return NULL;
    488 
    489    cinfo = (NSSCMSContentInfo *)src_or_dest;
    490    type = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    491    switch (type) {
    492        default:
    493            theTemplate = NSS_CMSType_GetTemplate(type);
    494            break;
    495        case SEC_OID_PKCS7_DATA:
    496            theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
    497            break;
    498        case SEC_OID_PKCS7_SIGNED_DATA:
    499            theTemplate = NSS_PointerToCMSSignedDataTemplate;
    500            break;
    501        case SEC_OID_PKCS7_ENVELOPED_DATA:
    502            theTemplate = NSS_PointerToCMSEnvelopedDataTemplate;
    503            break;
    504        case SEC_OID_PKCS7_DIGESTED_DATA:
    505            theTemplate = NSS_PointerToCMSDigestedDataTemplate;
    506            break;
    507        case SEC_OID_PKCS7_ENCRYPTED_DATA:
    508            theTemplate = NSS_PointerToCMSEncryptedDataTemplate;
    509            break;
    510    }
    511    return theTemplate;
    512 }