155714Skris/* pkcs12.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4160814Ssimon * project. 555714Skris */ 655714Skris/* ==================================================================== 7162911Ssimon * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. 855714Skris * 955714Skris * Redistribution and use in source and binary forms, with or without 1055714Skris * modification, are permitted provided that the following conditions 1155714Skris * are met: 1255714Skris * 1355714Skris * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 1555714Skris * 1655714Skris * 2. Redistributions in binary form must reproduce the above copyright 1755714Skris * notice, this list of conditions and the following disclaimer in 1855714Skris * the documentation and/or other materials provided with the 1955714Skris * distribution. 2055714Skris * 2155714Skris * 3. All advertising materials mentioning features or use of this 2255714Skris * software must display the following acknowledgment: 2355714Skris * "This product includes software developed by the OpenSSL Project 2455714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2555714Skris * 2655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2755714Skris * endorse or promote products derived from this software without 2855714Skris * prior written permission. For written permission, please contact 2955714Skris * licensing@OpenSSL.org. 3055714Skris * 3155714Skris * 5. Products derived from this software may not be called "OpenSSL" 3255714Skris * nor may "OpenSSL" appear in their names without prior written 3355714Skris * permission of the OpenSSL Project. 3455714Skris * 3555714Skris * 6. Redistributions of any form whatsoever must retain the following 3655714Skris * acknowledgment: 3755714Skris * "This product includes software developed by the OpenSSL Project 3855714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3955714Skris * 4055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4355714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5255714Skris * ==================================================================== 5355714Skris * 5455714Skris * This product includes cryptographic software written by Eric Young 5555714Skris * (eay@cryptsoft.com). This product includes software written by Tim 5655714Skris * Hudson (tjh@cryptsoft.com). 5755714Skris * 5855714Skris */ 5955714Skris 60160814Ssimon#include <openssl/opensslconf.h> 61160814Ssimon#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) 62160814Ssimon 63296341Sdelphij# include <stdio.h> 64296341Sdelphij# include <stdlib.h> 65296341Sdelphij# include <string.h> 66296341Sdelphij# include "apps.h" 67296341Sdelphij# include <openssl/crypto.h> 68296341Sdelphij# include <openssl/err.h> 69296341Sdelphij# include <openssl/pem.h> 70296341Sdelphij# include <openssl/pkcs12.h> 7155714Skris 72296341Sdelphij# define PROG pkcs12_main 7355714Skris 74109998Smarkmconst EVP_CIPHER *enc; 7555714Skris 76296341Sdelphij# define NOKEYS 0x1 77296341Sdelphij# define NOCERTS 0x2 78296341Sdelphij# define INFO 0x4 79296341Sdelphij# define CLCERTS 0x8 80296341Sdelphij# define CACERTS 0x10 8155714Skris 82296341Sdelphijint get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain); 83296341Sdelphijint dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, 84296341Sdelphij int options, char *pempass); 85296341Sdelphijint dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, 86296341Sdelphij char *pass, int passlen, int options, 87296341Sdelphij char *pempass); 88296341Sdelphijint dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, 89296341Sdelphij int passlen, int options, char *pempass); 90296341Sdelphijint print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, 91296341Sdelphij const char *name); 9255714Skrisvoid hex_prin(BIO *out, unsigned char *buf, int len); 9355714Skrisint alg_print(BIO *x, X509_ALGOR *alg); 9455714Skrisint cert_load(BIO *in, STACK_OF(X509) *sk); 95238405Sjkimstatic int set_pbe(BIO *err, int *ppbe, const char *str); 9659191Skris 9759191Skrisint MAIN(int, char **); 9859191Skris 9955714Skrisint MAIN(int argc, char **argv) 10055714Skris{ 101109998Smarkm ENGINE *e = NULL; 102296341Sdelphij char *infile = NULL, *outfile = NULL, *keyname = NULL; 103296341Sdelphij char *certfile = NULL; 104296341Sdelphij BIO *in = NULL, *out = NULL; 10555714Skris char **args; 10655714Skris char *name = NULL; 107109998Smarkm char *csp_name = NULL; 108194206Ssimon int add_lmk = 0; 10955714Skris PKCS12 *p12 = NULL; 11055714Skris char pass[50], macpass[50]; 11155714Skris int export_cert = 0; 11255714Skris int options = 0; 11355714Skris int chain = 0; 11455714Skris int badarg = 0; 11555714Skris int iter = PKCS12_DEFAULT_ITER; 11659191Skris int maciter = PKCS12_DEFAULT_ITER; 11755714Skris int twopass = 0; 11855714Skris int keytype = 0; 119264331Sjkim int cert_pbe; 12059191Skris int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 12155714Skris int ret = 1; 12255714Skris int macver = 1; 12355714Skris int noprompt = 0; 124238405Sjkim STACK_OF(OPENSSL_STRING) *canames = NULL; 12555714Skris char *cpass = NULL, *mpass = NULL; 12659191Skris char *passargin = NULL, *passargout = NULL, *passarg = NULL; 12759191Skris char *passin = NULL, *passout = NULL; 12859191Skris char *inrand = NULL; 129238405Sjkim char *macalg = NULL; 13068651Skris char *CApath = NULL, *CAfile = NULL; 131296341Sdelphij# ifndef OPENSSL_NO_ENGINE 132296341Sdelphij char *engine = NULL; 133296341Sdelphij# endif 13455714Skris 13555714Skris apps_startup(); 13655714Skris 137296341Sdelphij# ifdef OPENSSL_FIPS 138264331Sjkim if (FIPS_mode()) 139296341Sdelphij cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 140264331Sjkim else 141296341Sdelphij# endif 142296341Sdelphij cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; 143264331Sjkim 14455714Skris enc = EVP_des_ede3_cbc(); 145296341Sdelphij if (bio_err == NULL) 146296341Sdelphij bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 14755714Skris 148296341Sdelphij if (!load_config(bio_err, NULL)) 149296341Sdelphij goto end; 150109998Smarkm 15155714Skris args = argv + 1; 15255714Skris 15355714Skris while (*args) { 154296341Sdelphij if (*args[0] == '-') { 155296341Sdelphij if (!strcmp(*args, "-nokeys")) 156296341Sdelphij options |= NOKEYS; 157296341Sdelphij else if (!strcmp(*args, "-keyex")) 158296341Sdelphij keytype = KEY_EX; 159296341Sdelphij else if (!strcmp(*args, "-keysig")) 160296341Sdelphij keytype = KEY_SIG; 161296341Sdelphij else if (!strcmp(*args, "-nocerts")) 162296341Sdelphij options |= NOCERTS; 163296341Sdelphij else if (!strcmp(*args, "-clcerts")) 164296341Sdelphij options |= CLCERTS; 165296341Sdelphij else if (!strcmp(*args, "-cacerts")) 166296341Sdelphij options |= CACERTS; 167296341Sdelphij else if (!strcmp(*args, "-noout")) 168296341Sdelphij options |= (NOKEYS | NOCERTS); 169296341Sdelphij else if (!strcmp(*args, "-info")) 170296341Sdelphij options |= INFO; 171296341Sdelphij else if (!strcmp(*args, "-chain")) 172296341Sdelphij chain = 1; 173296341Sdelphij else if (!strcmp(*args, "-twopass")) 174296341Sdelphij twopass = 1; 175296341Sdelphij else if (!strcmp(*args, "-nomacver")) 176296341Sdelphij macver = 0; 177296341Sdelphij else if (!strcmp(*args, "-descert")) 178296341Sdelphij cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 179296341Sdelphij else if (!strcmp(*args, "-export")) 180296341Sdelphij export_cert = 1; 181296341Sdelphij else if (!strcmp(*args, "-des")) 182296341Sdelphij enc = EVP_des_cbc(); 183296341Sdelphij else if (!strcmp(*args, "-des3")) 184296341Sdelphij enc = EVP_des_ede3_cbc(); 185296341Sdelphij# ifndef OPENSSL_NO_IDEA 186296341Sdelphij else if (!strcmp(*args, "-idea")) 187296341Sdelphij enc = EVP_idea_cbc(); 188296341Sdelphij# endif 189296341Sdelphij# ifndef OPENSSL_NO_SEED 190296341Sdelphij else if (!strcmp(*args, "-seed")) 191296341Sdelphij enc = EVP_seed_cbc(); 192296341Sdelphij# endif 193296341Sdelphij# ifndef OPENSSL_NO_AES 194296341Sdelphij else if (!strcmp(*args, "-aes128")) 195296341Sdelphij enc = EVP_aes_128_cbc(); 196296341Sdelphij else if (!strcmp(*args, "-aes192")) 197296341Sdelphij enc = EVP_aes_192_cbc(); 198296341Sdelphij else if (!strcmp(*args, "-aes256")) 199296341Sdelphij enc = EVP_aes_256_cbc(); 200296341Sdelphij# endif 201296341Sdelphij# ifndef OPENSSL_NO_CAMELLIA 202296341Sdelphij else if (!strcmp(*args, "-camellia128")) 203296341Sdelphij enc = EVP_camellia_128_cbc(); 204296341Sdelphij else if (!strcmp(*args, "-camellia192")) 205296341Sdelphij enc = EVP_camellia_192_cbc(); 206296341Sdelphij else if (!strcmp(*args, "-camellia256")) 207296341Sdelphij enc = EVP_camellia_256_cbc(); 208296341Sdelphij# endif 209296341Sdelphij else if (!strcmp(*args, "-noiter")) 210296341Sdelphij iter = 1; 211296341Sdelphij else if (!strcmp(*args, "-maciter")) 212296341Sdelphij maciter = PKCS12_DEFAULT_ITER; 213296341Sdelphij else if (!strcmp(*args, "-nomaciter")) 214296341Sdelphij maciter = 1; 215296341Sdelphij else if (!strcmp(*args, "-nomac")) 216296341Sdelphij maciter = -1; 217296341Sdelphij else if (!strcmp(*args, "-macalg")) 218296341Sdelphij if (args[1]) { 219296341Sdelphij args++; 220296341Sdelphij macalg = *args; 221296341Sdelphij } else 222296341Sdelphij badarg = 1; 223296341Sdelphij else if (!strcmp(*args, "-nodes")) 224296341Sdelphij enc = NULL; 225296341Sdelphij else if (!strcmp(*args, "-certpbe")) { 226296341Sdelphij if (!set_pbe(bio_err, &cert_pbe, *++args)) 227296341Sdelphij badarg = 1; 228296341Sdelphij } else if (!strcmp(*args, "-keypbe")) { 229296341Sdelphij if (!set_pbe(bio_err, &key_pbe, *++args)) 230296341Sdelphij badarg = 1; 231296341Sdelphij } else if (!strcmp(*args, "-rand")) { 232296341Sdelphij if (args[1]) { 233296341Sdelphij args++; 234296341Sdelphij inrand = *args; 235296341Sdelphij } else 236296341Sdelphij badarg = 1; 237296341Sdelphij } else if (!strcmp(*args, "-inkey")) { 238296341Sdelphij if (args[1]) { 239296341Sdelphij args++; 240296341Sdelphij keyname = *args; 241296341Sdelphij } else 242296341Sdelphij badarg = 1; 243296341Sdelphij } else if (!strcmp(*args, "-certfile")) { 244296341Sdelphij if (args[1]) { 245296341Sdelphij args++; 246296341Sdelphij certfile = *args; 247296341Sdelphij } else 248296341Sdelphij badarg = 1; 249296341Sdelphij } else if (!strcmp(*args, "-name")) { 250296341Sdelphij if (args[1]) { 251296341Sdelphij args++; 252296341Sdelphij name = *args; 253296341Sdelphij } else 254296341Sdelphij badarg = 1; 255296341Sdelphij } else if (!strcmp(*args, "-LMK")) 256296341Sdelphij add_lmk = 1; 257296341Sdelphij else if (!strcmp(*args, "-CSP")) { 258296341Sdelphij if (args[1]) { 259296341Sdelphij args++; 260296341Sdelphij csp_name = *args; 261296341Sdelphij } else 262296341Sdelphij badarg = 1; 263296341Sdelphij } else if (!strcmp(*args, "-caname")) { 264296341Sdelphij if (args[1]) { 265296341Sdelphij args++; 266296341Sdelphij if (!canames) 267296341Sdelphij canames = sk_OPENSSL_STRING_new_null(); 268296341Sdelphij sk_OPENSSL_STRING_push(canames, *args); 269296341Sdelphij } else 270296341Sdelphij badarg = 1; 271296341Sdelphij } else if (!strcmp(*args, "-in")) { 272296341Sdelphij if (args[1]) { 273296341Sdelphij args++; 274296341Sdelphij infile = *args; 275296341Sdelphij } else 276296341Sdelphij badarg = 1; 277296341Sdelphij } else if (!strcmp(*args, "-out")) { 278296341Sdelphij if (args[1]) { 279296341Sdelphij args++; 280296341Sdelphij outfile = *args; 281296341Sdelphij } else 282296341Sdelphij badarg = 1; 283296341Sdelphij } else if (!strcmp(*args, "-passin")) { 284296341Sdelphij if (args[1]) { 285296341Sdelphij args++; 286296341Sdelphij passargin = *args; 287296341Sdelphij } else 288296341Sdelphij badarg = 1; 289296341Sdelphij } else if (!strcmp(*args, "-passout")) { 290296341Sdelphij if (args[1]) { 291296341Sdelphij args++; 292296341Sdelphij passargout = *args; 293296341Sdelphij } else 294296341Sdelphij badarg = 1; 295296341Sdelphij } else if (!strcmp(*args, "-password")) { 296296341Sdelphij if (args[1]) { 297296341Sdelphij args++; 298296341Sdelphij passarg = *args; 299296341Sdelphij noprompt = 1; 300296341Sdelphij } else 301296341Sdelphij badarg = 1; 302296341Sdelphij } else if (!strcmp(*args, "-CApath")) { 303296341Sdelphij if (args[1]) { 304296341Sdelphij args++; 305296341Sdelphij CApath = *args; 306296341Sdelphij } else 307296341Sdelphij badarg = 1; 308296341Sdelphij } else if (!strcmp(*args, "-CAfile")) { 309296341Sdelphij if (args[1]) { 310296341Sdelphij args++; 311296341Sdelphij CAfile = *args; 312296341Sdelphij } else 313296341Sdelphij badarg = 1; 314296341Sdelphij# ifndef OPENSSL_NO_ENGINE 315296341Sdelphij } else if (!strcmp(*args, "-engine")) { 316296341Sdelphij if (args[1]) { 317296341Sdelphij args++; 318296341Sdelphij engine = *args; 319296341Sdelphij } else 320296341Sdelphij badarg = 1; 321296341Sdelphij# endif 322296341Sdelphij } else 323296341Sdelphij badarg = 1; 32455714Skris 325296341Sdelphij } else 326296341Sdelphij badarg = 1; 327296341Sdelphij args++; 32855714Skris } 32955714Skris 33055714Skris if (badarg) { 331296341Sdelphij BIO_printf(bio_err, "Usage: pkcs12 [options]\n"); 332296341Sdelphij BIO_printf(bio_err, "where options are\n"); 333296341Sdelphij BIO_printf(bio_err, "-export output PKCS12 file\n"); 334296341Sdelphij BIO_printf(bio_err, "-chain add certificate chain\n"); 335296341Sdelphij BIO_printf(bio_err, "-inkey file private key if not infile\n"); 336296341Sdelphij BIO_printf(bio_err, "-certfile f add all certs in f\n"); 337296341Sdelphij BIO_printf(bio_err, "-CApath arg - PEM format directory of CA's\n"); 338296341Sdelphij BIO_printf(bio_err, "-CAfile arg - PEM format file of CA's\n"); 339296341Sdelphij BIO_printf(bio_err, "-name \"name\" use name as friendly name\n"); 340296341Sdelphij BIO_printf(bio_err, 341296341Sdelphij "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); 342296341Sdelphij BIO_printf(bio_err, "-in infile input filename\n"); 343296341Sdelphij BIO_printf(bio_err, "-out outfile output filename\n"); 344296341Sdelphij BIO_printf(bio_err, 345296341Sdelphij "-noout don't output anything, just verify.\n"); 346296341Sdelphij BIO_printf(bio_err, "-nomacver don't verify MAC.\n"); 347296341Sdelphij BIO_printf(bio_err, "-nocerts don't output certificates.\n"); 348296341Sdelphij BIO_printf(bio_err, 349296341Sdelphij "-clcerts only output client certificates.\n"); 350296341Sdelphij BIO_printf(bio_err, "-cacerts only output CA certificates.\n"); 351296341Sdelphij BIO_printf(bio_err, "-nokeys don't output private keys.\n"); 352296341Sdelphij BIO_printf(bio_err, 353296341Sdelphij "-info give info about PKCS#12 structure.\n"); 354296341Sdelphij BIO_printf(bio_err, "-des encrypt private keys with DES\n"); 355296341Sdelphij BIO_printf(bio_err, 356296341Sdelphij "-des3 encrypt private keys with triple DES (default)\n"); 357296341Sdelphij# ifndef OPENSSL_NO_IDEA 358296341Sdelphij BIO_printf(bio_err, "-idea encrypt private keys with idea\n"); 359296341Sdelphij# endif 360296341Sdelphij# ifndef OPENSSL_NO_SEED 361296341Sdelphij BIO_printf(bio_err, "-seed encrypt private keys with seed\n"); 362296341Sdelphij# endif 363296341Sdelphij# ifndef OPENSSL_NO_AES 364296341Sdelphij BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); 365296341Sdelphij BIO_printf(bio_err, 366296341Sdelphij " encrypt PEM output with cbc aes\n"); 367296341Sdelphij# endif 368296341Sdelphij# ifndef OPENSSL_NO_CAMELLIA 369296341Sdelphij BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); 370296341Sdelphij BIO_printf(bio_err, 371296341Sdelphij " encrypt PEM output with cbc camellia\n"); 372296341Sdelphij# endif 373296341Sdelphij BIO_printf(bio_err, "-nodes don't encrypt private keys\n"); 374296341Sdelphij BIO_printf(bio_err, "-noiter don't use encryption iteration\n"); 375296341Sdelphij BIO_printf(bio_err, "-nomaciter don't use MAC iteration\n"); 376296341Sdelphij BIO_printf(bio_err, "-maciter use MAC iteration\n"); 377296341Sdelphij BIO_printf(bio_err, "-nomac don't generate MAC\n"); 378296341Sdelphij BIO_printf(bio_err, 379296341Sdelphij "-twopass separate MAC, encryption passwords\n"); 380296341Sdelphij BIO_printf(bio_err, 381296341Sdelphij "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); 382296341Sdelphij BIO_printf(bio_err, 383296341Sdelphij "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); 384296341Sdelphij BIO_printf(bio_err, 385296341Sdelphij "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); 386296341Sdelphij BIO_printf(bio_err, 387296341Sdelphij "-macalg alg digest algorithm used in MAC (default SHA1)\n"); 388296341Sdelphij BIO_printf(bio_err, "-keyex set MS key exchange type\n"); 389296341Sdelphij BIO_printf(bio_err, "-keysig set MS key signature type\n"); 390296341Sdelphij BIO_printf(bio_err, 391296341Sdelphij "-password p set import/export password source\n"); 392296341Sdelphij BIO_printf(bio_err, "-passin p input file pass phrase source\n"); 393296341Sdelphij BIO_printf(bio_err, "-passout p output file pass phrase source\n"); 394296341Sdelphij# ifndef OPENSSL_NO_ENGINE 395296341Sdelphij BIO_printf(bio_err, 396296341Sdelphij "-engine e use engine e, possibly a hardware device.\n"); 397296341Sdelphij# endif 398296341Sdelphij BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, 399296341Sdelphij LIST_SEPARATOR_CHAR); 400296341Sdelphij BIO_printf(bio_err, 401296341Sdelphij " load the file (or the files in the directory) into\n"); 402296341Sdelphij BIO_printf(bio_err, " the random number generator\n"); 403296341Sdelphij BIO_printf(bio_err, "-CSP name Microsoft CSP name\n"); 404296341Sdelphij BIO_printf(bio_err, 405296341Sdelphij "-LMK Add local machine keyset attribute to private key\n"); 406296341Sdelphij goto end; 40755714Skris } 408296341Sdelphij# ifndef OPENSSL_NO_ENGINE 409109998Smarkm e = setup_engine(bio_err, engine, 0); 410296341Sdelphij# endif 411109998Smarkm 412296341Sdelphij if (passarg) { 413296341Sdelphij if (export_cert) 414296341Sdelphij passargout = passarg; 415296341Sdelphij else 416296341Sdelphij passargin = passarg; 41759191Skris } 41859191Skris 419296341Sdelphij if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 420296341Sdelphij BIO_printf(bio_err, "Error getting passwords\n"); 421296341Sdelphij goto end; 42259191Skris } 42359191Skris 424296341Sdelphij if (!cpass) { 425296341Sdelphij if (export_cert) 426296341Sdelphij cpass = passout; 427296341Sdelphij else 428296341Sdelphij cpass = passin; 42959191Skris } 43059191Skris 431296341Sdelphij if (cpass) { 432296341Sdelphij mpass = cpass; 433296341Sdelphij noprompt = 1; 43459191Skris } else { 435296341Sdelphij cpass = pass; 436296341Sdelphij mpass = macpass; 43755714Skris } 43855714Skris 439296341Sdelphij if (export_cert || inrand) { 440296341Sdelphij app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 44159191Skris if (inrand != NULL) 442296341Sdelphij BIO_printf(bio_err, "%ld semi-random bytes loaded\n", 443296341Sdelphij app_RAND_load_files(inrand)); 44459191Skris } 44555714Skris ERR_load_crypto_strings(); 44655714Skris 447296341Sdelphij# ifdef CRYPTO_MDEBUG 44859191Skris CRYPTO_push_info("read files"); 449296341Sdelphij# endif 45059191Skris 451296341Sdelphij if (!infile) 452296341Sdelphij in = BIO_new_fp(stdin, BIO_NOCLOSE); 453296341Sdelphij else 454296341Sdelphij in = BIO_new_file(infile, "rb"); 45555714Skris if (!in) { 456296341Sdelphij BIO_printf(bio_err, "Error opening input file %s\n", 457296341Sdelphij infile ? infile : "<stdin>"); 458296341Sdelphij perror(infile); 459296341Sdelphij goto end; 460296341Sdelphij } 461296341Sdelphij# ifdef CRYPTO_MDEBUG 46259191Skris CRYPTO_pop_info(); 46359191Skris CRYPTO_push_info("write files"); 464296341Sdelphij# endif 46559191Skris 46668651Skris if (!outfile) { 467296341Sdelphij out = BIO_new_fp(stdout, BIO_NOCLOSE); 468296341Sdelphij# ifdef OPENSSL_SYS_VMS 469296341Sdelphij { 470296341Sdelphij BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 471296341Sdelphij out = BIO_push(tmpbio, out); 472296341Sdelphij } 473296341Sdelphij# endif 474296341Sdelphij } else 475296341Sdelphij out = BIO_new_file(outfile, "wb"); 47655714Skris if (!out) { 477296341Sdelphij BIO_printf(bio_err, "Error opening output file %s\n", 478296341Sdelphij outfile ? outfile : "<stdout>"); 479296341Sdelphij perror(outfile); 480296341Sdelphij goto end; 48155714Skris } 48255714Skris if (twopass) { 483296341Sdelphij# ifdef CRYPTO_MDEBUG 484296341Sdelphij CRYPTO_push_info("read MAC password"); 485296341Sdelphij# endif 486296341Sdelphij if (EVP_read_pw_string 487296341Sdelphij (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { 488296341Sdelphij BIO_printf(bio_err, "Can't read Password\n"); 489296341Sdelphij goto end; 490296341Sdelphij } 491296341Sdelphij# ifdef CRYPTO_MDEBUG 492296341Sdelphij CRYPTO_pop_info(); 493296341Sdelphij# endif 49455714Skris } 49555714Skris 49659191Skris if (export_cert) { 497296341Sdelphij EVP_PKEY *key = NULL; 498296341Sdelphij X509 *ucert = NULL, *x = NULL; 499296341Sdelphij STACK_OF(X509) *certs = NULL; 500296341Sdelphij const EVP_MD *macmd = NULL; 501296341Sdelphij unsigned char *catmp = NULL; 502296341Sdelphij int i; 50359191Skris 504296341Sdelphij if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { 505296341Sdelphij BIO_printf(bio_err, "Nothing to do!\n"); 506296341Sdelphij goto export_end; 507296341Sdelphij } 508160814Ssimon 509296341Sdelphij if (options & NOCERTS) 510296341Sdelphij chain = 0; 511160814Ssimon 512296341Sdelphij# ifdef CRYPTO_MDEBUG 513296341Sdelphij CRYPTO_push_info("process -export_cert"); 514296341Sdelphij CRYPTO_push_info("reading private key"); 515296341Sdelphij# endif 516296341Sdelphij if (!(options & NOKEYS)) { 517296341Sdelphij key = load_key(bio_err, keyname ? keyname : infile, 518296341Sdelphij FORMAT_PEM, 1, passin, e, "private key"); 519296341Sdelphij if (!key) 520296341Sdelphij goto export_end; 521296341Sdelphij } 522296341Sdelphij# ifdef CRYPTO_MDEBUG 523296341Sdelphij CRYPTO_pop_info(); 524296341Sdelphij CRYPTO_push_info("reading certs from input"); 525296341Sdelphij# endif 52655714Skris 527296341Sdelphij /* Load in all certs in input file */ 528296341Sdelphij if (!(options & NOCERTS)) { 529296341Sdelphij certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, 530296341Sdelphij "certificates"); 531296341Sdelphij if (!certs) 532296341Sdelphij goto export_end; 53355714Skris 534296341Sdelphij if (key) { 535296341Sdelphij /* Look for matching private key */ 536296341Sdelphij for (i = 0; i < sk_X509_num(certs); i++) { 537296341Sdelphij x = sk_X509_value(certs, i); 538296341Sdelphij if (X509_check_private_key(x, key)) { 539296341Sdelphij ucert = x; 540296341Sdelphij /* Zero keyid and alias */ 541296341Sdelphij X509_keyid_set1(ucert, NULL, 0); 542296341Sdelphij X509_alias_set1(ucert, NULL, 0); 543296341Sdelphij /* Remove from list */ 544296341Sdelphij (void)sk_X509_delete(certs, i); 545296341Sdelphij break; 546296341Sdelphij } 547296341Sdelphij } 548296341Sdelphij if (!ucert) { 549296341Sdelphij BIO_printf(bio_err, 550296341Sdelphij "No certificate matches private key\n"); 551296341Sdelphij goto export_end; 552296341Sdelphij } 553296341Sdelphij } 55455714Skris 555296341Sdelphij } 556296341Sdelphij# ifdef CRYPTO_MDEBUG 557296341Sdelphij CRYPTO_pop_info(); 558296341Sdelphij CRYPTO_push_info("reading certs from input 2"); 559296341Sdelphij# endif 56068651Skris 561296341Sdelphij /* Add any more certificates asked for */ 562296341Sdelphij if (certfile) { 563296341Sdelphij STACK_OF(X509) *morecerts = NULL; 564296341Sdelphij if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, 565296341Sdelphij NULL, e, 566296341Sdelphij "certificates from certfile"))) 567296341Sdelphij goto export_end; 568296341Sdelphij while (sk_X509_num(morecerts) > 0) 569296341Sdelphij sk_X509_push(certs, sk_X509_shift(morecerts)); 570296341Sdelphij sk_X509_free(morecerts); 571296341Sdelphij } 572296341Sdelphij# ifdef CRYPTO_MDEBUG 573296341Sdelphij CRYPTO_pop_info(); 574296341Sdelphij CRYPTO_push_info("reading certs from certfile"); 575296341Sdelphij# endif 576160814Ssimon 577296341Sdelphij# ifdef CRYPTO_MDEBUG 578296341Sdelphij CRYPTO_pop_info(); 579296341Sdelphij CRYPTO_push_info("building chain"); 580296341Sdelphij# endif 58155714Skris 582296341Sdelphij /* If chaining get chain from user cert */ 583296341Sdelphij if (chain) { 584296341Sdelphij int vret; 585296341Sdelphij STACK_OF(X509) *chain2; 586296341Sdelphij X509_STORE *store = X509_STORE_new(); 587296341Sdelphij if (!store) { 588296341Sdelphij BIO_printf(bio_err, "Memory allocation error\n"); 589296341Sdelphij goto export_end; 590296341Sdelphij } 591296341Sdelphij if (!X509_STORE_load_locations(store, CAfile, CApath)) 592296341Sdelphij X509_STORE_set_default_paths(store); 59355714Skris 594296341Sdelphij vret = get_cert_chain(ucert, store, &chain2); 595296341Sdelphij X509_STORE_free(store); 596160814Ssimon 597296341Sdelphij if (!vret) { 598296341Sdelphij /* Exclude verified certificate */ 599296341Sdelphij for (i = 1; i < sk_X509_num(chain2); i++) 600296341Sdelphij sk_X509_push(certs, sk_X509_value(chain2, i)); 601296341Sdelphij /* Free first certificate */ 602296341Sdelphij X509_free(sk_X509_value(chain2, 0)); 603296341Sdelphij sk_X509_free(chain2); 604296341Sdelphij } else { 605296341Sdelphij if (vret >= 0) 606296341Sdelphij BIO_printf(bio_err, "Error %s getting chain.\n", 607296341Sdelphij X509_verify_cert_error_string(vret)); 608296341Sdelphij else 609296341Sdelphij ERR_print_errors(bio_err); 610296341Sdelphij goto export_end; 611296341Sdelphij } 612296341Sdelphij } 61368651Skris 614296341Sdelphij /* Add any CA names */ 61568651Skris 616296341Sdelphij for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) { 617296341Sdelphij catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i); 618296341Sdelphij X509_alias_set1(sk_X509_value(certs, i), catmp, -1); 619296341Sdelphij } 62068651Skris 621296341Sdelphij if (csp_name && key) 622296341Sdelphij EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, 623296341Sdelphij MBSTRING_ASC, (unsigned char *)csp_name, 624296341Sdelphij -1); 62555714Skris 626296341Sdelphij if (add_lmk && key) 627296341Sdelphij EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); 62868651Skris 629296341Sdelphij# ifdef CRYPTO_MDEBUG 630296341Sdelphij CRYPTO_pop_info(); 631296341Sdelphij CRYPTO_push_info("reading password"); 632296341Sdelphij# endif 63355714Skris 634296341Sdelphij if (!noprompt && 635296341Sdelphij EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 636296341Sdelphij 1)) { 637296341Sdelphij BIO_printf(bio_err, "Can't read Password\n"); 638296341Sdelphij goto export_end; 639296341Sdelphij } 640296341Sdelphij if (!twopass) 641296341Sdelphij BUF_strlcpy(macpass, pass, sizeof macpass); 642160814Ssimon 643296341Sdelphij# ifdef CRYPTO_MDEBUG 644296341Sdelphij CRYPTO_pop_info(); 645296341Sdelphij CRYPTO_push_info("creating PKCS#12 structure"); 646296341Sdelphij# endif 647194206Ssimon 648296341Sdelphij p12 = PKCS12_create(cpass, name, key, ucert, certs, 649296341Sdelphij key_pbe, cert_pbe, iter, -1, keytype); 65068651Skris 651296341Sdelphij if (!p12) { 652296341Sdelphij ERR_print_errors(bio_err); 653296341Sdelphij goto export_end; 654296341Sdelphij } 65555714Skris 656296341Sdelphij if (macalg) { 657296341Sdelphij macmd = EVP_get_digestbyname(macalg); 658296341Sdelphij if (!macmd) { 659296341Sdelphij BIO_printf(bio_err, "Unknown digest algorithm %s\n", macalg); 660296341Sdelphij } 661296341Sdelphij } 66268651Skris 663296341Sdelphij if (maciter != -1) 664296341Sdelphij PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); 66568651Skris 666296341Sdelphij# ifdef CRYPTO_MDEBUG 667296341Sdelphij CRYPTO_pop_info(); 668296341Sdelphij CRYPTO_push_info("writing pkcs12"); 669296341Sdelphij# endif 67068651Skris 671296341Sdelphij i2d_PKCS12_bio(out, p12); 672238405Sjkim 673296341Sdelphij ret = 0; 67455714Skris 675296341Sdelphij export_end: 676296341Sdelphij# ifdef CRYPTO_MDEBUG 677296341Sdelphij CRYPTO_pop_info(); 678296341Sdelphij CRYPTO_pop_info(); 679296341Sdelphij CRYPTO_push_info("process -export_cert: freeing"); 680296341Sdelphij# endif 68168651Skris 682296341Sdelphij if (key) 683296341Sdelphij EVP_PKEY_free(key); 684296341Sdelphij if (certs) 685296341Sdelphij sk_X509_pop_free(certs, X509_free); 686296341Sdelphij if (ucert) 687296341Sdelphij X509_free(ucert); 68855714Skris 689296341Sdelphij# ifdef CRYPTO_MDEBUG 690296341Sdelphij CRYPTO_pop_info(); 691296341Sdelphij# endif 692296341Sdelphij goto end; 69359191Skris 69455714Skris } 69555714Skris 696296341Sdelphij if (!(p12 = d2i_PKCS12_bio(in, NULL))) { 697296341Sdelphij ERR_print_errors(bio_err); 698296341Sdelphij goto end; 69955714Skris } 700296341Sdelphij# ifdef CRYPTO_MDEBUG 70159191Skris CRYPTO_push_info("read import password"); 702296341Sdelphij# endif 703296341Sdelphij if (!noprompt 704296341Sdelphij && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 705296341Sdelphij 0)) { 706296341Sdelphij BIO_printf(bio_err, "Can't read Password\n"); 707296341Sdelphij goto end; 70855714Skris } 709296341Sdelphij# ifdef CRYPTO_MDEBUG 71059191Skris CRYPTO_pop_info(); 711296341Sdelphij# endif 71255714Skris 713296341Sdelphij if (!twopass) 714296341Sdelphij BUF_strlcpy(macpass, pass, sizeof macpass); 71555714Skris 716296341Sdelphij if ((options & INFO) && p12->mac) 717296341Sdelphij BIO_printf(bio_err, "MAC Iteration %ld\n", 718296341Sdelphij p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1); 719296341Sdelphij if (macver) { 720296341Sdelphij# ifdef CRYPTO_MDEBUG 721296341Sdelphij CRYPTO_push_info("verify MAC"); 722296341Sdelphij# endif 723296341Sdelphij /* If we enter empty password try no password first */ 724296341Sdelphij if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { 725296341Sdelphij /* If mac and crypto pass the same set it to NULL too */ 726296341Sdelphij if (!twopass) 727296341Sdelphij cpass = NULL; 728296341Sdelphij } else if (!PKCS12_verify_mac(p12, mpass, -1)) { 729296341Sdelphij BIO_printf(bio_err, "Mac verify error: invalid password?\n"); 730296341Sdelphij ERR_print_errors(bio_err); 731296341Sdelphij goto end; 732296341Sdelphij } 733296341Sdelphij BIO_printf(bio_err, "MAC verified OK\n"); 734296341Sdelphij# ifdef CRYPTO_MDEBUG 735296341Sdelphij CRYPTO_pop_info(); 736296341Sdelphij# endif 73755714Skris } 738296341Sdelphij# ifdef CRYPTO_MDEBUG 73959191Skris CRYPTO_push_info("output keys and certificates"); 740296341Sdelphij# endif 741296341Sdelphij if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) { 742296341Sdelphij BIO_printf(bio_err, "Error outputting keys and certificates\n"); 743296341Sdelphij ERR_print_errors(bio_err); 744296341Sdelphij goto end; 74555714Skris } 746296341Sdelphij# ifdef CRYPTO_MDEBUG 74759191Skris CRYPTO_pop_info(); 748296341Sdelphij# endif 74955714Skris ret = 0; 75068651Skris end: 751296341Sdelphij if (p12) 752296341Sdelphij PKCS12_free(p12); 753296341Sdelphij if (export_cert || inrand) 754296341Sdelphij app_RAND_write_file(NULL, bio_err); 755296341Sdelphij# ifdef CRYPTO_MDEBUG 75659191Skris CRYPTO_remove_all_info(); 757296341Sdelphij# endif 75859191Skris BIO_free(in); 75968651Skris BIO_free_all(out); 760296341Sdelphij if (canames) 761296341Sdelphij sk_OPENSSL_STRING_free(canames); 762296341Sdelphij if (passin) 763296341Sdelphij OPENSSL_free(passin); 764296341Sdelphij if (passout) 765296341Sdelphij OPENSSL_free(passout); 766109998Smarkm apps_shutdown(); 767109998Smarkm OPENSSL_EXIT(ret); 76855714Skris} 76955714Skris 770296341Sdelphijint dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, 771296341Sdelphij int passlen, int options, char *pempass) 77255714Skris{ 773296341Sdelphij STACK_OF(PKCS7) *asafes = NULL; 774296341Sdelphij STACK_OF(PKCS12_SAFEBAG) *bags; 775296341Sdelphij int i, bagnid; 776296341Sdelphij int ret = 0; 777296341Sdelphij PKCS7 *p7; 77868651Skris 779296341Sdelphij if (!(asafes = PKCS12_unpack_authsafes(p12))) 780296341Sdelphij return 0; 781296341Sdelphij for (i = 0; i < sk_PKCS7_num(asafes); i++) { 782296341Sdelphij p7 = sk_PKCS7_value(asafes, i); 783296341Sdelphij bagnid = OBJ_obj2nid(p7->type); 784296341Sdelphij if (bagnid == NID_pkcs7_data) { 785296341Sdelphij bags = PKCS12_unpack_p7data(p7); 786296341Sdelphij if (options & INFO) 787296341Sdelphij BIO_printf(bio_err, "PKCS7 Data\n"); 788296341Sdelphij } else if (bagnid == NID_pkcs7_encrypted) { 789296341Sdelphij if (options & INFO) { 790296341Sdelphij BIO_printf(bio_err, "PKCS7 Encrypted data: "); 791296341Sdelphij alg_print(bio_err, p7->d.encrypted->enc_data->algorithm); 792296341Sdelphij } 793296341Sdelphij bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 794296341Sdelphij } else 795296341Sdelphij continue; 796296341Sdelphij if (!bags) 797296341Sdelphij goto err; 798296341Sdelphij if (!dump_certs_pkeys_bags(out, bags, pass, passlen, 799296341Sdelphij options, pempass)) { 800296341Sdelphij sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 801296341Sdelphij goto err; 802296341Sdelphij } 803296341Sdelphij sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 804296341Sdelphij bags = NULL; 805296341Sdelphij } 806296341Sdelphij ret = 1; 807160814Ssimon 808296341Sdelphij err: 809160814Ssimon 810296341Sdelphij if (asafes) 811296341Sdelphij sk_PKCS7_pop_free(asafes, PKCS7_free); 812296341Sdelphij return ret; 81355714Skris} 81455714Skris 815296341Sdelphijint dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, 816296341Sdelphij char *pass, int passlen, int options, char *pempass) 81755714Skris{ 818296341Sdelphij int i; 819296341Sdelphij for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 820296341Sdelphij if (!dump_certs_pkeys_bag(out, 821296341Sdelphij sk_PKCS12_SAFEBAG_value(bags, i), 822296341Sdelphij pass, passlen, options, pempass)) 823296341Sdelphij return 0; 824296341Sdelphij } 825296341Sdelphij return 1; 82655714Skris} 82755714Skris 828296341Sdelphijint dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, 829296341Sdelphij int passlen, int options, char *pempass) 83055714Skris{ 831296341Sdelphij EVP_PKEY *pkey; 832296341Sdelphij PKCS8_PRIV_KEY_INFO *p8; 833296341Sdelphij X509 *x509; 83455714Skris 835296341Sdelphij switch (M_PKCS12_bag_type(bag)) { 836296341Sdelphij case NID_keyBag: 837296341Sdelphij if (options & INFO) 838296341Sdelphij BIO_printf(bio_err, "Key bag\n"); 839296341Sdelphij if (options & NOKEYS) 840296341Sdelphij return 1; 841296341Sdelphij print_attribs(out, bag->attrib, "Bag Attributes"); 842296341Sdelphij p8 = bag->value.keybag; 843296341Sdelphij if (!(pkey = EVP_PKCS82PKEY(p8))) 844296341Sdelphij return 0; 845296341Sdelphij print_attribs(out, p8->attributes, "Key Attributes"); 846296341Sdelphij PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); 847296341Sdelphij EVP_PKEY_free(pkey); 848296341Sdelphij break; 84955714Skris 850296341Sdelphij case NID_pkcs8ShroudedKeyBag: 851296341Sdelphij if (options & INFO) { 852296341Sdelphij BIO_printf(bio_err, "Shrouded Keybag: "); 853296341Sdelphij alg_print(bio_err, bag->value.shkeybag->algor); 854296341Sdelphij } 855296341Sdelphij if (options & NOKEYS) 856296341Sdelphij return 1; 857296341Sdelphij print_attribs(out, bag->attrib, "Bag Attributes"); 858296341Sdelphij if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 859296341Sdelphij return 0; 860296341Sdelphij if (!(pkey = EVP_PKCS82PKEY(p8))) { 861296341Sdelphij PKCS8_PRIV_KEY_INFO_free(p8); 862296341Sdelphij return 0; 863296341Sdelphij } 864296341Sdelphij print_attribs(out, p8->attributes, "Key Attributes"); 865296341Sdelphij PKCS8_PRIV_KEY_INFO_free(p8); 866296341Sdelphij PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); 867296341Sdelphij EVP_PKEY_free(pkey); 868296341Sdelphij break; 86955714Skris 870296341Sdelphij case NID_certBag: 871296341Sdelphij if (options & INFO) 872296341Sdelphij BIO_printf(bio_err, "Certificate bag\n"); 873296341Sdelphij if (options & NOCERTS) 874296341Sdelphij return 1; 875296341Sdelphij if (PKCS12_get_attr(bag, NID_localKeyID)) { 876296341Sdelphij if (options & CACERTS) 877296341Sdelphij return 1; 878296341Sdelphij } else if (options & CLCERTS) 879296341Sdelphij return 1; 880296341Sdelphij print_attribs(out, bag->attrib, "Bag Attributes"); 881296341Sdelphij if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) 882296341Sdelphij return 1; 883296341Sdelphij if (!(x509 = PKCS12_certbag2x509(bag))) 884296341Sdelphij return 0; 885296341Sdelphij dump_cert_text(out, x509); 886296341Sdelphij PEM_write_bio_X509(out, x509); 887296341Sdelphij X509_free(x509); 888296341Sdelphij break; 889296341Sdelphij 890296341Sdelphij case NID_safeContentsBag: 891296341Sdelphij if (options & INFO) 892296341Sdelphij BIO_printf(bio_err, "Safe Contents bag\n"); 893296341Sdelphij print_attribs(out, bag->attrib, "Bag Attributes"); 894296341Sdelphij return dump_certs_pkeys_bags(out, bag->value.safes, pass, 895296341Sdelphij passlen, options, pempass); 896296341Sdelphij 897296341Sdelphij default: 898296341Sdelphij BIO_printf(bio_err, "Warning unsupported bag type: "); 899296341Sdelphij i2a_ASN1_OBJECT(bio_err, bag->type); 900296341Sdelphij BIO_printf(bio_err, "\n"); 901296341Sdelphij return 1; 902296341Sdelphij break; 903296341Sdelphij } 904296341Sdelphij return 1; 90555714Skris} 90655714Skris 90755714Skris/* Given a single certificate return a verified chain or NULL if error */ 90855714Skris 90955714Skris/* Hope this is OK .... */ 91055714Skris 911296341Sdelphijint get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) 91255714Skris{ 913296341Sdelphij X509_STORE_CTX store_ctx; 914296341Sdelphij STACK_OF(X509) *chn; 915296341Sdelphij int i = 0; 91659191Skris 917296341Sdelphij /* 918296341Sdelphij * FIXME: Should really check the return status of X509_STORE_CTX_init 919296341Sdelphij * for an error, but how that fits into the return value of this function 920296341Sdelphij * is less obvious. 921296341Sdelphij */ 922296341Sdelphij X509_STORE_CTX_init(&store_ctx, store, cert, NULL); 923296341Sdelphij if (X509_verify_cert(&store_ctx) <= 0) { 924296341Sdelphij i = X509_STORE_CTX_get_error(&store_ctx); 925296341Sdelphij if (i == 0) 926296341Sdelphij /* 927296341Sdelphij * avoid returning 0 if X509_verify_cert() did not set an 928296341Sdelphij * appropriate error value in the context 929296341Sdelphij */ 930296341Sdelphij i = -1; 931296341Sdelphij chn = NULL; 932296341Sdelphij goto err; 933296341Sdelphij } else 934296341Sdelphij chn = X509_STORE_CTX_get1_chain(&store_ctx); 935296341Sdelphij err: 936296341Sdelphij X509_STORE_CTX_cleanup(&store_ctx); 937296341Sdelphij *chain = chn; 93855714Skris 939296341Sdelphij return i; 940296341Sdelphij} 941296341Sdelphij 942296341Sdelphijint alg_print(BIO *x, X509_ALGOR *alg) 94355714Skris{ 944296341Sdelphij PBEPARAM *pbe; 945296341Sdelphij const unsigned char *p; 946296341Sdelphij p = alg->parameter->value.sequence->data; 947296341Sdelphij pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); 948296341Sdelphij if (!pbe) 949296341Sdelphij return 1; 950296341Sdelphij BIO_printf(bio_err, "%s, Iteration %ld\n", 951296341Sdelphij OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), 952296341Sdelphij ASN1_INTEGER_get(pbe->iter)); 953296341Sdelphij PBEPARAM_free(pbe); 954296341Sdelphij return 1; 95555714Skris} 95655714Skris 95755714Skris/* Load all certificates from a given file */ 95855714Skris 95955714Skrisint cert_load(BIO *in, STACK_OF(X509) *sk) 96055714Skris{ 961296341Sdelphij int ret; 962296341Sdelphij X509 *cert; 963296341Sdelphij ret = 0; 964296341Sdelphij# ifdef CRYPTO_MDEBUG 965296341Sdelphij CRYPTO_push_info("cert_load(): reading one cert"); 966296341Sdelphij# endif 967296341Sdelphij while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) { 968296341Sdelphij# ifdef CRYPTO_MDEBUG 969296341Sdelphij CRYPTO_pop_info(); 970296341Sdelphij# endif 971296341Sdelphij ret = 1; 972296341Sdelphij sk_X509_push(sk, cert); 973296341Sdelphij# ifdef CRYPTO_MDEBUG 974296341Sdelphij CRYPTO_push_info("cert_load(): reading one cert"); 975296341Sdelphij# endif 976296341Sdelphij } 977296341Sdelphij# ifdef CRYPTO_MDEBUG 978296341Sdelphij CRYPTO_pop_info(); 979296341Sdelphij# endif 980296341Sdelphij if (ret) 981296341Sdelphij ERR_clear_error(); 982296341Sdelphij return ret; 98355714Skris} 98455714Skris 98555714Skris/* Generalised attribute print: handle PKCS#8 and bag attributes */ 98655714Skris 987296341Sdelphijint print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, 988296341Sdelphij const char *name) 98955714Skris{ 990296341Sdelphij X509_ATTRIBUTE *attr; 991296341Sdelphij ASN1_TYPE *av; 992296341Sdelphij char *value; 993296341Sdelphij int i, attr_nid; 994296341Sdelphij if (!attrlst) { 995296341Sdelphij BIO_printf(out, "%s: <No Attributes>\n", name); 996296341Sdelphij return 1; 997296341Sdelphij } 998296341Sdelphij if (!sk_X509_ATTRIBUTE_num(attrlst)) { 999296341Sdelphij BIO_printf(out, "%s: <Empty Attributes>\n", name); 1000296341Sdelphij return 1; 1001296341Sdelphij } 1002296341Sdelphij BIO_printf(out, "%s\n", name); 1003296341Sdelphij for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { 1004296341Sdelphij attr = sk_X509_ATTRIBUTE_value(attrlst, i); 1005296341Sdelphij attr_nid = OBJ_obj2nid(attr->object); 1006296341Sdelphij BIO_printf(out, " "); 1007296341Sdelphij if (attr_nid == NID_undef) { 1008296341Sdelphij i2a_ASN1_OBJECT(out, attr->object); 1009296341Sdelphij BIO_printf(out, ": "); 1010296341Sdelphij } else 1011296341Sdelphij BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); 101255714Skris 1013296341Sdelphij if (sk_ASN1_TYPE_num(attr->value.set)) { 1014296341Sdelphij av = sk_ASN1_TYPE_value(attr->value.set, 0); 1015296341Sdelphij switch (av->type) { 1016296341Sdelphij case V_ASN1_BMPSTRING: 1017296341Sdelphij value = OPENSSL_uni2asc(av->value.bmpstring->data, 1018296341Sdelphij av->value.bmpstring->length); 1019296341Sdelphij BIO_printf(out, "%s\n", value); 1020296341Sdelphij OPENSSL_free(value); 1021296341Sdelphij break; 102255714Skris 1023296341Sdelphij case V_ASN1_OCTET_STRING: 1024296341Sdelphij hex_prin(out, av->value.octet_string->data, 1025296341Sdelphij av->value.octet_string->length); 1026296341Sdelphij BIO_printf(out, "\n"); 1027296341Sdelphij break; 102855714Skris 1029296341Sdelphij case V_ASN1_BIT_STRING: 1030296341Sdelphij hex_prin(out, av->value.bit_string->data, 1031296341Sdelphij av->value.bit_string->length); 1032296341Sdelphij BIO_printf(out, "\n"); 1033296341Sdelphij break; 103455714Skris 1035296341Sdelphij default: 1036296341Sdelphij BIO_printf(out, "<Unsupported tag %d>\n", av->type); 1037296341Sdelphij break; 1038296341Sdelphij } 1039296341Sdelphij } else 1040296341Sdelphij BIO_printf(out, "<No Values>\n"); 1041296341Sdelphij } 1042296341Sdelphij return 1; 104355714Skris} 104455714Skris 104555714Skrisvoid hex_prin(BIO *out, unsigned char *buf, int len) 104655714Skris{ 1047296341Sdelphij int i; 1048296341Sdelphij for (i = 0; i < len; i++) 1049296341Sdelphij BIO_printf(out, "%02X ", buf[i]); 105055714Skris} 105155714Skris 1052238405Sjkimstatic int set_pbe(BIO *err, int *ppbe, const char *str) 1053296341Sdelphij{ 1054296341Sdelphij if (!str) 1055296341Sdelphij return 0; 1056296341Sdelphij if (!strcmp(str, "NONE")) { 1057296341Sdelphij *ppbe = -1; 1058296341Sdelphij return 1; 1059296341Sdelphij } 1060296341Sdelphij *ppbe = OBJ_txt2nid(str); 1061296341Sdelphij if (*ppbe == NID_undef) { 1062296341Sdelphij BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str); 1063296341Sdelphij return 0; 1064296341Sdelphij } 1065296341Sdelphij return 1; 1066296341Sdelphij} 1067296341Sdelphij 106855714Skris#endif 1069