Line data Source code
1 : /*
2 : * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "hx_locl.h"
35 :
36 : struct ks_pkcs12 {
37 : hx509_certs certs;
38 : char *fn;
39 : unsigned int store_no_priv_keys;
40 : };
41 :
42 : typedef int (*collector_func)(hx509_context,
43 : struct hx509_collector *,
44 : int,
45 : const void *, size_t,
46 : const PKCS12_Attributes *);
47 :
48 : struct type {
49 : const heim_oid *oid;
50 : collector_func func;
51 : };
52 :
53 : static void
54 : parse_pkcs12_type(hx509_context, struct hx509_collector *, int,
55 : const heim_oid *, const void *, size_t,
56 : const PKCS12_Attributes *);
57 :
58 :
59 : static const PKCS12_Attribute *
60 0 : find_attribute(const PKCS12_Attributes *attrs, const heim_oid *oid)
61 : {
62 0 : size_t i;
63 0 : if (attrs == NULL)
64 0 : return NULL;
65 0 : for (i = 0; i < attrs->len; i++)
66 0 : if (der_heim_oid_cmp(oid, &attrs->val[i].attrId) == 0)
67 0 : return &attrs->val[i];
68 0 : return NULL;
69 : }
70 :
71 : static int
72 0 : keyBag_parser(hx509_context context,
73 : struct hx509_collector *c,
74 : int flags,
75 : const void *data, size_t length,
76 : const PKCS12_Attributes *attrs)
77 : {
78 0 : const PKCS12_Attribute *attr;
79 0 : PKCS8PrivateKeyInfo ki;
80 0 : const heim_octet_string *os = NULL;
81 0 : int ret;
82 :
83 0 : if (flags & HX509_CERTS_NO_PRIVATE_KEYS)
84 0 : return 0;
85 :
86 0 : attr = find_attribute(attrs, &asn1_oid_id_pkcs_9_at_localKeyId);
87 0 : if (attr)
88 0 : os = &attr->attrValues;
89 :
90 0 : ret = decode_PKCS8PrivateKeyInfo(data, length, &ki, NULL);
91 0 : if (ret)
92 0 : return ret;
93 :
94 0 : ret = _hx509_collector_private_key_add(context,
95 : c,
96 : &ki.privateKeyAlgorithm,
97 : NULL,
98 : &ki.privateKey,
99 : os);
100 0 : free_PKCS8PrivateKeyInfo(&ki);
101 0 : return ret;
102 : }
103 :
104 : static int
105 0 : ShroudedKeyBag_parser(hx509_context context,
106 : struct hx509_collector *c,
107 : int flags,
108 : const void *data, size_t length,
109 : const PKCS12_Attributes *attrs)
110 : {
111 0 : PKCS8EncryptedPrivateKeyInfo pk;
112 0 : heim_octet_string content;
113 0 : int ret;
114 :
115 0 : memset(&pk, 0, sizeof(pk));
116 :
117 0 : ret = decode_PKCS8EncryptedPrivateKeyInfo(data, length, &pk, NULL);
118 0 : if (ret)
119 0 : return ret;
120 :
121 0 : ret = _hx509_pbe_decrypt(context,
122 : _hx509_collector_get_lock(c),
123 : &pk.encryptionAlgorithm,
124 : &pk.encryptedData,
125 : &content);
126 0 : free_PKCS8EncryptedPrivateKeyInfo(&pk);
127 0 : if (ret)
128 0 : return ret;
129 :
130 0 : ret = keyBag_parser(context, c, flags, content.data, content.length,
131 : attrs);
132 0 : der_free_octet_string(&content);
133 0 : return ret;
134 : }
135 :
136 : static int
137 0 : certBag_parser(hx509_context context,
138 : struct hx509_collector *c,
139 : int flags,
140 : const void *data, size_t length,
141 : const PKCS12_Attributes *attrs)
142 : {
143 0 : heim_error_t error = NULL;
144 0 : heim_octet_string os;
145 0 : hx509_cert cert;
146 0 : PKCS12_CertBag cb;
147 0 : int ret;
148 :
149 0 : ret = decode_PKCS12_CertBag(data, length, &cb, NULL);
150 0 : if (ret)
151 0 : return ret;
152 :
153 0 : if (der_heim_oid_cmp(&asn1_oid_id_pkcs_9_at_certTypes_x509, &cb.certType)) {
154 0 : free_PKCS12_CertBag(&cb);
155 0 : return 0;
156 : }
157 :
158 0 : ret = decode_PKCS12_OctetString(cb.certValue.data,
159 : cb.certValue.length,
160 : &os,
161 : NULL);
162 0 : free_PKCS12_CertBag(&cb);
163 0 : if (ret)
164 0 : return ret;
165 :
166 0 : cert = hx509_cert_init_data(context, os.data, os.length, &error);
167 0 : der_free_octet_string(&os);
168 0 : if (cert == NULL) {
169 0 : ret = heim_error_get_code(error);
170 0 : heim_release(error);
171 0 : return ret;
172 : }
173 :
174 0 : ret = _hx509_collector_certs_add(context, c, cert);
175 0 : if (ret) {
176 0 : hx509_cert_free(cert);
177 0 : return ret;
178 : }
179 :
180 : {
181 0 : const PKCS12_Attribute *attr;
182 0 : const heim_oid *oids[] = {
183 : &asn1_oid_id_pkcs_9_at_localKeyId, &asn1_oid_id_pkcs_9_at_friendlyName
184 : };
185 0 : size_t i;
186 :
187 0 : for (i = 0; i < sizeof(oids)/sizeof(oids[0]); i++) {
188 0 : const heim_oid *oid = oids[i];
189 0 : attr = find_attribute(attrs, oid);
190 0 : if (attr)
191 0 : _hx509_set_cert_attribute(context, cert, oid,
192 0 : &attr->attrValues);
193 : }
194 : }
195 :
196 0 : hx509_cert_free(cert);
197 :
198 0 : return 0;
199 : }
200 :
201 : static int
202 0 : parse_safe_content(hx509_context context,
203 : struct hx509_collector *c,
204 : int flags,
205 : const unsigned char *p, size_t len)
206 : {
207 0 : PKCS12_SafeContents sc;
208 0 : int ret;
209 0 : size_t i;
210 :
211 0 : memset(&sc, 0, sizeof(sc));
212 :
213 0 : ret = decode_PKCS12_SafeContents(p, len, &sc, NULL);
214 0 : if (ret)
215 0 : return ret;
216 :
217 0 : for (i = 0; i < sc.len ; i++)
218 0 : parse_pkcs12_type(context,
219 : c,
220 : flags,
221 0 : &sc.val[i].bagId,
222 0 : sc.val[i].bagValue.data,
223 0 : sc.val[i].bagValue.length,
224 0 : sc.val[i].bagAttributes);
225 :
226 0 : free_PKCS12_SafeContents(&sc);
227 0 : return 0;
228 : }
229 :
230 : static int
231 0 : safeContent_parser(hx509_context context,
232 : struct hx509_collector *c,
233 : int flags,
234 : const void *data, size_t length,
235 : const PKCS12_Attributes *attrs)
236 : {
237 0 : heim_octet_string os;
238 0 : int ret;
239 :
240 0 : ret = decode_PKCS12_OctetString(data, length, &os, NULL);
241 0 : if (ret)
242 0 : return ret;
243 0 : ret = parse_safe_content(context, c, flags, os.data, os.length);
244 0 : der_free_octet_string(&os);
245 0 : return ret;
246 : }
247 :
248 : static int
249 0 : encryptedData_parser(hx509_context context,
250 : struct hx509_collector *c,
251 : int flags,
252 : const void *data, size_t length,
253 : const PKCS12_Attributes *attrs)
254 : {
255 0 : heim_octet_string content;
256 0 : heim_oid contentType;
257 0 : int ret;
258 :
259 0 : memset(&contentType, 0, sizeof(contentType));
260 :
261 0 : ret = hx509_cms_decrypt_encrypted(context,
262 : _hx509_collector_get_lock(c),
263 : data, length,
264 : &contentType,
265 : &content);
266 0 : if (ret)
267 0 : return ret;
268 :
269 0 : if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0)
270 0 : ret = parse_safe_content(context, c, flags,
271 0 : content.data, content.length);
272 :
273 0 : der_free_octet_string(&content);
274 0 : der_free_oid(&contentType);
275 0 : return ret;
276 : }
277 :
278 : static int
279 0 : envelopedData_parser(hx509_context context,
280 : struct hx509_collector *c,
281 : int flags,
282 : const void *data, size_t length,
283 : const PKCS12_Attributes *attrs)
284 : {
285 0 : heim_octet_string content;
286 0 : heim_oid contentType;
287 0 : hx509_lock lock;
288 0 : int ret;
289 :
290 0 : memset(&contentType, 0, sizeof(contentType));
291 :
292 0 : lock = _hx509_collector_get_lock(c);
293 :
294 0 : ret = hx509_cms_unenvelope(context,
295 : _hx509_lock_unlock_certs(lock),
296 : 0,
297 : data, length,
298 : NULL,
299 : 0,
300 : &contentType,
301 : &content);
302 0 : if (ret) {
303 0 : hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
304 : "PKCS12 failed to unenvelope");
305 0 : return ret;
306 : }
307 :
308 0 : if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0)
309 0 : ret = parse_safe_content(context, c, flags,
310 0 : content.data, content.length);
311 :
312 0 : der_free_octet_string(&content);
313 0 : der_free_oid(&contentType);
314 :
315 0 : return ret;
316 : }
317 :
318 :
319 : struct type bagtypes[] = {
320 : { &asn1_oid_id_pkcs12_keyBag, keyBag_parser },
321 : { &asn1_oid_id_pkcs12_pkcs8ShroudedKeyBag, ShroudedKeyBag_parser },
322 : { &asn1_oid_id_pkcs12_certBag, certBag_parser },
323 : { &asn1_oid_id_pkcs7_data, safeContent_parser },
324 : { &asn1_oid_id_pkcs7_encryptedData, encryptedData_parser },
325 : { &asn1_oid_id_pkcs7_envelopedData, envelopedData_parser }
326 : };
327 :
328 : static void
329 0 : parse_pkcs12_type(hx509_context context,
330 : struct hx509_collector *c,
331 : int flags,
332 : const heim_oid *oid,
333 : const void *data, size_t length,
334 : const PKCS12_Attributes *attrs)
335 : {
336 0 : size_t i;
337 :
338 0 : for (i = 0; i < sizeof(bagtypes)/sizeof(bagtypes[0]); i++)
339 0 : if (der_heim_oid_cmp(bagtypes[i].oid, oid) == 0)
340 0 : (*bagtypes[i].func)(context, c, flags, data, length, attrs);
341 0 : }
342 :
343 : static int
344 0 : p12_init(hx509_context context,
345 : hx509_certs certs, void **data, int flags,
346 : const char *residue, hx509_lock lock)
347 : {
348 0 : struct ks_pkcs12 *p12;
349 0 : size_t len;
350 0 : void *buf;
351 0 : PKCS12_PFX pfx;
352 0 : PKCS12_AuthenticatedSafe as;
353 0 : int ret;
354 0 : size_t i;
355 0 : struct hx509_collector *c;
356 :
357 0 : *data = NULL;
358 :
359 0 : if (residue == NULL || residue[0] == '\0') {
360 0 : hx509_set_error_string(context, 0, EINVAL,
361 : "PKCS#12 file not specified");
362 0 : return EINVAL;
363 : }
364 :
365 0 : if (lock == NULL)
366 0 : lock = _hx509_empty_lock;
367 :
368 0 : ret = _hx509_collector_alloc(context, lock, &c);
369 0 : if (ret)
370 0 : return ret;
371 :
372 0 : p12 = calloc(1, sizeof(*p12));
373 0 : if (p12 == NULL) {
374 0 : ret = ENOMEM;
375 0 : hx509_set_error_string(context, 0, ret, "out of memory");
376 0 : goto out;
377 : }
378 :
379 0 : p12->fn = strdup(residue);
380 0 : if (p12->fn == NULL) {
381 0 : ret = ENOMEM;
382 0 : hx509_set_error_string(context, 0, ret, "out of memory");
383 0 : goto out;
384 : }
385 :
386 0 : if (flags & HX509_CERTS_CREATE) {
387 0 : ret = hx509_certs_init(context, "MEMORY:ks-file-create",
388 : 0, lock, &p12->certs);
389 0 : if (ret == 0)
390 0 : *data = p12;
391 0 : goto out;
392 : }
393 :
394 0 : ret = rk_undumpdata(residue, &buf, &len);
395 0 : if (ret) {
396 0 : hx509_clear_error_string(context);
397 0 : goto out;
398 : }
399 :
400 0 : ret = decode_PKCS12_PFX(buf, len, &pfx, NULL);
401 0 : rk_xfree(buf);
402 0 : if (ret) {
403 0 : hx509_set_error_string(context, 0, ret,
404 : "Failed to decode the PFX in %s", residue);
405 0 : goto out;
406 : }
407 :
408 0 : if (der_heim_oid_cmp(&pfx.authSafe.contentType, &asn1_oid_id_pkcs7_data) != 0) {
409 0 : free_PKCS12_PFX(&pfx);
410 0 : ret = EINVAL;
411 0 : hx509_set_error_string(context, 0, ret,
412 : "PKCS PFX isn't a pkcs7-data container");
413 0 : goto out;
414 : }
415 :
416 0 : if (pfx.authSafe.content == NULL) {
417 0 : free_PKCS12_PFX(&pfx);
418 0 : ret = EINVAL;
419 0 : hx509_set_error_string(context, 0, ret,
420 : "PKCS PFX missing data");
421 0 : goto out;
422 : }
423 :
424 : {
425 0 : heim_octet_string asdata;
426 :
427 0 : ret = decode_PKCS12_OctetString(pfx.authSafe.content->data,
428 0 : pfx.authSafe.content->length,
429 : &asdata,
430 : NULL);
431 0 : free_PKCS12_PFX(&pfx);
432 0 : if (ret) {
433 0 : hx509_clear_error_string(context);
434 0 : goto out;
435 : }
436 0 : ret = decode_PKCS12_AuthenticatedSafe(asdata.data,
437 : asdata.length,
438 : &as,
439 : NULL);
440 0 : der_free_octet_string(&asdata);
441 0 : if (ret) {
442 0 : hx509_clear_error_string(context);
443 0 : goto out;
444 : }
445 : }
446 :
447 0 : for (i = 0; i < as.len; i++)
448 0 : parse_pkcs12_type(context,
449 : c,
450 : flags,
451 0 : &as.val[i].contentType,
452 0 : as.val[i].content->data,
453 0 : as.val[i].content->length,
454 : NULL);
455 :
456 0 : free_PKCS12_AuthenticatedSafe(&as);
457 :
458 0 : ret = _hx509_collector_collect_certs(context, c, &p12->certs);
459 0 : if (ret == 0)
460 0 : *data = p12;
461 :
462 0 : out:
463 0 : _hx509_collector_free(c);
464 :
465 0 : if (ret && p12) {
466 0 : if (p12->fn)
467 0 : free(p12->fn);
468 0 : if (p12->certs)
469 0 : hx509_certs_free(&p12->certs);
470 0 : free(p12);
471 : }
472 :
473 0 : return ret;
474 : }
475 :
476 : static int
477 0 : addBag(hx509_context context,
478 : PKCS12_AuthenticatedSafe *as,
479 : const heim_oid *oid,
480 : void *data,
481 : size_t length)
482 : {
483 0 : void *ptr;
484 0 : int ret;
485 :
486 0 : ptr = realloc(as->val, sizeof(as->val[0]) * (as->len + 1));
487 0 : if (ptr == NULL) {
488 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
489 0 : return ENOMEM;
490 : }
491 0 : as->val = ptr;
492 :
493 0 : ret = der_copy_oid(oid, &as->val[as->len].contentType);
494 0 : if (ret) {
495 0 : hx509_set_error_string(context, 0, ret, "out of memory");
496 0 : return ret;
497 : }
498 :
499 0 : as->val[as->len].content = calloc(1, sizeof(*as->val[0].content));
500 0 : if (as->val[as->len].content == NULL) {
501 0 : der_free_oid(&as->val[as->len].contentType);
502 0 : hx509_set_error_string(context, 0, ENOMEM, "malloc out of memory");
503 0 : return ENOMEM;
504 : }
505 :
506 0 : as->val[as->len].content->data = data;
507 0 : as->val[as->len].content->length = length;
508 :
509 0 : as->len++;
510 :
511 0 : return 0;
512 : }
513 :
514 : struct store_func_ctx {
515 : PKCS12_AuthenticatedSafe as;
516 : int store_flags;
517 : };
518 :
519 : static int HX509_LIB_CALL
520 0 : store_func(hx509_context context, void *d, hx509_cert c)
521 : {
522 0 : struct store_func_ctx *ctx = d;
523 0 : PKCS12_OctetString os;
524 0 : PKCS12_CertBag cb;
525 0 : size_t size;
526 0 : int ret;
527 :
528 0 : if ((ctx->store_flags & HX509_CERTS_STORE_NO_ROOTS)) {
529 0 : int is_root = 0;
530 :
531 0 : ret = hx509_cert_is_root(context, c, &is_root);
532 0 : if (ret || is_root)
533 0 : return ret;
534 : }
535 :
536 0 : memset(&os, 0, sizeof(os));
537 0 : memset(&cb, 0, sizeof(cb));
538 :
539 0 : os.data = NULL;
540 0 : os.length = 0;
541 :
542 0 : ret = hx509_cert_binary(context, c, &os);
543 0 : if (ret)
544 0 : return ret;
545 :
546 0 : ASN1_MALLOC_ENCODE(PKCS12_OctetString,
547 : cb.certValue.data,cb.certValue.length,
548 : &os, &size, ret);
549 0 : free(os.data);
550 0 : if (ret)
551 0 : goto out;
552 0 : ret = der_copy_oid(&asn1_oid_id_pkcs_9_at_certTypes_x509, &cb.certType);
553 0 : if (ret) {
554 0 : free_PKCS12_CertBag(&cb);
555 0 : goto out;
556 : }
557 0 : ASN1_MALLOC_ENCODE(PKCS12_CertBag, os.data, os.length,
558 : &cb, &size, ret);
559 0 : free_PKCS12_CertBag(&cb);
560 0 : if (ret)
561 0 : goto out;
562 :
563 0 : ret = addBag(context, &ctx->as, &asn1_oid_id_pkcs12_certBag, os.data,
564 : os.length);
565 :
566 0 : if (_hx509_cert_private_key_exportable(c) &&
567 0 : !(ctx->store_flags & HX509_CERTS_STORE_NO_PRIVATE_KEYS)) {
568 0 : hx509_private_key key = _hx509_cert_private_key(c);
569 0 : PKCS8PrivateKeyInfo pki;
570 :
571 0 : memset(&pki, 0, sizeof(pki));
572 :
573 0 : ret = der_parse_hex_heim_integer("00", &pki.version);
574 0 : if (ret)
575 0 : return ret;
576 0 : ret = _hx509_private_key_oid(context, key,
577 : &pki.privateKeyAlgorithm.algorithm);
578 0 : if (ret) {
579 0 : free_PKCS8PrivateKeyInfo(&pki);
580 0 : return ret;
581 : }
582 0 : ret = _hx509_private_key_export(context,
583 : _hx509_cert_private_key(c),
584 : HX509_KEY_FORMAT_DER,
585 : &pki.privateKey);
586 0 : if (ret) {
587 0 : free_PKCS8PrivateKeyInfo(&pki);
588 0 : return ret;
589 : }
590 : /* set attribute, asn1_oid_id_pkcs_9_at_localKeyId */
591 :
592 0 : ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, os.data, os.length,
593 : &pki, &size, ret);
594 0 : free_PKCS8PrivateKeyInfo(&pki);
595 0 : if (ret)
596 0 : return ret;
597 :
598 0 : ret = addBag(context, &ctx->as, &asn1_oid_id_pkcs12_keyBag, os.data,
599 : os.length);
600 0 : if (ret)
601 0 : return ret;
602 : }
603 :
604 0 : out:
605 0 : return ret;
606 : }
607 :
608 : static int
609 0 : p12_store(hx509_context context,
610 : hx509_certs certs, void *data, int flags, hx509_lock lock)
611 : {
612 0 : struct ks_pkcs12 *p12 = data;
613 0 : PKCS12_PFX pfx;
614 0 : struct store_func_ctx ctx;
615 0 : PKCS12_OctetString asdata;
616 0 : size_t size;
617 0 : int ret;
618 :
619 0 : memset(&ctx, 0, sizeof(ctx));
620 0 : memset(&pfx, 0, sizeof(pfx));
621 0 : ctx.store_flags = flags;
622 :
623 0 : ret = hx509_certs_iter_f(context, p12->certs, store_func, &ctx);
624 0 : if (ret)
625 0 : goto out;
626 :
627 0 : ASN1_MALLOC_ENCODE(PKCS12_AuthenticatedSafe, asdata.data, asdata.length,
628 : &ctx.as, &size, ret);
629 0 : free_PKCS12_AuthenticatedSafe(&ctx.as);
630 0 : if (ret)
631 0 : return ret;
632 :
633 0 : ret = der_parse_hex_heim_integer("03", &pfx.version);
634 0 : if (ret) {
635 0 : free(asdata.data);
636 0 : goto out;
637 : }
638 :
639 0 : pfx.authSafe.content = calloc(1, sizeof(*pfx.authSafe.content));
640 :
641 0 : ASN1_MALLOC_ENCODE(PKCS12_OctetString,
642 : pfx.authSafe.content->data,
643 : pfx.authSafe.content->length,
644 : &asdata, &size, ret);
645 0 : free(asdata.data);
646 0 : if (ret)
647 0 : goto out;
648 :
649 0 : ret = der_copy_oid(&asn1_oid_id_pkcs7_data, &pfx.authSafe.contentType);
650 0 : if (ret)
651 0 : goto out;
652 :
653 0 : ASN1_MALLOC_ENCODE(PKCS12_PFX, asdata.data, asdata.length,
654 : &pfx, &size, ret);
655 0 : if (ret)
656 0 : goto out;
657 :
658 : #if 0
659 : const struct _hx509_password *pw;
660 :
661 : pw = _hx509_lock_get_passwords(lock);
662 : if (pw != NULL) {
663 : pfx.macData = calloc(1, sizeof(*pfx.macData));
664 : if (pfx.macData == NULL) {
665 : ret = ENOMEM;
666 : hx509_set_error_string(context, 0, ret, "malloc out of memory");
667 : return ret;
668 : }
669 : if (pfx.macData == NULL) {
670 : free(asdata.data);
671 : goto out;
672 : }
673 : }
674 : ret = calculate_hash(&aspath, pw, pfx.macData);
675 : #endif
676 :
677 0 : rk_dumpdata(p12->fn, asdata.data, asdata.length);
678 0 : free(asdata.data);
679 :
680 0 : out:
681 0 : free_PKCS12_AuthenticatedSafe(&ctx.as);
682 0 : free_PKCS12_PFX(&pfx);
683 :
684 0 : return ret;
685 : }
686 :
687 :
688 : static int
689 0 : p12_free(hx509_certs certs, void *data)
690 : {
691 0 : struct ks_pkcs12 *p12 = data;
692 0 : hx509_certs_free(&p12->certs);
693 0 : free(p12->fn);
694 0 : free(p12);
695 0 : return 0;
696 : }
697 :
698 : static int
699 0 : p12_add(hx509_context context, hx509_certs certs, void *data, hx509_cert c)
700 : {
701 0 : struct ks_pkcs12 *p12 = data;
702 0 : return hx509_certs_add(context, p12->certs, c);
703 : }
704 :
705 : static int
706 0 : p12_iter_start(hx509_context context,
707 : hx509_certs certs,
708 : void *data,
709 : void **cursor)
710 : {
711 0 : struct ks_pkcs12 *p12 = data;
712 0 : return hx509_certs_start_seq(context, p12->certs, cursor);
713 : }
714 :
715 : static int
716 0 : p12_iter(hx509_context context,
717 : hx509_certs certs,
718 : void *data,
719 : void *cursor,
720 : hx509_cert *cert)
721 : {
722 0 : struct ks_pkcs12 *p12 = data;
723 0 : return hx509_certs_next_cert(context, p12->certs, cursor, cert);
724 : }
725 :
726 : static int
727 0 : p12_iter_end(hx509_context context,
728 : hx509_certs certs,
729 : void *data,
730 : void *cursor)
731 : {
732 0 : struct ks_pkcs12 *p12 = data;
733 0 : return hx509_certs_end_seq(context, p12->certs, cursor);
734 : }
735 :
736 : static int
737 0 : p12_destroy(hx509_context context, hx509_certs certs, void *data)
738 : {
739 0 : struct ks_pkcs12 *p12 = data;
740 0 : return _hx509_erase_file(context, p12->fn);
741 : }
742 :
743 : static struct hx509_keyset_ops keyset_pkcs12 = {
744 : "PKCS12",
745 : 0,
746 : p12_init,
747 : p12_store,
748 : p12_free,
749 : p12_add,
750 : NULL,
751 : p12_iter_start,
752 : p12_iter,
753 : p12_iter_end,
754 : NULL,
755 : NULL,
756 : NULL,
757 : p12_destroy
758 : };
759 :
760 : HX509_LIB_FUNCTION void HX509_LIB_CALL
761 792004 : _hx509_ks_pkcs12_register(hx509_context context)
762 : {
763 792004 : _hx509_ks_register(context, &keyset_pkcs12);
764 792004 : }
|