3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
6 /* ====================================================================
7 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
35 * 6. Redistributions of any form whatsoever must retain the following
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
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 * ====================================================================
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).
60 #include <openssl/opensslconf.h>
61 #if !defined(OPENSSL_NO_DES)
67 # include <openssl/crypto.h>
68 # include <openssl/err.h>
69 # include <openssl/pem.h>
70 # include <openssl/pkcs12.h>
72 # define PROG pkcs12_main
74 const EVP_CIPHER
*enc
;
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
,
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
,
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
);
97 int MAIN(int, char **);
99 int MAIN(int argc
, char **argv
)
102 char *infile
= NULL
, *outfile
= NULL
, *keyname
= NULL
;
103 char *certfile
= NULL
;
104 BIO
*in
= NULL
, *out
= NULL
;
107 char *csp_name
= NULL
;
110 char pass
[50], macpass
[50];
115 int iter
= PKCS12_DEFAULT_ITER
;
116 int maciter
= PKCS12_DEFAULT_ITER
;
119 int cert_pbe
= NID_pbe_WithSHA1And40BitRC2_CBC
;
120 int key_pbe
= NID_pbe_WithSHA1And3_Key_TripleDES_CBC
;
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
;
130 char *CApath
= NULL
, *CAfile
= NULL
;
131 # ifndef OPENSSL_NO_ENGINE
137 enc
= EVP_des_ede3_cbc();
139 bio_err
= BIO_new_fp(stderr
, BIO_NOCLOSE
);
141 if (!load_config(bio_err
, NULL
))
147 if (*args
[0] == '-') {
148 if (!strcmp(*args
, "-nokeys"))
150 else if (!strcmp(*args
, "-keyex"))
152 else if (!strcmp(*args
, "-keysig"))
154 else if (!strcmp(*args
, "-nocerts"))
156 else if (!strcmp(*args
, "-clcerts"))
158 else if (!strcmp(*args
, "-cacerts"))
160 else if (!strcmp(*args
, "-noout"))
161 options
|= (NOKEYS
| NOCERTS
);
162 else if (!strcmp(*args
, "-info"))
164 else if (!strcmp(*args
, "-chain"))
166 else if (!strcmp(*args
, "-twopass"))
168 else if (!strcmp(*args
, "-nomacver"))
170 else if (!strcmp(*args
, "-descert"))
171 cert_pbe
= NID_pbe_WithSHA1And3_Key_TripleDES_CBC
;
172 else if (!strcmp(*args
, "-export"))
174 else if (!strcmp(*args
, "-des"))
176 else if (!strcmp(*args
, "-des3"))
177 enc
= EVP_des_ede3_cbc();
178 # ifndef OPENSSL_NO_IDEA
179 else if (!strcmp(*args
, "-idea"))
180 enc
= EVP_idea_cbc();
182 # ifndef OPENSSL_NO_SEED
183 else if (!strcmp(*args
, "-seed"))
184 enc
= EVP_seed_cbc();
186 # ifndef OPENSSL_NO_AES
187 else if (!strcmp(*args
, "-aes128"))
188 enc
= EVP_aes_128_cbc();
189 else if (!strcmp(*args
, "-aes192"))
190 enc
= EVP_aes_192_cbc();
191 else if (!strcmp(*args
, "-aes256"))
192 enc
= EVP_aes_256_cbc();
194 # ifndef OPENSSL_NO_CAMELLIA
195 else if (!strcmp(*args
, "-camellia128"))
196 enc
= EVP_camellia_128_cbc();
197 else if (!strcmp(*args
, "-camellia192"))
198 enc
= EVP_camellia_192_cbc();
199 else if (!strcmp(*args
, "-camellia256"))
200 enc
= EVP_camellia_256_cbc();
202 else if (!strcmp(*args
, "-noiter"))
204 else if (!strcmp(*args
, "-maciter"))
205 maciter
= PKCS12_DEFAULT_ITER
;
206 else if (!strcmp(*args
, "-nomaciter"))
208 else if (!strcmp(*args
, "-nomac"))
210 else if (!strcmp(*args
, "-macalg"))
216 else if (!strcmp(*args
, "-nodes"))
218 else if (!strcmp(*args
, "-certpbe")) {
219 if (!set_pbe(bio_err
, &cert_pbe
, *++args
))
221 } else if (!strcmp(*args
, "-keypbe")) {
222 if (!set_pbe(bio_err
, &key_pbe
, *++args
))
224 } else if (!strcmp(*args
, "-rand")) {
230 } else if (!strcmp(*args
, "-inkey")) {
236 } else if (!strcmp(*args
, "-certfile")) {
242 } else if (!strcmp(*args
, "-name")) {
248 } else if (!strcmp(*args
, "-LMK"))
250 else if (!strcmp(*args
, "-CSP")) {
256 } else if (!strcmp(*args
, "-caname")) {
260 canames
= sk_OPENSSL_STRING_new_null();
261 sk_OPENSSL_STRING_push(canames
, *args
);
264 } else if (!strcmp(*args
, "-in")) {
270 } else if (!strcmp(*args
, "-out")) {
276 } else if (!strcmp(*args
, "-passin")) {
282 } else if (!strcmp(*args
, "-passout")) {
288 } else if (!strcmp(*args
, "-password")) {
295 } else if (!strcmp(*args
, "-CApath")) {
301 } else if (!strcmp(*args
, "-CAfile")) {
307 # ifndef OPENSSL_NO_ENGINE
308 } else if (!strcmp(*args
, "-engine")) {
324 BIO_printf(bio_err
, "Usage: pkcs12 [options]\n");
325 BIO_printf(bio_err
, "where options are\n");
326 BIO_printf(bio_err
, "-export output PKCS12 file\n");
327 BIO_printf(bio_err
, "-chain add certificate chain\n");
328 BIO_printf(bio_err
, "-inkey file private key if not infile\n");
329 BIO_printf(bio_err
, "-certfile f add all certs in f\n");
330 BIO_printf(bio_err
, "-CApath arg - PEM format directory of CA's\n");
331 BIO_printf(bio_err
, "-CAfile arg - PEM format file of CA's\n");
332 BIO_printf(bio_err
, "-name \"name\" use name as friendly name\n");
334 "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n");
335 BIO_printf(bio_err
, "-in infile input filename\n");
336 BIO_printf(bio_err
, "-out outfile output filename\n");
338 "-noout don't output anything, just verify.\n");
339 BIO_printf(bio_err
, "-nomacver don't verify MAC.\n");
340 BIO_printf(bio_err
, "-nocerts don't output certificates.\n");
342 "-clcerts only output client certificates.\n");
343 BIO_printf(bio_err
, "-cacerts only output CA certificates.\n");
344 BIO_printf(bio_err
, "-nokeys don't output private keys.\n");
346 "-info give info about PKCS#12 structure.\n");
347 BIO_printf(bio_err
, "-des encrypt private keys with DES\n");
349 "-des3 encrypt private keys with triple DES (default)\n");
350 # ifndef OPENSSL_NO_IDEA
351 BIO_printf(bio_err
, "-idea encrypt private keys with idea\n");
353 # ifndef OPENSSL_NO_SEED
354 BIO_printf(bio_err
, "-seed encrypt private keys with seed\n");
356 # ifndef OPENSSL_NO_AES
357 BIO_printf(bio_err
, "-aes128, -aes192, -aes256\n");
359 " encrypt PEM output with cbc aes\n");
361 # ifndef OPENSSL_NO_CAMELLIA
362 BIO_printf(bio_err
, "-camellia128, -camellia192, -camellia256\n");
364 " encrypt PEM output with cbc camellia\n");
366 BIO_printf(bio_err
, "-nodes don't encrypt private keys\n");
367 BIO_printf(bio_err
, "-noiter don't use encryption iteration\n");
368 BIO_printf(bio_err
, "-nomaciter don't use MAC iteration\n");
369 BIO_printf(bio_err
, "-maciter use MAC iteration\n");
370 BIO_printf(bio_err
, "-nomac don't generate MAC\n");
372 "-twopass separate MAC, encryption passwords\n");
374 "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
376 "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n");
378 "-keypbe alg specify private key PBE algorithm (default 3DES)\n");
380 "-macalg alg digest algorithm used in MAC (default SHA1)\n");
381 BIO_printf(bio_err
, "-keyex set MS key exchange type\n");
382 BIO_printf(bio_err
, "-keysig set MS key signature type\n");
384 "-password p set import/export password source\n");
385 BIO_printf(bio_err
, "-passin p input file pass phrase source\n");
386 BIO_printf(bio_err
, "-passout p output file pass phrase source\n");
387 # ifndef OPENSSL_NO_ENGINE
389 "-engine e use engine e, possibly a hardware device.\n");
391 BIO_printf(bio_err
, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR
,
392 LIST_SEPARATOR_CHAR
);
394 " load the file (or the files in the directory) into\n");
395 BIO_printf(bio_err
, " the random number generator\n");
396 BIO_printf(bio_err
, "-CSP name Microsoft CSP name\n");
398 "-LMK Add local machine keyset attribute to private key\n");
401 # ifndef OPENSSL_NO_ENGINE
402 e
= setup_engine(bio_err
, engine
, 0);
407 passargout
= passarg
;
412 if (!app_passwd(bio_err
, passargin
, passargout
, &passin
, &passout
)) {
413 BIO_printf(bio_err
, "Error getting passwords\n");
432 if (export_cert
|| inrand
) {
433 app_RAND_load_file(NULL
, bio_err
, (inrand
!= NULL
));
435 BIO_printf(bio_err
, "%ld semi-random bytes loaded\n",
436 app_RAND_load_files(inrand
));
438 ERR_load_crypto_strings();
440 # ifdef CRYPTO_MDEBUG
441 CRYPTO_push_info("read files");
445 in
= BIO_new_fp(stdin
, BIO_NOCLOSE
);
447 in
= BIO_new_file(infile
, "rb");
449 BIO_printf(bio_err
, "Error opening input file %s\n",
450 infile
? infile
: "<stdin>");
454 # ifdef CRYPTO_MDEBUG
456 CRYPTO_push_info("write files");
460 out
= BIO_new_fp(stdout
, BIO_NOCLOSE
);
461 # ifdef OPENSSL_SYS_VMS
463 BIO
*tmpbio
= BIO_new(BIO_f_linebuffer());
464 out
= BIO_push(tmpbio
, out
);
468 out
= BIO_new_file(outfile
, "wb");
470 BIO_printf(bio_err
, "Error opening output file %s\n",
471 outfile
? outfile
: "<stdout>");
476 # ifdef CRYPTO_MDEBUG
477 CRYPTO_push_info("read MAC password");
479 if (EVP_read_pw_string
480 (macpass
, sizeof macpass
, "Enter MAC Password:", export_cert
)) {
481 BIO_printf(bio_err
, "Can't read Password\n");
484 # ifdef CRYPTO_MDEBUG
490 EVP_PKEY
*key
= NULL
;
491 X509
*ucert
= NULL
, *x
= NULL
;
492 STACK_OF(X509
) *certs
= NULL
;
493 const EVP_MD
*macmd
= NULL
;
494 unsigned char *catmp
= NULL
;
497 if ((options
& (NOCERTS
| NOKEYS
)) == (NOCERTS
| NOKEYS
)) {
498 BIO_printf(bio_err
, "Nothing to do!\n");
502 if (options
& NOCERTS
)
505 # ifdef CRYPTO_MDEBUG
506 CRYPTO_push_info("process -export_cert");
507 CRYPTO_push_info("reading private key");
509 if (!(options
& NOKEYS
)) {
510 key
= load_key(bio_err
, keyname
? keyname
: infile
,
511 FORMAT_PEM
, 1, passin
, e
, "private key");
515 # ifdef CRYPTO_MDEBUG
517 CRYPTO_push_info("reading certs from input");
520 /* Load in all certs in input file */
521 if (!(options
& NOCERTS
)) {
522 certs
= load_certs(bio_err
, infile
, FORMAT_PEM
, NULL
, e
,
528 /* Look for matching private key */
529 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
530 x
= sk_X509_value(certs
, i
);
531 if (X509_check_private_key(x
, key
)) {
533 /* Zero keyid and alias */
534 X509_keyid_set1(ucert
, NULL
, 0);
535 X509_alias_set1(ucert
, NULL
, 0);
536 /* Remove from list */
537 (void)sk_X509_delete(certs
, i
);
543 "No certificate matches private key\n");
549 # ifdef CRYPTO_MDEBUG
551 CRYPTO_push_info("reading certs from input 2");
554 /* Add any more certificates asked for */
556 STACK_OF(X509
) *morecerts
= NULL
;
557 if (!(morecerts
= load_certs(bio_err
, certfile
, FORMAT_PEM
,
559 "certificates from certfile")))
561 while (sk_X509_num(morecerts
) > 0)
562 sk_X509_push(certs
, sk_X509_shift(morecerts
));
563 sk_X509_free(morecerts
);
565 # ifdef CRYPTO_MDEBUG
567 CRYPTO_push_info("reading certs from certfile");
570 # ifdef CRYPTO_MDEBUG
572 CRYPTO_push_info("building chain");
575 /* If chaining get chain from user cert */
578 STACK_OF(X509
) *chain2
;
579 X509_STORE
*store
= X509_STORE_new();
581 BIO_printf(bio_err
, "Memory allocation error\n");
584 if (!X509_STORE_load_locations(store
, CAfile
, CApath
))
585 X509_STORE_set_default_paths(store
);
587 vret
= get_cert_chain(ucert
, store
, &chain2
);
588 X509_STORE_free(store
);
591 /* Exclude verified certificate */
592 for (i
= 1; i
< sk_X509_num(chain2
); i
++)
593 sk_X509_push(certs
, sk_X509_value(chain2
, i
));
594 /* Free first certificate */
595 X509_free(sk_X509_value(chain2
, 0));
596 sk_X509_free(chain2
);
599 BIO_printf(bio_err
, "Error %s getting chain.\n",
600 X509_verify_cert_error_string(vret
));
602 ERR_print_errors(bio_err
);
607 /* Add any CA names */
609 for (i
= 0; i
< sk_OPENSSL_STRING_num(canames
); i
++) {
610 catmp
= (unsigned char *)sk_OPENSSL_STRING_value(canames
, i
);
611 X509_alias_set1(sk_X509_value(certs
, i
), catmp
, -1);
615 EVP_PKEY_add1_attr_by_NID(key
, NID_ms_csp_name
,
616 MBSTRING_ASC
, (unsigned char *)csp_name
,
620 EVP_PKEY_add1_attr_by_NID(key
, NID_LocalKeySet
, 0, NULL
, -1);
622 # ifdef CRYPTO_MDEBUG
624 CRYPTO_push_info("reading password");
628 EVP_read_pw_string(pass
, sizeof pass
, "Enter Export Password:",
630 BIO_printf(bio_err
, "Can't read Password\n");
634 BUF_strlcpy(macpass
, pass
, sizeof macpass
);
636 # ifdef CRYPTO_MDEBUG
638 CRYPTO_push_info("creating PKCS#12 structure");
641 p12
= PKCS12_create(cpass
, name
, key
, ucert
, certs
,
642 key_pbe
, cert_pbe
, iter
, -1, keytype
);
645 ERR_print_errors(bio_err
);
650 macmd
= EVP_get_digestbyname(macalg
);
652 BIO_printf(bio_err
, "Unknown digest algorithm %s\n", macalg
);
657 PKCS12_set_mac(p12
, mpass
, -1, NULL
, 0, maciter
, macmd
);
659 # ifdef CRYPTO_MDEBUG
661 CRYPTO_push_info("writing pkcs12");
664 i2d_PKCS12_bio(out
, p12
);
669 # ifdef CRYPTO_MDEBUG
672 CRYPTO_push_info("process -export_cert: freeing");
677 sk_X509_pop_free(certs
, X509_free
);
681 # ifdef CRYPTO_MDEBUG
688 if (!(p12
= d2i_PKCS12_bio(in
, NULL
))) {
689 ERR_print_errors(bio_err
);
692 # ifdef CRYPTO_MDEBUG
693 CRYPTO_push_info("read import password");
696 && EVP_read_pw_string(pass
, sizeof pass
, "Enter Import Password:",
698 BIO_printf(bio_err
, "Can't read Password\n");
701 # ifdef CRYPTO_MDEBUG
706 BUF_strlcpy(macpass
, pass
, sizeof macpass
);
708 if ((options
& INFO
) && p12
->mac
)
709 BIO_printf(bio_err
, "MAC Iteration %ld\n",
710 p12
->mac
->iter
? ASN1_INTEGER_get(p12
->mac
->iter
) : 1);
712 # ifdef CRYPTO_MDEBUG
713 CRYPTO_push_info("verify MAC");
715 /* If we enter empty password try no password first */
716 if (!mpass
[0] && PKCS12_verify_mac(p12
, NULL
, 0)) {
717 /* If mac and crypto pass the same set it to NULL too */
720 } else if (!PKCS12_verify_mac(p12
, mpass
, -1)) {
721 BIO_printf(bio_err
, "Mac verify error: invalid password?\n");
722 ERR_print_errors(bio_err
);
725 BIO_printf(bio_err
, "MAC verified OK\n");
726 # ifdef CRYPTO_MDEBUG
730 # ifdef CRYPTO_MDEBUG
731 CRYPTO_push_info("output keys and certificates");
733 if (!dump_certs_keys_p12(out
, p12
, cpass
, -1, options
, passout
)) {
734 BIO_printf(bio_err
, "Error outputting keys and certificates\n");
735 ERR_print_errors(bio_err
);
738 # ifdef CRYPTO_MDEBUG
744 if (export_cert
|| inrand
)
745 app_RAND_write_file(NULL
, bio_err
);
746 # ifdef CRYPTO_MDEBUG
747 CRYPTO_remove_all_info();
752 sk_OPENSSL_STRING_free(canames
);
754 OPENSSL_free(passin
);
756 OPENSSL_free(passout
);
761 int dump_certs_keys_p12(BIO
*out
, PKCS12
*p12
, char *pass
,
762 int passlen
, int options
, char *pempass
)
764 STACK_OF(PKCS7
) *asafes
= NULL
;
765 STACK_OF(PKCS12_SAFEBAG
) *bags
;
770 if (!(asafes
= PKCS12_unpack_authsafes(p12
)))
772 for (i
= 0; i
< sk_PKCS7_num(asafes
); i
++) {
773 p7
= sk_PKCS7_value(asafes
, i
);
774 bagnid
= OBJ_obj2nid(p7
->type
);
775 if (bagnid
== NID_pkcs7_data
) {
776 bags
= PKCS12_unpack_p7data(p7
);
778 BIO_printf(bio_err
, "PKCS7 Data\n");
779 } else if (bagnid
== NID_pkcs7_encrypted
) {
780 if (options
& INFO
) {
781 BIO_printf(bio_err
, "PKCS7 Encrypted data: ");
782 alg_print(bio_err
, p7
->d
.encrypted
->enc_data
->algorithm
);
784 bags
= PKCS12_unpack_p7encdata(p7
, pass
, passlen
);
789 if (!dump_certs_pkeys_bags(out
, bags
, pass
, passlen
,
791 sk_PKCS12_SAFEBAG_pop_free(bags
, PKCS12_SAFEBAG_free
);
794 sk_PKCS12_SAFEBAG_pop_free(bags
, PKCS12_SAFEBAG_free
);
800 sk_PKCS7_pop_free(asafes
, PKCS7_free
);
804 int dump_certs_pkeys_bags(BIO
*out
, STACK_OF(PKCS12_SAFEBAG
) *bags
,
805 char *pass
, int passlen
, int options
, char *pempass
)
808 for (i
= 0; i
< sk_PKCS12_SAFEBAG_num(bags
); i
++) {
809 if (!dump_certs_pkeys_bag(out
,
810 sk_PKCS12_SAFEBAG_value(bags
, i
),
811 pass
, passlen
, options
, pempass
))
817 int dump_certs_pkeys_bag(BIO
*out
, PKCS12_SAFEBAG
*bag
, char *pass
,
818 int passlen
, int options
, char *pempass
)
821 PKCS8_PRIV_KEY_INFO
*p8
;
824 switch (M_PKCS12_bag_type(bag
)) {
827 BIO_printf(bio_err
, "Key bag\n");
828 if (options
& NOKEYS
)
830 print_attribs(out
, bag
->attrib
, "Bag Attributes");
831 p8
= bag
->value
.keybag
;
832 if (!(pkey
= EVP_PKCS82PKEY(p8
)))
834 print_attribs(out
, p8
->attributes
, "Key Attributes");
835 PEM_write_bio_PrivateKey(out
, pkey
, enc
, NULL
, 0, NULL
, pempass
);
839 case NID_pkcs8ShroudedKeyBag
:
840 if (options
& INFO
) {
841 BIO_printf(bio_err
, "Shrouded Keybag: ");
842 alg_print(bio_err
, bag
->value
.shkeybag
->algor
);
844 if (options
& NOKEYS
)
846 print_attribs(out
, bag
->attrib
, "Bag Attributes");
847 if (!(p8
= PKCS12_decrypt_skey(bag
, pass
, passlen
)))
849 if (!(pkey
= EVP_PKCS82PKEY(p8
))) {
850 PKCS8_PRIV_KEY_INFO_free(p8
);
853 print_attribs(out
, p8
->attributes
, "Key Attributes");
854 PKCS8_PRIV_KEY_INFO_free(p8
);
855 PEM_write_bio_PrivateKey(out
, pkey
, enc
, NULL
, 0, NULL
, pempass
);
861 BIO_printf(bio_err
, "Certificate bag\n");
862 if (options
& NOCERTS
)
864 if (PKCS12_get_attr(bag
, NID_localKeyID
)) {
865 if (options
& CACERTS
)
867 } else if (options
& CLCERTS
)
869 print_attribs(out
, bag
->attrib
, "Bag Attributes");
870 if (M_PKCS12_cert_bag_type(bag
) != NID_x509Certificate
)
872 if (!(x509
= PKCS12_certbag2x509(bag
)))
874 dump_cert_text(out
, x509
);
875 PEM_write_bio_X509(out
, x509
);
879 case NID_safeContentsBag
:
881 BIO_printf(bio_err
, "Safe Contents bag\n");
882 print_attribs(out
, bag
->attrib
, "Bag Attributes");
883 return dump_certs_pkeys_bags(out
, bag
->value
.safes
, pass
,
884 passlen
, options
, pempass
);
887 BIO_printf(bio_err
, "Warning unsupported bag type: ");
888 i2a_ASN1_OBJECT(bio_err
, bag
->type
);
889 BIO_printf(bio_err
, "\n");
895 /* Given a single certificate return a verified chain or NULL if error */
897 /* Hope this is OK .... */
899 int get_cert_chain(X509
*cert
, X509_STORE
*store
, STACK_OF(X509
) **chain
)
901 X509_STORE_CTX store_ctx
;
906 * FIXME: Should really check the return status of X509_STORE_CTX_init
907 * for an error, but how that fits into the return value of this function
910 X509_STORE_CTX_init(&store_ctx
, store
, cert
, NULL
);
911 if (X509_verify_cert(&store_ctx
) <= 0) {
912 i
= X509_STORE_CTX_get_error(&store_ctx
);
915 * avoid returning 0 if X509_verify_cert() did not set an
916 * appropriate error value in the context
922 chn
= X509_STORE_CTX_get1_chain(&store_ctx
);
924 X509_STORE_CTX_cleanup(&store_ctx
);
930 int alg_print(BIO
*x
, X509_ALGOR
*alg
)
933 const unsigned char *p
;
934 p
= alg
->parameter
->value
.sequence
->data
;
935 pbe
= d2i_PBEPARAM(NULL
, &p
, alg
->parameter
->value
.sequence
->length
);
938 BIO_printf(bio_err
, "%s, Iteration %ld\n",
939 OBJ_nid2ln(OBJ_obj2nid(alg
->algorithm
)),
940 ASN1_INTEGER_get(pbe
->iter
));
945 /* Load all certificates from a given file */
947 int cert_load(BIO
*in
, STACK_OF(X509
) *sk
)
952 # ifdef CRYPTO_MDEBUG
953 CRYPTO_push_info("cert_load(): reading one cert");
955 while ((cert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
))) {
956 # ifdef CRYPTO_MDEBUG
960 sk_X509_push(sk
, cert
);
961 # ifdef CRYPTO_MDEBUG
962 CRYPTO_push_info("cert_load(): reading one cert");
965 # ifdef CRYPTO_MDEBUG
973 /* Generalised attribute print: handle PKCS#8 and bag attributes */
975 int print_attribs(BIO
*out
, STACK_OF(X509_ATTRIBUTE
) *attrlst
,
978 X509_ATTRIBUTE
*attr
;
983 BIO_printf(out
, "%s: <No Attributes>\n", name
);
986 if (!sk_X509_ATTRIBUTE_num(attrlst
)) {
987 BIO_printf(out
, "%s: <Empty Attributes>\n", name
);
990 BIO_printf(out
, "%s\n", name
);
991 for (i
= 0; i
< sk_X509_ATTRIBUTE_num(attrlst
); i
++) {
992 ASN1_OBJECT
*attr_obj
;
993 attr
= sk_X509_ATTRIBUTE_value(attrlst
, i
);
994 attr_obj
= X509_ATTRIBUTE_get0_object(attr
);
995 attr_nid
= OBJ_obj2nid(attr_obj
);
996 BIO_printf(out
, " ");
997 if (attr_nid
== NID_undef
) {
998 i2a_ASN1_OBJECT(out
, attr_obj
);
999 BIO_printf(out
, ": ");
1001 BIO_printf(out
, "%s: ", OBJ_nid2ln(attr_nid
));
1003 if (X509_ATTRIBUTE_count(attr
)) {
1004 av
= X509_ATTRIBUTE_get0_type(attr
, 0);
1006 case V_ASN1_BMPSTRING
:
1007 value
= OPENSSL_uni2asc(av
->value
.bmpstring
->data
,
1008 av
->value
.bmpstring
->length
);
1009 BIO_printf(out
, "%s\n", value
);
1010 OPENSSL_free(value
);
1013 case V_ASN1_OCTET_STRING
:
1014 hex_prin(out
, av
->value
.octet_string
->data
,
1015 av
->value
.octet_string
->length
);
1016 BIO_printf(out
, "\n");
1019 case V_ASN1_BIT_STRING
:
1020 hex_prin(out
, av
->value
.bit_string
->data
,
1021 av
->value
.bit_string
->length
);
1022 BIO_printf(out
, "\n");
1026 BIO_printf(out
, "<Unsupported tag %d>\n", av
->type
);
1030 BIO_printf(out
, "<No Values>\n");
1035 void hex_prin(BIO
*out
, unsigned char *buf
, int len
)
1038 for (i
= 0; i
< len
; i
++)
1039 BIO_printf(out
, "%02X ", buf
[i
]);
1042 static int set_pbe(BIO
*err
, int *ppbe
, const char *str
)
1046 if (!strcmp(str
, "NONE")) {
1050 *ppbe
= OBJ_txt2nid(str
);
1051 if (*ppbe
== NID_undef
) {
1052 BIO_printf(bio_err
, "Unknown PBE algorithm %s\n", str
);