1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/tsrc/topenssl/src/pkcs12.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,938 @@
1.4 +/* pkcs12.c */
1.5 +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
1.6 + * project.
1.7 + */
1.8 +/* ====================================================================
1.9 + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
1.10 + *
1.11 + * Redistribution and use in source and binary forms, with or without
1.12 + * modification, are permitted provided that the following conditions
1.13 + * are met:
1.14 + *
1.15 + * 1. Redistributions of source code must retain the above copyright
1.16 + * notice, this list of conditions and the following disclaimer.
1.17 + *
1.18 + * 2. Redistributions in binary form must reproduce the above copyright
1.19 + * notice, this list of conditions and the following disclaimer in
1.20 + * the documentation and/or other materials provided with the
1.21 + * distribution.
1.22 + *
1.23 + * 3. All advertising materials mentioning features or use of this
1.24 + * software must display the following acknowledgment:
1.25 + * "This product includes software developed by the OpenSSL Project
1.26 + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
1.27 + *
1.28 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.29 + * endorse or promote products derived from this software without
1.30 + * prior written permission. For written permission, please contact
1.31 + * licensing@OpenSSL.org.
1.32 + *
1.33 + * 5. Products derived from this software may not be called "OpenSSL"
1.34 + * nor may "OpenSSL" appear in their names without prior written
1.35 + * permission of the OpenSSL Project.
1.36 + *
1.37 + * 6. Redistributions of any form whatsoever must retain the following
1.38 + * acknowledgment:
1.39 + * "This product includes software developed by the OpenSSL Project
1.40 + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
1.41 + *
1.42 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.43 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.44 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.45 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.46 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.47 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.48 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.49 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.50 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.51 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.52 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.53 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.54 + * ====================================================================
1.55 + *
1.56 + * This product includes cryptographic software written by Eric Young
1.57 + * (eay@cryptsoft.com). This product includes software written by Tim
1.58 + * Hudson (tjh@cryptsoft.com).
1.59 + *
1.60 + */
1.61 +
1.62 +#include <openssl/opensslconf.h>
1.63 +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
1.64 +
1.65 +#include <stdio.h>
1.66 +#include <stdlib.h>
1.67 +#include <string.h>
1.68 +#include "apps.h"
1.69 +#include <openssl/crypto.h>
1.70 +#include <openssl/err.h>
1.71 +#include <openssl/pem.h>
1.72 +#include <openssl/pkcs12.h>
1.73 +
1.74 +#define PROG pkcs12_main
1.75 +
1.76 +const EVP_CIPHER *enc;
1.77 +
1.78 +
1.79 +#define NOKEYS 0x1
1.80 +#define NOCERTS 0x2
1.81 +#define INFO 0x4
1.82 +#define CLCERTS 0x8
1.83 +#define CACERTS 0x10
1.84 +
1.85 +int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain);
1.86 +int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass);
1.87 +int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass,
1.88 + int passlen, int options, char *pempass);
1.89 +int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass);
1.90 +int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name);
1.91 +void hex_prin(BIO *out, unsigned char *buf, int len);
1.92 +int alg_print(BIO *x, X509_ALGOR *alg);
1.93 +int cert_load(BIO *in, STACK_OF(X509) *sk);
1.94 +
1.95 +
1.96 +int MAIN(int, char **);
1.97 +
1.98 +int MAIN(int argc, char **argv)
1.99 +{
1.100 + ENGINE *e = NULL;
1.101 + char *infile=NULL, *outfile=NULL, *keyname = NULL;
1.102 + char *certfile=NULL;
1.103 + BIO *in=NULL, *out = NULL;
1.104 + char **args;
1.105 + char *name = NULL;
1.106 + char *csp_name = NULL;
1.107 + PKCS12 *p12 = NULL;
1.108 + char pass[50], macpass[50];
1.109 + int export_cert = 0;
1.110 + int options = 0;
1.111 + int chain = 0;
1.112 + int badarg = 0;
1.113 + int iter = PKCS12_DEFAULT_ITER;
1.114 + int maciter = PKCS12_DEFAULT_ITER;
1.115 + int twopass = 0;
1.116 + int keytype = 0;
1.117 + int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
1.118 + int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
1.119 + int ret = 1;
1.120 + int macver = 1;
1.121 + int noprompt = 0;
1.122 + STACK *canames = NULL;
1.123 + char *cpass = NULL, *mpass = NULL;
1.124 + char *passargin = NULL, *passargout = NULL, *passarg = NULL;
1.125 + char *passin = NULL, *passout = NULL;
1.126 + char *inrand = NULL;
1.127 + char *CApath = NULL, *CAfile = NULL;
1.128 +#ifndef OPENSSL_NO_ENGINE
1.129 + char *engine=NULL;
1.130 +#endif
1.131 +
1.132 + apps_startup();
1.133 +
1.134 + enc = EVP_des_ede3_cbc();
1.135 + if (bio_err == NULL )
1.136 + bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
1.137 + if (!load_config(bio_err, NULL))
1.138 + goto end;
1.139 +
1.140 + args = argv + 1;
1.141 +
1.142 +
1.143 + while (*args) {
1.144 + if (*args[0] == '-') {
1.145 + if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
1.146 + else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
1.147 + else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
1.148 + else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
1.149 + else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
1.150 + else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
1.151 + else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
1.152 + else if (!strcmp (*args, "-info")) options |= INFO;
1.153 + else if (!strcmp (*args, "-chain")) chain = 1;
1.154 + else if (!strcmp (*args, "-twopass")) twopass = 1;
1.155 + else if (!strcmp (*args, "-nomacver")) macver = 0;
1.156 + else if (!strcmp (*args, "-descert"))
1.157 + cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
1.158 + else if (!strcmp (*args, "-export")) export_cert = 1;
1.159 + else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
1.160 + else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
1.161 +#ifndef OPENSSL_NO_IDEA
1.162 + else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
1.163 +#endif
1.164 + else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
1.165 +#ifndef OPENSSL_NO_AES
1.166 + else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
1.167 + else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
1.168 + else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
1.169 +#endif
1.170 + else if (!strcmp (*args, "-noiter")) iter = 1;
1.171 + else if (!strcmp (*args, "-maciter"))
1.172 + maciter = PKCS12_DEFAULT_ITER;
1.173 + else if (!strcmp (*args, "-nomaciter"))
1.174 + maciter = 1;
1.175 + else if (!strcmp (*args, "-nomac"))
1.176 + maciter = -1;
1.177 + else if (!strcmp (*args, "-nodes")) enc=NULL;
1.178 + else if (!strcmp (*args, "-certpbe")) {
1.179 + if (args[1]) {
1.180 + args++;
1.181 + if (!strcmp(*args, "NONE"))
1.182 + cert_pbe = -1;
1.183 + else
1.184 + cert_pbe=OBJ_txt2nid(*args);
1.185 + if(cert_pbe == NID_undef) {
1.186 + BIO_printf(bio_err,
1.187 + "Unknown PBE algorithm %s\n", *args);
1.188 + badarg = 1;
1.189 + }
1.190 + } else badarg = 1;
1.191 + } else if (!strcmp (*args, "-keypbe")) {
1.192 + if (args[1]) {
1.193 + args++;
1.194 + if (!strcmp(*args, "NONE"))
1.195 + key_pbe = -1;
1.196 + else
1.197 + key_pbe=OBJ_txt2nid(*args);
1.198 + if(key_pbe == NID_undef) {
1.199 + BIO_printf(bio_err,
1.200 + "Unknown PBE algorithm %s\n", *args);
1.201 + badarg = 1;
1.202 + }
1.203 + } else badarg = 1;
1.204 + } else if (!strcmp (*args, "-rand")) {
1.205 + if (args[1]) {
1.206 + args++;
1.207 + inrand = *args;
1.208 + } else badarg = 1;
1.209 + } else if (!strcmp (*args, "-inkey")) {
1.210 + if (args[1]) {
1.211 + args++;
1.212 + keyname = *args;
1.213 + } else badarg = 1;
1.214 + } else if (!strcmp (*args, "-certfile")) {
1.215 + if (args[1]) {
1.216 + args++;
1.217 + certfile = *args;
1.218 + } else badarg = 1;
1.219 + } else if (!strcmp (*args, "-name")) {
1.220 + if (args[1]) {
1.221 + args++;
1.222 + name = *args;
1.223 + } else badarg = 1;
1.224 + } else if (!strcmp (*args, "-CSP")) {
1.225 + if (args[1]) {
1.226 + args++;
1.227 + csp_name = *args;
1.228 + } else badarg = 1;
1.229 + } else if (!strcmp (*args, "-caname")) {
1.230 + if (args[1]) {
1.231 + args++;
1.232 + if (!canames) canames = sk_new_null();
1.233 + sk_push(canames, *args);
1.234 + } else badarg = 1;
1.235 + } else if (!strcmp (*args, "-in")) {
1.236 + if (args[1]) {
1.237 + args++;
1.238 + infile = *args;
1.239 + } else badarg = 1;
1.240 + } else if (!strcmp (*args, "-out")) {
1.241 + if (args[1]) {
1.242 + args++;
1.243 + outfile = *args;
1.244 + } else badarg = 1;
1.245 + } else if (!strcmp(*args,"-passin")) {
1.246 + if (args[1]) {
1.247 + args++;
1.248 + passargin = *args;
1.249 + } else badarg = 1;
1.250 + } else if (!strcmp(*args,"-passout")) {
1.251 + if (args[1]) {
1.252 + args++;
1.253 + passargout = *args;
1.254 + } else badarg = 1;
1.255 + } else if (!strcmp (*args, "-password")) {
1.256 + if (args[1]) {
1.257 + args++;
1.258 + passarg = *args;
1.259 + noprompt = 1;
1.260 + } else badarg = 1;
1.261 + } else if (!strcmp(*args,"-CApath")) {
1.262 + if (args[1]) {
1.263 + args++;
1.264 + CApath = *args;
1.265 + } else badarg = 1;
1.266 + } else if (!strcmp(*args,"-CAfile")) {
1.267 + if (args[1]) {
1.268 + args++;
1.269 + CAfile = *args;
1.270 + } else badarg = 1;
1.271 +#ifndef OPENSSL_NO_ENGINE
1.272 + } else if (!strcmp(*args,"-engine")) {
1.273 + if (args[1]) {
1.274 + args++;
1.275 + engine = *args;
1.276 + } else badarg = 1;
1.277 +#endif
1.278 + } else badarg = 1;
1.279 +
1.280 + } else badarg = 1;
1.281 + args++;
1.282 + }
1.283 +
1.284 + if (badarg) {
1.285 + BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
1.286 + BIO_printf (bio_err, "where options are\n");
1.287 + BIO_printf (bio_err, "-export output PKCS12 file\n");
1.288 + BIO_printf (bio_err, "-chain add certificate chain\n");
1.289 + BIO_printf (bio_err, "-inkey file private key if not infile\n");
1.290 + BIO_printf (bio_err, "-certfile f add all certs in f\n");
1.291 + BIO_printf (bio_err, "-CApath arg - PEM format directory of CA's\n");
1.292 + BIO_printf (bio_err, "-CAfile arg - PEM format file of CA's\n");
1.293 + BIO_printf (bio_err, "-name \"name\" use name as friendly name\n");
1.294 + BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n");
1.295 + BIO_printf (bio_err, "-in infile input filename\n");
1.296 + BIO_printf (bio_err, "-out outfile output filename\n");
1.297 + BIO_printf (bio_err, "-noout don't output anything, just verify.\n");
1.298 + BIO_printf (bio_err, "-nomacver don't verify MAC.\n");
1.299 + BIO_printf (bio_err, "-nocerts don't output certificates.\n");
1.300 + BIO_printf (bio_err, "-clcerts only output client certificates.\n");
1.301 + BIO_printf (bio_err, "-cacerts only output CA certificates.\n");
1.302 + BIO_printf (bio_err, "-nokeys don't output private keys.\n");
1.303 + BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n");
1.304 + BIO_printf (bio_err, "-des encrypt private keys with DES\n");
1.305 + BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n");
1.306 +#ifndef OPENSSL_NO_IDEA
1.307 + BIO_printf (bio_err, "-idea encrypt private keys with idea\n");
1.308 +#endif
1.309 +#ifndef OPENSSL_NO_AES
1.310 + BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
1.311 + BIO_printf (bio_err, " encrypt PEM output with cbc aes\n");
1.312 +#endif
1.313 + BIO_printf (bio_err, "-nodes don't encrypt private keys\n");
1.314 + BIO_printf (bio_err, "-noiter don't use encryption iteration\n");
1.315 + BIO_printf (bio_err, "-maciter use MAC iteration\n");
1.316 + BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n");
1.317 + BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
1.318 + BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n");
1.319 + BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n");
1.320 + BIO_printf (bio_err, "-keyex set MS key exchange type\n");
1.321 + BIO_printf (bio_err, "-keysig set MS key signature type\n");
1.322 + BIO_printf (bio_err, "-password p set import/export password source\n");
1.323 + BIO_printf (bio_err, "-passin p input file pass phrase source\n");
1.324 + BIO_printf (bio_err, "-passout p output file pass phrase source\n");
1.325 +#ifndef OPENSSL_NO_ENGINE
1.326 + BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n");
1.327 +#endif
1.328 + BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
1.329 + BIO_printf(bio_err, " load the file (or the files in the directory) into\n");
1.330 + BIO_printf(bio_err, " the random number generator\n");
1.331 + goto end;
1.332 + }
1.333 +
1.334 +#ifndef OPENSSL_NO_ENGINE
1.335 + e = setup_engine(bio_err, engine, 0);
1.336 +#endif
1.337 +
1.338 + if(passarg) {
1.339 + if(export_cert) passargout = passarg;
1.340 + else passargin = passarg;
1.341 + }
1.342 +
1.343 + if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
1.344 + BIO_printf(bio_err, "Error getting passwords\n");
1.345 + goto end;
1.346 + }
1.347 +
1.348 + if(!cpass) {
1.349 + if(export_cert) cpass = passout;
1.350 + else cpass = passin;
1.351 + }
1.352 +
1.353 + if(cpass) {
1.354 + mpass = cpass;
1.355 + noprompt = 1;
1.356 + } else {
1.357 + cpass = pass;
1.358 + mpass = macpass;
1.359 + }
1.360 +
1.361 + if(export_cert || inrand) {
1.362 + app_RAND_load_file(NULL, bio_err, (inrand != NULL));
1.363 + if (inrand != NULL)
1.364 + BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
1.365 + app_RAND_load_files(inrand));
1.366 + }
1.367 + ERR_load_crypto_strings();
1.368 +
1.369 +#ifdef CRYPTO_MDEBUG
1.370 + CRYPTO_push_info("read files");
1.371 +#endif
1.372 + if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
1.373 + else in = BIO_new_file(infile, "rb");
1.374 + if (!in) {
1.375 + BIO_printf(bio_err, "Error opening input file %s\n",
1.376 + infile ? infile : "<stdin>");
1.377 + perror (infile);
1.378 + goto end;
1.379 + }
1.380 +
1.381 +#ifdef CRYPTO_MDEBUG
1.382 + CRYPTO_pop_info();
1.383 + CRYPTO_push_info("write files");
1.384 +#endif
1.385 +
1.386 + if (!outfile) {
1.387 + out = BIO_new_fp(stdout, BIO_NOCLOSE);
1.388 +
1.389 +#ifdef OPENSSL_SYS_VMS
1.390 + {
1.391 + BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1.392 + out = BIO_push(tmpbio, out);
1.393 + }
1.394 +#endif
1.395 + } else out = BIO_new_file(outfile, "wb");
1.396 + if (!out) {
1.397 + BIO_printf(bio_err, "Error opening output file %s\n",
1.398 + outfile ? outfile : "<stdout>");
1.399 + perror (outfile);
1.400 + goto end;
1.401 + }
1.402 + if (twopass) {
1.403 +#ifdef CRYPTO_MDEBUG
1.404 + CRYPTO_push_info("read MAC password");
1.405 +#endif
1.406 + if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert))
1.407 + {
1.408 + BIO_printf (bio_err, "Can't read Password\n");
1.409 + goto end;
1.410 + }
1.411 +#ifdef CRYPTO_MDEBUG
1.412 + CRYPTO_pop_info();
1.413 +#endif
1.414 + }
1.415 +
1.416 + if (export_cert) {
1.417 + EVP_PKEY *key = NULL;
1.418 + X509 *ucert = NULL, *x = NULL;
1.419 + STACK_OF(X509) *certs=NULL;
1.420 + unsigned char *catmp = NULL;
1.421 + int i;
1.422 +
1.423 + if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
1.424 + {
1.425 + BIO_printf(bio_err, "Nothing to do!\n");
1.426 + goto export_end;
1.427 + }
1.428 +
1.429 + if (options & NOCERTS)
1.430 + chain = 0;
1.431 +
1.432 +#ifdef CRYPTO_MDEBUG
1.433 + CRYPTO_push_info("process -export_cert");
1.434 + CRYPTO_push_info("reading private key");
1.435 +#endif
1.436 + if (!(options & NOKEYS))
1.437 + {
1.438 + key = load_key(bio_err, keyname ? keyname : infile,
1.439 + FORMAT_PEM, 1, passin, e, "private key");
1.440 + if (!key)
1.441 + goto export_end;
1.442 + }
1.443 +
1.444 +#ifdef CRYPTO_MDEBUG
1.445 + CRYPTO_pop_info();
1.446 + CRYPTO_push_info("reading certs from input");
1.447 +#endif
1.448 +
1.449 + /* Load in all certs in input file */
1.450 + if(!(options & NOCERTS))
1.451 + {
1.452 + certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
1.453 + "certificates");
1.454 + if (!certs)
1.455 + goto export_end;
1.456 +
1.457 + if (key)
1.458 + {
1.459 + /* Look for matching private key */
1.460 + for(i = 0; i < sk_X509_num(certs); i++)
1.461 + {
1.462 + x = sk_X509_value(certs, i);
1.463 + if(X509_check_private_key(x, key))
1.464 + {
1.465 + ucert = x;
1.466 + /* Zero keyid and alias */
1.467 + X509_keyid_set1(ucert, NULL, 0);
1.468 + X509_alias_set1(ucert, NULL, 0);
1.469 + /* Remove from list */
1.470 + (void)sk_X509_delete(certs, i);
1.471 + break;
1.472 + }
1.473 + }
1.474 + if (!ucert)
1.475 + {
1.476 + BIO_printf(bio_err, "No certificate matches private key\n");
1.477 + goto export_end;
1.478 + }
1.479 + }
1.480 +
1.481 + }
1.482 +
1.483 +#ifdef CRYPTO_MDEBUG
1.484 + CRYPTO_pop_info();
1.485 + CRYPTO_push_info("reading certs from input 2");
1.486 +#endif
1.487 +
1.488 + /* Add any more certificates asked for */
1.489 + if(certfile)
1.490 + {
1.491 + STACK_OF(X509) *morecerts=NULL;
1.492 + if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
1.493 + NULL, e,
1.494 + "certificates from certfile")))
1.495 + goto export_end;
1.496 + while(sk_X509_num(morecerts) > 0)
1.497 + sk_X509_push(certs, sk_X509_shift(morecerts));
1.498 + sk_X509_free(morecerts);
1.499 + }
1.500 +
1.501 +#ifdef CRYPTO_MDEBUG
1.502 + CRYPTO_pop_info();
1.503 + CRYPTO_push_info("reading certs from certfile");
1.504 +#endif
1.505 +
1.506 +#ifdef CRYPTO_MDEBUG
1.507 + CRYPTO_pop_info();
1.508 + CRYPTO_push_info("building chain");
1.509 +#endif
1.510 +
1.511 + /* If chaining get chain from user cert */
1.512 + if (chain) {
1.513 + int vret;
1.514 + STACK_OF(X509) *chain2;
1.515 + X509_STORE *store = X509_STORE_new();
1.516 + if (!store)
1.517 + {
1.518 + BIO_printf (bio_err, "Memory allocation error\n");
1.519 + goto export_end;
1.520 + }
1.521 + if (!X509_STORE_load_locations(store, CAfile, CApath))
1.522 + X509_STORE_set_default_paths (store);
1.523 +
1.524 + vret = get_cert_chain (ucert, store, &chain2);
1.525 + X509_STORE_free(store);
1.526 +
1.527 + if (!vret) {
1.528 + /* Exclude verified certificate */
1.529 + for (i = 1; i < sk_X509_num (chain2) ; i++)
1.530 + sk_X509_push(certs, sk_X509_value (chain2, i));
1.531 + /* Free first certificate */
1.532 + X509_free(sk_X509_value(chain2, 0));
1.533 + sk_X509_free(chain2);
1.534 + } else {
1.535 + if (vret >= 0)
1.536 + BIO_printf (bio_err, "Error %s getting chain.\n",
1.537 + X509_verify_cert_error_string(vret));
1.538 + else
1.539 + ERR_print_errors(bio_err);
1.540 + goto export_end;
1.541 + }
1.542 + }
1.543 +
1.544 + /* Add any CA names */
1.545 +
1.546 + for (i = 0; i < sk_num(canames); i++)
1.547 + {
1.548 + catmp = (unsigned char *)sk_value(canames, i);
1.549 + X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
1.550 + }
1.551 +
1.552 + if (csp_name && key)
1.553 + EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
1.554 + MBSTRING_ASC, (unsigned char *)csp_name, -1);
1.555 +
1.556 +
1.557 +#ifdef CRYPTO_MDEBUG
1.558 + CRYPTO_pop_info();
1.559 + CRYPTO_push_info("reading password");
1.560 +#endif
1.561 +
1.562 + if(!noprompt &&
1.563 + EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
1.564 + {
1.565 + BIO_printf (bio_err, "Can't read Password\n");
1.566 + goto export_end;
1.567 + }
1.568 + if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
1.569 +
1.570 +#ifdef CRYPTO_MDEBUG
1.571 + CRYPTO_pop_info();
1.572 + CRYPTO_push_info("creating PKCS#12 structure");
1.573 +#endif
1.574 +
1.575 + p12 = PKCS12_create(cpass, name, key, ucert, certs,
1.576 + key_pbe, cert_pbe, iter, -1, keytype);
1.577 +
1.578 + if (!p12)
1.579 + {
1.580 + ERR_print_errors (bio_err);
1.581 + goto export_end;
1.582 + }
1.583 +
1.584 + if (maciter != -1)
1.585 + PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL);
1.586 +
1.587 +#ifdef CRYPTO_MDEBUG
1.588 + CRYPTO_pop_info();
1.589 + CRYPTO_push_info("writing pkcs12");
1.590 +#endif
1.591 +
1.592 + i2d_PKCS12_bio(out, p12);
1.593 +
1.594 + ret = 0;
1.595 +
1.596 + export_end:
1.597 +#ifdef CRYPTO_MDEBUG
1.598 + CRYPTO_pop_info();
1.599 + CRYPTO_pop_info();
1.600 + CRYPTO_push_info("process -export_cert: freeing");
1.601 +#endif
1.602 +
1.603 + if (key) EVP_PKEY_free(key);
1.604 + if (certs) sk_X509_pop_free(certs, X509_free);
1.605 + if (ucert) X509_free(ucert);
1.606 +
1.607 +#ifdef CRYPTO_MDEBUG
1.608 + CRYPTO_pop_info();
1.609 +#endif
1.610 + goto end;
1.611 +
1.612 + }
1.613 +
1.614 + if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
1.615 + ERR_print_errors(bio_err);
1.616 + goto end;
1.617 + }
1.618 +
1.619 +#ifdef CRYPTO_MDEBUG
1.620 + CRYPTO_push_info("read import password");
1.621 +#endif
1.622 + if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
1.623 + BIO_printf (bio_err, "Can't read Password\n");
1.624 + goto end;
1.625 + }
1.626 +#ifdef CRYPTO_MDEBUG
1.627 + CRYPTO_pop_info();
1.628 +#endif
1.629 +
1.630 + if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
1.631 +
1.632 + if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
1.633 + if(macver) {
1.634 +#ifdef CRYPTO_MDEBUG
1.635 + CRYPTO_push_info("verify MAC");
1.636 +#endif
1.637 + /* If we enter empty password try no password first */
1.638 + if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
1.639 + /* If mac and crypto pass the same set it to NULL too */
1.640 + if(!twopass) cpass = NULL;
1.641 + } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
1.642 + BIO_printf (bio_err, "Mac verify error: invalid password?\n");
1.643 + ERR_print_errors (bio_err);
1.644 + goto end;
1.645 + }
1.646 + BIO_printf (bio_err, "MAC verified OK\n");
1.647 +#ifdef CRYPTO_MDEBUG
1.648 + CRYPTO_pop_info();
1.649 +#endif
1.650 + }
1.651 +
1.652 +#ifdef CRYPTO_MDEBUG
1.653 + CRYPTO_push_info("output keys and certificates");
1.654 +#endif
1.655 + if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
1.656 + BIO_printf(bio_err, "Error outputting keys and certificates\n");
1.657 + ERR_print_errors (bio_err);
1.658 + goto end;
1.659 + }
1.660 +#ifdef CRYPTO_MDEBUG
1.661 + CRYPTO_pop_info();
1.662 +#endif
1.663 + ret = 0;
1.664 + end:
1.665 + if (p12) PKCS12_free(p12);
1.666 + if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
1.667 +#ifdef CRYPTO_MDEBUG
1.668 + CRYPTO_remove_all_info();
1.669 +#endif
1.670 + BIO_free(in);
1.671 + BIO_free_all(out);
1.672 + if (canames) sk_free(canames);
1.673 + if(passin) OPENSSL_free(passin);
1.674 + if(passout) OPENSSL_free(passout);
1.675 + apps_shutdown();
1.676 + OPENSSL_EXIT(ret);
1.677 +}
1.678 +
1.679 +int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass,
1.680 + int passlen, int options, char *pempass)
1.681 +{
1.682 + STACK_OF(PKCS7) *asafes = NULL;
1.683 + STACK_OF(PKCS12_SAFEBAG) *bags;
1.684 + int i, bagnid;
1.685 + int ret = 0;
1.686 + PKCS7 *p7;
1.687 +
1.688 + if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0;
1.689 + for (i = 0; i < sk_PKCS7_num (asafes); i++) {
1.690 + p7 = sk_PKCS7_value (asafes, i);
1.691 + bagnid = OBJ_obj2nid (p7->type);
1.692 + if (bagnid == NID_pkcs7_data) {
1.693 + bags = PKCS12_unpack_p7data(p7);
1.694 + if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n");
1.695 + } else if (bagnid == NID_pkcs7_encrypted) {
1.696 + if (options & INFO) {
1.697 + BIO_printf(bio_err, "PKCS7 Encrypted data: ");
1.698 + alg_print(bio_err,
1.699 + p7->d.encrypted->enc_data->algorithm);
1.700 + }
1.701 + bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
1.702 + } else continue;
1.703 + if (!bags) goto err;
1.704 + if (!dump_certs_pkeys_bags (out, bags, pass, passlen,
1.705 + options, pempass)) {
1.706 + sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
1.707 + goto err;
1.708 + }
1.709 + sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
1.710 + bags = NULL;
1.711 + }
1.712 + ret = 1;
1.713 +
1.714 + err:
1.715 +
1.716 + if (asafes)
1.717 + sk_PKCS7_pop_free (asafes, PKCS7_free);
1.718 + return ret;
1.719 +}
1.720 +
1.721 +int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
1.722 + char *pass, int passlen, int options, char *pempass)
1.723 +{
1.724 + int i;
1.725 + for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) {
1.726 + if (!dump_certs_pkeys_bag (out,
1.727 + sk_PKCS12_SAFEBAG_value (bags, i),
1.728 + pass, passlen,
1.729 + options, pempass))
1.730 + return 0;
1.731 + }
1.732 + return 1;
1.733 +}
1.734 +
1.735 +int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass,
1.736 + int passlen, int options, char *pempass)
1.737 +{
1.738 + EVP_PKEY *pkey;
1.739 + PKCS8_PRIV_KEY_INFO *p8;
1.740 + X509 *x509;
1.741 +
1.742 + switch (M_PKCS12_bag_type(bag))
1.743 + {
1.744 + case NID_keyBag:
1.745 + if (options & INFO) BIO_printf (bio_err, "Key bag\n");
1.746 + if (options & NOKEYS) return 1;
1.747 + print_attribs (out, bag->attrib, "Bag Attributes");
1.748 + p8 = bag->value.keybag;
1.749 + if (!(pkey = EVP_PKCS82PKEY (p8))) return 0;
1.750 + print_attribs (out, p8->attributes, "Key Attributes");
1.751 + PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
1.752 + EVP_PKEY_free(pkey);
1.753 + break;
1.754 +
1.755 + case NID_pkcs8ShroudedKeyBag:
1.756 + if (options & INFO) {
1.757 + BIO_printf (bio_err, "Shrouded Keybag: ");
1.758 + alg_print (bio_err, bag->value.shkeybag->algor);
1.759 + }
1.760 + if (options & NOKEYS) return 1;
1.761 + print_attribs (out, bag->attrib, "Bag Attributes");
1.762 + if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
1.763 + return 0;
1.764 + if (!(pkey = EVP_PKCS82PKEY (p8))) {
1.765 + PKCS8_PRIV_KEY_INFO_free(p8);
1.766 + return 0;
1.767 + }
1.768 + print_attribs (out, p8->attributes, "Key Attributes");
1.769 + PKCS8_PRIV_KEY_INFO_free(p8);
1.770 + PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
1.771 + EVP_PKEY_free(pkey);
1.772 + break;
1.773 +
1.774 + case NID_certBag:
1.775 + if (options & INFO) BIO_printf (bio_err, "Certificate bag\n");
1.776 + if (options & NOCERTS) return 1;
1.777 + if (PKCS12_get_attr(bag, NID_localKeyID)) {
1.778 + if (options & CACERTS) return 1;
1.779 + } else if (options & CLCERTS) return 1;
1.780 + print_attribs (out, bag->attrib, "Bag Attributes");
1.781 + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
1.782 + return 1;
1.783 + if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
1.784 + dump_cert_text (out, x509);
1.785 + PEM_write_bio_X509 (out, x509);
1.786 + X509_free(x509);
1.787 + break;
1.788 +
1.789 + case NID_safeContentsBag:
1.790 + if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n");
1.791 + print_attribs (out, bag->attrib, "Bag Attributes");
1.792 + return dump_certs_pkeys_bags (out, bag->value.safes, pass,
1.793 + passlen, options, pempass);
1.794 +
1.795 + default:
1.796 + BIO_printf (bio_err, "Warning unsupported bag type: ");
1.797 + i2a_ASN1_OBJECT (bio_err, bag->type);
1.798 + BIO_printf (bio_err, "\n");
1.799 + return 1;
1.800 + break;
1.801 + }
1.802 + return 1;
1.803 +}
1.804 +
1.805 +/* Given a single certificate return a verified chain or NULL if error */
1.806 +
1.807 +/* Hope this is OK .... */
1.808 +
1.809 +int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
1.810 +{
1.811 + X509_STORE_CTX store_ctx;
1.812 + STACK_OF(X509) *chn;
1.813 + int i = 0;
1.814 +
1.815 + /* FIXME: Should really check the return status of X509_STORE_CTX_init
1.816 + * for an error, but how that fits into the return value of this
1.817 + * function is less obvious. */
1.818 + X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
1.819 + if (X509_verify_cert(&store_ctx) <= 0) {
1.820 + i = X509_STORE_CTX_get_error (&store_ctx);
1.821 + if (i == 0)
1.822 + /* avoid returning 0 if X509_verify_cert() did not
1.823 + * set an appropriate error value in the context */
1.824 + i = -1;
1.825 + chn = NULL;
1.826 + goto err;
1.827 + } else
1.828 + chn = X509_STORE_CTX_get1_chain(&store_ctx);
1.829 +err:
1.830 + X509_STORE_CTX_cleanup(&store_ctx);
1.831 + *chain = chn;
1.832 +
1.833 + return i;
1.834 +}
1.835 +
1.836 +int alg_print (BIO *x, X509_ALGOR *alg)
1.837 +{
1.838 + PBEPARAM *pbe;
1.839 + const unsigned char *p;
1.840 + p = alg->parameter->value.sequence->data;
1.841 + pbe = d2i_PBEPARAM (NULL, &p, alg->parameter->value.sequence->length);
1.842 + if (!pbe)
1.843 + return 1;
1.844 + BIO_printf (bio_err, "%s, Iteration %ld\n",
1.845 + OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
1.846 + ASN1_INTEGER_get(pbe->iter));
1.847 + PBEPARAM_free (pbe);
1.848 + return 1;
1.849 +}
1.850 +
1.851 +/* Load all certificates from a given file */
1.852 +
1.853 +int cert_load(BIO *in, STACK_OF(X509) *sk)
1.854 +{
1.855 + int ret;
1.856 + X509 *cert;
1.857 + ret = 0;
1.858 +#ifdef CRYPTO_MDEBUG
1.859 + CRYPTO_push_info("cert_load(): reading one cert");
1.860 +#endif
1.861 + while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1.862 +#ifdef CRYPTO_MDEBUG
1.863 + CRYPTO_pop_info();
1.864 +#endif
1.865 + ret = 1;
1.866 + sk_X509_push(sk, cert);
1.867 +#ifdef CRYPTO_MDEBUG
1.868 + CRYPTO_push_info("cert_load(): reading one cert");
1.869 +#endif
1.870 + }
1.871 +#ifdef CRYPTO_MDEBUG
1.872 + CRYPTO_pop_info();
1.873 +#endif
1.874 + if(ret) ERR_clear_error();
1.875 + return ret;
1.876 +}
1.877 +
1.878 +/* Generalised attribute print: handle PKCS#8 and bag attributes */
1.879 +
1.880 +int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name)
1.881 +{
1.882 + X509_ATTRIBUTE *attr;
1.883 + ASN1_TYPE *av;
1.884 + char *value;
1.885 + int i, attr_nid;
1.886 + if(!attrlst) {
1.887 + BIO_printf(out, "%s: <No Attributes>\n", name);
1.888 + return 1;
1.889 + }
1.890 + if(!sk_X509_ATTRIBUTE_num(attrlst)) {
1.891 + BIO_printf(out, "%s: <Empty Attributes>\n", name);
1.892 + return 1;
1.893 + }
1.894 + BIO_printf(out, "%s\n", name);
1.895 + for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
1.896 + attr = sk_X509_ATTRIBUTE_value(attrlst, i);
1.897 + attr_nid = OBJ_obj2nid(attr->object);
1.898 + BIO_printf(out, " ");
1.899 + if(attr_nid == NID_undef) {
1.900 + i2a_ASN1_OBJECT (out, attr->object);
1.901 + BIO_printf(out, ": ");
1.902 + } else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
1.903 +
1.904 + if(sk_ASN1_TYPE_num(attr->value.set)) {
1.905 + av = sk_ASN1_TYPE_value(attr->value.set, 0);
1.906 + switch(av->type) {
1.907 + case V_ASN1_BMPSTRING:
1.908 + value = uni2asc(av->value.bmpstring->data,
1.909 + av->value.bmpstring->length);
1.910 + BIO_printf(out, "%s\n", value);
1.911 + OPENSSL_free(value);
1.912 + break;
1.913 +
1.914 + case V_ASN1_OCTET_STRING:
1.915 + hex_prin(out, av->value.octet_string->data,
1.916 + av->value.octet_string->length);
1.917 + BIO_printf(out, "\n");
1.918 + break;
1.919 +
1.920 + case V_ASN1_BIT_STRING:
1.921 + hex_prin(out, av->value.bit_string->data,
1.922 + av->value.bit_string->length);
1.923 + BIO_printf(out, "\n");
1.924 + break;
1.925 +
1.926 + default:
1.927 + BIO_printf(out, "<Unsupported tag %d>\n", av->type);
1.928 + break;
1.929 + }
1.930 + } else BIO_printf(out, "<No Values>\n");
1.931 + }
1.932 + return 1;
1.933 +}
1.934 +
1.935 +void hex_prin(BIO *out, unsigned char *buf, int len)
1.936 +{
1.937 + int i;
1.938 + for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
1.939 +}
1.940 +
1.941 +#endif