xref: /dragonfly/crypto/libressl/crypto/pkcs7/pk7_asn1.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
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