xref: /freebsd/crypto/openssl/apps/pkcs12.c (revision b2d48be1bc7df45ddd13b143a160d0acb5a383c5)
1 /* pkcs12.c */
2 /*
3  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4  * project.
5  */
6 /* ====================================================================
7  * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. All advertising materials mentioning features or use of this
22  *    software must display the following acknowledgment:
23  *    "This product includes software developed by the OpenSSL Project
24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25  *
26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27  *    endorse or promote products derived from this software without
28  *    prior written permission. For written permission, please contact
29  *    licensing@OpenSSL.org.
30  *
31  * 5. Products derived from this software may not be called "OpenSSL"
32  *    nor may "OpenSSL" appear in their names without prior written
33  *    permission of the OpenSSL Project.
34  *
35  * 6. Redistributions of any form whatsoever must retain the following
36  *    acknowledgment:
37  *    "This product includes software developed by the OpenSSL Project
38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51  * OF THE POSSIBILITY OF SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This product includes cryptographic software written by Eric Young
55  * (eay@cryptsoft.com).  This product includes software written by Tim
56  * Hudson (tjh@cryptsoft.com).
57  *
58  */
59 
60 #include <openssl/opensslconf.h>
61 #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
62 
63 # include <stdio.h>
64 # include <stdlib.h>
65 # include <string.h>
66 # include "apps.h"
67 # include <openssl/crypto.h>
68 # include <openssl/err.h>
69 # include <openssl/pem.h>
70 # include <openssl/pkcs12.h>
71 
72 # define PROG pkcs12_main
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,
86                           char *pass, int passlen, int options,
87                           char *pempass);
88 int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass,
89                          int passlen, int options, char *pempass);
90 int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,
91                   const char *name);
92 void hex_prin(BIO *out, unsigned char *buf, int len);
93 int alg_print(BIO *x, X509_ALGOR *alg);
94 int cert_load(BIO *in, STACK_OF(X509) *sk);
95 static int set_pbe(BIO *err, int *ppbe, const char *str);
96 
97 int MAIN(int, char **);
98 
99 int MAIN(int argc, char **argv)
100 {
101     ENGINE *e = NULL;
102     char *infile = NULL, *outfile = NULL, *keyname = NULL;
103     char *certfile = NULL;
104     BIO *in = NULL, *out = NULL;
105     char **args;
106     char *name = NULL;
107     char *csp_name = NULL;
108     int add_lmk = 0;
109     PKCS12 *p12 = NULL;
110     char pass[50], macpass[50];
111     int export_cert = 0;
112     int options = 0;
113     int chain = 0;
114     int badarg = 0;
115     int iter = PKCS12_DEFAULT_ITER;
116     int maciter = PKCS12_DEFAULT_ITER;
117     int twopass = 0;
118     int keytype = 0;
119     int cert_pbe;
120     int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
121     int ret = 1;
122     int macver = 1;
123     int noprompt = 0;
124     STACK_OF(OPENSSL_STRING) *canames = NULL;
125     char *cpass = NULL, *mpass = NULL;
126     char *passargin = NULL, *passargout = NULL, *passarg = NULL;
127     char *passin = NULL, *passout = NULL;
128     char *inrand = NULL;
129     char *macalg = NULL;
130     char *CApath = NULL, *CAfile = NULL;
131 # ifndef OPENSSL_NO_ENGINE
132     char *engine = NULL;
133 # endif
134 
135     apps_startup();
136 
137 # ifdef OPENSSL_FIPS
138     if (FIPS_mode())
139         cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
140     else
141 # endif
142         cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
143 
144     enc = EVP_des_ede3_cbc();
145     if (bio_err == NULL)
146         bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
147 
148     if (!load_config(bio_err, NULL))
149         goto end;
150 
151     args = argv + 1;
152 
153     while (*args) {
154         if (*args[0] == '-') {
155             if (!strcmp(*args, "-nokeys"))
156                 options |= NOKEYS;
157             else if (!strcmp(*args, "-keyex"))
158                 keytype = KEY_EX;
159             else if (!strcmp(*args, "-keysig"))
160                 keytype = KEY_SIG;
161             else if (!strcmp(*args, "-nocerts"))
162                 options |= NOCERTS;
163             else if (!strcmp(*args, "-clcerts"))
164                 options |= CLCERTS;
165             else if (!strcmp(*args, "-cacerts"))
166                 options |= CACERTS;
167             else if (!strcmp(*args, "-noout"))
168                 options |= (NOKEYS | NOCERTS);
169             else if (!strcmp(*args, "-info"))
170                 options |= INFO;
171             else if (!strcmp(*args, "-chain"))
172                 chain = 1;
173             else if (!strcmp(*args, "-twopass"))
174                 twopass = 1;
175             else if (!strcmp(*args, "-nomacver"))
176                 macver = 0;
177             else if (!strcmp(*args, "-descert"))
178                 cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
179             else if (!strcmp(*args, "-export"))
180                 export_cert = 1;
181             else if (!strcmp(*args, "-des"))
182                 enc = EVP_des_cbc();
183             else if (!strcmp(*args, "-des3"))
184                 enc = EVP_des_ede3_cbc();
185 # ifndef OPENSSL_NO_IDEA
186             else if (!strcmp(*args, "-idea"))
187                 enc = EVP_idea_cbc();
188 # endif
189 # ifndef OPENSSL_NO_SEED
190             else if (!strcmp(*args, "-seed"))
191                 enc = EVP_seed_cbc();
192 # endif
193 # ifndef OPENSSL_NO_AES
194             else if (!strcmp(*args, "-aes128"))
195                 enc = EVP_aes_128_cbc();
196             else if (!strcmp(*args, "-aes192"))
197                 enc = EVP_aes_192_cbc();
198             else if (!strcmp(*args, "-aes256"))
199                 enc = EVP_aes_256_cbc();
200 # endif
201 # ifndef OPENSSL_NO_CAMELLIA
202             else if (!strcmp(*args, "-camellia128"))
203                 enc = EVP_camellia_128_cbc();
204             else if (!strcmp(*args, "-camellia192"))
205                 enc = EVP_camellia_192_cbc();
206             else if (!strcmp(*args, "-camellia256"))
207                 enc = EVP_camellia_256_cbc();
208 # endif
209             else if (!strcmp(*args, "-noiter"))
210                 iter = 1;
211             else if (!strcmp(*args, "-maciter"))
212                 maciter = PKCS12_DEFAULT_ITER;
213             else if (!strcmp(*args, "-nomaciter"))
214                 maciter = 1;
215             else if (!strcmp(*args, "-nomac"))
216                 maciter = -1;
217             else if (!strcmp(*args, "-macalg"))
218                 if (args[1]) {
219                     args++;
220                     macalg = *args;
221                 } else
222                     badarg = 1;
223             else if (!strcmp(*args, "-nodes"))
224                 enc = NULL;
225             else if (!strcmp(*args, "-certpbe")) {
226                 if (!set_pbe(bio_err, &cert_pbe, *++args))
227                     badarg = 1;
228             } else if (!strcmp(*args, "-keypbe")) {
229                 if (!set_pbe(bio_err, &key_pbe, *++args))
230                     badarg = 1;
231             } else if (!strcmp(*args, "-rand")) {
232                 if (args[1]) {
233                     args++;
234                     inrand = *args;
235                 } else
236                     badarg = 1;
237             } else if (!strcmp(*args, "-inkey")) {
238                 if (args[1]) {
239                     args++;
240                     keyname = *args;
241                 } else
242                     badarg = 1;
243             } else if (!strcmp(*args, "-certfile")) {
244                 if (args[1]) {
245                     args++;
246                     certfile = *args;
247                 } else
248                     badarg = 1;
249             } else if (!strcmp(*args, "-name")) {
250                 if (args[1]) {
251                     args++;
252                     name = *args;
253                 } else
254                     badarg = 1;
255             } else if (!strcmp(*args, "-LMK"))
256                 add_lmk = 1;
257             else if (!strcmp(*args, "-CSP")) {
258                 if (args[1]) {
259                     args++;
260                     csp_name = *args;
261                 } else
262                     badarg = 1;
263             } else if (!strcmp(*args, "-caname")) {
264                 if (args[1]) {
265                     args++;
266                     if (!canames)
267                         canames = sk_OPENSSL_STRING_new_null();
268                     sk_OPENSSL_STRING_push(canames, *args);
269                 } else
270                     badarg = 1;
271             } else if (!strcmp(*args, "-in")) {
272                 if (args[1]) {
273                     args++;
274                     infile = *args;
275                 } else
276                     badarg = 1;
277             } else if (!strcmp(*args, "-out")) {
278                 if (args[1]) {
279                     args++;
280                     outfile = *args;
281                 } else
282                     badarg = 1;
283             } else if (!strcmp(*args, "-passin")) {
284                 if (args[1]) {
285                     args++;
286                     passargin = *args;
287                 } else
288                     badarg = 1;
289             } else if (!strcmp(*args, "-passout")) {
290                 if (args[1]) {
291                     args++;
292                     passargout = *args;
293                 } else
294                     badarg = 1;
295             } else if (!strcmp(*args, "-password")) {
296                 if (args[1]) {
297                     args++;
298                     passarg = *args;
299                     noprompt = 1;
300                 } else
301                     badarg = 1;
302             } else if (!strcmp(*args, "-CApath")) {
303                 if (args[1]) {
304                     args++;
305                     CApath = *args;
306                 } else
307                     badarg = 1;
308             } else if (!strcmp(*args, "-CAfile")) {
309                 if (args[1]) {
310                     args++;
311                     CAfile = *args;
312                 } else
313                     badarg = 1;
314 # ifndef OPENSSL_NO_ENGINE
315             } else if (!strcmp(*args, "-engine")) {
316                 if (args[1]) {
317                     args++;
318                     engine = *args;
319                 } else
320                     badarg = 1;
321 # endif
322             } else
323                 badarg = 1;
324 
325         } else
326             badarg = 1;
327         args++;
328     }
329 
330     if (badarg) {
331         BIO_printf(bio_err, "Usage: pkcs12 [options]\n");
332         BIO_printf(bio_err, "where options are\n");
333         BIO_printf(bio_err, "-export       output PKCS12 file\n");
334         BIO_printf(bio_err, "-chain        add certificate chain\n");
335         BIO_printf(bio_err, "-inkey file   private key if not infile\n");
336         BIO_printf(bio_err, "-certfile f   add all certs in f\n");
337         BIO_printf(bio_err, "-CApath arg   - PEM format directory of CA's\n");
338         BIO_printf(bio_err, "-CAfile arg   - PEM format file of CA's\n");
339         BIO_printf(bio_err, "-name \"name\"  use name as friendly name\n");
340         BIO_printf(bio_err,
341                    "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
342         BIO_printf(bio_err, "-in  infile   input filename\n");
343         BIO_printf(bio_err, "-out outfile  output filename\n");
344         BIO_printf(bio_err,
345                    "-noout        don't output anything, just verify.\n");
346         BIO_printf(bio_err, "-nomacver     don't verify MAC.\n");
347         BIO_printf(bio_err, "-nocerts      don't output certificates.\n");
348         BIO_printf(bio_err,
349                    "-clcerts      only output client certificates.\n");
350         BIO_printf(bio_err, "-cacerts      only output CA certificates.\n");
351         BIO_printf(bio_err, "-nokeys       don't output private keys.\n");
352         BIO_printf(bio_err,
353                    "-info         give info about PKCS#12 structure.\n");
354         BIO_printf(bio_err, "-des          encrypt private keys with DES\n");
355         BIO_printf(bio_err,
356                    "-des3         encrypt private keys with triple DES (default)\n");
357 # ifndef OPENSSL_NO_IDEA
358         BIO_printf(bio_err, "-idea         encrypt private keys with idea\n");
359 # endif
360 # ifndef OPENSSL_NO_SEED
361         BIO_printf(bio_err, "-seed         encrypt private keys with seed\n");
362 # endif
363 # ifndef OPENSSL_NO_AES
364         BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");
365         BIO_printf(bio_err,
366                    "              encrypt PEM output with cbc aes\n");
367 # endif
368 # ifndef OPENSSL_NO_CAMELLIA
369         BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");
370         BIO_printf(bio_err,
371                    "              encrypt PEM output with cbc camellia\n");
372 # endif
373         BIO_printf(bio_err, "-nodes        don't encrypt private keys\n");
374         BIO_printf(bio_err, "-noiter       don't use encryption iteration\n");
375         BIO_printf(bio_err, "-nomaciter    don't use MAC iteration\n");
376         BIO_printf(bio_err, "-maciter      use MAC iteration\n");
377         BIO_printf(bio_err, "-nomac        don't generate MAC\n");
378         BIO_printf(bio_err,
379                    "-twopass      separate MAC, encryption passwords\n");
380         BIO_printf(bio_err,
381                    "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
382         BIO_printf(bio_err,
383                    "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
384         BIO_printf(bio_err,
385                    "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
386         BIO_printf(bio_err,
387                    "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
388         BIO_printf(bio_err, "-keyex        set MS key exchange type\n");
389         BIO_printf(bio_err, "-keysig       set MS key signature type\n");
390         BIO_printf(bio_err,
391                    "-password p   set import/export password source\n");
392         BIO_printf(bio_err, "-passin p     input file pass phrase source\n");
393         BIO_printf(bio_err, "-passout p    output file pass phrase source\n");
394 # ifndef OPENSSL_NO_ENGINE
395         BIO_printf(bio_err,
396                    "-engine e     use engine e, possibly a hardware device.\n");
397 # endif
398         BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
399                    LIST_SEPARATOR_CHAR);
400         BIO_printf(bio_err,
401                    "              load the file (or the files in the directory) into\n");
402         BIO_printf(bio_err, "              the random number generator\n");
403         BIO_printf(bio_err, "-CSP name     Microsoft CSP name\n");
404         BIO_printf(bio_err,
405                    "-LMK          Add local machine keyset attribute to private key\n");
406         goto end;
407     }
408 # ifndef OPENSSL_NO_ENGINE
409     e = setup_engine(bio_err, engine, 0);
410 # endif
411 
412     if (passarg) {
413         if (export_cert)
414             passargout = passarg;
415         else
416             passargin = passarg;
417     }
418 
419     if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
420         BIO_printf(bio_err, "Error getting passwords\n");
421         goto end;
422     }
423 
424     if (!cpass) {
425         if (export_cert)
426             cpass = passout;
427         else
428             cpass = passin;
429     }
430 
431     if (cpass) {
432         mpass = cpass;
433         noprompt = 1;
434     } else {
435         cpass = pass;
436         mpass = macpass;
437     }
438 
439     if (export_cert || inrand) {
440         app_RAND_load_file(NULL, bio_err, (inrand != NULL));
441         if (inrand != NULL)
442             BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
443                        app_RAND_load_files(inrand));
444     }
445     ERR_load_crypto_strings();
446 
447 # ifdef CRYPTO_MDEBUG
448     CRYPTO_push_info("read files");
449 # endif
450 
451     if (!infile)
452         in = BIO_new_fp(stdin, BIO_NOCLOSE);
453     else
454         in = BIO_new_file(infile, "rb");
455     if (!in) {
456         BIO_printf(bio_err, "Error opening input file %s\n",
457                    infile ? infile : "<stdin>");
458         perror(infile);
459         goto end;
460     }
461 # ifdef CRYPTO_MDEBUG
462     CRYPTO_pop_info();
463     CRYPTO_push_info("write files");
464 # endif
465 
466     if (!outfile) {
467         out = BIO_new_fp(stdout, BIO_NOCLOSE);
468 # ifdef OPENSSL_SYS_VMS
469         {
470             BIO *tmpbio = BIO_new(BIO_f_linebuffer());
471             out = BIO_push(tmpbio, out);
472         }
473 # endif
474     } else
475         out = BIO_new_file(outfile, "wb");
476     if (!out) {
477         BIO_printf(bio_err, "Error opening output file %s\n",
478                    outfile ? outfile : "<stdout>");
479         perror(outfile);
480         goto end;
481     }
482     if (twopass) {
483 # ifdef CRYPTO_MDEBUG
484         CRYPTO_push_info("read MAC password");
485 # endif
486         if (EVP_read_pw_string
487             (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) {
488             BIO_printf(bio_err, "Can't read Password\n");
489             goto end;
490         }
491 # ifdef CRYPTO_MDEBUG
492         CRYPTO_pop_info();
493 # endif
494     }
495 
496     if (export_cert) {
497         EVP_PKEY *key = NULL;
498         X509 *ucert = NULL, *x = NULL;
499         STACK_OF(X509) *certs = NULL;
500         const EVP_MD *macmd = NULL;
501         unsigned char *catmp = NULL;
502         int i;
503 
504         if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
505             BIO_printf(bio_err, "Nothing to do!\n");
506             goto export_end;
507         }
508 
509         if (options & NOCERTS)
510             chain = 0;
511 
512 # ifdef CRYPTO_MDEBUG
513         CRYPTO_push_info("process -export_cert");
514         CRYPTO_push_info("reading private key");
515 # endif
516         if (!(options & NOKEYS)) {
517             key = load_key(bio_err, keyname ? keyname : infile,
518                            FORMAT_PEM, 1, passin, e, "private key");
519             if (!key)
520                 goto export_end;
521         }
522 # ifdef CRYPTO_MDEBUG
523         CRYPTO_pop_info();
524         CRYPTO_push_info("reading certs from input");
525 # endif
526 
527         /* Load in all certs in input file */
528         if (!(options & NOCERTS)) {
529             certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
530                                "certificates");
531             if (!certs)
532                 goto export_end;
533 
534             if (key) {
535                 /* Look for matching private key */
536                 for (i = 0; i < sk_X509_num(certs); i++) {
537                     x = sk_X509_value(certs, i);
538                     if (X509_check_private_key(x, key)) {
539                         ucert = x;
540                         /* Zero keyid and alias */
541                         X509_keyid_set1(ucert, NULL, 0);
542                         X509_alias_set1(ucert, NULL, 0);
543                         /* Remove from list */
544                         (void)sk_X509_delete(certs, i);
545                         break;
546                     }
547                 }
548                 if (!ucert) {
549                     BIO_printf(bio_err,
550                                "No certificate matches private key\n");
551                     goto export_end;
552                 }
553             }
554 
555         }
556 # ifdef CRYPTO_MDEBUG
557         CRYPTO_pop_info();
558         CRYPTO_push_info("reading certs from input 2");
559 # endif
560 
561         /* Add any more certificates asked for */
562         if (certfile) {
563             STACK_OF(X509) *morecerts = NULL;
564             if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
565                                          NULL, e,
566                                          "certificates from certfile")))
567                 goto export_end;
568             while (sk_X509_num(morecerts) > 0)
569                 sk_X509_push(certs, sk_X509_shift(morecerts));
570             sk_X509_free(morecerts);
571         }
572 # ifdef CRYPTO_MDEBUG
573         CRYPTO_pop_info();
574         CRYPTO_push_info("reading certs from certfile");
575 # endif
576 
577 # ifdef CRYPTO_MDEBUG
578         CRYPTO_pop_info();
579         CRYPTO_push_info("building chain");
580 # endif
581 
582         /* If chaining get chain from user cert */
583         if (chain) {
584             int vret;
585             STACK_OF(X509) *chain2;
586             X509_STORE *store = X509_STORE_new();
587             if (!store) {
588                 BIO_printf(bio_err, "Memory allocation error\n");
589                 goto export_end;
590             }
591             if (!X509_STORE_load_locations(store, CAfile, CApath))
592                 X509_STORE_set_default_paths(store);
593 
594             vret = get_cert_chain(ucert, store, &chain2);
595             X509_STORE_free(store);
596 
597             if (!vret) {
598                 /* Exclude verified certificate */
599                 for (i = 1; i < sk_X509_num(chain2); i++)
600                     sk_X509_push(certs, sk_X509_value(chain2, i));
601                 /* Free first certificate */
602                 X509_free(sk_X509_value(chain2, 0));
603                 sk_X509_free(chain2);
604             } else {
605                 if (vret >= 0)
606                     BIO_printf(bio_err, "Error %s getting chain.\n",
607                                X509_verify_cert_error_string(vret));
608                 else
609                     ERR_print_errors(bio_err);
610                 goto export_end;
611             }
612         }
613 
614         /* Add any CA names */
615 
616         for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
617             catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
618             X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
619         }
620 
621         if (csp_name && key)
622             EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
623                                       MBSTRING_ASC, (unsigned char *)csp_name,
624                                       -1);
625 
626         if (add_lmk && key)
627             EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
628 
629 # ifdef CRYPTO_MDEBUG
630         CRYPTO_pop_info();
631         CRYPTO_push_info("reading password");
632 # endif
633 
634         if (!noprompt &&
635             EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:",
636                                1)) {
637             BIO_printf(bio_err, "Can't read Password\n");
638             goto export_end;
639         }
640         if (!twopass)
641             BUF_strlcpy(macpass, pass, sizeof macpass);
642 
643 # ifdef CRYPTO_MDEBUG
644         CRYPTO_pop_info();
645         CRYPTO_push_info("creating PKCS#12 structure");
646 # endif
647 
648         p12 = PKCS12_create(cpass, name, key, ucert, certs,
649                             key_pbe, cert_pbe, iter, -1, keytype);
650 
651         if (!p12) {
652             ERR_print_errors(bio_err);
653             goto export_end;
654         }
655 
656         if (macalg) {
657             macmd = EVP_get_digestbyname(macalg);
658             if (!macmd) {
659                 BIO_printf(bio_err, "Unknown digest algorithm %s\n", macalg);
660             }
661         }
662 
663         if (maciter != -1)
664             PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
665 
666 # ifdef CRYPTO_MDEBUG
667         CRYPTO_pop_info();
668         CRYPTO_push_info("writing pkcs12");
669 # endif
670 
671         i2d_PKCS12_bio(out, p12);
672 
673         ret = 0;
674 
675  export_end:
676 # ifdef CRYPTO_MDEBUG
677         CRYPTO_pop_info();
678         CRYPTO_pop_info();
679         CRYPTO_push_info("process -export_cert: freeing");
680 # endif
681 
682         if (key)
683             EVP_PKEY_free(key);
684         if (certs)
685             sk_X509_pop_free(certs, X509_free);
686         if (ucert)
687             X509_free(ucert);
688 
689 # ifdef CRYPTO_MDEBUG
690         CRYPTO_pop_info();
691 # endif
692         goto end;
693 
694     }
695 
696     if (!(p12 = d2i_PKCS12_bio(in, NULL))) {
697         ERR_print_errors(bio_err);
698         goto end;
699     }
700 # ifdef CRYPTO_MDEBUG
701     CRYPTO_push_info("read import password");
702 # endif
703     if (!noprompt
704         && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:",
705                               0)) {
706         BIO_printf(bio_err, "Can't read Password\n");
707         goto end;
708     }
709 # ifdef CRYPTO_MDEBUG
710     CRYPTO_pop_info();
711 # endif
712 
713     if (!twopass)
714         BUF_strlcpy(macpass, pass, sizeof macpass);
715 
716     if ((options & INFO) && p12->mac)
717         BIO_printf(bio_err, "MAC Iteration %ld\n",
718                    p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1);
719     if (macver) {
720 # ifdef CRYPTO_MDEBUG
721         CRYPTO_push_info("verify MAC");
722 # endif
723         /* If we enter empty password try no password first */
724         if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
725             /* If mac and crypto pass the same set it to NULL too */
726             if (!twopass)
727                 cpass = NULL;
728         } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
729             BIO_printf(bio_err, "Mac verify error: invalid password?\n");
730             ERR_print_errors(bio_err);
731             goto end;
732         }
733         BIO_printf(bio_err, "MAC verified OK\n");
734 # ifdef CRYPTO_MDEBUG
735         CRYPTO_pop_info();
736 # endif
737     }
738 # ifdef CRYPTO_MDEBUG
739     CRYPTO_push_info("output keys and certificates");
740 # endif
741     if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) {
742         BIO_printf(bio_err, "Error outputting keys and certificates\n");
743         ERR_print_errors(bio_err);
744         goto end;
745     }
746 # ifdef CRYPTO_MDEBUG
747     CRYPTO_pop_info();
748 # endif
749     ret = 0;
750  end:
751     if (p12)
752         PKCS12_free(p12);
753     if (export_cert || inrand)
754         app_RAND_write_file(NULL, bio_err);
755 # ifdef CRYPTO_MDEBUG
756     CRYPTO_remove_all_info();
757 # endif
758     BIO_free(in);
759     BIO_free_all(out);
760     if (canames)
761         sk_OPENSSL_STRING_free(canames);
762     if (passin)
763         OPENSSL_free(passin);
764     if (passout)
765         OPENSSL_free(passout);
766     apps_shutdown();
767     OPENSSL_EXIT(ret);
768 }
769 
770 int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass,
771                         int passlen, int options, char *pempass)
772 {
773     STACK_OF(PKCS7) *asafes = NULL;
774     STACK_OF(PKCS12_SAFEBAG) *bags;
775     int i, bagnid;
776     int ret = 0;
777     PKCS7 *p7;
778 
779     if (!(asafes = PKCS12_unpack_authsafes(p12)))
780         return 0;
781     for (i = 0; i < sk_PKCS7_num(asafes); i++) {
782         p7 = sk_PKCS7_value(asafes, i);
783         bagnid = OBJ_obj2nid(p7->type);
784         if (bagnid == NID_pkcs7_data) {
785             bags = PKCS12_unpack_p7data(p7);
786             if (options & INFO)
787                 BIO_printf(bio_err, "PKCS7 Data\n");
788         } else if (bagnid == NID_pkcs7_encrypted) {
789             if (options & INFO) {
790                 BIO_printf(bio_err, "PKCS7 Encrypted data: ");
791                 alg_print(bio_err, p7->d.encrypted->enc_data->algorithm);
792             }
793             bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
794         } else
795             continue;
796         if (!bags)
797             goto err;
798         if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
799                                    options, pempass)) {
800             sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
801             goto err;
802         }
803         sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
804         bags = NULL;
805     }
806     ret = 1;
807 
808  err:
809 
810     if (asafes)
811         sk_PKCS7_pop_free(asafes, PKCS7_free);
812     return ret;
813 }
814 
815 int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
816                           char *pass, int passlen, int options, char *pempass)
817 {
818     int i;
819     for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
820         if (!dump_certs_pkeys_bag(out,
821                                   sk_PKCS12_SAFEBAG_value(bags, i),
822                                   pass, passlen, options, pempass))
823             return 0;
824     }
825     return 1;
826 }
827 
828 int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass,
829                          int passlen, int options, char *pempass)
830 {
831     EVP_PKEY *pkey;
832     PKCS8_PRIV_KEY_INFO *p8;
833     X509 *x509;
834 
835     switch (M_PKCS12_bag_type(bag)) {
836     case NID_keyBag:
837         if (options & INFO)
838             BIO_printf(bio_err, "Key bag\n");
839         if (options & NOKEYS)
840             return 1;
841         print_attribs(out, bag->attrib, "Bag Attributes");
842         p8 = bag->value.keybag;
843         if (!(pkey = EVP_PKCS82PKEY(p8)))
844             return 0;
845         print_attribs(out, p8->attributes, "Key Attributes");
846         PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
847         EVP_PKEY_free(pkey);
848         break;
849 
850     case NID_pkcs8ShroudedKeyBag:
851         if (options & INFO) {
852             BIO_printf(bio_err, "Shrouded Keybag: ");
853             alg_print(bio_err, bag->value.shkeybag->algor);
854         }
855         if (options & NOKEYS)
856             return 1;
857         print_attribs(out, bag->attrib, "Bag Attributes");
858         if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
859             return 0;
860         if (!(pkey = EVP_PKCS82PKEY(p8))) {
861             PKCS8_PRIV_KEY_INFO_free(p8);
862             return 0;
863         }
864         print_attribs(out, p8->attributes, "Key Attributes");
865         PKCS8_PRIV_KEY_INFO_free(p8);
866         PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
867         EVP_PKEY_free(pkey);
868         break;
869 
870     case NID_certBag:
871         if (options & INFO)
872             BIO_printf(bio_err, "Certificate bag\n");
873         if (options & NOCERTS)
874             return 1;
875         if (PKCS12_get_attr(bag, NID_localKeyID)) {
876             if (options & CACERTS)
877                 return 1;
878         } else if (options & CLCERTS)
879             return 1;
880         print_attribs(out, bag->attrib, "Bag Attributes");
881         if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
882             return 1;
883         if (!(x509 = PKCS12_certbag2x509(bag)))
884             return 0;
885         dump_cert_text(out, x509);
886         PEM_write_bio_X509(out, x509);
887         X509_free(x509);
888         break;
889 
890     case NID_safeContentsBag:
891         if (options & INFO)
892             BIO_printf(bio_err, "Safe Contents bag\n");
893         print_attribs(out, bag->attrib, "Bag Attributes");
894         return dump_certs_pkeys_bags(out, bag->value.safes, pass,
895                                      passlen, options, pempass);
896 
897     default:
898         BIO_printf(bio_err, "Warning unsupported bag type: ");
899         i2a_ASN1_OBJECT(bio_err, bag->type);
900         BIO_printf(bio_err, "\n");
901         return 1;
902         break;
903     }
904     return 1;
905 }
906 
907 /* Given a single certificate return a verified chain or NULL if error */
908 
909 /* Hope this is OK .... */
910 
911 int get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
912 {
913     X509_STORE_CTX store_ctx;
914     STACK_OF(X509) *chn;
915     int i = 0;
916 
917     /*
918      * FIXME: Should really check the return status of X509_STORE_CTX_init
919      * for an error, but how that fits into the return value of this function
920      * is less obvious.
921      */
922     X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
923     if (X509_verify_cert(&store_ctx) <= 0) {
924         i = X509_STORE_CTX_get_error(&store_ctx);
925         if (i == 0)
926             /*
927              * avoid returning 0 if X509_verify_cert() did not set an
928              * appropriate error value in the context
929              */
930             i = -1;
931         chn = NULL;
932         goto err;
933     } else
934         chn = X509_STORE_CTX_get1_chain(&store_ctx);
935  err:
936     X509_STORE_CTX_cleanup(&store_ctx);
937     *chain = chn;
938 
939     return i;
940 }
941 
942 int alg_print(BIO *x, X509_ALGOR *alg)
943 {
944     PBEPARAM *pbe;
945     const unsigned char *p;
946     p = alg->parameter->value.sequence->data;
947     pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
948     if (!pbe)
949         return 1;
950     BIO_printf(bio_err, "%s, Iteration %ld\n",
951                OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
952                ASN1_INTEGER_get(pbe->iter));
953     PBEPARAM_free(pbe);
954     return 1;
955 }
956 
957 /* Load all certificates from a given file */
958 
959 int cert_load(BIO *in, STACK_OF(X509) *sk)
960 {
961     int ret;
962     X509 *cert;
963     ret = 0;
964 # ifdef CRYPTO_MDEBUG
965     CRYPTO_push_info("cert_load(): reading one cert");
966 # endif
967     while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
968 # ifdef CRYPTO_MDEBUG
969         CRYPTO_pop_info();
970 # endif
971         ret = 1;
972         sk_X509_push(sk, cert);
973 # ifdef CRYPTO_MDEBUG
974         CRYPTO_push_info("cert_load(): reading one cert");
975 # endif
976     }
977 # ifdef CRYPTO_MDEBUG
978     CRYPTO_pop_info();
979 # endif
980     if (ret)
981         ERR_clear_error();
982     return ret;
983 }
984 
985 /* Generalised attribute print: handle PKCS#8 and bag attributes */
986 
987 int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,
988                   const char *name)
989 {
990     X509_ATTRIBUTE *attr;
991     ASN1_TYPE *av;
992     char *value;
993     int i, attr_nid;
994     if (!attrlst) {
995         BIO_printf(out, "%s: <No Attributes>\n", name);
996         return 1;
997     }
998     if (!sk_X509_ATTRIBUTE_num(attrlst)) {
999         BIO_printf(out, "%s: <Empty Attributes>\n", name);
1000         return 1;
1001     }
1002     BIO_printf(out, "%s\n", name);
1003     for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
1004         attr = sk_X509_ATTRIBUTE_value(attrlst, i);
1005         attr_nid = OBJ_obj2nid(attr->object);
1006         BIO_printf(out, "    ");
1007         if (attr_nid == NID_undef) {
1008             i2a_ASN1_OBJECT(out, attr->object);
1009             BIO_printf(out, ": ");
1010         } else
1011             BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
1012 
1013         if (sk_ASN1_TYPE_num(attr->value.set)) {
1014             av = sk_ASN1_TYPE_value(attr->value.set, 0);
1015             switch (av->type) {
1016             case V_ASN1_BMPSTRING:
1017                 value = OPENSSL_uni2asc(av->value.bmpstring->data,
1018                                         av->value.bmpstring->length);
1019                 BIO_printf(out, "%s\n", value);
1020                 OPENSSL_free(value);
1021                 break;
1022 
1023             case V_ASN1_OCTET_STRING:
1024                 hex_prin(out, av->value.octet_string->data,
1025                          av->value.octet_string->length);
1026                 BIO_printf(out, "\n");
1027                 break;
1028 
1029             case V_ASN1_BIT_STRING:
1030                 hex_prin(out, av->value.bit_string->data,
1031                          av->value.bit_string->length);
1032                 BIO_printf(out, "\n");
1033                 break;
1034 
1035             default:
1036                 BIO_printf(out, "<Unsupported tag %d>\n", av->type);
1037                 break;
1038             }
1039         } else
1040             BIO_printf(out, "<No Values>\n");
1041     }
1042     return 1;
1043 }
1044 
1045 void hex_prin(BIO *out, unsigned char *buf, int len)
1046 {
1047     int i;
1048     for (i = 0; i < len; i++)
1049         BIO_printf(out, "%02X ", buf[i]);
1050 }
1051 
1052 static int set_pbe(BIO *err, int *ppbe, const char *str)
1053 {
1054     if (!str)
1055         return 0;
1056     if (!strcmp(str, "NONE")) {
1057         *ppbe = -1;
1058         return 1;
1059     }
1060     *ppbe = OBJ_txt2nid(str);
1061     if (*ppbe == NID_undef) {
1062         BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
1063         return 0;
1064     }
1065     return 1;
1066 }
1067 
1068 #endif
1069