1 /* $OpenBSD: pk7_asn1.c,v 1.13 2022/01/14 08:16:13 tb 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 .tbl = PKCS7_adbtbl,
150 .tblcount = sizeof(PKCS7_adbtbl) / sizeof(ASN1_ADB_TABLE),
151 .default_tt = &p7default_tt,
152 .null_tt = NULL,
153 };
154
155 /* PKCS#7 streaming support */
156 static int
pk7_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)157 pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
158 {
159 ASN1_STREAM_ARG *sarg = exarg;
160 PKCS7 **pp7 = (PKCS7 **)pval;
161
162 switch (operation) {
163 case ASN1_OP_STREAM_PRE:
164 if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
165 return 0;
166
167 case ASN1_OP_DETACHED_PRE:
168 sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
169 if (!sarg->ndef_bio)
170 return 0;
171 break;
172
173 case ASN1_OP_STREAM_POST:
174 case ASN1_OP_DETACHED_POST:
175 if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
176 return 0;
177 break;
178 }
179 return 1;
180 }
181
182 static const ASN1_AUX PKCS7_aux = {
183 .app_data = NULL,
184 .flags = 0,
185 .ref_offset = 0,
186 .ref_lock = 0,
187 .asn1_cb = pk7_cb,
188 .enc_offset = 0,
189 };
190 static const ASN1_TEMPLATE PKCS7_seq_tt[] = {
191 {
192 .flags = 0,
193 .tag = 0,
194 .offset = offsetof(PKCS7, type),
195 .field_name = "type",
196 .item = &ASN1_OBJECT_it,
197 },
198 {
199 .flags = ASN1_TFLG_ADB_OID,
200 .tag = -1,
201 .offset = 0,
202 .field_name = "PKCS7",
203 .item = (const ASN1_ITEM *)&PKCS7_adb,
204 },
205 };
206
207 const ASN1_ITEM PKCS7_it = {
208 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
209 .utype = V_ASN1_SEQUENCE,
210 .templates = PKCS7_seq_tt,
211 .tcount = sizeof(PKCS7_seq_tt) / sizeof(ASN1_TEMPLATE),
212 .funcs = &PKCS7_aux,
213 .size = sizeof(PKCS7),
214 .sname = "PKCS7",
215 };
216
217
218 PKCS7 *
d2i_PKCS7(PKCS7 ** a,const unsigned char ** in,long len)219 d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len)
220 {
221 return (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
222 &PKCS7_it);
223 }
224
225 int
i2d_PKCS7(PKCS7 * a,unsigned char ** out)226 i2d_PKCS7(PKCS7 *a, unsigned char **out)
227 {
228 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_it);
229 }
230
231 PKCS7 *
PKCS7_new(void)232 PKCS7_new(void)
233 {
234 return (PKCS7 *)ASN1_item_new(&PKCS7_it);
235 }
236
237 void
PKCS7_free(PKCS7 * a)238 PKCS7_free(PKCS7 *a)
239 {
240 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_it);
241 }
242
243 int
i2d_PKCS7_NDEF(PKCS7 * a,unsigned char ** out)244 i2d_PKCS7_NDEF(PKCS7 *a, unsigned char **out)
245 {
246 return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, &PKCS7_it);
247 }
248
249 PKCS7 *
PKCS7_dup(PKCS7 * x)250 PKCS7_dup(PKCS7 *x)
251 {
252 return ASN1_item_dup(&PKCS7_it, x);
253 }
254
255 static const ASN1_TEMPLATE PKCS7_SIGNED_seq_tt[] = {
256 {
257 .flags = 0,
258 .tag = 0,
259 .offset = offsetof(PKCS7_SIGNED, version),
260 .field_name = "version",
261 .item = &ASN1_INTEGER_it,
262 },
263 {
264 .flags = ASN1_TFLG_SET_OF,
265 .tag = 0,
266 .offset = offsetof(PKCS7_SIGNED, md_algs),
267 .field_name = "md_algs",
268 .item = &X509_ALGOR_it,
269 },
270 {
271 .flags = 0,
272 .tag = 0,
273 .offset = offsetof(PKCS7_SIGNED, contents),
274 .field_name = "contents",
275 .item = &PKCS7_it,
276 },
277 {
278 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
279 .tag = 0,
280 .offset = offsetof(PKCS7_SIGNED, cert),
281 .field_name = "cert",
282 .item = &X509_it,
283 },
284 {
285 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
286 .tag = 1,
287 .offset = offsetof(PKCS7_SIGNED, crl),
288 .field_name = "crl",
289 .item = &X509_CRL_it,
290 },
291 {
292 .flags = ASN1_TFLG_SET_OF,
293 .tag = 0,
294 .offset = offsetof(PKCS7_SIGNED, signer_info),
295 .field_name = "signer_info",
296 .item = &PKCS7_SIGNER_INFO_it,
297 },
298 };
299
300 const ASN1_ITEM PKCS7_SIGNED_it = {
301 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
302 .utype = V_ASN1_SEQUENCE,
303 .templates = PKCS7_SIGNED_seq_tt,
304 .tcount = sizeof(PKCS7_SIGNED_seq_tt) / sizeof(ASN1_TEMPLATE),
305 .funcs = NULL,
306 .size = sizeof(PKCS7_SIGNED),
307 .sname = "PKCS7_SIGNED",
308 };
309
310
311 PKCS7_SIGNED *
d2i_PKCS7_SIGNED(PKCS7_SIGNED ** a,const unsigned char ** in,long len)312 d2i_PKCS7_SIGNED(PKCS7_SIGNED **a, const unsigned char **in, long len)
313 {
314 return (PKCS7_SIGNED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
315 &PKCS7_SIGNED_it);
316 }
317
318 int
i2d_PKCS7_SIGNED(PKCS7_SIGNED * a,unsigned char ** out)319 i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out)
320 {
321 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNED_it);
322 }
323
324 PKCS7_SIGNED *
PKCS7_SIGNED_new(void)325 PKCS7_SIGNED_new(void)
326 {
327 return (PKCS7_SIGNED *)ASN1_item_new(&PKCS7_SIGNED_it);
328 }
329
330 void
PKCS7_SIGNED_free(PKCS7_SIGNED * a)331 PKCS7_SIGNED_free(PKCS7_SIGNED *a)
332 {
333 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNED_it);
334 }
335
336 /* Minor tweak to operation: free up EVP_PKEY */
337 static int
si_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)338 si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
339 {
340 if (operation == ASN1_OP_FREE_POST) {
341 PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
342 EVP_PKEY_free(si->pkey);
343 }
344 return 1;
345 }
346
347 static const ASN1_AUX PKCS7_SIGNER_INFO_aux = {
348 .app_data = NULL,
349 .flags = 0,
350 .ref_offset = 0,
351 .ref_lock = 0,
352 .asn1_cb = si_cb,
353 .enc_offset = 0,
354 };
355 static const ASN1_TEMPLATE PKCS7_SIGNER_INFO_seq_tt[] = {
356 {
357 .flags = 0,
358 .tag = 0,
359 .offset = offsetof(PKCS7_SIGNER_INFO, version),
360 .field_name = "version",
361 .item = &ASN1_INTEGER_it,
362 },
363 {
364 .flags = 0,
365 .tag = 0,
366 .offset = offsetof(PKCS7_SIGNER_INFO, issuer_and_serial),
367 .field_name = "issuer_and_serial",
368 .item = &PKCS7_ISSUER_AND_SERIAL_it,
369 },
370 {
371 .flags = 0,
372 .tag = 0,
373 .offset = offsetof(PKCS7_SIGNER_INFO, digest_alg),
374 .field_name = "digest_alg",
375 .item = &X509_ALGOR_it,
376 },
377 /* NB this should be a SET OF but we use a SEQUENCE OF so the
378 * original order * is retained when the structure is reencoded.
379 * Since the attributes are implicitly tagged this will not affect
380 * the encoding.
381 */
382 {
383 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
384 .tag = 0,
385 .offset = offsetof(PKCS7_SIGNER_INFO, auth_attr),
386 .field_name = "auth_attr",
387 .item = &X509_ATTRIBUTE_it,
388 },
389 {
390 .flags = 0,
391 .tag = 0,
392 .offset = offsetof(PKCS7_SIGNER_INFO, digest_enc_alg),
393 .field_name = "digest_enc_alg",
394 .item = &X509_ALGOR_it,
395 },
396 {
397 .flags = 0,
398 .tag = 0,
399 .offset = offsetof(PKCS7_SIGNER_INFO, enc_digest),
400 .field_name = "enc_digest",
401 .item = &ASN1_OCTET_STRING_it,
402 },
403 {
404 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
405 .tag = 1,
406 .offset = offsetof(PKCS7_SIGNER_INFO, unauth_attr),
407 .field_name = "unauth_attr",
408 .item = &X509_ATTRIBUTE_it,
409 },
410 };
411
412 const ASN1_ITEM PKCS7_SIGNER_INFO_it = {
413 .itype = ASN1_ITYPE_SEQUENCE,
414 .utype = V_ASN1_SEQUENCE,
415 .templates = PKCS7_SIGNER_INFO_seq_tt,
416 .tcount = sizeof(PKCS7_SIGNER_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
417 .funcs = &PKCS7_SIGNER_INFO_aux,
418 .size = sizeof(PKCS7_SIGNER_INFO),
419 .sname = "PKCS7_SIGNER_INFO",
420 };
421
422
423 PKCS7_SIGNER_INFO *
d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO ** a,const unsigned char ** in,long len)424 d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a, const unsigned char **in, long len)
425 {
426 return (PKCS7_SIGNER_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
427 &PKCS7_SIGNER_INFO_it);
428 }
429
430 int
i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO * a,unsigned char ** out)431 i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a, unsigned char **out)
432 {
433 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNER_INFO_it);
434 }
435
436 PKCS7_SIGNER_INFO *
PKCS7_SIGNER_INFO_new(void)437 PKCS7_SIGNER_INFO_new(void)
438 {
439 return (PKCS7_SIGNER_INFO *)ASN1_item_new(&PKCS7_SIGNER_INFO_it);
440 }
441
442 void
PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO * a)443 PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a)
444 {
445 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNER_INFO_it);
446 }
447
448 static const ASN1_TEMPLATE PKCS7_ISSUER_AND_SERIAL_seq_tt[] = {
449 {
450 .flags = 0,
451 .tag = 0,
452 .offset = offsetof(PKCS7_ISSUER_AND_SERIAL, issuer),
453 .field_name = "issuer",
454 .item = &X509_NAME_it,
455 },
456 {
457 .flags = 0,
458 .tag = 0,
459 .offset = offsetof(PKCS7_ISSUER_AND_SERIAL, serial),
460 .field_name = "serial",
461 .item = &ASN1_INTEGER_it,
462 },
463 };
464
465 const ASN1_ITEM PKCS7_ISSUER_AND_SERIAL_it = {
466 .itype = ASN1_ITYPE_SEQUENCE,
467 .utype = V_ASN1_SEQUENCE,
468 .templates = PKCS7_ISSUER_AND_SERIAL_seq_tt,
469 .tcount = sizeof(PKCS7_ISSUER_AND_SERIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
470 .funcs = NULL,
471 .size = sizeof(PKCS7_ISSUER_AND_SERIAL),
472 .sname = "PKCS7_ISSUER_AND_SERIAL",
473 };
474
475
476 PKCS7_ISSUER_AND_SERIAL *
d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL ** a,const unsigned char ** in,long len)477 d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL **a, const unsigned char **in, long len)
478 {
479 return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
480 &PKCS7_ISSUER_AND_SERIAL_it);
481 }
482
483 int
i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL * a,unsigned char ** out)484 i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL *a, unsigned char **out)
485 {
486 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ISSUER_AND_SERIAL_it);
487 }
488
489 PKCS7_ISSUER_AND_SERIAL *
PKCS7_ISSUER_AND_SERIAL_new(void)490 PKCS7_ISSUER_AND_SERIAL_new(void)
491 {
492 return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_new(&PKCS7_ISSUER_AND_SERIAL_it);
493 }
494
495 void
PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL * a)496 PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL *a)
497 {
498 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ISSUER_AND_SERIAL_it);
499 }
500
501 static const ASN1_TEMPLATE PKCS7_ENVELOPE_seq_tt[] = {
502 {
503 .flags = 0,
504 .tag = 0,
505 .offset = offsetof(PKCS7_ENVELOPE, version),
506 .field_name = "version",
507 .item = &ASN1_INTEGER_it,
508 },
509 {
510 .flags = ASN1_TFLG_SET_OF,
511 .tag = 0,
512 .offset = offsetof(PKCS7_ENVELOPE, recipientinfo),
513 .field_name = "recipientinfo",
514 .item = &PKCS7_RECIP_INFO_it,
515 },
516 {
517 .flags = 0,
518 .tag = 0,
519 .offset = offsetof(PKCS7_ENVELOPE, enc_data),
520 .field_name = "enc_data",
521 .item = &PKCS7_ENC_CONTENT_it,
522 },
523 };
524
525 const ASN1_ITEM PKCS7_ENVELOPE_it = {
526 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
527 .utype = V_ASN1_SEQUENCE,
528 .templates = PKCS7_ENVELOPE_seq_tt,
529 .tcount = sizeof(PKCS7_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE),
530 .funcs = NULL,
531 .size = sizeof(PKCS7_ENVELOPE),
532 .sname = "PKCS7_ENVELOPE",
533 };
534
535
536 PKCS7_ENVELOPE *
d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE ** a,const unsigned char ** in,long len)537 d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a, const unsigned char **in, long len)
538 {
539 return (PKCS7_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
540 &PKCS7_ENVELOPE_it);
541 }
542
543 int
i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE * a,unsigned char ** out)544 i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **out)
545 {
546 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENVELOPE_it);
547 }
548
549 PKCS7_ENVELOPE *
PKCS7_ENVELOPE_new(void)550 PKCS7_ENVELOPE_new(void)
551 {
552 return (PKCS7_ENVELOPE *)ASN1_item_new(&PKCS7_ENVELOPE_it);
553 }
554
555 void
PKCS7_ENVELOPE_free(PKCS7_ENVELOPE * a)556 PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a)
557 {
558 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENVELOPE_it);
559 }
560
561 /* Minor tweak to operation: free up X509 */
562 static int
ri_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)563 ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
564 {
565 if (operation == ASN1_OP_FREE_POST) {
566 PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
567 X509_free(ri->cert);
568 }
569 return 1;
570 }
571
572 static const ASN1_AUX PKCS7_RECIP_INFO_aux = {
573 .app_data = NULL,
574 .flags = 0,
575 .ref_offset = 0,
576 .ref_lock = 0,
577 .asn1_cb = ri_cb,
578 .enc_offset = 0,
579 };
580 static const ASN1_TEMPLATE PKCS7_RECIP_INFO_seq_tt[] = {
581 {
582 .flags = 0,
583 .tag = 0,
584 .offset = offsetof(PKCS7_RECIP_INFO, version),
585 .field_name = "version",
586 .item = &ASN1_INTEGER_it,
587 },
588 {
589 .flags = 0,
590 .tag = 0,
591 .offset = offsetof(PKCS7_RECIP_INFO, issuer_and_serial),
592 .field_name = "issuer_and_serial",
593 .item = &PKCS7_ISSUER_AND_SERIAL_it,
594 },
595 {
596 .flags = 0,
597 .tag = 0,
598 .offset = offsetof(PKCS7_RECIP_INFO, key_enc_algor),
599 .field_name = "key_enc_algor",
600 .item = &X509_ALGOR_it,
601 },
602 {
603 .flags = 0,
604 .tag = 0,
605 .offset = offsetof(PKCS7_RECIP_INFO, enc_key),
606 .field_name = "enc_key",
607 .item = &ASN1_OCTET_STRING_it,
608 },
609 };
610
611 const ASN1_ITEM PKCS7_RECIP_INFO_it = {
612 .itype = ASN1_ITYPE_SEQUENCE,
613 .utype = V_ASN1_SEQUENCE,
614 .templates = PKCS7_RECIP_INFO_seq_tt,
615 .tcount = sizeof(PKCS7_RECIP_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
616 .funcs = &PKCS7_RECIP_INFO_aux,
617 .size = sizeof(PKCS7_RECIP_INFO),
618 .sname = "PKCS7_RECIP_INFO",
619 };
620
621
622 PKCS7_RECIP_INFO *
d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO ** a,const unsigned char ** in,long len)623 d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a, const unsigned char **in, long len)
624 {
625 return (PKCS7_RECIP_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
626 &PKCS7_RECIP_INFO_it);
627 }
628
629 int
i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO * a,unsigned char ** out)630 i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a, unsigned char **out)
631 {
632 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_RECIP_INFO_it);
633 }
634
635 PKCS7_RECIP_INFO *
PKCS7_RECIP_INFO_new(void)636 PKCS7_RECIP_INFO_new(void)
637 {
638 return (PKCS7_RECIP_INFO *)ASN1_item_new(&PKCS7_RECIP_INFO_it);
639 }
640
641 void
PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO * a)642 PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a)
643 {
644 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_RECIP_INFO_it);
645 }
646
647 static const ASN1_TEMPLATE PKCS7_ENC_CONTENT_seq_tt[] = {
648 {
649 .flags = 0,
650 .tag = 0,
651 .offset = offsetof(PKCS7_ENC_CONTENT, content_type),
652 .field_name = "content_type",
653 .item = &ASN1_OBJECT_it,
654 },
655 {
656 .flags = 0,
657 .tag = 0,
658 .offset = offsetof(PKCS7_ENC_CONTENT, algorithm),
659 .field_name = "algorithm",
660 .item = &X509_ALGOR_it,
661 },
662 {
663 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
664 .tag = 0,
665 .offset = offsetof(PKCS7_ENC_CONTENT, enc_data),
666 .field_name = "enc_data",
667 .item = &ASN1_OCTET_STRING_NDEF_it,
668 },
669 };
670
671 const ASN1_ITEM PKCS7_ENC_CONTENT_it = {
672 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
673 .utype = V_ASN1_SEQUENCE,
674 .templates = PKCS7_ENC_CONTENT_seq_tt,
675 .tcount = sizeof(PKCS7_ENC_CONTENT_seq_tt) / sizeof(ASN1_TEMPLATE),
676 .funcs = NULL,
677 .size = sizeof(PKCS7_ENC_CONTENT),
678 .sname = "PKCS7_ENC_CONTENT",
679 };
680
681
682 PKCS7_ENC_CONTENT *
d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT ** a,const unsigned char ** in,long len)683 d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a, const unsigned char **in, long len)
684 {
685 return (PKCS7_ENC_CONTENT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
686 &PKCS7_ENC_CONTENT_it);
687 }
688
689 int
i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT * a,unsigned char ** out)690 i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **out)
691 {
692 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENC_CONTENT_it);
693 }
694
695 PKCS7_ENC_CONTENT *
PKCS7_ENC_CONTENT_new(void)696 PKCS7_ENC_CONTENT_new(void)
697 {
698 return (PKCS7_ENC_CONTENT *)ASN1_item_new(&PKCS7_ENC_CONTENT_it);
699 }
700
701 void
PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT * a)702 PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a)
703 {
704 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENC_CONTENT_it);
705 }
706
707 static const ASN1_TEMPLATE PKCS7_SIGN_ENVELOPE_seq_tt[] = {
708 {
709 .flags = 0,
710 .tag = 0,
711 .offset = offsetof(PKCS7_SIGN_ENVELOPE, version),
712 .field_name = "version",
713 .item = &ASN1_INTEGER_it,
714 },
715 {
716 .flags = ASN1_TFLG_SET_OF,
717 .tag = 0,
718 .offset = offsetof(PKCS7_SIGN_ENVELOPE, recipientinfo),
719 .field_name = "recipientinfo",
720 .item = &PKCS7_RECIP_INFO_it,
721 },
722 {
723 .flags = ASN1_TFLG_SET_OF,
724 .tag = 0,
725 .offset = offsetof(PKCS7_SIGN_ENVELOPE, md_algs),
726 .field_name = "md_algs",
727 .item = &X509_ALGOR_it,
728 },
729 {
730 .flags = 0,
731 .tag = 0,
732 .offset = offsetof(PKCS7_SIGN_ENVELOPE, enc_data),
733 .field_name = "enc_data",
734 .item = &PKCS7_ENC_CONTENT_it,
735 },
736 {
737 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
738 .tag = 0,
739 .offset = offsetof(PKCS7_SIGN_ENVELOPE, cert),
740 .field_name = "cert",
741 .item = &X509_it,
742 },
743 {
744 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
745 .tag = 1,
746 .offset = offsetof(PKCS7_SIGN_ENVELOPE, crl),
747 .field_name = "crl",
748 .item = &X509_CRL_it,
749 },
750 {
751 .flags = ASN1_TFLG_SET_OF,
752 .tag = 0,
753 .offset = offsetof(PKCS7_SIGN_ENVELOPE, signer_info),
754 .field_name = "signer_info",
755 .item = &PKCS7_SIGNER_INFO_it,
756 },
757 };
758
759 const ASN1_ITEM PKCS7_SIGN_ENVELOPE_it = {
760 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
761 .utype = V_ASN1_SEQUENCE,
762 .templates = PKCS7_SIGN_ENVELOPE_seq_tt,
763 .tcount = sizeof(PKCS7_SIGN_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE),
764 .funcs = NULL,
765 .size = sizeof(PKCS7_SIGN_ENVELOPE),
766 .sname = "PKCS7_SIGN_ENVELOPE",
767 };
768
769
770 PKCS7_SIGN_ENVELOPE *
d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE ** a,const unsigned char ** in,long len)771 d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a, const unsigned char **in, long len)
772 {
773 return (PKCS7_SIGN_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
774 &PKCS7_SIGN_ENVELOPE_it);
775 }
776
777 int
i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE * a,unsigned char ** out)778 i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a, unsigned char **out)
779 {
780 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGN_ENVELOPE_it);
781 }
782
783 PKCS7_SIGN_ENVELOPE *
PKCS7_SIGN_ENVELOPE_new(void)784 PKCS7_SIGN_ENVELOPE_new(void)
785 {
786 return (PKCS7_SIGN_ENVELOPE *)ASN1_item_new(&PKCS7_SIGN_ENVELOPE_it);
787 }
788
789 void
PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE * a)790 PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a)
791 {
792 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGN_ENVELOPE_it);
793 }
794
795 static const ASN1_TEMPLATE PKCS7_ENCRYPT_seq_tt[] = {
796 {
797 .flags = 0,
798 .tag = 0,
799 .offset = offsetof(PKCS7_ENCRYPT, version),
800 .field_name = "version",
801 .item = &ASN1_INTEGER_it,
802 },
803 {
804 .flags = 0,
805 .tag = 0,
806 .offset = offsetof(PKCS7_ENCRYPT, enc_data),
807 .field_name = "enc_data",
808 .item = &PKCS7_ENC_CONTENT_it,
809 },
810 };
811
812 const ASN1_ITEM PKCS7_ENCRYPT_it = {
813 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
814 .utype = V_ASN1_SEQUENCE,
815 .templates = PKCS7_ENCRYPT_seq_tt,
816 .tcount = sizeof(PKCS7_ENCRYPT_seq_tt) / sizeof(ASN1_TEMPLATE),
817 .funcs = NULL,
818 .size = sizeof(PKCS7_ENCRYPT),
819 .sname = "PKCS7_ENCRYPT",
820 };
821
822
823 PKCS7_ENCRYPT *
d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT ** a,const unsigned char ** in,long len)824 d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a, const unsigned char **in, long len)
825 {
826 return (PKCS7_ENCRYPT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
827 &PKCS7_ENCRYPT_it);
828 }
829
830 int
i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT * a,unsigned char ** out)831 i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a, unsigned char **out)
832 {
833 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENCRYPT_it);
834 }
835
836 PKCS7_ENCRYPT *
PKCS7_ENCRYPT_new(void)837 PKCS7_ENCRYPT_new(void)
838 {
839 return (PKCS7_ENCRYPT *)ASN1_item_new(&PKCS7_ENCRYPT_it);
840 }
841
842 void
PKCS7_ENCRYPT_free(PKCS7_ENCRYPT * a)843 PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a)
844 {
845 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENCRYPT_it);
846 }
847
848 static const ASN1_TEMPLATE PKCS7_DIGEST_seq_tt[] = {
849 {
850 .flags = 0,
851 .tag = 0,
852 .offset = offsetof(PKCS7_DIGEST, version),
853 .field_name = "version",
854 .item = &ASN1_INTEGER_it,
855 },
856 {
857 .flags = 0,
858 .tag = 0,
859 .offset = offsetof(PKCS7_DIGEST, md),
860 .field_name = "md",
861 .item = &X509_ALGOR_it,
862 },
863 {
864 .flags = 0,
865 .tag = 0,
866 .offset = offsetof(PKCS7_DIGEST, contents),
867 .field_name = "contents",
868 .item = &PKCS7_it,
869 },
870 {
871 .flags = 0,
872 .tag = 0,
873 .offset = offsetof(PKCS7_DIGEST, digest),
874 .field_name = "digest",
875 .item = &ASN1_OCTET_STRING_it,
876 },
877 };
878
879 const ASN1_ITEM PKCS7_DIGEST_it = {
880 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
881 .utype = V_ASN1_SEQUENCE,
882 .templates = PKCS7_DIGEST_seq_tt,
883 .tcount = sizeof(PKCS7_DIGEST_seq_tt) / sizeof(ASN1_TEMPLATE),
884 .funcs = NULL,
885 .size = sizeof(PKCS7_DIGEST),
886 .sname = "PKCS7_DIGEST",
887 };
888
889
890 PKCS7_DIGEST *
d2i_PKCS7_DIGEST(PKCS7_DIGEST ** a,const unsigned char ** in,long len)891 d2i_PKCS7_DIGEST(PKCS7_DIGEST **a, const unsigned char **in, long len)
892 {
893 return (PKCS7_DIGEST *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
894 &PKCS7_DIGEST_it);
895 }
896
897 int
i2d_PKCS7_DIGEST(PKCS7_DIGEST * a,unsigned char ** out)898 i2d_PKCS7_DIGEST(PKCS7_DIGEST *a, unsigned char **out)
899 {
900 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_DIGEST_it);
901 }
902
903 PKCS7_DIGEST *
PKCS7_DIGEST_new(void)904 PKCS7_DIGEST_new(void)
905 {
906 return (PKCS7_DIGEST *)ASN1_item_new(&PKCS7_DIGEST_it);
907 }
908
909 void
PKCS7_DIGEST_free(PKCS7_DIGEST * a)910 PKCS7_DIGEST_free(PKCS7_DIGEST *a)
911 {
912 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_DIGEST_it);
913 }
914
915 /* Specials for authenticated attributes */
916
917 /* When signing attributes we want to reorder them to match the sorted
918 * encoding.
919 */
920
921 static const ASN1_TEMPLATE PKCS7_ATTR_SIGN_item_tt = {
922 .flags = ASN1_TFLG_SET_ORDER,
923 .tag = 0,
924 .offset = 0,
925 .field_name = "PKCS7_ATTRIBUTES",
926 .item = &X509_ATTRIBUTE_it,
927 };
928
929 const ASN1_ITEM PKCS7_ATTR_SIGN_it = {
930 .itype = ASN1_ITYPE_PRIMITIVE,
931 .utype = -1,
932 .templates = &PKCS7_ATTR_SIGN_item_tt,
933 .tcount = 0,
934 .funcs = NULL,
935 .size = 0,
936 .sname = "PKCS7_ATTR_SIGN",
937 };
938
939 /* When verifying attributes we need to use the received order. So
940 * we use SEQUENCE OF and tag it to SET OF
941 */
942
943 static const ASN1_TEMPLATE PKCS7_ATTR_VERIFY_item_tt = {
944 .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
945 .tag = V_ASN1_SET,
946 .offset = 0,
947 .field_name = "PKCS7_ATTRIBUTES",
948 .item = &X509_ATTRIBUTE_it,
949 };
950
951 const ASN1_ITEM PKCS7_ATTR_VERIFY_it = {
952 .itype = ASN1_ITYPE_PRIMITIVE,
953 .utype = -1,
954 .templates = &PKCS7_ATTR_VERIFY_item_tt,
955 .tcount = 0,
956 .funcs = NULL,
957 .size = 0,
958 .sname = "PKCS7_ATTR_VERIFY",
959 };
960
961
962 int
PKCS7_print_ctx(BIO * out,PKCS7 * x,int indent,const ASN1_PCTX * pctx)963 PKCS7_print_ctx(BIO *out, PKCS7 *x, int indent, const ASN1_PCTX *pctx)
964 {
965 return ASN1_item_print(out, (ASN1_VALUE *)x, indent,
966 &PKCS7_it, pctx);
967 }
968