1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/tsrc/BC/libcrypto/topenssl/src/pkcs12.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,927 @@
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 +#ifndef OPENSSL_NO_IDEA
1.161 + else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
1.162 +#endif
1.163 + else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
1.164 +#ifndef OPENSSL_NO_AES
1.165 + else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
1.166 + else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
1.167 + else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
1.168 +#endif
1.169 + else if (!strcmp (*args, "-noiter")) iter = 1;
1.170 + else if (!strcmp (*args, "-maciter"))
1.171 + maciter = PKCS12_DEFAULT_ITER;
1.172 + else if (!strcmp (*args, "-nomaciter"))
1.173 + maciter = 1;
1.174 + else if (!strcmp (*args, "-nomac"))
1.175 + maciter = -1;
1.176 + else if (!strcmp (*args, "-nodes")) enc=NULL;
1.177 + else if (!strcmp (*args, "-certpbe")) {
1.178 + if (args[1]) {
1.179 + args++;
1.180 + if (!strcmp(*args, "NONE"))
1.181 + cert_pbe = -1;
1.182 + cert_pbe=OBJ_txt2nid(*args);
1.183 + if(cert_pbe == NID_undef) {
1.184 + BIO_printf(bio_err,
1.185 + "Unknown PBE algorithm %s\n", *args);
1.186 + badarg = 1;
1.187 + }
1.188 + } else badarg = 1;
1.189 + } else if (!strcmp (*args, "-keypbe")) {
1.190 + if (args[1]) {
1.191 + args++;
1.192 + if (!strcmp(*args, "NONE"))
1.193 + key_pbe = -1;
1.194 + else
1.195 + key_pbe=OBJ_txt2nid(*args);
1.196 + if(key_pbe == NID_undef) {
1.197 + BIO_printf(bio_err,
1.198 + "Unknown PBE algorithm %s\n", *args);
1.199 + badarg = 1;
1.200 + }
1.201 + } else badarg = 1;
1.202 + } else if (!strcmp (*args, "-rand")) {
1.203 + if (args[1]) {
1.204 + args++;
1.205 + inrand = *args;
1.206 + } else badarg = 1;
1.207 + } else if (!strcmp (*args, "-inkey")) {
1.208 + if (args[1]) {
1.209 + args++;
1.210 + keyname = *args;
1.211 + } else badarg = 1;
1.212 + } else if (!strcmp (*args, "-certfile")) {
1.213 + if (args[1]) {
1.214 + args++;
1.215 + certfile = *args;
1.216 + } else badarg = 1;
1.217 + } else if (!strcmp (*args, "-name")) {
1.218 + if (args[1]) {
1.219 + args++;
1.220 + name = *args;
1.221 + } else badarg = 1;
1.222 + } else if (!strcmp (*args, "-CSP")) {
1.223 + if (args[1]) {
1.224 + args++;
1.225 + csp_name = *args;
1.226 + } else badarg = 1;
1.227 + } else if (!strcmp (*args, "-caname")) {
1.228 + if (args[1]) {
1.229 + args++;
1.230 + if (!canames) canames = sk_new_null();
1.231 + sk_push(canames, *args);
1.232 + } else badarg = 1;
1.233 + } else if (!strcmp (*args, "-in")) {
1.234 + if (args[1]) {
1.235 + args++;
1.236 + infile = *args;
1.237 + } else badarg = 1;
1.238 + } else if (!strcmp (*args, "-out")) {
1.239 + if (args[1]) {
1.240 + args++;
1.241 + outfile = *args;
1.242 + } else badarg = 1;
1.243 + } else if (!strcmp(*args,"-passin")) {
1.244 + if (args[1]) {
1.245 + args++;
1.246 + passargin = *args;
1.247 + } else badarg = 1;
1.248 + } else if (!strcmp(*args,"-passout")) {
1.249 + if (args[1]) {
1.250 + args++;
1.251 + passargout = *args;
1.252 + } else badarg = 1;
1.253 + } else if (!strcmp (*args, "-password")) {
1.254 + if (args[1]) {
1.255 + args++;
1.256 + passarg = *args;
1.257 + noprompt = 1;
1.258 + } else badarg = 1;
1.259 + } else if (!strcmp(*args,"-CApath")) {
1.260 + if (args[1]) {
1.261 + args++;
1.262 + CApath = *args;
1.263 + } else badarg = 1;
1.264 + } else if (!strcmp(*args,"-CAfile")) {
1.265 + if (args[1]) {
1.266 + args++;
1.267 + CAfile = *args;
1.268 + } else badarg = 1;
1.269 +#ifndef OPENSSL_NO_ENGINE
1.270 + } else if (!strcmp(*args,"-engine")) {
1.271 + if (args[1]) {
1.272 + args++;
1.273 + engine = *args;
1.274 + } else badarg = 1;
1.275 +#endif
1.276 + } else badarg = 1;
1.277 +
1.278 + } else badarg = 1;
1.279 + args++;
1.280 + }
1.281 +
1.282 + if (badarg) {
1.283 + BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
1.284 + BIO_printf (bio_err, "where options are\n");
1.285 + BIO_printf (bio_err, "-export output PKCS12 file\n");
1.286 + BIO_printf (bio_err, "-chain add certificate chain\n");
1.287 + BIO_printf (bio_err, "-inkey file private key if not infile\n");
1.288 + BIO_printf (bio_err, "-certfile f add all certs in f\n");
1.289 + BIO_printf (bio_err, "-CApath arg - PEM format directory of CA's\n");
1.290 + BIO_printf (bio_err, "-CAfile arg - PEM format file of CA's\n");
1.291 + BIO_printf (bio_err, "-name \"name\" use name as friendly name\n");
1.292 + BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n");
1.293 + BIO_printf (bio_err, "-in infile input filename\n");
1.294 + BIO_printf (bio_err, "-out outfile output filename\n");
1.295 + BIO_printf (bio_err, "-noout don't output anything, just verify.\n");
1.296 + BIO_printf (bio_err, "-nomacver don't verify MAC.\n");
1.297 + BIO_printf (bio_err, "-nocerts don't output certificates.\n");
1.298 + BIO_printf (bio_err, "-clcerts only output client certificates.\n");
1.299 + BIO_printf (bio_err, "-cacerts only output CA certificates.\n");
1.300 + BIO_printf (bio_err, "-nokeys don't output private keys.\n");
1.301 + BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n");
1.302 + BIO_printf (bio_err, "-des encrypt private keys with DES\n");
1.303 + BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n");
1.304 +#ifndef OPENSSL_NO_IDEA
1.305 + BIO_printf (bio_err, "-idea encrypt private keys with idea\n");
1.306 +#endif
1.307 +#ifndef OPENSSL_NO_AES
1.308 + BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
1.309 + BIO_printf (bio_err, " encrypt PEM output with cbc aes\n");
1.310 +#endif
1.311 + BIO_printf (bio_err, "-nodes don't encrypt private keys\n");
1.312 + BIO_printf (bio_err, "-noiter don't use encryption iteration\n");
1.313 + BIO_printf (bio_err, "-maciter use MAC iteration\n");
1.314 + BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n");
1.315 + BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
1.316 + BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n");
1.317 + BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n");
1.318 + BIO_printf (bio_err, "-keyex set MS key exchange type\n");
1.319 + BIO_printf (bio_err, "-keysig set MS key signature type\n");
1.320 + BIO_printf (bio_err, "-password p set import/export password source\n");
1.321 + BIO_printf (bio_err, "-passin p input file pass phrase source\n");
1.322 + BIO_printf (bio_err, "-passout p output file pass phrase source\n");
1.323 +#ifndef OPENSSL_NO_ENGINE
1.324 + BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n");
1.325 +#endif
1.326 + BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
1.327 + BIO_printf(bio_err, " load the file (or the files in the directory) into\n");
1.328 + BIO_printf(bio_err, " the random number generator\n");
1.329 + goto end;
1.330 + }
1.331 +
1.332 +#ifndef OPENSSL_NO_ENGINE
1.333 + e = setup_engine(bio_err, engine, 0);
1.334 +#endif
1.335 +
1.336 + if(passarg) {
1.337 + if(export_cert) passargout = passarg;
1.338 + else passargin = passarg;
1.339 + }
1.340 +
1.341 + if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
1.342 + BIO_printf(bio_err, "Error getting passwords\n");
1.343 + goto end;
1.344 + }
1.345 +
1.346 + if(!cpass) {
1.347 + if(export_cert) cpass = passout;
1.348 + else cpass = passin;
1.349 + }
1.350 +
1.351 + if(cpass) {
1.352 + mpass = cpass;
1.353 + noprompt = 1;
1.354 + } else {
1.355 + cpass = pass;
1.356 + mpass = macpass;
1.357 + }
1.358 +
1.359 + if(export_cert || inrand) {
1.360 + app_RAND_load_file(NULL, bio_err, (inrand != NULL));
1.361 + if (inrand != NULL)
1.362 + BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
1.363 + app_RAND_load_files(inrand));
1.364 + }
1.365 + ERR_load_crypto_strings();
1.366 +
1.367 +#ifdef CRYPTO_MDEBUG
1.368 + CRYPTO_push_info("read files");
1.369 +#endif
1.370 + if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
1.371 + else in = BIO_new_file(infile, "rb");
1.372 + if (!in) {
1.373 + BIO_printf(bio_err, "Error opening input file %s\n",
1.374 + infile ? infile : "<stdin>");
1.375 + perror (infile);
1.376 + goto end;
1.377 + }
1.378 +
1.379 +#ifdef CRYPTO_MDEBUG
1.380 + CRYPTO_pop_info();
1.381 + CRYPTO_push_info("write files");
1.382 +#endif
1.383 +
1.384 + if (!outfile) {
1.385 + out = BIO_new_fp(stdout, BIO_NOCLOSE);
1.386 +
1.387 +#ifdef OPENSSL_SYS_VMS
1.388 + {
1.389 + BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1.390 + out = BIO_push(tmpbio, out);
1.391 + }
1.392 +#endif
1.393 + } else out = BIO_new_file(outfile, "wb");
1.394 + if (!out) {
1.395 + BIO_printf(bio_err, "Error opening output file %s\n",
1.396 + outfile ? outfile : "<stdout>");
1.397 + perror (outfile);
1.398 + goto end;
1.399 + }
1.400 + if (twopass) {
1.401 +#ifdef CRYPTO_MDEBUG
1.402 + CRYPTO_push_info("read MAC password");
1.403 +#endif
1.404 + if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert))
1.405 + {
1.406 + BIO_printf (bio_err, "Can't read Password\n");
1.407 + goto end;
1.408 + }
1.409 +#ifdef CRYPTO_MDEBUG
1.410 + CRYPTO_pop_info();
1.411 +#endif
1.412 + }
1.413 +
1.414 + if (export_cert) {
1.415 + EVP_PKEY *key = NULL;
1.416 + X509 *ucert = NULL, *x = NULL;
1.417 + STACK_OF(X509) *certs=NULL;
1.418 + unsigned char *catmp = NULL;
1.419 + int i;
1.420 +
1.421 + if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
1.422 + {
1.423 + BIO_printf(bio_err, "Nothing to do!\n");
1.424 + goto export_end;
1.425 + }
1.426 +
1.427 + if (options & NOCERTS)
1.428 + chain = 0;
1.429 +
1.430 +#ifdef CRYPTO_MDEBUG
1.431 + CRYPTO_push_info("process -export_cert");
1.432 + CRYPTO_push_info("reading private key");
1.433 +#endif
1.434 + if (!(options & NOKEYS))
1.435 + {
1.436 + key = load_key(bio_err, keyname ? keyname : infile,
1.437 + FORMAT_PEM, 1, passin, e, "private key");
1.438 + if (!key)
1.439 + goto export_end;
1.440 + }
1.441 +
1.442 +#ifdef CRYPTO_MDEBUG
1.443 + CRYPTO_pop_info();
1.444 + CRYPTO_push_info("reading certs from input");
1.445 +#endif
1.446 +
1.447 + /* Load in all certs in input file */
1.448 + if(!(options & NOCERTS))
1.449 + {
1.450 + certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
1.451 + "certificates");
1.452 + if (!certs)
1.453 + goto export_end;
1.454 +
1.455 + if (key)
1.456 + {
1.457 + /* Look for matching private key */
1.458 + for(i = 0; i < sk_X509_num(certs); i++)
1.459 + {
1.460 + x = sk_X509_value(certs, i);
1.461 + if(X509_check_private_key(x, key))
1.462 + {
1.463 + ucert = x;
1.464 + /* Zero keyid and alias */
1.465 + X509_keyid_set1(ucert, NULL, 0);
1.466 + X509_alias_set1(ucert, NULL, 0);
1.467 + /* Remove from list */
1.468 + sk_X509_delete(certs, i);
1.469 + break;
1.470 + }
1.471 + }
1.472 + if (!ucert)
1.473 + {
1.474 + BIO_printf(bio_err, "No certificate matches private key\n");
1.475 + goto export_end;
1.476 + }
1.477 + }
1.478 +
1.479 + }
1.480 +
1.481 +#ifdef CRYPTO_MDEBUG
1.482 + CRYPTO_pop_info();
1.483 + CRYPTO_push_info("reading certs from input 2");
1.484 +#endif
1.485 +
1.486 + /* Add any more certificates asked for */
1.487 + if(certfile)
1.488 + {
1.489 + STACK_OF(X509) *morecerts=NULL;
1.490 + if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
1.491 + NULL, e,
1.492 + "certificates from certfile")))
1.493 + goto export_end;
1.494 + while(sk_X509_num(morecerts) > 0)
1.495 + sk_X509_push(certs, sk_X509_shift(morecerts));
1.496 + sk_X509_free(morecerts);
1.497 + }
1.498 +
1.499 +#ifdef CRYPTO_MDEBUG
1.500 + CRYPTO_pop_info();
1.501 + CRYPTO_push_info("reading certs from certfile");
1.502 +#endif
1.503 +
1.504 +#ifdef CRYPTO_MDEBUG
1.505 + CRYPTO_pop_info();
1.506 + CRYPTO_push_info("building chain");
1.507 +#endif
1.508 +
1.509 + /* If chaining get chain from user cert */
1.510 + if (chain) {
1.511 + int vret;
1.512 + STACK_OF(X509) *chain2;
1.513 + X509_STORE *store = X509_STORE_new();
1.514 + if (!store)
1.515 + {
1.516 + BIO_printf (bio_err, "Memory allocation error\n");
1.517 + goto export_end;
1.518 + }
1.519 + if (!X509_STORE_load_locations(store, CAfile, CApath))
1.520 + X509_STORE_set_default_paths (store);
1.521 +
1.522 + vret = get_cert_chain (ucert, store, &chain2);
1.523 + X509_STORE_free(store);
1.524 +
1.525 + if (!vret) {
1.526 + /* Exclude verified certificate */
1.527 + for (i = 1; i < sk_X509_num (chain2) ; i++)
1.528 + sk_X509_push(certs, sk_X509_value (chain2, i));
1.529 + /* Free first certificate */
1.530 + X509_free(sk_X509_value(chain2, 0));
1.531 + sk_X509_free(chain2);
1.532 + } else {
1.533 + BIO_printf (bio_err, "Error %s getting chain.\n",
1.534 + X509_verify_cert_error_string(vret));
1.535 + goto export_end;
1.536 + }
1.537 + }
1.538 +
1.539 + /* Add any CA names */
1.540 +
1.541 + for (i = 0; i < sk_num(canames); i++)
1.542 + {
1.543 + catmp = (unsigned char *)sk_value(canames, i);
1.544 + X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
1.545 + }
1.546 +
1.547 + if (csp_name && key)
1.548 + EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
1.549 + MBSTRING_ASC, (unsigned char *)csp_name, -1);
1.550 +
1.551 +
1.552 +#ifdef CRYPTO_MDEBUG
1.553 + CRYPTO_pop_info();
1.554 + CRYPTO_push_info("reading password");
1.555 +#endif
1.556 +
1.557 + if(!noprompt &&
1.558 + EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
1.559 + {
1.560 + BIO_printf (bio_err, "Can't read Password\n");
1.561 + goto export_end;
1.562 + }
1.563 + if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
1.564 +
1.565 +#ifdef CRYPTO_MDEBUG
1.566 + CRYPTO_pop_info();
1.567 + CRYPTO_push_info("creating PKCS#12 structure");
1.568 +#endif
1.569 +
1.570 + p12 = PKCS12_create(cpass, name, key, ucert, certs,
1.571 + key_pbe, cert_pbe, iter, -1, keytype);
1.572 +
1.573 + if (!p12)
1.574 + {
1.575 + ERR_print_errors (bio_err);
1.576 + goto export_end;
1.577 + }
1.578 +
1.579 + if (maciter != -1)
1.580 + PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL);
1.581 +
1.582 +#ifdef CRYPTO_MDEBUG
1.583 + CRYPTO_pop_info();
1.584 + CRYPTO_push_info("writing pkcs12");
1.585 +#endif
1.586 +
1.587 + i2d_PKCS12_bio(out, p12);
1.588 +
1.589 + ret = 0;
1.590 +
1.591 + export_end:
1.592 +#ifdef CRYPTO_MDEBUG
1.593 + CRYPTO_pop_info();
1.594 + CRYPTO_pop_info();
1.595 + CRYPTO_push_info("process -export_cert: freeing");
1.596 +#endif
1.597 +
1.598 + if (key) EVP_PKEY_free(key);
1.599 + if (certs) sk_X509_pop_free(certs, X509_free);
1.600 + if (ucert) X509_free(ucert);
1.601 +
1.602 +#ifdef CRYPTO_MDEBUG
1.603 + CRYPTO_pop_info();
1.604 +#endif
1.605 + goto end;
1.606 +
1.607 + }
1.608 +
1.609 + if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
1.610 + ERR_print_errors(bio_err);
1.611 + goto end;
1.612 + }
1.613 +
1.614 +#ifdef CRYPTO_MDEBUG
1.615 + CRYPTO_push_info("read import password");
1.616 +#endif
1.617 + if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
1.618 + BIO_printf (bio_err, "Can't read Password\n");
1.619 + goto end;
1.620 + }
1.621 +#ifdef CRYPTO_MDEBUG
1.622 + CRYPTO_pop_info();
1.623 +#endif
1.624 +
1.625 + if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
1.626 +
1.627 + if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
1.628 + if(macver) {
1.629 +#ifdef CRYPTO_MDEBUG
1.630 + CRYPTO_push_info("verify MAC");
1.631 +#endif
1.632 + /* If we enter empty password try no password first */
1.633 + if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
1.634 + /* If mac and crypto pass the same set it to NULL too */
1.635 + if(!twopass) cpass = NULL;
1.636 + } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
1.637 + BIO_printf (bio_err, "Mac verify error: invalid password?\n");
1.638 + ERR_print_errors (bio_err);
1.639 + goto end;
1.640 + }
1.641 + BIO_printf (bio_err, "MAC verified OK\n");
1.642 +#ifdef CRYPTO_MDEBUG
1.643 + CRYPTO_pop_info();
1.644 +#endif
1.645 + }
1.646 +
1.647 +#ifdef CRYPTO_MDEBUG
1.648 + CRYPTO_push_info("output keys and certificates");
1.649 +#endif
1.650 + if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
1.651 + BIO_printf(bio_err, "Error outputting keys and certificates\n");
1.652 + ERR_print_errors (bio_err);
1.653 + goto end;
1.654 + }
1.655 +#ifdef CRYPTO_MDEBUG
1.656 + CRYPTO_pop_info();
1.657 +#endif
1.658 + ret = 0;
1.659 + end:
1.660 + if (p12) PKCS12_free(p12);
1.661 + if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
1.662 +#ifdef CRYPTO_MDEBUG
1.663 + CRYPTO_remove_all_info();
1.664 +#endif
1.665 + BIO_free(in);
1.666 + BIO_free_all(out);
1.667 + if (canames) sk_free(canames);
1.668 + if(passin) OPENSSL_free(passin);
1.669 + if(passout) OPENSSL_free(passout);
1.670 + apps_shutdown();
1.671 + OPENSSL_EXIT(ret);
1.672 +}
1.673 +
1.674 +int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass,
1.675 + int passlen, int options, char *pempass)
1.676 +{
1.677 + STACK_OF(PKCS7) *asafes = NULL;
1.678 + STACK_OF(PKCS12_SAFEBAG) *bags;
1.679 + int i, bagnid;
1.680 + int ret = 0;
1.681 + PKCS7 *p7;
1.682 +
1.683 + if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0;
1.684 + for (i = 0; i < sk_PKCS7_num (asafes); i++) {
1.685 + p7 = sk_PKCS7_value (asafes, i);
1.686 + bagnid = OBJ_obj2nid (p7->type);
1.687 + if (bagnid == NID_pkcs7_data) {
1.688 + bags = PKCS12_unpack_p7data(p7);
1.689 + if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n");
1.690 + } else if (bagnid == NID_pkcs7_encrypted) {
1.691 + if (options & INFO) {
1.692 + BIO_printf(bio_err, "PKCS7 Encrypted data: ");
1.693 + alg_print(bio_err,
1.694 + p7->d.encrypted->enc_data->algorithm);
1.695 + }
1.696 + bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
1.697 + } else continue;
1.698 + if (!bags) goto err;
1.699 + if (!dump_certs_pkeys_bags (out, bags, pass, passlen,
1.700 + options, pempass)) {
1.701 + sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
1.702 + goto err;
1.703 + }
1.704 + sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
1.705 + bags = NULL;
1.706 + }
1.707 + ret = 1;
1.708 +
1.709 + err:
1.710 +
1.711 + if (asafes)
1.712 + sk_PKCS7_pop_free (asafes, PKCS7_free);
1.713 + return ret;
1.714 +}
1.715 +
1.716 +int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
1.717 + char *pass, int passlen, int options, char *pempass)
1.718 +{
1.719 + int i;
1.720 + for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) {
1.721 + if (!dump_certs_pkeys_bag (out,
1.722 + sk_PKCS12_SAFEBAG_value (bags, i),
1.723 + pass, passlen,
1.724 + options, pempass))
1.725 + return 0;
1.726 + }
1.727 + return 1;
1.728 +}
1.729 +
1.730 +int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass,
1.731 + int passlen, int options, char *pempass)
1.732 +{
1.733 + EVP_PKEY *pkey;
1.734 + PKCS8_PRIV_KEY_INFO *p8;
1.735 + X509 *x509;
1.736 +
1.737 + switch (M_PKCS12_bag_type(bag))
1.738 + {
1.739 + case NID_keyBag:
1.740 + if (options & INFO) BIO_printf (bio_err, "Key bag\n");
1.741 + if (options & NOKEYS) return 1;
1.742 + print_attribs (out, bag->attrib, "Bag Attributes");
1.743 + p8 = bag->value.keybag;
1.744 + if (!(pkey = EVP_PKCS82PKEY (p8))) return 0;
1.745 + print_attribs (out, p8->attributes, "Key Attributes");
1.746 + PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
1.747 + EVP_PKEY_free(pkey);
1.748 + break;
1.749 +
1.750 + case NID_pkcs8ShroudedKeyBag:
1.751 + if (options & INFO) {
1.752 + BIO_printf (bio_err, "Shrouded Keybag: ");
1.753 + alg_print (bio_err, bag->value.shkeybag->algor);
1.754 + }
1.755 + if (options & NOKEYS) return 1;
1.756 + print_attribs (out, bag->attrib, "Bag Attributes");
1.757 + if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
1.758 + return 0;
1.759 + if (!(pkey = EVP_PKCS82PKEY (p8))) {
1.760 + PKCS8_PRIV_KEY_INFO_free(p8);
1.761 + return 0;
1.762 + }
1.763 + print_attribs (out, p8->attributes, "Key Attributes");
1.764 + PKCS8_PRIV_KEY_INFO_free(p8);
1.765 + PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
1.766 + EVP_PKEY_free(pkey);
1.767 + break;
1.768 +
1.769 + case NID_certBag:
1.770 + if (options & INFO) BIO_printf (bio_err, "Certificate bag\n");
1.771 + if (options & NOCERTS) return 1;
1.772 + if (PKCS12_get_attr(bag, NID_localKeyID)) {
1.773 + if (options & CACERTS) return 1;
1.774 + } else if (options & CLCERTS) return 1;
1.775 + print_attribs (out, bag->attrib, "Bag Attributes");
1.776 + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
1.777 + return 1;
1.778 + if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
1.779 + dump_cert_text (out, x509);
1.780 + PEM_write_bio_X509 (out, x509);
1.781 + X509_free(x509);
1.782 + break;
1.783 +
1.784 + case NID_safeContentsBag:
1.785 + if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n");
1.786 + print_attribs (out, bag->attrib, "Bag Attributes");
1.787 + return dump_certs_pkeys_bags (out, bag->value.safes, pass,
1.788 + passlen, options, pempass);
1.789 +
1.790 + default:
1.791 + BIO_printf (bio_err, "Warning unsupported bag type: ");
1.792 + i2a_ASN1_OBJECT (bio_err, bag->type);
1.793 + BIO_printf (bio_err, "\n");
1.794 + return 1;
1.795 + break;
1.796 + }
1.797 + return 1;
1.798 +}
1.799 +
1.800 +/* Given a single certificate return a verified chain or NULL if error */
1.801 +
1.802 +/* Hope this is OK .... */
1.803 +
1.804 +int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
1.805 +{
1.806 + X509_STORE_CTX store_ctx;
1.807 + STACK_OF(X509) *chn;
1.808 + int i;
1.809 +
1.810 + /* FIXME: Should really check the return status of X509_STORE_CTX_init
1.811 + * for an error, but how that fits into the return value of this
1.812 + * function is less obvious. */
1.813 + X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
1.814 + if (X509_verify_cert(&store_ctx) <= 0) {
1.815 + i = X509_STORE_CTX_get_error (&store_ctx);
1.816 + goto err;
1.817 + }
1.818 + chn = X509_STORE_CTX_get1_chain(&store_ctx);
1.819 + i = 0;
1.820 + *chain = chn;
1.821 +err:
1.822 + X509_STORE_CTX_cleanup(&store_ctx);
1.823 +
1.824 + return i;
1.825 +}
1.826 +
1.827 +int alg_print (BIO *x, X509_ALGOR *alg)
1.828 +{
1.829 + PBEPARAM *pbe;
1.830 + const unsigned char *p;
1.831 + p = alg->parameter->value.sequence->data;
1.832 + pbe = d2i_PBEPARAM (NULL, &p, alg->parameter->value.sequence->length);
1.833 + BIO_printf (bio_err, "%s, Iteration %ld\n",
1.834 + OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
1.835 + ASN1_INTEGER_get(pbe->iter));
1.836 + PBEPARAM_free (pbe);
1.837 + return 0;
1.838 +}
1.839 +
1.840 +/* Load all certificates from a given file */
1.841 +
1.842 +int cert_load(BIO *in, STACK_OF(X509) *sk)
1.843 +{
1.844 + int ret;
1.845 + X509 *cert;
1.846 + ret = 0;
1.847 +#ifdef CRYPTO_MDEBUG
1.848 + CRYPTO_push_info("cert_load(): reading one cert");
1.849 +#endif
1.850 + while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1.851 +#ifdef CRYPTO_MDEBUG
1.852 + CRYPTO_pop_info();
1.853 +#endif
1.854 + ret = 1;
1.855 + sk_X509_push(sk, cert);
1.856 +#ifdef CRYPTO_MDEBUG
1.857 + CRYPTO_push_info("cert_load(): reading one cert");
1.858 +#endif
1.859 + }
1.860 +#ifdef CRYPTO_MDEBUG
1.861 + CRYPTO_pop_info();
1.862 +#endif
1.863 + if(ret) ERR_clear_error();
1.864 + return ret;
1.865 +}
1.866 +
1.867 +/* Generalised attribute print: handle PKCS#8 and bag attributes */
1.868 +
1.869 +int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name)
1.870 +{
1.871 + X509_ATTRIBUTE *attr;
1.872 + ASN1_TYPE *av;
1.873 + char *value;
1.874 + int i, attr_nid;
1.875 + if(!attrlst) {
1.876 + BIO_printf(out, "%s: <No Attributes>\n", name);
1.877 + return 1;
1.878 + }
1.879 + if(!sk_X509_ATTRIBUTE_num(attrlst)) {
1.880 + BIO_printf(out, "%s: <Empty Attributes>\n", name);
1.881 + return 1;
1.882 + }
1.883 + BIO_printf(out, "%s\n", name);
1.884 + for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
1.885 + attr = sk_X509_ATTRIBUTE_value(attrlst, i);
1.886 + attr_nid = OBJ_obj2nid(attr->object);
1.887 + BIO_printf(out, " ");
1.888 + if(attr_nid == NID_undef) {
1.889 + i2a_ASN1_OBJECT (out, attr->object);
1.890 + BIO_printf(out, ": ");
1.891 + } else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
1.892 +
1.893 + if(sk_ASN1_TYPE_num(attr->value.set)) {
1.894 + av = sk_ASN1_TYPE_value(attr->value.set, 0);
1.895 + switch(av->type) {
1.896 + case V_ASN1_BMPSTRING:
1.897 + value = uni2asc(av->value.bmpstring->data,
1.898 + av->value.bmpstring->length);
1.899 + BIO_printf(out, "%s\n", value);
1.900 + OPENSSL_free(value);
1.901 + break;
1.902 +
1.903 + case V_ASN1_OCTET_STRING:
1.904 + hex_prin(out, av->value.octet_string->data,
1.905 + av->value.octet_string->length);
1.906 + BIO_printf(out, "\n");
1.907 + break;
1.908 +
1.909 + case V_ASN1_BIT_STRING:
1.910 + hex_prin(out, av->value.bit_string->data,
1.911 + av->value.bit_string->length);
1.912 + BIO_printf(out, "\n");
1.913 + break;
1.914 +
1.915 + default:
1.916 + BIO_printf(out, "<Unsupported tag %d>\n", av->type);
1.917 + break;
1.918 + }
1.919 + } else BIO_printf(out, "<No Values>\n");
1.920 + }
1.921 + return 1;
1.922 +}
1.923 +
1.924 +void hex_prin(BIO *out, unsigned char *buf, int len)
1.925 +{
1.926 + int i;
1.927 + for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
1.928 +}
1.929 +
1.930 +#endif