xref: /openbsd/lib/libcrypto/pkcs12/p12_asn.c (revision 11f540e6)
1 /* $OpenBSD: p12_asn.c,v 1.16 2024/07/09 06:13:22 beck Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 1999.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999 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/pkcs12.h>
63 
64 #include "pkcs12_local.h"
65 
66 /* PKCS#12 ASN1 module */
67 
68 static const ASN1_TEMPLATE PKCS12_seq_tt[] = {
69 	{
70 		.flags = 0,
71 		.tag = 0,
72 		.offset = offsetof(PKCS12, version),
73 		.field_name = "version",
74 		.item = &ASN1_INTEGER_it,
75 	},
76 	{
77 		.flags = 0,
78 		.tag = 0,
79 		.offset = offsetof(PKCS12, authsafes),
80 		.field_name = "authsafes",
81 		.item = &PKCS7_it,
82 	},
83 	{
84 		.flags = ASN1_TFLG_OPTIONAL,
85 		.tag = 0,
86 		.offset = offsetof(PKCS12, mac),
87 		.field_name = "mac",
88 		.item = &PKCS12_MAC_DATA_it,
89 	},
90 };
91 
92 const ASN1_ITEM PKCS12_it = {
93 	.itype = ASN1_ITYPE_SEQUENCE,
94 	.utype = V_ASN1_SEQUENCE,
95 	.templates = PKCS12_seq_tt,
96 	.tcount = sizeof(PKCS12_seq_tt) / sizeof(ASN1_TEMPLATE),
97 	.funcs = NULL,
98 	.size = sizeof(PKCS12),
99 	.sname = "PKCS12",
100 };
101 LCRYPTO_ALIAS(PKCS12_it);
102 
103 
104 PKCS12 *
d2i_PKCS12(PKCS12 ** a,const unsigned char ** in,long len)105 d2i_PKCS12(PKCS12 **a, const unsigned char **in, long len)
106 {
107 	return (PKCS12 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
108 	    &PKCS12_it);
109 }
110 LCRYPTO_ALIAS(d2i_PKCS12);
111 
112 int
i2d_PKCS12(PKCS12 * a,unsigned char ** out)113 i2d_PKCS12(PKCS12 *a, unsigned char **out)
114 {
115 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_it);
116 }
117 LCRYPTO_ALIAS(i2d_PKCS12);
118 
119 PKCS12 *
PKCS12_new(void)120 PKCS12_new(void)
121 {
122 	return (PKCS12 *)ASN1_item_new(&PKCS12_it);
123 }
124 LCRYPTO_ALIAS(PKCS12_new);
125 
126 void
PKCS12_free(PKCS12 * a)127 PKCS12_free(PKCS12 *a)
128 {
129 	ASN1_item_free((ASN1_VALUE *)a, &PKCS12_it);
130 }
131 LCRYPTO_ALIAS(PKCS12_free);
132 
133 static const ASN1_TEMPLATE PKCS12_MAC_DATA_seq_tt[] = {
134 	{
135 		.flags = 0,
136 		.tag = 0,
137 		.offset = offsetof(PKCS12_MAC_DATA, dinfo),
138 		.field_name = "dinfo",
139 		.item = &X509_SIG_it,
140 	},
141 	{
142 		.flags = 0,
143 		.tag = 0,
144 		.offset = offsetof(PKCS12_MAC_DATA, salt),
145 		.field_name = "salt",
146 		.item = &ASN1_OCTET_STRING_it,
147 	},
148 	{
149 		.flags = ASN1_TFLG_OPTIONAL,
150 		.tag = 0,
151 		.offset = offsetof(PKCS12_MAC_DATA, iter),
152 		.field_name = "iter",
153 		.item = &ASN1_INTEGER_it,
154 	},
155 };
156 
157 const ASN1_ITEM PKCS12_MAC_DATA_it = {
158 	.itype = ASN1_ITYPE_SEQUENCE,
159 	.utype = V_ASN1_SEQUENCE,
160 	.templates = PKCS12_MAC_DATA_seq_tt,
161 	.tcount = sizeof(PKCS12_MAC_DATA_seq_tt) / sizeof(ASN1_TEMPLATE),
162 	.funcs = NULL,
163 	.size = sizeof(PKCS12_MAC_DATA),
164 	.sname = "PKCS12_MAC_DATA",
165 };
166 
167 
168 PKCS12_MAC_DATA *
d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA ** a,const unsigned char ** in,long len)169 d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA **a, const unsigned char **in, long len)
170 {
171 	return (PKCS12_MAC_DATA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
172 	    &PKCS12_MAC_DATA_it);
173 }
174 
175 int
i2d_PKCS12_MAC_DATA(PKCS12_MAC_DATA * a,unsigned char ** out)176 i2d_PKCS12_MAC_DATA(PKCS12_MAC_DATA *a, unsigned char **out)
177 {
178 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_MAC_DATA_it);
179 }
180 
181 PKCS12_MAC_DATA *
PKCS12_MAC_DATA_new(void)182 PKCS12_MAC_DATA_new(void)
183 {
184 	return (PKCS12_MAC_DATA *)ASN1_item_new(&PKCS12_MAC_DATA_it);
185 }
186 
187 void
PKCS12_MAC_DATA_free(PKCS12_MAC_DATA * a)188 PKCS12_MAC_DATA_free(PKCS12_MAC_DATA *a)
189 {
190 	ASN1_item_free((ASN1_VALUE *)a, &PKCS12_MAC_DATA_it);
191 }
192 
193 static const ASN1_TEMPLATE bag_default_tt = {
194 	.flags = ASN1_TFLG_EXPLICIT,
195 	.tag = 0,
196 	.offset = offsetof(PKCS12_BAGS, value.other),
197 	.field_name = "value.other",
198 	.item = &ASN1_ANY_it,
199 };
200 
201 static const ASN1_ADB_TABLE PKCS12_BAGS_adbtbl[] = {
202 	{
203 		.value = NID_x509Certificate,
204 		.tt = {
205 			.flags = ASN1_TFLG_EXPLICIT,
206 			.tag = 0,
207 			.offset = offsetof(PKCS12_BAGS, value.x509cert),
208 			.field_name = "value.x509cert",
209 			.item = &ASN1_OCTET_STRING_it,
210 		},
211 
212 	},
213 	{
214 		.value = NID_x509Crl,
215 		.tt = {
216 			.flags = ASN1_TFLG_EXPLICIT,
217 			.tag = 0,
218 			.offset = offsetof(PKCS12_BAGS, value.x509crl),
219 			.field_name = "value.x509crl",
220 			.item = &ASN1_OCTET_STRING_it,
221 		},
222 
223 	},
224 	{
225 		.value = NID_sdsiCertificate,
226 		.tt = {
227 			.flags = ASN1_TFLG_EXPLICIT,
228 			.tag = 0,
229 			.offset = offsetof(PKCS12_BAGS, value.sdsicert),
230 			.field_name = "value.sdsicert",
231 			.item = &ASN1_IA5STRING_it,
232 		},
233 
234 	},
235 };
236 
237 static const ASN1_ADB PKCS12_BAGS_adb = {
238 	.flags = 0,
239 	.offset = offsetof(PKCS12_BAGS, type),
240 	.tbl = PKCS12_BAGS_adbtbl,
241 	.tblcount = sizeof(PKCS12_BAGS_adbtbl) / sizeof(ASN1_ADB_TABLE),
242 	.default_tt = &bag_default_tt,
243 	.null_tt = NULL,
244 };
245 
246 static const ASN1_TEMPLATE PKCS12_BAGS_seq_tt[] = {
247 	{
248 		.flags = 0,
249 		.tag = 0,
250 		.offset = offsetof(PKCS12_BAGS, type),
251 		.field_name = "type",
252 		.item = &ASN1_OBJECT_it,
253 	},
254 	{
255 		.flags = ASN1_TFLG_ADB_OID,
256 		.tag = -1,
257 		.offset = 0,
258 		.field_name = "PKCS12_BAGS",
259 		.item = (const ASN1_ITEM *)&PKCS12_BAGS_adb,
260 	},
261 };
262 
263 const ASN1_ITEM PKCS12_BAGS_it = {
264 	.itype = ASN1_ITYPE_SEQUENCE,
265 	.utype = V_ASN1_SEQUENCE,
266 	.templates = PKCS12_BAGS_seq_tt,
267 	.tcount = sizeof(PKCS12_BAGS_seq_tt) / sizeof(ASN1_TEMPLATE),
268 	.funcs = NULL,
269 	.size = sizeof(PKCS12_BAGS),
270 	.sname = "PKCS12_BAGS",
271 };
272 
273 
274 PKCS12_BAGS *
d2i_PKCS12_BAGS(PKCS12_BAGS ** a,const unsigned char ** in,long len)275 d2i_PKCS12_BAGS(PKCS12_BAGS **a, const unsigned char **in, long len)
276 {
277 	return (PKCS12_BAGS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
278 	    &PKCS12_BAGS_it);
279 }
280 
281 int
i2d_PKCS12_BAGS(PKCS12_BAGS * a,unsigned char ** out)282 i2d_PKCS12_BAGS(PKCS12_BAGS *a, unsigned char **out)
283 {
284 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_BAGS_it);
285 }
286 
287 PKCS12_BAGS *
PKCS12_BAGS_new(void)288 PKCS12_BAGS_new(void)
289 {
290 	return (PKCS12_BAGS *)ASN1_item_new(&PKCS12_BAGS_it);
291 }
292 
293 void
PKCS12_BAGS_free(PKCS12_BAGS * a)294 PKCS12_BAGS_free(PKCS12_BAGS *a)
295 {
296 	ASN1_item_free((ASN1_VALUE *)a, &PKCS12_BAGS_it);
297 }
298 
299 static const ASN1_TEMPLATE safebag_default_tt = {
300 	.flags = ASN1_TFLG_EXPLICIT,
301 	.tag = 0,
302 	.offset = offsetof(PKCS12_SAFEBAG, value.other),
303 	.field_name = "value.other",
304 	.item = &ASN1_ANY_it,
305 };
306 
307 static const ASN1_ADB_TABLE PKCS12_SAFEBAG_adbtbl[] = {
308 	{
309 		.value = NID_keyBag,
310 		.tt = {
311 			.flags = ASN1_TFLG_EXPLICIT,
312 			.tag = 0,
313 			.offset = offsetof(PKCS12_SAFEBAG, value.keybag),
314 			.field_name = "value.keybag",
315 			.item = &PKCS8_PRIV_KEY_INFO_it,
316 		},
317 
318 	},
319 	{
320 		.value = NID_pkcs8ShroudedKeyBag,
321 		.tt = {
322 			.flags = ASN1_TFLG_EXPLICIT,
323 			.tag = 0,
324 			.offset = offsetof(PKCS12_SAFEBAG, value.shkeybag),
325 			.field_name = "value.shkeybag",
326 			.item = &X509_SIG_it,
327 		},
328 
329 	},
330 	{
331 		.value = NID_safeContentsBag,
332 		.tt = {
333 			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF,
334 			.tag = 0,
335 			.offset = offsetof(PKCS12_SAFEBAG, value.safes),
336 			.field_name = "value.safes",
337 			.item = &PKCS12_SAFEBAG_it,
338 		},
339 	},
340 	{
341 		.value = NID_certBag,
342 		.tt = {
343 			.flags = ASN1_TFLG_EXPLICIT,
344 			.tag = 0,
345 			.offset = offsetof(PKCS12_SAFEBAG, value.bag),
346 			.field_name = "value.bag",
347 			.item = &PKCS12_BAGS_it,
348 		},
349 
350 	},
351 	{
352 		.value = NID_crlBag,
353 		.tt = {
354 			.flags = ASN1_TFLG_EXPLICIT,
355 			.tag = 0,
356 			.offset = offsetof(PKCS12_SAFEBAG, value.bag),
357 			.field_name = "value.bag",
358 			.item = &PKCS12_BAGS_it,
359 		},
360 
361 	},
362 	{
363 		.value = NID_secretBag,
364 		.tt = {
365 			.flags = ASN1_TFLG_EXPLICIT,
366 			.tag = 0,
367 			.offset = offsetof(PKCS12_SAFEBAG, value.bag),
368 			.field_name = "value.bag",
369 			.item = &PKCS12_BAGS_it,
370 		},
371 
372 	},
373 };
374 
375 static const ASN1_ADB PKCS12_SAFEBAG_adb = {
376 	.flags = 0,
377 	.offset = offsetof(PKCS12_SAFEBAG, type),
378 	.tbl = PKCS12_SAFEBAG_adbtbl,
379 	.tblcount = sizeof(PKCS12_SAFEBAG_adbtbl) / sizeof(ASN1_ADB_TABLE),
380 	.default_tt = &safebag_default_tt,
381 	.null_tt = NULL,
382 };
383 
384 static const ASN1_TEMPLATE PKCS12_SAFEBAG_seq_tt[] = {
385 	{
386 		.flags = 0,
387 		.tag = 0,
388 		.offset = offsetof(PKCS12_SAFEBAG, type),
389 		.field_name = "type",
390 		.item = &ASN1_OBJECT_it,
391 	},
392 	{
393 		.flags = ASN1_TFLG_ADB_OID,
394 		.tag = -1,
395 		.offset = 0,
396 		.field_name = "PKCS12_SAFEBAG",
397 		.item = (const ASN1_ITEM *)&PKCS12_SAFEBAG_adb,
398 	},
399 	{
400 		.flags = ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
401 		.tag = 0,
402 		.offset = offsetof(PKCS12_SAFEBAG, attrib),
403 		.field_name = "attrib",
404 		.item = &X509_ATTRIBUTE_it,
405 	},
406 };
407 
408 const ASN1_ITEM PKCS12_SAFEBAG_it = {
409 	.itype = ASN1_ITYPE_SEQUENCE,
410 	.utype = V_ASN1_SEQUENCE,
411 	.templates = PKCS12_SAFEBAG_seq_tt,
412 	.tcount = sizeof(PKCS12_SAFEBAG_seq_tt) / sizeof(ASN1_TEMPLATE),
413 	.funcs = NULL,
414 	.size = sizeof(PKCS12_SAFEBAG),
415 	.sname = "PKCS12_SAFEBAG",
416 };
417 LCRYPTO_ALIAS(PKCS12_SAFEBAG_it);
418 
419 
420 PKCS12_SAFEBAG *
d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG ** a,const unsigned char ** in,long len)421 d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG **a, const unsigned char **in, long len)
422 {
423 	return (PKCS12_SAFEBAG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
424 	    &PKCS12_SAFEBAG_it);
425 }
426 LCRYPTO_ALIAS(d2i_PKCS12_SAFEBAG);
427 
428 int
i2d_PKCS12_SAFEBAG(PKCS12_SAFEBAG * a,unsigned char ** out)429 i2d_PKCS12_SAFEBAG(PKCS12_SAFEBAG *a, unsigned char **out)
430 {
431 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_SAFEBAG_it);
432 }
433 LCRYPTO_ALIAS(i2d_PKCS12_SAFEBAG);
434 
435 PKCS12_SAFEBAG *
PKCS12_SAFEBAG_new(void)436 PKCS12_SAFEBAG_new(void)
437 {
438 	return (PKCS12_SAFEBAG *)ASN1_item_new(&PKCS12_SAFEBAG_it);
439 }
440 LCRYPTO_ALIAS(PKCS12_SAFEBAG_new);
441 
442 void
PKCS12_SAFEBAG_free(PKCS12_SAFEBAG * a)443 PKCS12_SAFEBAG_free(PKCS12_SAFEBAG *a)
444 {
445 	ASN1_item_free((ASN1_VALUE *)a, &PKCS12_SAFEBAG_it);
446 }
447 LCRYPTO_ALIAS(PKCS12_SAFEBAG_free);
448 
449 /* SEQUENCE OF SafeBag */
450 static const ASN1_TEMPLATE PKCS12_SAFEBAGS_item_tt = {
451 	.flags = ASN1_TFLG_SEQUENCE_OF,
452 	.tag = 0,
453 	.offset = 0,
454 	.field_name = "PKCS12_SAFEBAGS",
455 	.item = &PKCS12_SAFEBAG_it,
456 };
457 
458 const ASN1_ITEM PKCS12_SAFEBAGS_it = {
459 	.itype = ASN1_ITYPE_PRIMITIVE,
460 	.utype = -1,
461 	.templates = &PKCS12_SAFEBAGS_item_tt,
462 	.tcount = 0,
463 	.funcs = NULL,
464 	.size = 0,
465 	.sname = "PKCS12_SAFEBAGS",
466 };
467 
468 /* Authsafes: SEQUENCE OF PKCS7 */
469 static const ASN1_TEMPLATE PKCS12_AUTHSAFES_item_tt = {
470 	.flags = ASN1_TFLG_SEQUENCE_OF,
471 	.tag = 0,
472 	.offset = 0,
473 	.field_name = "PKCS12_AUTHSAFES",
474 	.item = &PKCS7_it,
475 };
476 
477 const ASN1_ITEM PKCS12_AUTHSAFES_it = {
478 	.itype = ASN1_ITYPE_PRIMITIVE,
479 	.utype = -1,
480 	.templates = &PKCS12_AUTHSAFES_item_tt,
481 	.tcount = 0,
482 	.funcs = NULL,
483 	.size = 0,
484 	.sname = "PKCS12_AUTHSAFES",
485 };
486