xref: /openbsd/lib/libcrypto/pkcs7/pk7_asn1.c (revision 5af055cd)
1 /* $OpenBSD: pk7_asn1.c,v 1.12 2015/07/25 15:33:06 jsing Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2000.
4  */
5 /* ====================================================================
6  * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 
59 #include <stdio.h>
60 
61 #include <openssl/asn1t.h>
62 #include <openssl/pkcs7.h>
63 #include <openssl/x509.h>
64 
65 /* PKCS#7 ASN1 module */
66 
67 /* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
68 
69 static const ASN1_TEMPLATE p7default_tt = {
70 	.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
71 	.tag = 0,
72 	.offset = offsetof(PKCS7, d.other),
73 	.field_name = "d.other",
74 	.item = &ASN1_ANY_it,
75 };
76 
77 static const ASN1_ADB_TABLE PKCS7_adbtbl[] = {
78 	{
79 		.value = NID_pkcs7_data,
80 		.tt = {
81 			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
82 			.tag = 0,
83 			.offset = offsetof(PKCS7, d.data),
84 			.field_name = "d.data",
85 			.item = &ASN1_OCTET_STRING_NDEF_it,
86 		},
87 
88 	},
89 	{
90 		.value = NID_pkcs7_signed,
91 		.tt = {
92 			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
93 			.tag = 0,
94 			.offset = offsetof(PKCS7, d.sign),
95 			.field_name = "d.sign",
96 			.item = &PKCS7_SIGNED_it,
97 		},
98 
99 	},
100 	{
101 		.value = NID_pkcs7_enveloped,
102 		.tt = {
103 			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
104 			.tag = 0,
105 			.offset = offsetof(PKCS7, d.enveloped),
106 			.field_name = "d.enveloped",
107 			.item = &PKCS7_ENVELOPE_it,
108 		},
109 
110 	},
111 	{
112 		.value = NID_pkcs7_signedAndEnveloped,
113 		.tt = {
114 			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
115 			.tag = 0,
116 			.offset = offsetof(PKCS7, d.signed_and_enveloped),
117 			.field_name = "d.signed_and_enveloped",
118 			.item = &PKCS7_SIGN_ENVELOPE_it,
119 		},
120 
121 	},
122 	{
123 		.value = NID_pkcs7_digest,
124 		.tt = {
125 			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
126 			.tag = 0,
127 			.offset = offsetof(PKCS7, d.digest),
128 			.field_name = "d.digest",
129 			.item = &PKCS7_DIGEST_it,
130 		},
131 
132 	},
133 	{
134 		.value = NID_pkcs7_encrypted,
135 		.tt = {
136 			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
137 			.tag = 0,
138 			.offset = offsetof(PKCS7, d.encrypted),
139 			.field_name = "d.encrypted",
140 			.item = &PKCS7_ENCRYPT_it,
141 		},
142 
143 	},
144 };
145 
146 static const ASN1_ADB PKCS7_adb = {
147 	.flags = 0,
148 	.offset = offsetof(PKCS7, type),
149 	.app_items = 0,
150 	.tbl = PKCS7_adbtbl,
151 	.tblcount = sizeof(PKCS7_adbtbl) / sizeof(ASN1_ADB_TABLE),
152 	.default_tt = &p7default_tt,
153 	.null_tt = NULL,
154 };
155 
156 /* PKCS#7 streaming support */
157 static int
158 pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
159 {
160 	ASN1_STREAM_ARG *sarg = exarg;
161 	PKCS7 **pp7 = (PKCS7 **)pval;
162 
163 	switch (operation) {
164 	case ASN1_OP_STREAM_PRE:
165 		if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
166 			return 0;
167 
168 	case ASN1_OP_DETACHED_PRE:
169 		sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
170 		if (!sarg->ndef_bio)
171 			return 0;
172 		break;
173 
174 	case ASN1_OP_STREAM_POST:
175 	case ASN1_OP_DETACHED_POST:
176 		if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
177 			return 0;
178 		break;
179 	}
180 	return 1;
181 }
182 
183 static const ASN1_AUX PKCS7_aux = {
184 	.app_data = NULL,
185 	.flags = 0,
186 	.ref_offset = 0,
187 	.ref_lock = 0,
188 	.asn1_cb = pk7_cb,
189 	.enc_offset = 0,
190 };
191 static const ASN1_TEMPLATE PKCS7_seq_tt[] = {
192 	{
193 		.flags = 0,
194 		.tag = 0,
195 		.offset = offsetof(PKCS7, type),
196 		.field_name = "type",
197 		.item = &ASN1_OBJECT_it,
198 	},
199 	{
200 		.flags = ASN1_TFLG_ADB_OID,
201 		.tag = -1,
202 		.offset = 0,
203 		.field_name = "PKCS7",
204 		.item = (const ASN1_ITEM *)&PKCS7_adb,
205 	},
206 };
207 
208 const ASN1_ITEM PKCS7_it = {
209 	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
210 	.utype = V_ASN1_SEQUENCE,
211 	.templates = PKCS7_seq_tt,
212 	.tcount = sizeof(PKCS7_seq_tt) / sizeof(ASN1_TEMPLATE),
213 	.funcs = &PKCS7_aux,
214 	.size = sizeof(PKCS7),
215 	.sname = "PKCS7",
216 };
217 
218 
219 PKCS7 *
220 d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len)
221 {
222 	return (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
223 	    &PKCS7_it);
224 }
225 
226 int
227 i2d_PKCS7(PKCS7 *a, unsigned char **out)
228 {
229 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_it);
230 }
231 
232 PKCS7 *
233 PKCS7_new(void)
234 {
235 	return (PKCS7 *)ASN1_item_new(&PKCS7_it);
236 }
237 
238 void
239 PKCS7_free(PKCS7 *a)
240 {
241 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_it);
242 }
243 
244 int
245 i2d_PKCS7_NDEF(PKCS7 *a, unsigned char **out)
246 {
247 	return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, &PKCS7_it);
248 }
249 
250 PKCS7 *
251 PKCS7_dup(PKCS7 *x)
252 {
253 	return ASN1_item_dup(&PKCS7_it, x);
254 }
255 
256 static const ASN1_TEMPLATE PKCS7_SIGNED_seq_tt[] = {
257 	{
258 		.flags = 0,
259 		.tag = 0,
260 		.offset = offsetof(PKCS7_SIGNED, version),
261 		.field_name = "version",
262 		.item = &ASN1_INTEGER_it,
263 	},
264 	{
265 		.flags = ASN1_TFLG_SET_OF,
266 		.tag = 0,
267 		.offset = offsetof(PKCS7_SIGNED, md_algs),
268 		.field_name = "md_algs",
269 		.item = &X509_ALGOR_it,
270 	},
271 	{
272 		.flags = 0,
273 		.tag = 0,
274 		.offset = offsetof(PKCS7_SIGNED, contents),
275 		.field_name = "contents",
276 		.item = &PKCS7_it,
277 	},
278 	{
279 		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
280 		.tag = 0,
281 		.offset = offsetof(PKCS7_SIGNED, cert),
282 		.field_name = "cert",
283 		.item = &X509_it,
284 	},
285 	{
286 		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
287 		.tag = 1,
288 		.offset = offsetof(PKCS7_SIGNED, crl),
289 		.field_name = "crl",
290 		.item = &X509_CRL_it,
291 	},
292 	{
293 		.flags = ASN1_TFLG_SET_OF,
294 		.tag = 0,
295 		.offset = offsetof(PKCS7_SIGNED, signer_info),
296 		.field_name = "signer_info",
297 		.item = &PKCS7_SIGNER_INFO_it,
298 	},
299 };
300 
301 const ASN1_ITEM PKCS7_SIGNED_it = {
302 	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
303 	.utype = V_ASN1_SEQUENCE,
304 	.templates = PKCS7_SIGNED_seq_tt,
305 	.tcount = sizeof(PKCS7_SIGNED_seq_tt) / sizeof(ASN1_TEMPLATE),
306 	.funcs = NULL,
307 	.size = sizeof(PKCS7_SIGNED),
308 	.sname = "PKCS7_SIGNED",
309 };
310 
311 
312 PKCS7_SIGNED *
313 d2i_PKCS7_SIGNED(PKCS7_SIGNED **a, const unsigned char **in, long len)
314 {
315 	return (PKCS7_SIGNED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
316 	    &PKCS7_SIGNED_it);
317 }
318 
319 int
320 i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out)
321 {
322 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNED_it);
323 }
324 
325 PKCS7_SIGNED *
326 PKCS7_SIGNED_new(void)
327 {
328 	return (PKCS7_SIGNED *)ASN1_item_new(&PKCS7_SIGNED_it);
329 }
330 
331 void
332 PKCS7_SIGNED_free(PKCS7_SIGNED *a)
333 {
334 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNED_it);
335 }
336 
337 /* Minor tweak to operation: free up EVP_PKEY */
338 static int
339 si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
340 {
341 	if (operation == ASN1_OP_FREE_POST) {
342 		PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
343 		EVP_PKEY_free(si->pkey);
344 	}
345 	return 1;
346 }
347 
348 static const ASN1_AUX PKCS7_SIGNER_INFO_aux = {
349 	.app_data = NULL,
350 	.flags = 0,
351 	.ref_offset = 0,
352 	.ref_lock = 0,
353 	.asn1_cb = si_cb,
354 	.enc_offset = 0,
355 };
356 static const ASN1_TEMPLATE PKCS7_SIGNER_INFO_seq_tt[] = {
357 	{
358 		.flags = 0,
359 		.tag = 0,
360 		.offset = offsetof(PKCS7_SIGNER_INFO, version),
361 		.field_name = "version",
362 		.item = &ASN1_INTEGER_it,
363 	},
364 	{
365 		.flags = 0,
366 		.tag = 0,
367 		.offset = offsetof(PKCS7_SIGNER_INFO, issuer_and_serial),
368 		.field_name = "issuer_and_serial",
369 		.item = &PKCS7_ISSUER_AND_SERIAL_it,
370 	},
371 	{
372 		.flags = 0,
373 		.tag = 0,
374 		.offset = offsetof(PKCS7_SIGNER_INFO, digest_alg),
375 		.field_name = "digest_alg",
376 		.item = &X509_ALGOR_it,
377 	},
378 	/* NB this should be a SET OF but we use a SEQUENCE OF so the
379 	 * original order * is retained when the structure is reencoded.
380 	 * Since the attributes are implicitly tagged this will not affect
381 	 * the encoding.
382 	 */
383 	{
384 		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
385 		.tag = 0,
386 		.offset = offsetof(PKCS7_SIGNER_INFO, auth_attr),
387 		.field_name = "auth_attr",
388 		.item = &X509_ATTRIBUTE_it,
389 	},
390 	{
391 		.flags = 0,
392 		.tag = 0,
393 		.offset = offsetof(PKCS7_SIGNER_INFO, digest_enc_alg),
394 		.field_name = "digest_enc_alg",
395 		.item = &X509_ALGOR_it,
396 	},
397 	{
398 		.flags = 0,
399 		.tag = 0,
400 		.offset = offsetof(PKCS7_SIGNER_INFO, enc_digest),
401 		.field_name = "enc_digest",
402 		.item = &ASN1_OCTET_STRING_it,
403 	},
404 	{
405 		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
406 		.tag = 1,
407 		.offset = offsetof(PKCS7_SIGNER_INFO, unauth_attr),
408 		.field_name = "unauth_attr",
409 		.item = &X509_ATTRIBUTE_it,
410 	},
411 };
412 
413 const ASN1_ITEM PKCS7_SIGNER_INFO_it = {
414 	.itype = ASN1_ITYPE_SEQUENCE,
415 	.utype = V_ASN1_SEQUENCE,
416 	.templates = PKCS7_SIGNER_INFO_seq_tt,
417 	.tcount = sizeof(PKCS7_SIGNER_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
418 	.funcs = &PKCS7_SIGNER_INFO_aux,
419 	.size = sizeof(PKCS7_SIGNER_INFO),
420 	.sname = "PKCS7_SIGNER_INFO",
421 };
422 
423 
424 PKCS7_SIGNER_INFO *
425 d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a, const unsigned char **in, long len)
426 {
427 	return (PKCS7_SIGNER_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
428 	    &PKCS7_SIGNER_INFO_it);
429 }
430 
431 int
432 i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a, unsigned char **out)
433 {
434 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNER_INFO_it);
435 }
436 
437 PKCS7_SIGNER_INFO *
438 PKCS7_SIGNER_INFO_new(void)
439 {
440 	return (PKCS7_SIGNER_INFO *)ASN1_item_new(&PKCS7_SIGNER_INFO_it);
441 }
442 
443 void
444 PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a)
445 {
446 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNER_INFO_it);
447 }
448 
449 static const ASN1_TEMPLATE PKCS7_ISSUER_AND_SERIAL_seq_tt[] = {
450 	{
451 		.flags = 0,
452 		.tag = 0,
453 		.offset = offsetof(PKCS7_ISSUER_AND_SERIAL, issuer),
454 		.field_name = "issuer",
455 		.item = &X509_NAME_it,
456 	},
457 	{
458 		.flags = 0,
459 		.tag = 0,
460 		.offset = offsetof(PKCS7_ISSUER_AND_SERIAL, serial),
461 		.field_name = "serial",
462 		.item = &ASN1_INTEGER_it,
463 	},
464 };
465 
466 const ASN1_ITEM PKCS7_ISSUER_AND_SERIAL_it = {
467 	.itype = ASN1_ITYPE_SEQUENCE,
468 	.utype = V_ASN1_SEQUENCE,
469 	.templates = PKCS7_ISSUER_AND_SERIAL_seq_tt,
470 	.tcount = sizeof(PKCS7_ISSUER_AND_SERIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
471 	.funcs = NULL,
472 	.size = sizeof(PKCS7_ISSUER_AND_SERIAL),
473 	.sname = "PKCS7_ISSUER_AND_SERIAL",
474 };
475 
476 
477 PKCS7_ISSUER_AND_SERIAL *
478 d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL **a, const unsigned char **in, long len)
479 {
480 	return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
481 	    &PKCS7_ISSUER_AND_SERIAL_it);
482 }
483 
484 int
485 i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL *a, unsigned char **out)
486 {
487 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ISSUER_AND_SERIAL_it);
488 }
489 
490 PKCS7_ISSUER_AND_SERIAL *
491 PKCS7_ISSUER_AND_SERIAL_new(void)
492 {
493 	return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_new(&PKCS7_ISSUER_AND_SERIAL_it);
494 }
495 
496 void
497 PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL *a)
498 {
499 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ISSUER_AND_SERIAL_it);
500 }
501 
502 static const ASN1_TEMPLATE PKCS7_ENVELOPE_seq_tt[] = {
503 	{
504 		.flags = 0,
505 		.tag = 0,
506 		.offset = offsetof(PKCS7_ENVELOPE, version),
507 		.field_name = "version",
508 		.item = &ASN1_INTEGER_it,
509 	},
510 	{
511 		.flags = ASN1_TFLG_SET_OF,
512 		.tag = 0,
513 		.offset = offsetof(PKCS7_ENVELOPE, recipientinfo),
514 		.field_name = "recipientinfo",
515 		.item = &PKCS7_RECIP_INFO_it,
516 	},
517 	{
518 		.flags = 0,
519 		.tag = 0,
520 		.offset = offsetof(PKCS7_ENVELOPE, enc_data),
521 		.field_name = "enc_data",
522 		.item = &PKCS7_ENC_CONTENT_it,
523 	},
524 };
525 
526 const ASN1_ITEM PKCS7_ENVELOPE_it = {
527 	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
528 	.utype = V_ASN1_SEQUENCE,
529 	.templates = PKCS7_ENVELOPE_seq_tt,
530 	.tcount = sizeof(PKCS7_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE),
531 	.funcs = NULL,
532 	.size = sizeof(PKCS7_ENVELOPE),
533 	.sname = "PKCS7_ENVELOPE",
534 };
535 
536 
537 PKCS7_ENVELOPE *
538 d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a, const unsigned char **in, long len)
539 {
540 	return (PKCS7_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
541 	    &PKCS7_ENVELOPE_it);
542 }
543 
544 int
545 i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **out)
546 {
547 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENVELOPE_it);
548 }
549 
550 PKCS7_ENVELOPE *
551 PKCS7_ENVELOPE_new(void)
552 {
553 	return (PKCS7_ENVELOPE *)ASN1_item_new(&PKCS7_ENVELOPE_it);
554 }
555 
556 void
557 PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a)
558 {
559 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENVELOPE_it);
560 }
561 
562 /* Minor tweak to operation: free up X509 */
563 static int
564 ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
565 {
566 	if (operation == ASN1_OP_FREE_POST) {
567 		PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
568 		X509_free(ri->cert);
569 	}
570 	return 1;
571 }
572 
573 static const ASN1_AUX PKCS7_RECIP_INFO_aux = {
574 	.app_data = NULL,
575 	.flags = 0,
576 	.ref_offset = 0,
577 	.ref_lock = 0,
578 	.asn1_cb = ri_cb,
579 	.enc_offset = 0,
580 };
581 static const ASN1_TEMPLATE PKCS7_RECIP_INFO_seq_tt[] = {
582 	{
583 		.flags = 0,
584 		.tag = 0,
585 		.offset = offsetof(PKCS7_RECIP_INFO, version),
586 		.field_name = "version",
587 		.item = &ASN1_INTEGER_it,
588 	},
589 	{
590 		.flags = 0,
591 		.tag = 0,
592 		.offset = offsetof(PKCS7_RECIP_INFO, issuer_and_serial),
593 		.field_name = "issuer_and_serial",
594 		.item = &PKCS7_ISSUER_AND_SERIAL_it,
595 	},
596 	{
597 		.flags = 0,
598 		.tag = 0,
599 		.offset = offsetof(PKCS7_RECIP_INFO, key_enc_algor),
600 		.field_name = "key_enc_algor",
601 		.item = &X509_ALGOR_it,
602 	},
603 	{
604 		.flags = 0,
605 		.tag = 0,
606 		.offset = offsetof(PKCS7_RECIP_INFO, enc_key),
607 		.field_name = "enc_key",
608 		.item = &ASN1_OCTET_STRING_it,
609 	},
610 };
611 
612 const ASN1_ITEM PKCS7_RECIP_INFO_it = {
613 	.itype = ASN1_ITYPE_SEQUENCE,
614 	.utype = V_ASN1_SEQUENCE,
615 	.templates = PKCS7_RECIP_INFO_seq_tt,
616 	.tcount = sizeof(PKCS7_RECIP_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
617 	.funcs = &PKCS7_RECIP_INFO_aux,
618 	.size = sizeof(PKCS7_RECIP_INFO),
619 	.sname = "PKCS7_RECIP_INFO",
620 };
621 
622 
623 PKCS7_RECIP_INFO *
624 d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a, const unsigned char **in, long len)
625 {
626 	return (PKCS7_RECIP_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
627 	    &PKCS7_RECIP_INFO_it);
628 }
629 
630 int
631 i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a, unsigned char **out)
632 {
633 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_RECIP_INFO_it);
634 }
635 
636 PKCS7_RECIP_INFO *
637 PKCS7_RECIP_INFO_new(void)
638 {
639 	return (PKCS7_RECIP_INFO *)ASN1_item_new(&PKCS7_RECIP_INFO_it);
640 }
641 
642 void
643 PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a)
644 {
645 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_RECIP_INFO_it);
646 }
647 
648 static const ASN1_TEMPLATE PKCS7_ENC_CONTENT_seq_tt[] = {
649 	{
650 		.flags = 0,
651 		.tag = 0,
652 		.offset = offsetof(PKCS7_ENC_CONTENT, content_type),
653 		.field_name = "content_type",
654 		.item = &ASN1_OBJECT_it,
655 	},
656 	{
657 		.flags = 0,
658 		.tag = 0,
659 		.offset = offsetof(PKCS7_ENC_CONTENT, algorithm),
660 		.field_name = "algorithm",
661 		.item = &X509_ALGOR_it,
662 	},
663 	{
664 		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
665 		.tag = 0,
666 		.offset = offsetof(PKCS7_ENC_CONTENT, enc_data),
667 		.field_name = "enc_data",
668 		.item = &ASN1_OCTET_STRING_NDEF_it,
669 	},
670 };
671 
672 const ASN1_ITEM PKCS7_ENC_CONTENT_it = {
673 	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
674 	.utype = V_ASN1_SEQUENCE,
675 	.templates = PKCS7_ENC_CONTENT_seq_tt,
676 	.tcount = sizeof(PKCS7_ENC_CONTENT_seq_tt) / sizeof(ASN1_TEMPLATE),
677 	.funcs = NULL,
678 	.size = sizeof(PKCS7_ENC_CONTENT),
679 	.sname = "PKCS7_ENC_CONTENT",
680 };
681 
682 
683 PKCS7_ENC_CONTENT *
684 d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a, const unsigned char **in, long len)
685 {
686 	return (PKCS7_ENC_CONTENT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
687 	    &PKCS7_ENC_CONTENT_it);
688 }
689 
690 int
691 i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **out)
692 {
693 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENC_CONTENT_it);
694 }
695 
696 PKCS7_ENC_CONTENT *
697 PKCS7_ENC_CONTENT_new(void)
698 {
699 	return (PKCS7_ENC_CONTENT *)ASN1_item_new(&PKCS7_ENC_CONTENT_it);
700 }
701 
702 void
703 PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a)
704 {
705 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENC_CONTENT_it);
706 }
707 
708 static const ASN1_TEMPLATE PKCS7_SIGN_ENVELOPE_seq_tt[] = {
709 	{
710 		.flags = 0,
711 		.tag = 0,
712 		.offset = offsetof(PKCS7_SIGN_ENVELOPE, version),
713 		.field_name = "version",
714 		.item = &ASN1_INTEGER_it,
715 	},
716 	{
717 		.flags = ASN1_TFLG_SET_OF,
718 		.tag = 0,
719 		.offset = offsetof(PKCS7_SIGN_ENVELOPE, recipientinfo),
720 		.field_name = "recipientinfo",
721 		.item = &PKCS7_RECIP_INFO_it,
722 	},
723 	{
724 		.flags = ASN1_TFLG_SET_OF,
725 		.tag = 0,
726 		.offset = offsetof(PKCS7_SIGN_ENVELOPE, md_algs),
727 		.field_name = "md_algs",
728 		.item = &X509_ALGOR_it,
729 	},
730 	{
731 		.flags = 0,
732 		.tag = 0,
733 		.offset = offsetof(PKCS7_SIGN_ENVELOPE, enc_data),
734 		.field_name = "enc_data",
735 		.item = &PKCS7_ENC_CONTENT_it,
736 	},
737 	{
738 		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
739 		.tag = 0,
740 		.offset = offsetof(PKCS7_SIGN_ENVELOPE, cert),
741 		.field_name = "cert",
742 		.item = &X509_it,
743 	},
744 	{
745 		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
746 		.tag = 1,
747 		.offset = offsetof(PKCS7_SIGN_ENVELOPE, crl),
748 		.field_name = "crl",
749 		.item = &X509_CRL_it,
750 	},
751 	{
752 		.flags = ASN1_TFLG_SET_OF,
753 		.tag = 0,
754 		.offset = offsetof(PKCS7_SIGN_ENVELOPE, signer_info),
755 		.field_name = "signer_info",
756 		.item = &PKCS7_SIGNER_INFO_it,
757 	},
758 };
759 
760 const ASN1_ITEM PKCS7_SIGN_ENVELOPE_it = {
761 	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
762 	.utype = V_ASN1_SEQUENCE,
763 	.templates = PKCS7_SIGN_ENVELOPE_seq_tt,
764 	.tcount = sizeof(PKCS7_SIGN_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE),
765 	.funcs = NULL,
766 	.size = sizeof(PKCS7_SIGN_ENVELOPE),
767 	.sname = "PKCS7_SIGN_ENVELOPE",
768 };
769 
770 
771 PKCS7_SIGN_ENVELOPE *
772 d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a, const unsigned char **in, long len)
773 {
774 	return (PKCS7_SIGN_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
775 	    &PKCS7_SIGN_ENVELOPE_it);
776 }
777 
778 int
779 i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a, unsigned char **out)
780 {
781 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGN_ENVELOPE_it);
782 }
783 
784 PKCS7_SIGN_ENVELOPE *
785 PKCS7_SIGN_ENVELOPE_new(void)
786 {
787 	return (PKCS7_SIGN_ENVELOPE *)ASN1_item_new(&PKCS7_SIGN_ENVELOPE_it);
788 }
789 
790 void
791 PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a)
792 {
793 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGN_ENVELOPE_it);
794 }
795 
796 static const ASN1_TEMPLATE PKCS7_ENCRYPT_seq_tt[] = {
797 	{
798 		.flags = 0,
799 		.tag = 0,
800 		.offset = offsetof(PKCS7_ENCRYPT, version),
801 		.field_name = "version",
802 		.item = &ASN1_INTEGER_it,
803 	},
804 	{
805 		.flags = 0,
806 		.tag = 0,
807 		.offset = offsetof(PKCS7_ENCRYPT, enc_data),
808 		.field_name = "enc_data",
809 		.item = &PKCS7_ENC_CONTENT_it,
810 	},
811 };
812 
813 const ASN1_ITEM PKCS7_ENCRYPT_it = {
814 	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
815 	.utype = V_ASN1_SEQUENCE,
816 	.templates = PKCS7_ENCRYPT_seq_tt,
817 	.tcount = sizeof(PKCS7_ENCRYPT_seq_tt) / sizeof(ASN1_TEMPLATE),
818 	.funcs = NULL,
819 	.size = sizeof(PKCS7_ENCRYPT),
820 	.sname = "PKCS7_ENCRYPT",
821 };
822 
823 
824 PKCS7_ENCRYPT *
825 d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a, const unsigned char **in, long len)
826 {
827 	return (PKCS7_ENCRYPT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
828 	    &PKCS7_ENCRYPT_it);
829 }
830 
831 int
832 i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a, unsigned char **out)
833 {
834 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENCRYPT_it);
835 }
836 
837 PKCS7_ENCRYPT *
838 PKCS7_ENCRYPT_new(void)
839 {
840 	return (PKCS7_ENCRYPT *)ASN1_item_new(&PKCS7_ENCRYPT_it);
841 }
842 
843 void
844 PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a)
845 {
846 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENCRYPT_it);
847 }
848 
849 static const ASN1_TEMPLATE PKCS7_DIGEST_seq_tt[] = {
850 	{
851 		.flags = 0,
852 		.tag = 0,
853 		.offset = offsetof(PKCS7_DIGEST, version),
854 		.field_name = "version",
855 		.item = &ASN1_INTEGER_it,
856 	},
857 	{
858 		.flags = 0,
859 		.tag = 0,
860 		.offset = offsetof(PKCS7_DIGEST, md),
861 		.field_name = "md",
862 		.item = &X509_ALGOR_it,
863 	},
864 	{
865 		.flags = 0,
866 		.tag = 0,
867 		.offset = offsetof(PKCS7_DIGEST, contents),
868 		.field_name = "contents",
869 		.item = &PKCS7_it,
870 	},
871 	{
872 		.flags = 0,
873 		.tag = 0,
874 		.offset = offsetof(PKCS7_DIGEST, digest),
875 		.field_name = "digest",
876 		.item = &ASN1_OCTET_STRING_it,
877 	},
878 };
879 
880 const ASN1_ITEM PKCS7_DIGEST_it = {
881 	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
882 	.utype = V_ASN1_SEQUENCE,
883 	.templates = PKCS7_DIGEST_seq_tt,
884 	.tcount = sizeof(PKCS7_DIGEST_seq_tt) / sizeof(ASN1_TEMPLATE),
885 	.funcs = NULL,
886 	.size = sizeof(PKCS7_DIGEST),
887 	.sname = "PKCS7_DIGEST",
888 };
889 
890 
891 PKCS7_DIGEST *
892 d2i_PKCS7_DIGEST(PKCS7_DIGEST **a, const unsigned char **in, long len)
893 {
894 	return (PKCS7_DIGEST *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
895 	    &PKCS7_DIGEST_it);
896 }
897 
898 int
899 i2d_PKCS7_DIGEST(PKCS7_DIGEST *a, unsigned char **out)
900 {
901 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_DIGEST_it);
902 }
903 
904 PKCS7_DIGEST *
905 PKCS7_DIGEST_new(void)
906 {
907 	return (PKCS7_DIGEST *)ASN1_item_new(&PKCS7_DIGEST_it);
908 }
909 
910 void
911 PKCS7_DIGEST_free(PKCS7_DIGEST *a)
912 {
913 	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_DIGEST_it);
914 }
915 
916 /* Specials for authenticated attributes */
917 
918 /* When signing attributes we want to reorder them to match the sorted
919  * encoding.
920  */
921 
922 static const ASN1_TEMPLATE PKCS7_ATTR_SIGN_item_tt = {
923 	.flags = ASN1_TFLG_SET_ORDER,
924 	.tag = 0,
925 	.offset = 0,
926 	.field_name = "PKCS7_ATTRIBUTES",
927 	.item = &X509_ATTRIBUTE_it,
928 };
929 
930 const ASN1_ITEM PKCS7_ATTR_SIGN_it = {
931 	.itype = ASN1_ITYPE_PRIMITIVE,
932 	.utype = -1,
933 	.templates = &PKCS7_ATTR_SIGN_item_tt,
934 	.tcount = 0,
935 	.funcs = NULL,
936 	.size = 0,
937 	.sname = "PKCS7_ATTR_SIGN",
938 };
939 
940 /* When verifying attributes we need to use the received order. So
941  * we use SEQUENCE OF and tag it to SET OF
942  */
943 
944 static const ASN1_TEMPLATE PKCS7_ATTR_VERIFY_item_tt = {
945 	.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
946 	.tag = V_ASN1_SET,
947 	.offset = 0,
948 	.field_name = "PKCS7_ATTRIBUTES",
949 	.item = &X509_ATTRIBUTE_it,
950 };
951 
952 const ASN1_ITEM PKCS7_ATTR_VERIFY_it = {
953 	.itype = ASN1_ITYPE_PRIMITIVE,
954 	.utype = -1,
955 	.templates = &PKCS7_ATTR_VERIFY_item_tt,
956 	.tcount = 0,
957 	.funcs = NULL,
958 	.size = 0,
959 	.sname = "PKCS7_ATTR_VERIFY",
960 };
961 
962 
963 int
964 PKCS7_print_ctx(BIO *out, PKCS7 *x, int indent, const ASN1_PCTX *pctx)
965 {
966 	return ASN1_item_print(out, (ASN1_VALUE *)x, indent,
967 	    &PKCS7_it, pctx);
968 }
969