Annotation of src/usr.bin/openssl/pkcs12.c, Revision 1.7
1.7 ! doug 1: /* $OpenBSD: pkcs12.c,v 1.6 2015/10/17 07:51:10 semarie Exp $ */
1.1 jsing 2: /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3: * project.
4: */
5: /* ====================================================================
6: * Copyright (c) 1999-2006 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 <openssl/opensslconf.h>
60:
61: #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
62:
63: #include <stdio.h>
64: #include <stdlib.h>
65: #include <string.h>
66:
67: #include "apps.h"
68:
69: #include <openssl/crypto.h>
70: #include <openssl/err.h>
71: #include <openssl/pem.h>
72: #include <openssl/pkcs12.h>
73:
74: const EVP_CIPHER *enc;
75:
76: #define NOKEYS 0x1
77: #define NOCERTS 0x2
78: #define INFO 0x4
79: #define CLCERTS 0x8
80: #define CACERTS 0x10
81:
82: int get_cert_chain(X509 * cert, X509_STORE * store, STACK_OF(X509) ** chain);
83: int dump_certs_keys_p12(BIO * out, PKCS12 * p12, char *pass, int passlen,
84: int options, char *pempass);
85: int dump_certs_pkeys_bags(BIO * out, STACK_OF(PKCS12_SAFEBAG) * bags, char *pass,
86: int passlen, int options, char *pempass);
87: int dump_certs_pkeys_bag(BIO * out, PKCS12_SAFEBAG * bags, char *pass, int passlen,
88: int options, char *pempass);
89: int print_attribs(BIO * out, STACK_OF(X509_ATTRIBUTE) * attrlst, const char *name);
90: void hex_prin(BIO * out, unsigned char *buf, int len);
91: int alg_print(BIO * x, X509_ALGOR * alg);
92: int cert_load(BIO * in, STACK_OF(X509) * sk);
93: static int set_pbe(BIO * err, int *ppbe, const char *str);
94:
95: int
96: pkcs12_main(int argc, char **argv)
97: {
98: char *infile = NULL, *outfile = NULL, *keyname = NULL;
99: char *certfile = NULL;
100: BIO *in = NULL, *out = NULL;
101: char **args;
102: char *name = NULL;
103: char *csp_name = NULL;
104: int add_lmk = 0;
105: PKCS12 *p12 = NULL;
106: char pass[50], macpass[50];
107: int export_cert = 0;
108: int options = 0;
109: int chain = 0;
110: int badarg = 0;
111: int iter = PKCS12_DEFAULT_ITER;
112: int maciter = PKCS12_DEFAULT_ITER;
113: int twopass = 0;
114: int keytype = 0;
115: int cert_pbe;
116: int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
117: int ret = 1;
118: int macver = 1;
119: int noprompt = 0;
120: STACK_OF(OPENSSL_STRING) * canames = NULL;
121: char *cpass = NULL, *mpass = NULL;
122: char *passargin = NULL, *passargout = NULL, *passarg = NULL;
123: char *passin = NULL, *passout = NULL;
124: char *macalg = NULL;
125: char *CApath = NULL, *CAfile = NULL;
1.5 doug 126:
127: if (single_execution) {
1.7 ! doug 128: if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
1.5 doug 129: perror("pledge");
1.7 ! doug 130: exit(1);
! 131: }
1.5 doug 132: }
1.1 jsing 133:
134: cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
135:
136: enc = EVP_des_ede3_cbc();
137:
138: args = argv + 1;
139:
140: while (*args) {
141: if (*args[0] == '-') {
142: if (!strcmp(*args, "-nokeys"))
143: options |= NOKEYS;
144: else if (!strcmp(*args, "-keyex"))
145: keytype = KEY_EX;
146: else if (!strcmp(*args, "-keysig"))
147: keytype = KEY_SIG;
148: else if (!strcmp(*args, "-nocerts"))
149: options |= NOCERTS;
150: else if (!strcmp(*args, "-clcerts"))
151: options |= CLCERTS;
152: else if (!strcmp(*args, "-cacerts"))
153: options |= CACERTS;
154: else if (!strcmp(*args, "-noout"))
155: options |= (NOKEYS | NOCERTS);
156: else if (!strcmp(*args, "-info"))
157: options |= INFO;
158: else if (!strcmp(*args, "-chain"))
159: chain = 1;
160: else if (!strcmp(*args, "-twopass"))
161: twopass = 1;
162: else if (!strcmp(*args, "-nomacver"))
163: macver = 0;
164: else if (!strcmp(*args, "-descert"))
165: cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
166: else if (!strcmp(*args, "-export"))
167: export_cert = 1;
168: else if (!strcmp(*args, "-des"))
169: enc = EVP_des_cbc();
170: else if (!strcmp(*args, "-des3"))
171: enc = EVP_des_ede3_cbc();
172: #ifndef OPENSSL_NO_IDEA
173: else if (!strcmp(*args, "-idea"))
174: enc = EVP_idea_cbc();
175: #endif
176: #ifndef OPENSSL_NO_AES
177: else if (!strcmp(*args, "-aes128"))
178: enc = EVP_aes_128_cbc();
179: else if (!strcmp(*args, "-aes192"))
180: enc = EVP_aes_192_cbc();
181: else if (!strcmp(*args, "-aes256"))
182: enc = EVP_aes_256_cbc();
183: #endif
184: #ifndef OPENSSL_NO_CAMELLIA
185: else if (!strcmp(*args, "-camellia128"))
186: enc = EVP_camellia_128_cbc();
187: else if (!strcmp(*args, "-camellia192"))
188: enc = EVP_camellia_192_cbc();
189: else if (!strcmp(*args, "-camellia256"))
190: enc = EVP_camellia_256_cbc();
191: #endif
192: else if (!strcmp(*args, "-noiter"))
193: iter = 1;
194: else if (!strcmp(*args, "-maciter"))
195: maciter = PKCS12_DEFAULT_ITER;
196: else if (!strcmp(*args, "-nomaciter"))
197: maciter = 1;
198: else if (!strcmp(*args, "-nomac"))
199: maciter = -1;
200: else if (!strcmp(*args, "-macalg"))
201: if (args[1]) {
202: args++;
203: macalg = *args;
204: } else
205: badarg = 1;
206: else if (!strcmp(*args, "-nodes"))
207: enc = NULL;
208: else if (!strcmp(*args, "-certpbe")) {
209: if (!set_pbe(bio_err, &cert_pbe, *++args))
210: badarg = 1;
211: } else if (!strcmp(*args, "-keypbe")) {
212: if (!set_pbe(bio_err, &key_pbe, *++args))
213: badarg = 1;
214: } else if (!strcmp(*args, "-inkey")) {
215: if (args[1]) {
216: args++;
217: keyname = *args;
218: } else
219: badarg = 1;
220: } else if (!strcmp(*args, "-certfile")) {
221: if (args[1]) {
222: args++;
223: certfile = *args;
224: } else
225: badarg = 1;
226: } else if (!strcmp(*args, "-name")) {
227: if (args[1]) {
228: args++;
229: name = *args;
230: } else
231: badarg = 1;
232: } else if (!strcmp(*args, "-LMK"))
233: add_lmk = 1;
234: else if (!strcmp(*args, "-CSP")) {
235: if (args[1]) {
236: args++;
237: csp_name = *args;
238: } else
239: badarg = 1;
240: } else if (!strcmp(*args, "-caname")) {
241: if (args[1]) {
242: args++;
243: if (!canames)
244: canames = sk_OPENSSL_STRING_new_null();
245: sk_OPENSSL_STRING_push(canames, *args);
246: } else
247: badarg = 1;
248: } else if (!strcmp(*args, "-in")) {
249: if (args[1]) {
250: args++;
251: infile = *args;
252: } else
253: badarg = 1;
254: } else if (!strcmp(*args, "-out")) {
255: if (args[1]) {
256: args++;
257: outfile = *args;
258: } else
259: badarg = 1;
260: } else if (!strcmp(*args, "-passin")) {
261: if (args[1]) {
262: args++;
263: passargin = *args;
264: } else
265: badarg = 1;
266: } else if (!strcmp(*args, "-passout")) {
267: if (args[1]) {
268: args++;
269: passargout = *args;
270: } else
271: badarg = 1;
272: } else if (!strcmp(*args, "-password")) {
273: if (args[1]) {
274: args++;
275: passarg = *args;
276: noprompt = 1;
277: } else
278: badarg = 1;
279: } else if (!strcmp(*args, "-CApath")) {
280: if (args[1]) {
281: args++;
282: CApath = *args;
283: } else
284: badarg = 1;
285: } else if (!strcmp(*args, "-CAfile")) {
286: if (args[1]) {
287: args++;
288: CAfile = *args;
289: } else
290: badarg = 1;
291: } else
292: badarg = 1;
293:
294: } else
295: badarg = 1;
296: args++;
297: }
298:
299: if (badarg) {
300: BIO_printf(bio_err, "Usage: pkcs12 [options]\n");
301: BIO_printf(bio_err, "where options are\n");
302: BIO_printf(bio_err, "-export output PKCS12 file\n");
303: BIO_printf(bio_err, "-chain add certificate chain\n");
304: BIO_printf(bio_err, "-inkey file private key if not infile\n");
305: BIO_printf(bio_err, "-certfile f add all certs in f\n");
306: BIO_printf(bio_err, "-CApath arg - PEM format directory of CA's\n");
307: BIO_printf(bio_err, "-CAfile arg - PEM format file of CA's\n");
308: BIO_printf(bio_err, "-name \"name\" use name as friendly name\n");
309: BIO_printf(bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n");
310: BIO_printf(bio_err, "-in infile input filename\n");
311: BIO_printf(bio_err, "-out outfile output filename\n");
312: BIO_printf(bio_err, "-noout don't output anything, just verify.\n");
313: BIO_printf(bio_err, "-nomacver don't verify MAC.\n");
314: BIO_printf(bio_err, "-nocerts don't output certificates.\n");
315: BIO_printf(bio_err, "-clcerts only output client certificates.\n");
316: BIO_printf(bio_err, "-cacerts only output CA certificates.\n");
317: BIO_printf(bio_err, "-nokeys don't output private keys.\n");
318: BIO_printf(bio_err, "-info give info about PKCS#12 structure.\n");
319: BIO_printf(bio_err, "-des encrypt private keys with DES\n");
320: BIO_printf(bio_err, "-des3 encrypt private keys with triple DES (default)\n");
321: #ifndef OPENSSL_NO_IDEA
322: BIO_printf(bio_err, "-idea encrypt private keys with idea\n");
323: #endif
324: #ifndef OPENSSL_NO_AES
325: BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");
326: BIO_printf(bio_err, " encrypt PEM output with cbc aes\n");
327: #endif
328: #ifndef OPENSSL_NO_CAMELLIA
329: BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");
330: BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n");
331: #endif
332: BIO_printf(bio_err, "-nodes don't encrypt private keys\n");
333: BIO_printf(bio_err, "-noiter don't use encryption iteration\n");
334: BIO_printf(bio_err, "-nomaciter don't use MAC iteration\n");
335: BIO_printf(bio_err, "-maciter use MAC iteration\n");
336: BIO_printf(bio_err, "-nomac don't generate MAC\n");
337: BIO_printf(bio_err, "-twopass separate MAC, encryption passwords\n");
338: BIO_printf(bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
339: BIO_printf(bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n");
340: BIO_printf(bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n");
341: BIO_printf(bio_err, "-macalg alg digest algorithm used in MAC (default SHA1)\n");
342: BIO_printf(bio_err, "-keyex set MS key exchange type\n");
343: BIO_printf(bio_err, "-keysig set MS key signature type\n");
344: BIO_printf(bio_err, "-password p set import/export password source\n");
345: BIO_printf(bio_err, "-passin p input file pass phrase source\n");
346: BIO_printf(bio_err, "-passout p output file pass phrase source\n");
347: BIO_printf(bio_err, "-CSP name Microsoft CSP name\n");
348: BIO_printf(bio_err, "-LMK Add local machine keyset attribute to private key\n");
349: goto end;
350: }
351:
352: if (passarg) {
353: if (export_cert)
354: passargout = passarg;
355: else
356: passargin = passarg;
357: }
358: if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
359: BIO_printf(bio_err, "Error getting passwords\n");
360: goto end;
361: }
362: if (!cpass) {
363: if (export_cert)
364: cpass = passout;
365: else
366: cpass = passin;
367: }
368: if (cpass) {
369: mpass = cpass;
370: noprompt = 1;
371: } else {
372: cpass = pass;
373: mpass = macpass;
374: }
375:
376: if (!infile)
377: in = BIO_new_fp(stdin, BIO_NOCLOSE);
378: else
379: in = BIO_new_file(infile, "rb");
380: if (!in) {
381: BIO_printf(bio_err, "Error opening input file %s\n",
382: infile ? infile : "<stdin>");
383: perror(infile);
384: goto end;
385: }
386:
387: if (!outfile) {
388: out = BIO_new_fp(stdout, BIO_NOCLOSE);
389: } else
390: out = BIO_new_file(outfile, "wb");
391: if (!out) {
392: BIO_printf(bio_err, "Error opening output file %s\n",
393: outfile ? outfile : "<stdout>");
394: perror(outfile);
395: goto end;
396: }
397: if (twopass) {
398: if (EVP_read_pw_string(macpass, sizeof macpass, "Enter MAC Password:", export_cert)) {
399: BIO_printf(bio_err, "Can't read Password\n");
400: goto end;
401: }
402: }
403: if (export_cert) {
404: EVP_PKEY *key = NULL;
405: X509 *ucert = NULL, *x = NULL;
406: STACK_OF(X509) * certs = NULL;
407: const EVP_MD *macmd = NULL;
408: unsigned char *catmp = NULL;
409: int i;
410:
411: if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
412: BIO_printf(bio_err, "Nothing to do!\n");
413: goto export_end;
414: }
415: if (options & NOCERTS)
416: chain = 0;
417:
418: if (!(options & NOKEYS)) {
419: key = load_key(bio_err, keyname ? keyname : infile,
1.4 bcook 420: FORMAT_PEM, 1, passin, "private key");
1.1 jsing 421: if (!key)
422: goto export_end;
423: }
424:
425: /* Load in all certs in input file */
426: if (!(options & NOCERTS)) {
1.4 bcook 427: certs = load_certs(bio_err, infile, FORMAT_PEM, NULL,
1.1 jsing 428: "certificates");
429: if (!certs)
430: goto export_end;
431:
432: if (key) {
433: /* Look for matching private key */
434: for (i = 0; i < sk_X509_num(certs); i++) {
435: x = sk_X509_value(certs, i);
436: if (X509_check_private_key(x, key)) {
437: ucert = x;
438: /* Zero keyid and alias */
439: X509_keyid_set1(ucert, NULL, 0);
440: X509_alias_set1(ucert, NULL, 0);
441: /* Remove from list */
442: (void) sk_X509_delete(certs, i);
443: break;
444: }
445: }
446: if (!ucert) {
447: BIO_printf(bio_err, "No certificate matches private key\n");
448: goto export_end;
449: }
450: }
451: }
452:
453: /* Add any more certificates asked for */
454: if (certfile) {
455: STACK_OF(X509) * morecerts = NULL;
456: if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
1.4 bcook 457: NULL, "certificates from certfile")))
1.1 jsing 458: goto export_end;
459: while (sk_X509_num(morecerts) > 0)
460: sk_X509_push(certs, sk_X509_shift(morecerts));
461: sk_X509_free(morecerts);
462: }
463:
464:
465: /* If chaining get chain from user cert */
466: if (chain) {
467: int vret;
468: STACK_OF(X509) * chain2;
469: X509_STORE *store = X509_STORE_new();
470: if (!store) {
471: BIO_printf(bio_err, "Memory allocation error\n");
472: goto export_end;
473: }
474: if (!X509_STORE_load_locations(store, CAfile, CApath))
475: X509_STORE_set_default_paths(store);
476:
477: vret = get_cert_chain(ucert, store, &chain2);
478: X509_STORE_free(store);
479:
480: if (!vret) {
481: /* Exclude verified certificate */
482: for (i = 1; i < sk_X509_num(chain2); i++)
483: sk_X509_push(certs, sk_X509_value(chain2, i));
484: /* Free first certificate */
485: X509_free(sk_X509_value(chain2, 0));
486: sk_X509_free(chain2);
487: } else {
488: if (vret >= 0)
489: BIO_printf(bio_err, "Error %s getting chain.\n",
490: X509_verify_cert_error_string(vret));
491: else
492: ERR_print_errors(bio_err);
493: goto export_end;
494: }
495: }
496: /* Add any CA names */
497:
498: for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
499: catmp = (unsigned char *) sk_OPENSSL_STRING_value(canames, i);
500: X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
501: }
502:
503: if (csp_name && key)
504: EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
505: MBSTRING_ASC, (unsigned char *) csp_name, -1);
506:
507: if (add_lmk && key)
508: EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
509:
510:
511: if (!noprompt &&
512: EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1)) {
513: BIO_printf(bio_err, "Can't read Password\n");
514: goto export_end;
515: }
516: if (!twopass)
517: strlcpy(macpass, pass, sizeof macpass);
518:
519:
520: p12 = PKCS12_create(cpass, name, key, ucert, certs,
521: key_pbe, cert_pbe, iter, -1, keytype);
522:
523: if (!p12) {
524: ERR_print_errors(bio_err);
525: goto export_end;
526: }
527: if (macalg) {
528: macmd = EVP_get_digestbyname(macalg);
529: if (!macmd) {
530: BIO_printf(bio_err, "Unknown digest algorithm %s\n",
531: macalg);
532: }
533: }
534: if (maciter != -1)
535: PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
536:
537:
538: i2d_PKCS12_bio(out, p12);
539:
540: ret = 0;
541:
542: export_end:
543:
544: if (key)
545: EVP_PKEY_free(key);
546: if (certs)
547: sk_X509_pop_free(certs, X509_free);
548: if (ucert)
549: X509_free(ucert);
550:
551: goto end;
552:
553: }
554: if (!(p12 = d2i_PKCS12_bio(in, NULL))) {
555: ERR_print_errors(bio_err);
556: goto end;
557: }
558: if (!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
559: BIO_printf(bio_err, "Can't read Password\n");
560: goto end;
561: }
562:
563: if (!twopass)
564: strlcpy(macpass, pass, sizeof macpass);
565:
566: if ((options & INFO) && p12->mac)
567: BIO_printf(bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1);
568: if (macver) {
569: /* If we enter empty password try no password first */
570: if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
571: /* If mac and crypto pass the same set it to NULL too */
572: if (!twopass)
573: cpass = NULL;
574: } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
575: BIO_printf(bio_err, "Mac verify error: invalid password?\n");
576: ERR_print_errors(bio_err);
577: goto end;
578: }
579: BIO_printf(bio_err, "MAC verified OK\n");
580: }
581: if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) {
582: BIO_printf(bio_err, "Error outputting keys and certificates\n");
583: ERR_print_errors(bio_err);
584: goto end;
585: }
586: ret = 0;
587: end:
588: if (p12)
589: PKCS12_free(p12);
590: BIO_free(in);
591: BIO_free_all(out);
592: if (canames)
593: sk_OPENSSL_STRING_free(canames);
594: free(passin);
595: free(passout);
596:
597: return (ret);
598: }
599:
600: int
601: dump_certs_keys_p12(BIO * out, PKCS12 * p12, char *pass,
602: int passlen, int options, char *pempass)
603: {
604: STACK_OF(PKCS7) * asafes = NULL;
605: STACK_OF(PKCS12_SAFEBAG) * bags;
606: int i, bagnid;
607: int ret = 0;
608: PKCS7 *p7;
609:
610: if (!(asafes = PKCS12_unpack_authsafes(p12)))
611: return 0;
612: for (i = 0; i < sk_PKCS7_num(asafes); i++) {
613: p7 = sk_PKCS7_value(asafes, i);
614: bagnid = OBJ_obj2nid(p7->type);
615: if (bagnid == NID_pkcs7_data) {
616: bags = PKCS12_unpack_p7data(p7);
617: if (options & INFO)
618: BIO_printf(bio_err, "PKCS7 Data\n");
619: } else if (bagnid == NID_pkcs7_encrypted) {
620: if (options & INFO) {
621: BIO_printf(bio_err, "PKCS7 Encrypted data: ");
622: alg_print(bio_err,
623: p7->d.encrypted->enc_data->algorithm);
624: }
625: bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
626: } else
627: continue;
628: if (!bags)
629: goto err;
630: if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
631: options, pempass)) {
632: sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
633: goto err;
634: }
635: sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
636: bags = NULL;
637: }
638: ret = 1;
639:
640: err:
641:
642: if (asafes)
643: sk_PKCS7_pop_free(asafes, PKCS7_free);
644: return ret;
645: }
646:
647: int
648: dump_certs_pkeys_bags(BIO * out, STACK_OF(PKCS12_SAFEBAG) * bags,
649: char *pass, int passlen, int options, char *pempass)
650: {
651: int i;
652: for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
653: if (!dump_certs_pkeys_bag(out,
654: sk_PKCS12_SAFEBAG_value(bags, i),
655: pass, passlen,
656: options, pempass))
657: return 0;
658: }
659: return 1;
660: }
661:
662: int
663: dump_certs_pkeys_bag(BIO * out, PKCS12_SAFEBAG * bag, char *pass,
664: int passlen, int options, char *pempass)
665: {
666: EVP_PKEY *pkey;
667: PKCS8_PRIV_KEY_INFO *p8;
668: X509 *x509;
669:
670: switch (M_PKCS12_bag_type(bag)) {
671: case NID_keyBag:
672: if (options & INFO)
673: BIO_printf(bio_err, "Key bag\n");
674: if (options & NOKEYS)
675: return 1;
676: print_attribs(out, bag->attrib, "Bag Attributes");
677: p8 = bag->value.keybag;
678: if (!(pkey = EVP_PKCS82PKEY(p8)))
679: return 0;
680: print_attribs(out, p8->attributes, "Key Attributes");
681: PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
682: EVP_PKEY_free(pkey);
683: break;
684:
685: case NID_pkcs8ShroudedKeyBag:
686: if (options & INFO) {
687: BIO_printf(bio_err, "Shrouded Keybag: ");
688: alg_print(bio_err, bag->value.shkeybag->algor);
689: }
690: if (options & NOKEYS)
691: return 1;
692: print_attribs(out, bag->attrib, "Bag Attributes");
693: if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
694: return 0;
695: if (!(pkey = EVP_PKCS82PKEY(p8))) {
696: PKCS8_PRIV_KEY_INFO_free(p8);
697: return 0;
698: }
699: print_attribs(out, p8->attributes, "Key Attributes");
700: PKCS8_PRIV_KEY_INFO_free(p8);
701: PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
702: EVP_PKEY_free(pkey);
703: break;
704:
705: case NID_certBag:
706: if (options & INFO)
707: BIO_printf(bio_err, "Certificate bag\n");
708: if (options & NOCERTS)
709: return 1;
710: if (PKCS12_get_attr(bag, NID_localKeyID)) {
711: if (options & CACERTS)
712: return 1;
713: } else if (options & CLCERTS)
714: return 1;
715: print_attribs(out, bag->attrib, "Bag Attributes");
716: if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
717: return 1;
718: if (!(x509 = PKCS12_certbag2x509(bag)))
719: return 0;
720: dump_cert_text(out, x509);
721: PEM_write_bio_X509(out, x509);
722: X509_free(x509);
723: break;
724:
725: case NID_safeContentsBag:
726: if (options & INFO)
727: BIO_printf(bio_err, "Safe Contents bag\n");
728: print_attribs(out, bag->attrib, "Bag Attributes");
729: return dump_certs_pkeys_bags(out, bag->value.safes, pass,
730: passlen, options, pempass);
731:
732: default:
733: BIO_printf(bio_err, "Warning unsupported bag type: ");
734: i2a_ASN1_OBJECT(bio_err, bag->type);
735: BIO_printf(bio_err, "\n");
736: return 1;
737: break;
738: }
739: return 1;
740: }
741:
742: /* Given a single certificate return a verified chain or NULL if error */
743:
744: /* Hope this is OK .... */
745:
746: int
747: get_cert_chain(X509 * cert, X509_STORE * store, STACK_OF(X509) ** chain)
748: {
749: X509_STORE_CTX store_ctx;
750: STACK_OF(X509) * chn;
751: int i = 0;
752:
753: /*
754: * FIXME: Should really check the return status of
755: * X509_STORE_CTX_init for an error, but how that fits into the
756: * return value of this function is less obvious.
757: */
758: X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
759: if (X509_verify_cert(&store_ctx) <= 0) {
760: i = X509_STORE_CTX_get_error(&store_ctx);
761: if (i == 0)
762: /*
763: * avoid returning 0 if X509_verify_cert() did not
764: * set an appropriate error value in the context
765: */
766: i = -1;
767: chn = NULL;
768: goto err;
769: } else
770: chn = X509_STORE_CTX_get1_chain(&store_ctx);
771: err:
772: X509_STORE_CTX_cleanup(&store_ctx);
773: *chain = chn;
774:
775: return i;
776: }
777:
778: int
779: alg_print(BIO * x, X509_ALGOR * alg)
780: {
781: PBEPARAM *pbe;
782: const unsigned char *p;
783: p = alg->parameter->value.sequence->data;
784: pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
785: if (!pbe)
786: return 1;
787: BIO_printf(bio_err, "%s, Iteration %ld\n",
788: OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
789: ASN1_INTEGER_get(pbe->iter));
790: PBEPARAM_free(pbe);
791: return 1;
792: }
793:
794: /* Load all certificates from a given file */
795:
796: int
797: cert_load(BIO * in, STACK_OF(X509) * sk)
798: {
799: int ret;
800: X509 *cert;
801: ret = 0;
802: while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
803: ret = 1;
804: sk_X509_push(sk, cert);
805: }
806: if (ret)
807: ERR_clear_error();
808: return ret;
809: }
810:
811: /* Generalised attribute print: handle PKCS#8 and bag attributes */
812:
813: int
814: print_attribs(BIO * out, STACK_OF(X509_ATTRIBUTE) * attrlst, const char *name)
815: {
816: X509_ATTRIBUTE *attr;
817: ASN1_TYPE *av;
818: char *value;
819: int i, attr_nid;
820: if (!attrlst) {
821: BIO_printf(out, "%s: <No Attributes>\n", name);
822: return 1;
823: }
824: if (!sk_X509_ATTRIBUTE_num(attrlst)) {
825: BIO_printf(out, "%s: <Empty Attributes>\n", name);
826: return 1;
827: }
828: BIO_printf(out, "%s\n", name);
829: for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
830: attr = sk_X509_ATTRIBUTE_value(attrlst, i);
831: attr_nid = OBJ_obj2nid(attr->object);
832: BIO_printf(out, " ");
833: if (attr_nid == NID_undef) {
834: i2a_ASN1_OBJECT(out, attr->object);
835: BIO_printf(out, ": ");
836: } else
837: BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
838:
839: if (sk_ASN1_TYPE_num(attr->value.set)) {
840: av = sk_ASN1_TYPE_value(attr->value.set, 0);
841: switch (av->type) {
842: case V_ASN1_BMPSTRING:
843: value = OPENSSL_uni2asc(av->value.bmpstring->data,
844: av->value.bmpstring->length);
845: BIO_printf(out, "%s\n", value);
846: free(value);
847: break;
848:
849: case V_ASN1_OCTET_STRING:
850: hex_prin(out, av->value.octet_string->data,
851: av->value.octet_string->length);
852: BIO_printf(out, "\n");
853: break;
854:
855: case V_ASN1_BIT_STRING:
856: hex_prin(out, av->value.bit_string->data,
857: av->value.bit_string->length);
858: BIO_printf(out, "\n");
859: break;
860:
861: default:
862: BIO_printf(out, "<Unsupported tag %d>\n", av->type);
863: break;
864: }
865: } else
866: BIO_printf(out, "<No Values>\n");
867: }
868: return 1;
869: }
870:
871: void
872: hex_prin(BIO * out, unsigned char *buf, int len)
873: {
874: int i;
875: for (i = 0; i < len; i++)
876: BIO_printf(out, "%02X ", buf[i]);
877: }
878:
879: static int
880: set_pbe(BIO * err, int *ppbe, const char *str)
881: {
882: if (!str)
883: return 0;
884: if (!strcmp(str, "NONE")) {
885: *ppbe = -1;
886: return 1;
887: }
888: *ppbe = OBJ_txt2nid(str);
889: if (*ppbe == NID_undef) {
890: BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
891: return 0;
892: }
893: return 1;
894: }
895:
896: #endif