Coverage Report

Created: 2025-11-05 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/lib/smime/cmsasn1.c
Line
Count
Source
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
3.45k
{
481
3.45k
    const SEC_ASN1Template *theTemplate;
482
3.45k
    NSSCMSContentInfo *cinfo;
483
3.45k
    SECOidTag type;
484
485
3.45k
    PORT_Assert(src_or_dest != NULL);
486
3.45k
    if (src_or_dest == NULL)
487
0
        return NULL;
488
489
3.45k
    cinfo = (NSSCMSContentInfo *)src_or_dest;
490
3.45k
    type = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
491
3.45k
    switch (type) {
492
480
        default:
493
480
            theTemplate = NSS_CMSType_GetTemplate(type);
494
480
            break;
495
33
        case SEC_OID_PKCS7_DATA:
496
33
            theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
497
33
            break;
498
2.16k
        case SEC_OID_PKCS7_SIGNED_DATA:
499
2.16k
            theTemplate = NSS_PointerToCMSSignedDataTemplate;
500
2.16k
            break;
501
713
        case SEC_OID_PKCS7_ENVELOPED_DATA:
502
713
            theTemplate = NSS_PointerToCMSEnvelopedDataTemplate;
503
713
            break;
504
46
        case SEC_OID_PKCS7_DIGESTED_DATA:
505
46
            theTemplate = NSS_PointerToCMSDigestedDataTemplate;
506
46
            break;
507
16
        case SEC_OID_PKCS7_ENCRYPTED_DATA:
508
16
            theTemplate = NSS_PointerToCMSEncryptedDataTemplate;
509
16
            break;
510
3.45k
    }
511
3.45k
    return theTemplate;
512
3.45k
}