/ libsecurity_smime / lib / cmsasn1.c
cmsasn1.c
  1  /*
  2   * The contents of this file are subject to the Mozilla Public
  3   * License Version 1.1 (the "License"); you may not use this file
  4   * except in compliance with the License. You may obtain a copy of
  5   * the License at http://www.mozilla.org/MPL/
  6   * 
  7   * Software distributed under the License is distributed on an "AS
  8   * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9   * implied. See the License for the specific language governing
 10   * rights and limitations under the License.
 11   * 
 12   * The Original Code is the Netscape security libraries.
 13   * 
 14   * The Initial Developer of the Original Code is Netscape
 15   * Communications Corporation.  Portions created by Netscape are 
 16   * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
 17   * Rights Reserved.
 18   * 
 19   * Contributor(s):
 20   * 
 21   * Alternatively, the contents of this file may be used under the
 22   * terms of the GNU General Public License Version 2 or later (the
 23   * "GPL"), in which case the provisions of the GPL are applicable 
 24   * instead of those above.  If you wish to allow use of your 
 25   * version of this file only under the terms of the GPL and not to
 26   * allow others to use your version of this file under the MPL,
 27   * indicate your decision by deleting the provisions above and
 28   * replace them with the notice and other provisions required by
 29   * the GPL.  If you do not delete the provisions above, a recipient
 30   * may use your version of this file under either the MPL or the
 31   * GPL.
 32   */
 33  
 34  /*
 35   * CMS ASN.1 templates
 36   */
 37  
 38  #include <Security/SecCmsContentInfo.h>
 39  
 40  #include "cmslocal.h"
 41  
 42  #include "secoid.h"
 43  #include <security_asn1/secasn1.h>
 44  #include <security_asn1/secerr.h>
 45  #include <security_asn1/secport.h>
 46  
 47  extern const SecAsn1Template nss_cms_set_of_attribute_template[];
 48  
 49  //SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
 50  //SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
 51  SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
 52  SEC_ASN1_MKSUB(kSecAsn1BitStringTemplate)
 53  SEC_ASN1_MKSUB(kSecAsn1OctetStringTemplate)
 54  SEC_ASN1_MKSUB(kSecAsn1PointerToOctetStringTemplate)
 55  SEC_ASN1_MKSUB(kSecAsn1SetOfAnyTemplate)
 56  
 57  /* -----------------------------------------------------------------------------
 58   * MESSAGE
 59   * (uses SecCmsContentInfo)
 60   */
 61  
 62  /* forward declaration */
 63  static const SecAsn1Template *
 64  nss_cms_choose_content_template(void *src_or_dest, Boolean encoding, const char *buf, size_t len, void *dest);
 65  
 66  static const SecAsn1TemplateChooserPtr nss_cms_chooser
 67  	= nss_cms_choose_content_template;
 68  
 69  const SecAsn1Template SecCmsMessageTemplate[] = {
 70      { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
 71  	  0, NULL, sizeof(SecCmsMessage) },
 72      { SEC_ASN1_OBJECT_ID,
 73  	  offsetof(SecCmsMessage,contentInfo.contentType) },
 74      { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM
 75       | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
 76  	  offsetof(SecCmsMessage,contentInfo.content),
 77  	  &nss_cms_chooser },
 78      { 0 }
 79  };
 80  
 81  #if 0
 82  static const SecAsn1Template NSS_PointerToCMSMessageTemplate[] = {
 83      { SEC_ASN1_POINTER, 0, SecCmsMessageTemplate }
 84  };
 85  #endif
 86  
 87  /* -----------------------------------------------------------------------------
 88   * ENCAPSULATED & ENCRYPTED CONTENTINFO
 89   * (both use a SecCmsContentInfo)
 90   */
 91  static const SecAsn1Template SecCmsEncapsulatedContentInfoTemplate[] = {
 92      { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
 93  	  0, NULL, sizeof(SecCmsContentInfo) },
 94      { SEC_ASN1_OBJECT_ID,
 95  	  offsetof(SecCmsContentInfo,contentType) },
 96      { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_MAY_STREAM |
 97  	SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
 98  	  offsetof(SecCmsContentInfo,rawContent),
 99  	  SEC_ASN1_SUB(kSecAsn1PointerToOctetStringTemplate) },
100      { 0 }
101  };
102  
103  static const SecAsn1Template SecCmsEncryptedContentInfoTemplate[] = {
104      { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
105  	  0, NULL, sizeof(SecCmsContentInfo) },
106      { SEC_ASN1_OBJECT_ID,
107  	  offsetof(SecCmsContentInfo,contentType) },
108      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
109  	  offsetof(SecCmsContentInfo,contentEncAlg),
110  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
111      { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM | 
112        SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
113  	  offsetof(SecCmsContentInfo,rawContent),
114  	  SEC_ASN1_SUB(kSecAsn1OctetStringTemplate) },
115      { 0 }
116  };
117  
118  /* -----------------------------------------------------------------------------
119   * SIGNED DATA
120   */
121  
122  const SecAsn1Template SecCmsSignerInfoTemplate[];
123  
124  
125  const SecAsn1Template SecCmsSignedDataTemplate[] = {
126      { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
127  	  0, NULL, sizeof(SecCmsSignedData) },
128      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
129  	  offsetof(SecCmsSignedData,version) },
130      { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
131  	  offsetof(SecCmsSignedData,digestAlgorithms),
132  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
133      { SEC_ASN1_INLINE,
134  	  offsetof(SecCmsSignedData,contentInfo),
135  	  SecCmsEncapsulatedContentInfoTemplate },
136      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
137        SEC_ASN1_XTRN | 0,
138  	  offsetof(SecCmsSignedData,rawCerts),
139  	  SEC_ASN1_SUB(kSecAsn1SetOfAnyTemplate) },
140      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
141        SEC_ASN1_XTRN | 1,
142  	  offsetof(SecCmsSignedData,rawCrls),
143  	  SEC_ASN1_SUB(kSecAsn1SetOfAnyTemplate) },
144      { SEC_ASN1_SET_OF,
145  	  offsetof(SecCmsSignedData,signerInfos),
146  	  SecCmsSignerInfoTemplate },
147      { 0 }
148  };
149  
150  const SecAsn1Template NSS_PointerToCMSSignedDataTemplate[] = {
151      { SEC_ASN1_POINTER, 0, SecCmsSignedDataTemplate }
152  };
153  
154  /* -----------------------------------------------------------------------------
155   * signeridentifier
156   */
157  
158  static const SecAsn1Template SecCmsSignerIdentifierTemplate[] = {
159      { SEC_ASN1_CHOICE,
160  	  offsetof(SecCmsSignerIdentifier,identifierType), NULL,
161  	  sizeof(SecCmsSignerIdentifier) },
162      { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
163  	  offsetof(SecCmsSignerIdentifier,id.subjectKeyID),
164  	  SEC_ASN1_SUB(kSecAsn1OctetStringTemplate) ,
165  	  SecCmsRecipientIDSubjectKeyID },
166      { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
167  	  offsetof(SecCmsSignerIdentifier,id.issuerAndSN),
168  	  SEC_ASN1_SUB(SecCmsIssuerAndSNTemplate),
169  	  SecCmsRecipientIDIssuerSN },
170      { 0 }
171  };
172  
173  /* -----------------------------------------------------------------------------
174   * signerinfo
175   */
176  
177  const SecAsn1Template SecCmsSignerInfoTemplate[] = {
178      { SEC_ASN1_SEQUENCE,
179  	  0, NULL, sizeof(SecCmsSignerInfo) },
180      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
181  	  offsetof(SecCmsSignerInfo,version) },
182      { SEC_ASN1_INLINE,
183  	  offsetof(SecCmsSignerInfo,signerIdentifier),
184  	  SecCmsSignerIdentifierTemplate },
185      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
186  	  offsetof(SecCmsSignerInfo,digestAlg),
187  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
188      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
189  	  offsetof(SecCmsSignerInfo,authAttr),
190  	  nss_cms_set_of_attribute_template },
191      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
192  	  offsetof(SecCmsSignerInfo,digestEncAlg),
193  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
194      { SEC_ASN1_OCTET_STRING,
195  	  offsetof(SecCmsSignerInfo,encDigest) },
196      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
197  	  offsetof(SecCmsSignerInfo,unAuthAttr),
198  	  nss_cms_set_of_attribute_template },
199      { 0 }
200  };
201  
202  /* -----------------------------------------------------------------------------
203   * ENVELOPED DATA
204   */
205  
206  static const SecAsn1Template SecCmsOriginatorInfoTemplate[] = {
207      { SEC_ASN1_SEQUENCE,
208  	  0, NULL, sizeof(SecCmsOriginatorInfo) },
209      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
210        SEC_ASN1_XTRN | 0,
211  	  offsetof(SecCmsOriginatorInfo,rawCerts),
212  	  SEC_ASN1_SUB(kSecAsn1SetOfAnyTemplate) },
213      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
214        SEC_ASN1_XTRN | 1,
215  	  offsetof(SecCmsOriginatorInfo,rawCrls),
216  	  SEC_ASN1_SUB(kSecAsn1SetOfAnyTemplate) },
217      { 0 }
218  };
219  
220  const SecAsn1Template SecCmsRecipientInfoTemplate[];
221  
222  const SecAsn1Template SecCmsEnvelopedDataTemplate[] = {
223      { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
224  	  0, NULL, sizeof(SecCmsEnvelopedData) },
225      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
226  	  offsetof(SecCmsEnvelopedData,version) },
227      { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
228  	  offsetof(SecCmsEnvelopedData,originatorInfo),
229  	  SecCmsOriginatorInfoTemplate },
230      { SEC_ASN1_SET_OF,
231  	  offsetof(SecCmsEnvelopedData,recipientInfos),
232  	  SecCmsRecipientInfoTemplate },
233      { SEC_ASN1_INLINE,
234  	  offsetof(SecCmsEnvelopedData,contentInfo),
235  	  SecCmsEncryptedContentInfoTemplate },
236      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
237  	  offsetof(SecCmsEnvelopedData,unprotectedAttr),
238  	  nss_cms_set_of_attribute_template },
239      { 0 }
240  };
241  
242  const SecAsn1Template NSS_PointerToCMSEnvelopedDataTemplate[] = {
243      { SEC_ASN1_POINTER, 0, SecCmsEnvelopedDataTemplate }
244  };
245  
246  /* here come the 15 gazillion templates for all the v3 varieties of RecipientInfo */
247  
248  /* -----------------------------------------------------------------------------
249   * key transport recipient info
250   */
251  
252  static const SecAsn1Template SecCmsRecipientIdentifierTemplate[] = {
253      { SEC_ASN1_CHOICE,
254  	  offsetof(SecCmsRecipientIdentifier,identifierType), NULL,
255  	  sizeof(SecCmsRecipientIdentifier) },
256      { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
257  	  offsetof(SecCmsRecipientIdentifier,id.subjectKeyID),
258  	  SEC_ASN1_SUB(kSecAsn1OctetStringTemplate) ,
259  	  SecCmsRecipientIDSubjectKeyID },
260      { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
261  	  offsetof(SecCmsRecipientIdentifier,id.issuerAndSN),
262  	  SEC_ASN1_SUB(SecCmsIssuerAndSNTemplate),
263  	  SecCmsRecipientIDIssuerSN },
264      { 0 }
265  };
266  
267  
268  static const SecAsn1Template SecCmsKeyTransRecipientInfoTemplate[] = {
269      { SEC_ASN1_SEQUENCE,
270  	  0, NULL, sizeof(SecCmsKeyTransRecipientInfo) },
271      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
272  	  offsetof(SecCmsKeyTransRecipientInfo,version) },
273      { SEC_ASN1_INLINE,
274  	  offsetof(SecCmsKeyTransRecipientInfo,recipientIdentifier),
275  	  SecCmsRecipientIdentifierTemplate },
276      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
277  	  offsetof(SecCmsKeyTransRecipientInfo,keyEncAlg),
278  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
279      { SEC_ASN1_OCTET_STRING,
280  	  offsetof(SecCmsKeyTransRecipientInfo,encKey) },
281      { 0 }
282  };
283  
284  /* -----------------------------------------------------------------------------
285   * key agreement recipient info
286   */
287  
288  static const SecAsn1Template SecCmsOriginatorPublicKeyTemplate[] = {
289      { SEC_ASN1_SEQUENCE,
290  	  0, NULL, sizeof(SecCmsOriginatorPublicKey) },
291      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
292  	  offsetof(SecCmsOriginatorPublicKey,algorithmIdentifier),
293  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
294      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
295  	  offsetof(SecCmsOriginatorPublicKey,publicKey),
296  	  SEC_ASN1_SUB(kSecAsn1BitStringTemplate) },
297      { 0 }
298  };
299  
300  
301  static const SecAsn1Template SecCmsOriginatorIdentifierOrKeyTemplate[] = {
302      { SEC_ASN1_CHOICE,
303  	  offsetof(SecCmsOriginatorIdentifierOrKey,identifierType), NULL,
304  	  sizeof(SecCmsOriginatorIdentifierOrKey) },
305      { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
306  	  offsetof(SecCmsOriginatorIdentifierOrKey,id.issuerAndSN),
307  	  SEC_ASN1_SUB(SecCmsIssuerAndSNTemplate),
308  	  SecCmsOriginatorIDOrKeyIssuerSN },
309      { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
310        SEC_ASN1_XTRN | 0,
311  	  offsetof(SecCmsOriginatorIdentifierOrKey,id.subjectKeyID),
312  	  SEC_ASN1_SUB(kSecAsn1PointerToOctetStringTemplate) ,
313  	  SecCmsOriginatorIDOrKeySubjectKeyID },
314      { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
315  	  offsetof(SecCmsOriginatorIdentifierOrKey,id.originatorPublicKey),
316  	  SecCmsOriginatorPublicKeyTemplate,
317  	  SecCmsOriginatorIDOrKeyOriginatorPublicKey },
318      { 0 }
319  };
320  
321  const SecAsn1Template SecCmsRecipientKeyIdentifierTemplate[] = {
322      { SEC_ASN1_SEQUENCE,
323  	  0, NULL, sizeof(SecCmsRecipientKeyIdentifier) },
324      { SEC_ASN1_INLINE | SEC_ASN1_OCTET_STRING,
325          offsetof(SecCmsRecipientKeyIdentifier,subjectKeyIdentifier),
326          SEC_ASN1_SUB(kSecAsn1OctetStringTemplate) },
327      { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL | SEC_ASN1_GENERALIZED_TIME,
328          offsetof(SecCmsRecipientKeyIdentifier,date),
329          SEC_ASN1_SUB(kSecAsn1GeneralizedTimeTemplate) },
330      { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
331  	  offsetof(SecCmsRecipientKeyIdentifier,other) },
332      { 0 }
333  };
334  
335  
336  static const SecAsn1Template SecCmsKeyAgreeRecipientIdentifierTemplate[] = {
337      { SEC_ASN1_CHOICE,
338  	  offsetof(SecCmsKeyAgreeRecipientIdentifier,identifierType), NULL,
339  	  sizeof(SecCmsKeyAgreeRecipientIdentifier) },
340      { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
341  	  offsetof(SecCmsKeyAgreeRecipientIdentifier,id.issuerAndSN),
342  	  SEC_ASN1_SUB(SecCmsIssuerAndSNTemplate),
343  	  SecCmsKeyAgreeRecipientIDIssuerSN },
344      { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
345  	  offsetof(SecCmsKeyAgreeRecipientIdentifier,id.recipientKeyIdentifier),
346  	  SecCmsRecipientKeyIdentifierTemplate,
347  	  SecCmsKeyAgreeRecipientIDRKeyID },
348      { 0 }
349  };
350  
351  static const SecAsn1Template SecCmsRecipientEncryptedKeyTemplate[] = {
352      { SEC_ASN1_SEQUENCE,
353  	  0, NULL, sizeof(SecCmsRecipientEncryptedKey) },
354      { SEC_ASN1_INLINE,
355  	  offsetof(SecCmsRecipientEncryptedKey,recipientIdentifier),
356  	  SecCmsKeyAgreeRecipientIdentifierTemplate },
357      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
358  	  offsetof(SecCmsRecipientEncryptedKey,encKey),
359  	  SEC_ASN1_SUB(kSecAsn1OctetStringTemplate) },
360      { 0 }
361  };
362  
363  static const SecAsn1Template SecCmsKeyAgreeRecipientInfoTemplate[] = {
364      { SEC_ASN1_SEQUENCE,
365  	  0, NULL, sizeof(SecCmsKeyAgreeRecipientInfo) },
366      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
367  	  offsetof(SecCmsKeyAgreeRecipientInfo,version) },
368      { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
369  	  offsetof(SecCmsKeyAgreeRecipientInfo,originatorIdentifierOrKey),
370  	  SecCmsOriginatorIdentifierOrKeyTemplate },
371      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
372        SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
373  	  offsetof(SecCmsKeyAgreeRecipientInfo,ukm),
374  	  SEC_ASN1_SUB(kSecAsn1OctetStringTemplate) },
375      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
376  	  offsetof(SecCmsKeyAgreeRecipientInfo,keyEncAlg),
377  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
378      { SEC_ASN1_SEQUENCE_OF,
379  	  offsetof(SecCmsKeyAgreeRecipientInfo,recipientEncryptedKeys),
380  	  SecCmsRecipientEncryptedKeyTemplate },
381      { 0 }
382  };
383  
384  /* -----------------------------------------------------------------------------
385   * KEK recipient info
386   */
387  
388  static const SecAsn1Template SecCmsKEKIdentifierTemplate[] = {
389      { SEC_ASN1_SEQUENCE,
390  	  0, NULL, sizeof(SecCmsKEKIdentifier) },
391      { SEC_ASN1_OCTET_STRING,
392  	  offsetof(SecCmsKEKIdentifier,keyIdentifier) },
393      { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
394  	  offsetof(SecCmsKEKIdentifier,date) },
395      { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
396  	  offsetof(SecCmsKEKIdentifier,other) },
397      { 0 }
398  };
399  
400  static const SecAsn1Template SecCmsKEKRecipientInfoTemplate[] = {
401      { SEC_ASN1_SEQUENCE,
402  	  0, NULL, sizeof(SecCmsKEKRecipientInfo) },
403      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
404  	  offsetof(SecCmsKEKRecipientInfo,version) },
405      { SEC_ASN1_INLINE,
406  	  offsetof(SecCmsKEKRecipientInfo,kekIdentifier),
407  	  SecCmsKEKIdentifierTemplate },
408      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
409  	  offsetof(SecCmsKEKRecipientInfo,keyEncAlg),
410  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
411      { SEC_ASN1_OCTET_STRING,
412  	  offsetof(SecCmsKEKRecipientInfo,encKey) },
413      { 0 }
414  };
415  
416  /* -----------------------------------------------------------------------------
417   * recipient info
418   */
419  const SecAsn1Template SecCmsRecipientInfoTemplate[] = {
420      { SEC_ASN1_CHOICE,
421  	  offsetof(SecCmsRecipientInfo,recipientInfoType), NULL,
422  	  sizeof(SecCmsRecipientInfo) },
423      { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
424  	  offsetof(SecCmsRecipientInfo,ri.keyAgreeRecipientInfo),
425  	  SecCmsKeyAgreeRecipientInfoTemplate,
426  	  SecCmsRecipientInfoIDKeyAgree },
427      { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
428  	  offsetof(SecCmsRecipientInfo,ri.kekRecipientInfo),
429  	  SecCmsKEKRecipientInfoTemplate,
430  	  SecCmsRecipientInfoIDKEK },
431      { SEC_ASN1_INLINE,
432  	  offsetof(SecCmsRecipientInfo,ri.keyTransRecipientInfo),
433  	  SecCmsKeyTransRecipientInfoTemplate,
434  	  SecCmsRecipientInfoIDKeyTrans },
435      { 0 }
436  };
437  
438  /* -----------------------------------------------------------------------------
439   *
440   */
441  
442  const SecAsn1Template SecCmsDigestedDataTemplate[] = {
443      { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
444  	  0, NULL, sizeof(SecCmsDigestedData) },
445      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
446  	  offsetof(SecCmsDigestedData,version) },
447      { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
448  	  offsetof(SecCmsDigestedData,digestAlg),
449  	  SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
450      { SEC_ASN1_INLINE,
451  	  offsetof(SecCmsDigestedData,contentInfo),
452  	  SecCmsEncapsulatedContentInfoTemplate },
453      { SEC_ASN1_OCTET_STRING,
454  	  offsetof(SecCmsDigestedData,digest) },
455      { 0 }
456  };
457  
458  const SecAsn1Template NSS_PointerToCMSDigestedDataTemplate[] = {
459      { SEC_ASN1_POINTER, 0, SecCmsDigestedDataTemplate }
460  };
461  
462  const SecAsn1Template SecCmsEncryptedDataTemplate[] = {
463      { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
464  	  0, NULL, sizeof(SecCmsEncryptedData) },
465      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
466  	  offsetof(SecCmsEncryptedData,version) },
467      { SEC_ASN1_INLINE,
468  	  offsetof(SecCmsEncryptedData,contentInfo),
469  	  SecCmsEncryptedContentInfoTemplate },
470      { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
471  	  offsetof(SecCmsEncryptedData,unprotectedAttr),
472  	  nss_cms_set_of_attribute_template },
473      { 0 }
474  };
475  
476  const SecAsn1Template NSS_PointerToCMSEncryptedDataTemplate[] = {
477      { SEC_ASN1_POINTER, 0, SecCmsEncryptedDataTemplate }
478  };
479  
480  /* -----------------------------------------------------------------------------
481   * SetOfSignedCrlTemplate
482   */
483  const SecAsn1Template SecCmsIssuerAndSNTemplate[] = {
484      { SEC_ASN1_SEQUENCE,
485            0, NULL, sizeof(SecCmsIssuerAndSN) },
486  #if 1 // @@@ Switch to using NSS_NameTemplate
487      { SEC_ASN1_ANY,
488            offsetof(SecCmsIssuerAndSN,derIssuer) },
489  #else
490      { SEC_ASN1_INLINE,
491  	  offsetof(SecCmsIssuerAndSN,issuer),
492  	  NSS_NameTemplate },
493  #endif
494      { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT,
495            offsetof(SecCmsIssuerAndSN,serialNumber) },
496      { 0 }
497  };
498  
499  
500  /* -----------------------------------------------------------------------------
501   * FORTEZZA KEA
502   */
503  const SecAsn1Template NSS_SMIMEKEAParamTemplateSkipjack[] = {
504  	{ SEC_ASN1_SEQUENCE,
505  	  0, NULL, sizeof(SecCmsSMIMEKEAParameters) },
506  	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
507  	  offsetof(SecCmsSMIMEKEAParameters,originatorKEAKey) },
508  	{ SEC_ASN1_OCTET_STRING,
509  	  offsetof(SecCmsSMIMEKEAParameters,originatorRA) },
510  	{ 0 }
511  };
512  
513  const SecAsn1Template NSS_SMIMEKEAParamTemplateNoSkipjack[] = {
514  	{ SEC_ASN1_SEQUENCE,
515  	  0, NULL, sizeof(SecCmsSMIMEKEAParameters) },
516  	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
517  	  offsetof(SecCmsSMIMEKEAParameters,originatorKEAKey) },
518  	{ SEC_ASN1_OCTET_STRING,
519  	  offsetof(SecCmsSMIMEKEAParameters,originatorRA) },
520  	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
521  	  offsetof(SecCmsSMIMEKEAParameters,nonSkipjackIV) },
522  	{ 0 }
523  };
524  
525  const SecAsn1Template NSS_SMIMEKEAParamTemplateAllParams[] = {
526  	{ SEC_ASN1_SEQUENCE,
527  	  0, NULL, sizeof(SecCmsSMIMEKEAParameters) },
528  	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
529  	  offsetof(SecCmsSMIMEKEAParameters,originatorKEAKey) },
530  	{ SEC_ASN1_OCTET_STRING,
531  	  offsetof(SecCmsSMIMEKEAParameters,originatorRA) },
532  	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
533  	  offsetof(SecCmsSMIMEKEAParameters,nonSkipjackIV) },
534  	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
535  	  offsetof(SecCmsSMIMEKEAParameters,bulkKeySize) },
536  	{ 0 }
537  };
538  
539  const SecAsn1Template *
540  nss_cms_get_kea_template(SecCmsKEATemplateSelector whichTemplate)
541  {
542  	const SecAsn1Template *returnVal = NULL;
543  
544  	switch(whichTemplate)
545  	{
546  	case SecCmsKEAUsesNonSkipjack:
547  		returnVal = NSS_SMIMEKEAParamTemplateNoSkipjack;
548  		break;
549  	case SecCmsKEAUsesSkipjack:
550  		returnVal = NSS_SMIMEKEAParamTemplateSkipjack;
551  		break;
552  	case SecCmsKEAUsesNonSkipjackWithPaddedEncKey:
553  	default:
554  		returnVal = NSS_SMIMEKEAParamTemplateAllParams;
555  		break;
556  	}
557  	return returnVal;
558  }
559  
560  /* -----------------------------------------------------------------------------
561   *
562   */
563  static const SecAsn1Template *
564  nss_cms_choose_content_template(void *src_or_dest, Boolean encoding, const char *buf, size_t len, void *dest)
565  {
566      const SecAsn1Template *theTemplate;
567      SecCmsContentInfoRef cinfo;
568  
569      PORT_Assert (src_or_dest != NULL);
570      if (src_or_dest == NULL)
571  	return NULL;
572  
573      cinfo = (SecCmsContentInfoRef)src_or_dest;
574      switch (SecCmsContentInfoGetContentTypeTag(cinfo)) {
575      default:
576  	theTemplate = SEC_ASN1_GET(kSecAsn1PointerToAnyTemplate);
577  	break;
578      case SEC_OID_PKCS7_DATA:
579  	theTemplate = SEC_ASN1_GET(kSecAsn1PointerToOctetStringTemplate);
580  	break;
581      case SEC_OID_PKCS7_SIGNED_DATA:
582  	theTemplate = NSS_PointerToCMSSignedDataTemplate;
583  	break;
584      case SEC_OID_PKCS7_ENVELOPED_DATA:
585  	theTemplate = NSS_PointerToCMSEnvelopedDataTemplate;
586  	break;
587      case SEC_OID_PKCS7_DIGESTED_DATA:
588  	theTemplate = NSS_PointerToCMSDigestedDataTemplate;
589  	break;
590      case SEC_OID_PKCS7_ENCRYPTED_DATA:
591  	theTemplate = NSS_PointerToCMSEncryptedDataTemplate;
592  	break;
593      }
594      return theTemplate;
595  }