155714Skris/* pkcs12.c */ 2296465Sdelphij/* 3296465Sdelphij * 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 14296465Sdelphij * 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 63296465Sdelphij# include <stdio.h> 64296465Sdelphij# include <stdlib.h> 65296465Sdelphij# include <string.h> 66296465Sdelphij# include "apps.h" 67296465Sdelphij# include <openssl/crypto.h> 68296465Sdelphij# include <openssl/err.h> 69296465Sdelphij# include <openssl/pem.h> 70296465Sdelphij# include <openssl/pkcs12.h> 7155714Skris 72296465Sdelphij# ifdef OPENSSL_SYS_NETWARE 73205128Ssimon/* Rename these functions to avoid name clashes on NetWare OS */ 74296465Sdelphij# define uni2asc OPENSSL_uni2asc 75296465Sdelphij# define asc2uni OPENSSL_asc2uni 76296465Sdelphij# endif 77205128Ssimon 78296465Sdelphij# define PROG pkcs12_main 7955714Skris 80109998Smarkmconst EVP_CIPHER *enc; 8155714Skris 82296465Sdelphij# define NOKEYS 0x1 83296465Sdelphij# define NOCERTS 0x2 84296465Sdelphij# define INFO 0x4 85296465Sdelphij# define CLCERTS 0x8 86296465Sdelphij# define CACERTS 0x10 8755714Skris 88296465Sdelphijint get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain); 89296465Sdelphijint dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, 90296465Sdelphij int options, char *pempass); 91296465Sdelphijint dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, 92296465Sdelphij char *pass, int passlen, int options, 93296465Sdelphij char *pempass); 94296465Sdelphijint dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, 95296465Sdelphij int passlen, int options, char *pempass); 96296465Sdelphijint print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, 97296465Sdelphij const char *name); 9855714Skrisvoid hex_prin(BIO *out, unsigned char *buf, int len); 9955714Skrisint alg_print(BIO *x, X509_ALGOR *alg); 10055714Skrisint cert_load(BIO *in, STACK_OF(X509) *sk); 10159191Skris 10259191Skrisint MAIN(int, char **); 10359191Skris 10455714Skrisint MAIN(int argc, char **argv) 10555714Skris{ 106109998Smarkm ENGINE *e = NULL; 107296465Sdelphij char *infile = NULL, *outfile = NULL, *keyname = NULL; 108296465Sdelphij char *certfile = NULL; 109296465Sdelphij BIO *in = NULL, *out = NULL; 11055714Skris char **args; 11155714Skris char *name = NULL; 112109998Smarkm char *csp_name = NULL; 113194206Ssimon int add_lmk = 0; 11455714Skris PKCS12 *p12 = NULL; 11555714Skris char pass[50], macpass[50]; 11655714Skris int export_cert = 0; 11755714Skris int options = 0; 11855714Skris int chain = 0; 11955714Skris int badarg = 0; 12055714Skris int iter = PKCS12_DEFAULT_ITER; 12159191Skris int maciter = PKCS12_DEFAULT_ITER; 12255714Skris int twopass = 0; 12355714Skris int keytype = 0; 124194206Ssimon int cert_pbe; 12559191Skris int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 12655714Skris int ret = 1; 12755714Skris int macver = 1; 12855714Skris int noprompt = 0; 12955714Skris STACK *canames = NULL; 13055714Skris char *cpass = NULL, *mpass = NULL; 13159191Skris char *passargin = NULL, *passargout = NULL, *passarg = NULL; 13259191Skris char *passin = NULL, *passout = NULL; 13359191Skris char *inrand = NULL; 13468651Skris char *CApath = NULL, *CAfile = NULL; 135296465Sdelphij# ifndef OPENSSL_NO_ENGINE 136296465Sdelphij char *engine = NULL; 137296465Sdelphij# endif 13855714Skris 13955714Skris apps_startup(); 14055714Skris 141296465Sdelphij# ifdef OPENSSL_FIPS 142194206Ssimon if (FIPS_mode()) 143296465Sdelphij cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 144194206Ssimon else 145296465Sdelphij# endif 146296465Sdelphij cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; 147194206Ssimon 14855714Skris enc = EVP_des_ede3_cbc(); 149296465Sdelphij if (bio_err == NULL) 150296465Sdelphij bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 15155714Skris 152296465Sdelphij if (!load_config(bio_err, NULL)) 153296465Sdelphij goto end; 154109998Smarkm 15555714Skris args = argv + 1; 15655714Skris 15755714Skris while (*args) { 158296465Sdelphij if (*args[0] == '-') { 159296465Sdelphij if (!strcmp(*args, "-nokeys")) 160296465Sdelphij options |= NOKEYS; 161296465Sdelphij else if (!strcmp(*args, "-keyex")) 162296465Sdelphij keytype = KEY_EX; 163296465Sdelphij else if (!strcmp(*args, "-keysig")) 164296465Sdelphij keytype = KEY_SIG; 165296465Sdelphij else if (!strcmp(*args, "-nocerts")) 166296465Sdelphij options |= NOCERTS; 167296465Sdelphij else if (!strcmp(*args, "-clcerts")) 168296465Sdelphij options |= CLCERTS; 169296465Sdelphij else if (!strcmp(*args, "-cacerts")) 170296465Sdelphij options |= CACERTS; 171296465Sdelphij else if (!strcmp(*args, "-noout")) 172296465Sdelphij options |= (NOKEYS | NOCERTS); 173296465Sdelphij else if (!strcmp(*args, "-info")) 174296465Sdelphij options |= INFO; 175296465Sdelphij else if (!strcmp(*args, "-chain")) 176296465Sdelphij chain = 1; 177296465Sdelphij else if (!strcmp(*args, "-twopass")) 178296465Sdelphij twopass = 1; 179296465Sdelphij else if (!strcmp(*args, "-nomacver")) 180296465Sdelphij macver = 0; 181296465Sdelphij else if (!strcmp(*args, "-descert")) 182296465Sdelphij cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 183296465Sdelphij else if (!strcmp(*args, "-export")) 184296465Sdelphij export_cert = 1; 185296465Sdelphij else if (!strcmp(*args, "-des")) 186296465Sdelphij enc = EVP_des_cbc(); 187296465Sdelphij else if (!strcmp(*args, "-des3")) 188296465Sdelphij enc = EVP_des_ede3_cbc(); 189296465Sdelphij# ifndef OPENSSL_NO_IDEA 190296465Sdelphij else if (!strcmp(*args, "-idea")) 191296465Sdelphij enc = EVP_idea_cbc(); 192296465Sdelphij# endif 193296465Sdelphij# ifndef OPENSSL_NO_SEED 194296465Sdelphij else if (!strcmp(*args, "-seed")) 195296465Sdelphij enc = EVP_seed_cbc(); 196296465Sdelphij# endif 197296465Sdelphij# ifndef OPENSSL_NO_AES 198296465Sdelphij else if (!strcmp(*args, "-aes128")) 199296465Sdelphij enc = EVP_aes_128_cbc(); 200296465Sdelphij else if (!strcmp(*args, "-aes192")) 201296465Sdelphij enc = EVP_aes_192_cbc(); 202296465Sdelphij else if (!strcmp(*args, "-aes256")) 203296465Sdelphij enc = EVP_aes_256_cbc(); 204296465Sdelphij# endif 205296465Sdelphij# ifndef OPENSSL_NO_CAMELLIA 206296465Sdelphij else if (!strcmp(*args, "-camellia128")) 207296465Sdelphij enc = EVP_camellia_128_cbc(); 208296465Sdelphij else if (!strcmp(*args, "-camellia192")) 209296465Sdelphij enc = EVP_camellia_192_cbc(); 210296465Sdelphij else if (!strcmp(*args, "-camellia256")) 211296465Sdelphij enc = EVP_camellia_256_cbc(); 212296465Sdelphij# endif 213296465Sdelphij else if (!strcmp(*args, "-noiter")) 214296465Sdelphij iter = 1; 215296465Sdelphij else if (!strcmp(*args, "-maciter")) 216296465Sdelphij maciter = PKCS12_DEFAULT_ITER; 217296465Sdelphij else if (!strcmp(*args, "-nomaciter")) 218296465Sdelphij maciter = 1; 219296465Sdelphij else if (!strcmp(*args, "-nomac")) 220296465Sdelphij maciter = -1; 221296465Sdelphij else if (!strcmp(*args, "-nodes")) 222296465Sdelphij enc = NULL; 223296465Sdelphij else if (!strcmp(*args, "-certpbe")) { 224296465Sdelphij if (args[1]) { 225296465Sdelphij args++; 226296465Sdelphij if (!strcmp(*args, "NONE")) 227296465Sdelphij cert_pbe = -1; 228296465Sdelphij else 229296465Sdelphij cert_pbe = OBJ_txt2nid(*args); 230296465Sdelphij if (cert_pbe == NID_undef) { 231296465Sdelphij BIO_printf(bio_err, 232296465Sdelphij "Unknown PBE algorithm %s\n", *args); 233296465Sdelphij badarg = 1; 234296465Sdelphij } 235296465Sdelphij } else 236296465Sdelphij badarg = 1; 237296465Sdelphij } else if (!strcmp(*args, "-keypbe")) { 238296465Sdelphij if (args[1]) { 239296465Sdelphij args++; 240296465Sdelphij if (!strcmp(*args, "NONE")) 241296465Sdelphij key_pbe = -1; 242296465Sdelphij else 243296465Sdelphij key_pbe = OBJ_txt2nid(*args); 244296465Sdelphij if (key_pbe == NID_undef) { 245296465Sdelphij BIO_printf(bio_err, 246296465Sdelphij "Unknown PBE algorithm %s\n", *args); 247296465Sdelphij badarg = 1; 248296465Sdelphij } 249296465Sdelphij } else 250296465Sdelphij badarg = 1; 251296465Sdelphij } else if (!strcmp(*args, "-rand")) { 252296465Sdelphij if (args[1]) { 253296465Sdelphij args++; 254296465Sdelphij inrand = *args; 255296465Sdelphij } else 256296465Sdelphij badarg = 1; 257296465Sdelphij } else if (!strcmp(*args, "-inkey")) { 258296465Sdelphij if (args[1]) { 259296465Sdelphij args++; 260296465Sdelphij keyname = *args; 261296465Sdelphij } else 262296465Sdelphij badarg = 1; 263296465Sdelphij } else if (!strcmp(*args, "-certfile")) { 264296465Sdelphij if (args[1]) { 265296465Sdelphij args++; 266296465Sdelphij certfile = *args; 267296465Sdelphij } else 268296465Sdelphij badarg = 1; 269296465Sdelphij } else if (!strcmp(*args, "-name")) { 270296465Sdelphij if (args[1]) { 271296465Sdelphij args++; 272296465Sdelphij name = *args; 273296465Sdelphij } else 274296465Sdelphij badarg = 1; 275296465Sdelphij } else if (!strcmp(*args, "-LMK")) 276296465Sdelphij add_lmk = 1; 277296465Sdelphij else if (!strcmp(*args, "-CSP")) { 278296465Sdelphij if (args[1]) { 279296465Sdelphij args++; 280296465Sdelphij csp_name = *args; 281296465Sdelphij } else 282296465Sdelphij badarg = 1; 283296465Sdelphij } else if (!strcmp(*args, "-caname")) { 284296465Sdelphij if (args[1]) { 285296465Sdelphij args++; 286296465Sdelphij if (!canames) 287296465Sdelphij canames = sk_new_null(); 288296465Sdelphij sk_push(canames, *args); 289296465Sdelphij } else 290296465Sdelphij badarg = 1; 291296465Sdelphij } else if (!strcmp(*args, "-in")) { 292296465Sdelphij if (args[1]) { 293296465Sdelphij args++; 294296465Sdelphij infile = *args; 295296465Sdelphij } else 296296465Sdelphij badarg = 1; 297296465Sdelphij } else if (!strcmp(*args, "-out")) { 298296465Sdelphij if (args[1]) { 299296465Sdelphij args++; 300296465Sdelphij outfile = *args; 301296465Sdelphij } else 302296465Sdelphij badarg = 1; 303296465Sdelphij } else if (!strcmp(*args, "-passin")) { 304296465Sdelphij if (args[1]) { 305296465Sdelphij args++; 306296465Sdelphij passargin = *args; 307296465Sdelphij } else 308296465Sdelphij badarg = 1; 309296465Sdelphij } else if (!strcmp(*args, "-passout")) { 310296465Sdelphij if (args[1]) { 311296465Sdelphij args++; 312296465Sdelphij passargout = *args; 313296465Sdelphij } else 314296465Sdelphij badarg = 1; 315296465Sdelphij } else if (!strcmp(*args, "-password")) { 316296465Sdelphij if (args[1]) { 317296465Sdelphij args++; 318296465Sdelphij passarg = *args; 319296465Sdelphij noprompt = 1; 320296465Sdelphij } else 321296465Sdelphij badarg = 1; 322296465Sdelphij } else if (!strcmp(*args, "-CApath")) { 323296465Sdelphij if (args[1]) { 324296465Sdelphij args++; 325296465Sdelphij CApath = *args; 326296465Sdelphij } else 327296465Sdelphij badarg = 1; 328296465Sdelphij } else if (!strcmp(*args, "-CAfile")) { 329296465Sdelphij if (args[1]) { 330296465Sdelphij args++; 331296465Sdelphij CAfile = *args; 332296465Sdelphij } else 333296465Sdelphij badarg = 1; 334296465Sdelphij# ifndef OPENSSL_NO_ENGINE 335296465Sdelphij } else if (!strcmp(*args, "-engine")) { 336296465Sdelphij if (args[1]) { 337296465Sdelphij args++; 338296465Sdelphij engine = *args; 339296465Sdelphij } else 340296465Sdelphij badarg = 1; 341296465Sdelphij# endif 342296465Sdelphij } else 343296465Sdelphij badarg = 1; 34455714Skris 345296465Sdelphij } else 346296465Sdelphij badarg = 1; 347296465Sdelphij args++; 34855714Skris } 34955714Skris 35055714Skris if (badarg) { 351296465Sdelphij BIO_printf(bio_err, "Usage: pkcs12 [options]\n"); 352296465Sdelphij BIO_printf(bio_err, "where options are\n"); 353296465Sdelphij BIO_printf(bio_err, "-export output PKCS12 file\n"); 354296465Sdelphij BIO_printf(bio_err, "-chain add certificate chain\n"); 355296465Sdelphij BIO_printf(bio_err, "-inkey file private key if not infile\n"); 356296465Sdelphij BIO_printf(bio_err, "-certfile f add all certs in f\n"); 357296465Sdelphij BIO_printf(bio_err, "-CApath arg - PEM format directory of CA's\n"); 358296465Sdelphij BIO_printf(bio_err, "-CAfile arg - PEM format file of CA's\n"); 359296465Sdelphij BIO_printf(bio_err, "-name \"name\" use name as friendly name\n"); 360296465Sdelphij BIO_printf(bio_err, 361296465Sdelphij "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); 362296465Sdelphij BIO_printf(bio_err, "-in infile input filename\n"); 363296465Sdelphij BIO_printf(bio_err, "-out outfile output filename\n"); 364296465Sdelphij BIO_printf(bio_err, 365296465Sdelphij "-noout don't output anything, just verify.\n"); 366296465Sdelphij BIO_printf(bio_err, "-nomacver don't verify MAC.\n"); 367296465Sdelphij BIO_printf(bio_err, "-nocerts don't output certificates.\n"); 368296465Sdelphij BIO_printf(bio_err, 369296465Sdelphij "-clcerts only output client certificates.\n"); 370296465Sdelphij BIO_printf(bio_err, "-cacerts only output CA certificates.\n"); 371296465Sdelphij BIO_printf(bio_err, "-nokeys don't output private keys.\n"); 372296465Sdelphij BIO_printf(bio_err, 373296465Sdelphij "-info give info about PKCS#12 structure.\n"); 374296465Sdelphij BIO_printf(bio_err, "-des encrypt private keys with DES\n"); 375296465Sdelphij BIO_printf(bio_err, 376296465Sdelphij "-des3 encrypt private keys with triple DES (default)\n"); 377296465Sdelphij# ifndef OPENSSL_NO_IDEA 378296465Sdelphij BIO_printf(bio_err, "-idea encrypt private keys with idea\n"); 379296465Sdelphij# endif 380296465Sdelphij# ifndef OPENSSL_NO_SEED 381296465Sdelphij BIO_printf(bio_err, "-seed encrypt private keys with seed\n"); 382296465Sdelphij# endif 383296465Sdelphij# ifndef OPENSSL_NO_AES 384296465Sdelphij BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); 385296465Sdelphij BIO_printf(bio_err, 386296465Sdelphij " encrypt PEM output with cbc aes\n"); 387296465Sdelphij# endif 388296465Sdelphij# ifndef OPENSSL_NO_CAMELLIA 389296465Sdelphij BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); 390296465Sdelphij BIO_printf(bio_err, 391296465Sdelphij " encrypt PEM output with cbc camellia\n"); 392296465Sdelphij# endif 393296465Sdelphij BIO_printf(bio_err, "-nodes don't encrypt private keys\n"); 394296465Sdelphij BIO_printf(bio_err, "-noiter don't use encryption iteration\n"); 395296465Sdelphij BIO_printf(bio_err, "-maciter use MAC iteration\n"); 396296465Sdelphij BIO_printf(bio_err, 397296465Sdelphij "-twopass separate MAC, encryption passwords\n"); 398296465Sdelphij BIO_printf(bio_err, 399296465Sdelphij "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); 400296465Sdelphij BIO_printf(bio_err, 401296465Sdelphij "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); 402296465Sdelphij BIO_printf(bio_err, 403296465Sdelphij "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); 404296465Sdelphij BIO_printf(bio_err, "-keyex set MS key exchange type\n"); 405296465Sdelphij BIO_printf(bio_err, "-keysig set MS key signature type\n"); 406296465Sdelphij BIO_printf(bio_err, 407296465Sdelphij "-password p set import/export password source\n"); 408296465Sdelphij BIO_printf(bio_err, "-passin p input file pass phrase source\n"); 409296465Sdelphij BIO_printf(bio_err, "-passout p output file pass phrase source\n"); 410296465Sdelphij# ifndef OPENSSL_NO_ENGINE 411296465Sdelphij BIO_printf(bio_err, 412296465Sdelphij "-engine e use engine e, possibly a hardware device.\n"); 413296465Sdelphij# endif 414296465Sdelphij BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, 415296465Sdelphij LIST_SEPARATOR_CHAR); 416296465Sdelphij BIO_printf(bio_err, 417296465Sdelphij " load the file (or the files in the directory) into\n"); 418296465Sdelphij BIO_printf(bio_err, " the random number generator\n"); 419296465Sdelphij BIO_printf(bio_err, "-CSP name Microsoft CSP name\n"); 420296465Sdelphij BIO_printf(bio_err, 421296465Sdelphij "-LMK Add local machine keyset attribute to private key\n"); 422296465Sdelphij goto end; 42355714Skris } 424296465Sdelphij# ifndef OPENSSL_NO_ENGINE 425109998Smarkm e = setup_engine(bio_err, engine, 0); 426296465Sdelphij# endif 427109998Smarkm 428296465Sdelphij if (passarg) { 429296465Sdelphij if (export_cert) 430296465Sdelphij passargout = passarg; 431296465Sdelphij else 432296465Sdelphij passargin = passarg; 43359191Skris } 43459191Skris 435296465Sdelphij if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 436296465Sdelphij BIO_printf(bio_err, "Error getting passwords\n"); 437296465Sdelphij goto end; 43859191Skris } 43959191Skris 440296465Sdelphij if (!cpass) { 441296465Sdelphij if (export_cert) 442296465Sdelphij cpass = passout; 443296465Sdelphij else 444296465Sdelphij cpass = passin; 44559191Skris } 44659191Skris 447296465Sdelphij if (cpass) { 448296465Sdelphij mpass = cpass; 449296465Sdelphij noprompt = 1; 45059191Skris } else { 451296465Sdelphij cpass = pass; 452296465Sdelphij mpass = macpass; 45355714Skris } 45455714Skris 455296465Sdelphij if (export_cert || inrand) { 456296465Sdelphij app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 45759191Skris if (inrand != NULL) 458296465Sdelphij BIO_printf(bio_err, "%ld semi-random bytes loaded\n", 459296465Sdelphij app_RAND_load_files(inrand)); 46059191Skris } 46155714Skris ERR_load_crypto_strings(); 46255714Skris 463296465Sdelphij# ifdef CRYPTO_MDEBUG 46459191Skris CRYPTO_push_info("read files"); 465296465Sdelphij# endif 46659191Skris 467296465Sdelphij if (!infile) 468296465Sdelphij in = BIO_new_fp(stdin, BIO_NOCLOSE); 469296465Sdelphij else 470296465Sdelphij in = BIO_new_file(infile, "rb"); 47155714Skris if (!in) { 472296465Sdelphij BIO_printf(bio_err, "Error opening input file %s\n", 473296465Sdelphij infile ? infile : "<stdin>"); 474296465Sdelphij perror(infile); 475296465Sdelphij goto end; 476296465Sdelphij } 477296465Sdelphij# ifdef CRYPTO_MDEBUG 47859191Skris CRYPTO_pop_info(); 47959191Skris CRYPTO_push_info("write files"); 480296465Sdelphij# endif 48159191Skris 48268651Skris if (!outfile) { 483296465Sdelphij out = BIO_new_fp(stdout, BIO_NOCLOSE); 484296465Sdelphij# ifdef OPENSSL_SYS_VMS 485296465Sdelphij { 486296465Sdelphij BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 487296465Sdelphij out = BIO_push(tmpbio, out); 488296465Sdelphij } 489296465Sdelphij# endif 490296465Sdelphij } else 491296465Sdelphij out = BIO_new_file(outfile, "wb"); 49255714Skris if (!out) { 493296465Sdelphij BIO_printf(bio_err, "Error opening output file %s\n", 494296465Sdelphij outfile ? outfile : "<stdout>"); 495296465Sdelphij perror(outfile); 496296465Sdelphij goto end; 49755714Skris } 49855714Skris if (twopass) { 499296465Sdelphij# ifdef CRYPTO_MDEBUG 500296465Sdelphij CRYPTO_push_info("read MAC password"); 501296465Sdelphij# endif 502296465Sdelphij if (EVP_read_pw_string 503296465Sdelphij (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { 504296465Sdelphij BIO_printf(bio_err, "Can't read Password\n"); 505296465Sdelphij goto end; 506296465Sdelphij } 507296465Sdelphij# ifdef CRYPTO_MDEBUG 508296465Sdelphij CRYPTO_pop_info(); 509296465Sdelphij# endif 51055714Skris } 51155714Skris 51259191Skris if (export_cert) { 513296465Sdelphij EVP_PKEY *key = NULL; 514296465Sdelphij X509 *ucert = NULL, *x = NULL; 515296465Sdelphij STACK_OF(X509) *certs = NULL; 516296465Sdelphij unsigned char *catmp = NULL; 517296465Sdelphij int i; 51859191Skris 519296465Sdelphij if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { 520296465Sdelphij BIO_printf(bio_err, "Nothing to do!\n"); 521296465Sdelphij goto export_end; 522296465Sdelphij } 523160814Ssimon 524296465Sdelphij if (options & NOCERTS) 525296465Sdelphij chain = 0; 526160814Ssimon 527296465Sdelphij# ifdef CRYPTO_MDEBUG 528296465Sdelphij CRYPTO_push_info("process -export_cert"); 529296465Sdelphij CRYPTO_push_info("reading private key"); 530296465Sdelphij# endif 531296465Sdelphij if (!(options & NOKEYS)) { 532296465Sdelphij key = load_key(bio_err, keyname ? keyname : infile, 533296465Sdelphij FORMAT_PEM, 1, passin, e, "private key"); 534296465Sdelphij if (!key) 535296465Sdelphij goto export_end; 536296465Sdelphij } 537296465Sdelphij# ifdef CRYPTO_MDEBUG 538296465Sdelphij CRYPTO_pop_info(); 539296465Sdelphij CRYPTO_push_info("reading certs from input"); 540296465Sdelphij# endif 54155714Skris 542296465Sdelphij /* Load in all certs in input file */ 543296465Sdelphij if (!(options & NOCERTS)) { 544296465Sdelphij certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, 545296465Sdelphij "certificates"); 546296465Sdelphij if (!certs) 547296465Sdelphij goto export_end; 54855714Skris 549296465Sdelphij if (key) { 550296465Sdelphij /* Look for matching private key */ 551296465Sdelphij for (i = 0; i < sk_X509_num(certs); i++) { 552296465Sdelphij x = sk_X509_value(certs, i); 553296465Sdelphij if (X509_check_private_key(x, key)) { 554296465Sdelphij ucert = x; 555296465Sdelphij /* Zero keyid and alias */ 556296465Sdelphij X509_keyid_set1(ucert, NULL, 0); 557296465Sdelphij X509_alias_set1(ucert, NULL, 0); 558296465Sdelphij /* Remove from list */ 559296465Sdelphij (void)sk_X509_delete(certs, i); 560296465Sdelphij break; 561296465Sdelphij } 562296465Sdelphij } 563296465Sdelphij if (!ucert) { 564296465Sdelphij BIO_printf(bio_err, 565296465Sdelphij "No certificate matches private key\n"); 566296465Sdelphij goto export_end; 567296465Sdelphij } 568296465Sdelphij } 56955714Skris 570296465Sdelphij } 571296465Sdelphij# ifdef CRYPTO_MDEBUG 572296465Sdelphij CRYPTO_pop_info(); 573296465Sdelphij CRYPTO_push_info("reading certs from input 2"); 574296465Sdelphij# endif 57568651Skris 576296465Sdelphij /* Add any more certificates asked for */ 577296465Sdelphij if (certfile) { 578296465Sdelphij STACK_OF(X509) *morecerts = NULL; 579296465Sdelphij if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, 580296465Sdelphij NULL, e, 581296465Sdelphij "certificates from certfile"))) 582296465Sdelphij goto export_end; 583296465Sdelphij while (sk_X509_num(morecerts) > 0) 584296465Sdelphij sk_X509_push(certs, sk_X509_shift(morecerts)); 585296465Sdelphij sk_X509_free(morecerts); 586296465Sdelphij } 587296465Sdelphij# ifdef CRYPTO_MDEBUG 588296465Sdelphij CRYPTO_pop_info(); 589296465Sdelphij CRYPTO_push_info("reading certs from certfile"); 590296465Sdelphij# endif 591160814Ssimon 592296465Sdelphij# ifdef CRYPTO_MDEBUG 593296465Sdelphij CRYPTO_pop_info(); 594296465Sdelphij CRYPTO_push_info("building chain"); 595296465Sdelphij# endif 59655714Skris 597296465Sdelphij /* If chaining get chain from user cert */ 598296465Sdelphij if (chain) { 599296465Sdelphij int vret; 600296465Sdelphij STACK_OF(X509) *chain2; 601296465Sdelphij X509_STORE *store = X509_STORE_new(); 602296465Sdelphij if (!store) { 603296465Sdelphij BIO_printf(bio_err, "Memory allocation error\n"); 604296465Sdelphij goto export_end; 605296465Sdelphij } 606296465Sdelphij if (!X509_STORE_load_locations(store, CAfile, CApath)) 607296465Sdelphij X509_STORE_set_default_paths(store); 60855714Skris 609296465Sdelphij vret = get_cert_chain(ucert, store, &chain2); 610296465Sdelphij X509_STORE_free(store); 611160814Ssimon 612296465Sdelphij if (!vret) { 613296465Sdelphij /* Exclude verified certificate */ 614296465Sdelphij for (i = 1; i < sk_X509_num(chain2); i++) 615296465Sdelphij sk_X509_push(certs, sk_X509_value(chain2, i)); 616296465Sdelphij /* Free first certificate */ 617296465Sdelphij X509_free(sk_X509_value(chain2, 0)); 618296465Sdelphij sk_X509_free(chain2); 619296465Sdelphij } else { 620296465Sdelphij if (vret >= 0) 621296465Sdelphij BIO_printf(bio_err, "Error %s getting chain.\n", 622296465Sdelphij X509_verify_cert_error_string(vret)); 623296465Sdelphij else 624296465Sdelphij ERR_print_errors(bio_err); 625296465Sdelphij goto export_end; 626296465Sdelphij } 627296465Sdelphij } 62868651Skris 629296465Sdelphij /* Add any CA names */ 63068651Skris 631296465Sdelphij for (i = 0; i < sk_num(canames); i++) { 632296465Sdelphij catmp = (unsigned char *)sk_value(canames, i); 633296465Sdelphij X509_alias_set1(sk_X509_value(certs, i), catmp, -1); 634296465Sdelphij } 63568651Skris 636296465Sdelphij if (csp_name && key) 637296465Sdelphij EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, 638296465Sdelphij MBSTRING_ASC, (unsigned char *)csp_name, 639296465Sdelphij -1); 64055714Skris 641296465Sdelphij if (add_lmk && key) 642296465Sdelphij EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); 64368651Skris 644296465Sdelphij# ifdef CRYPTO_MDEBUG 645296465Sdelphij CRYPTO_pop_info(); 646296465Sdelphij CRYPTO_push_info("reading password"); 647296465Sdelphij# endif 64855714Skris 649296465Sdelphij if (!noprompt && 650296465Sdelphij EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 651296465Sdelphij 1)) { 652296465Sdelphij BIO_printf(bio_err, "Can't read Password\n"); 653296465Sdelphij goto export_end; 654296465Sdelphij } 655296465Sdelphij if (!twopass) 656296465Sdelphij BUF_strlcpy(macpass, pass, sizeof macpass); 657160814Ssimon 658296465Sdelphij# ifdef CRYPTO_MDEBUG 659296465Sdelphij CRYPTO_pop_info(); 660296465Sdelphij CRYPTO_push_info("creating PKCS#12 structure"); 661296465Sdelphij# endif 662194206Ssimon 663296465Sdelphij p12 = PKCS12_create(cpass, name, key, ucert, certs, 664296465Sdelphij key_pbe, cert_pbe, iter, -1, keytype); 66568651Skris 666296465Sdelphij if (!p12) { 667296465Sdelphij ERR_print_errors(bio_err); 668296465Sdelphij goto export_end; 669296465Sdelphij } 67055714Skris 671296465Sdelphij if (maciter != -1) 672296465Sdelphij PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL); 67368651Skris 674296465Sdelphij# ifdef CRYPTO_MDEBUG 675296465Sdelphij CRYPTO_pop_info(); 676296465Sdelphij CRYPTO_push_info("writing pkcs12"); 677296465Sdelphij# endif 67868651Skris 679296465Sdelphij i2d_PKCS12_bio(out, p12); 68068651Skris 681296465Sdelphij ret = 0; 68255714Skris 683296465Sdelphij export_end: 684296465Sdelphij# ifdef CRYPTO_MDEBUG 685296465Sdelphij CRYPTO_pop_info(); 686296465Sdelphij CRYPTO_pop_info(); 687296465Sdelphij CRYPTO_push_info("process -export_cert: freeing"); 688296465Sdelphij# endif 68968651Skris 690296465Sdelphij if (key) 691296465Sdelphij EVP_PKEY_free(key); 692296465Sdelphij if (certs) 693296465Sdelphij sk_X509_pop_free(certs, X509_free); 694296465Sdelphij if (ucert) 695296465Sdelphij X509_free(ucert); 69655714Skris 697296465Sdelphij# ifdef CRYPTO_MDEBUG 698296465Sdelphij CRYPTO_pop_info(); 699296465Sdelphij# endif 700296465Sdelphij goto end; 70159191Skris 70255714Skris } 70355714Skris 704296465Sdelphij if (!(p12 = d2i_PKCS12_bio(in, NULL))) { 705296465Sdelphij ERR_print_errors(bio_err); 706296465Sdelphij goto end; 70755714Skris } 708296465Sdelphij# ifdef CRYPTO_MDEBUG 70959191Skris CRYPTO_push_info("read import password"); 710296465Sdelphij# endif 711296465Sdelphij if (!noprompt 712296465Sdelphij && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 713296465Sdelphij 0)) { 714296465Sdelphij BIO_printf(bio_err, "Can't read Password\n"); 715296465Sdelphij goto end; 71655714Skris } 717296465Sdelphij# ifdef CRYPTO_MDEBUG 71859191Skris CRYPTO_pop_info(); 719296465Sdelphij# endif 72055714Skris 721296465Sdelphij if (!twopass) 722296465Sdelphij BUF_strlcpy(macpass, pass, sizeof macpass); 72355714Skris 724296465Sdelphij if ((options & INFO) && p12->mac) 725296465Sdelphij BIO_printf(bio_err, "MAC Iteration %ld\n", 726296465Sdelphij p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1); 727296465Sdelphij if (macver) { 728296465Sdelphij# ifdef CRYPTO_MDEBUG 729296465Sdelphij CRYPTO_push_info("verify MAC"); 730296465Sdelphij# endif 731296465Sdelphij /* If we enter empty password try no password first */ 732296465Sdelphij if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { 733296465Sdelphij /* If mac and crypto pass the same set it to NULL too */ 734296465Sdelphij if (!twopass) 735296465Sdelphij cpass = NULL; 736296465Sdelphij } else if (!PKCS12_verify_mac(p12, mpass, -1)) { 737296465Sdelphij BIO_printf(bio_err, "Mac verify error: invalid password?\n"); 738296465Sdelphij ERR_print_errors(bio_err); 739296465Sdelphij goto end; 740296465Sdelphij } 741296465Sdelphij BIO_printf(bio_err, "MAC verified OK\n"); 742296465Sdelphij# ifdef CRYPTO_MDEBUG 743296465Sdelphij CRYPTO_pop_info(); 744296465Sdelphij# endif 74555714Skris } 746296465Sdelphij# ifdef CRYPTO_MDEBUG 74759191Skris CRYPTO_push_info("output keys and certificates"); 748296465Sdelphij# endif 749296465Sdelphij if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) { 750296465Sdelphij BIO_printf(bio_err, "Error outputting keys and certificates\n"); 751296465Sdelphij ERR_print_errors(bio_err); 752296465Sdelphij goto end; 75355714Skris } 754296465Sdelphij# ifdef CRYPTO_MDEBUG 75559191Skris CRYPTO_pop_info(); 756296465Sdelphij# endif 75755714Skris ret = 0; 75868651Skris end: 759296465Sdelphij if (p12) 760296465Sdelphij PKCS12_free(p12); 761296465Sdelphij if (export_cert || inrand) 762296465Sdelphij app_RAND_write_file(NULL, bio_err); 763296465Sdelphij# ifdef CRYPTO_MDEBUG 76459191Skris CRYPTO_remove_all_info(); 765296465Sdelphij# endif 76659191Skris BIO_free(in); 76768651Skris BIO_free_all(out); 768296465Sdelphij if (canames) 769296465Sdelphij sk_free(canames); 770296465Sdelphij if (passin) 771296465Sdelphij OPENSSL_free(passin); 772296465Sdelphij if (passout) 773296465Sdelphij OPENSSL_free(passout); 774109998Smarkm apps_shutdown(); 775109998Smarkm OPENSSL_EXIT(ret); 77655714Skris} 77755714Skris 778296465Sdelphijint dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, 779296465Sdelphij int passlen, int options, char *pempass) 78055714Skris{ 781296465Sdelphij STACK_OF(PKCS7) *asafes = NULL; 782296465Sdelphij STACK_OF(PKCS12_SAFEBAG) *bags; 783296465Sdelphij int i, bagnid; 784296465Sdelphij int ret = 0; 785296465Sdelphij PKCS7 *p7; 78668651Skris 787296465Sdelphij if (!(asafes = PKCS12_unpack_authsafes(p12))) 788296465Sdelphij return 0; 789296465Sdelphij for (i = 0; i < sk_PKCS7_num(asafes); i++) { 790296465Sdelphij p7 = sk_PKCS7_value(asafes, i); 791296465Sdelphij bagnid = OBJ_obj2nid(p7->type); 792296465Sdelphij if (bagnid == NID_pkcs7_data) { 793296465Sdelphij bags = PKCS12_unpack_p7data(p7); 794296465Sdelphij if (options & INFO) 795296465Sdelphij BIO_printf(bio_err, "PKCS7 Data\n"); 796296465Sdelphij } else if (bagnid == NID_pkcs7_encrypted) { 797296465Sdelphij if (options & INFO) { 798296465Sdelphij BIO_printf(bio_err, "PKCS7 Encrypted data: "); 799296465Sdelphij alg_print(bio_err, p7->d.encrypted->enc_data->algorithm); 800296465Sdelphij } 801296465Sdelphij bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 802296465Sdelphij } else 803296465Sdelphij continue; 804296465Sdelphij if (!bags) 805296465Sdelphij goto err; 806296465Sdelphij if (!dump_certs_pkeys_bags(out, bags, pass, passlen, 807296465Sdelphij options, pempass)) { 808296465Sdelphij sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 809296465Sdelphij goto err; 810296465Sdelphij } 811296465Sdelphij sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 812296465Sdelphij bags = NULL; 813296465Sdelphij } 814296465Sdelphij ret = 1; 815160814Ssimon 816296465Sdelphij err: 817160814Ssimon 818296465Sdelphij if (asafes) 819296465Sdelphij sk_PKCS7_pop_free(asafes, PKCS7_free); 820296465Sdelphij return ret; 82155714Skris} 82255714Skris 823296465Sdelphijint dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, 824296465Sdelphij char *pass, int passlen, int options, char *pempass) 82555714Skris{ 826296465Sdelphij int i; 827296465Sdelphij for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 828296465Sdelphij if (!dump_certs_pkeys_bag(out, 829296465Sdelphij sk_PKCS12_SAFEBAG_value(bags, i), 830296465Sdelphij pass, passlen, options, pempass)) 831296465Sdelphij return 0; 832296465Sdelphij } 833296465Sdelphij return 1; 83455714Skris} 83555714Skris 836296465Sdelphijint dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, 837296465Sdelphij int passlen, int options, char *pempass) 83855714Skris{ 839296465Sdelphij EVP_PKEY *pkey; 840296465Sdelphij PKCS8_PRIV_KEY_INFO *p8; 841296465Sdelphij X509 *x509; 84255714Skris 843296465Sdelphij switch (M_PKCS12_bag_type(bag)) { 844296465Sdelphij case NID_keyBag: 845296465Sdelphij if (options & INFO) 846296465Sdelphij BIO_printf(bio_err, "Key bag\n"); 847296465Sdelphij if (options & NOKEYS) 848296465Sdelphij return 1; 849296465Sdelphij print_attribs(out, bag->attrib, "Bag Attributes"); 850296465Sdelphij p8 = bag->value.keybag; 851296465Sdelphij if (!(pkey = EVP_PKCS82PKEY(p8))) 852296465Sdelphij return 0; 853296465Sdelphij print_attribs(out, p8->attributes, "Key Attributes"); 854296465Sdelphij PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); 855296465Sdelphij EVP_PKEY_free(pkey); 856296465Sdelphij break; 85755714Skris 858296465Sdelphij case NID_pkcs8ShroudedKeyBag: 859296465Sdelphij if (options & INFO) { 860296465Sdelphij BIO_printf(bio_err, "Shrouded Keybag: "); 861296465Sdelphij alg_print(bio_err, bag->value.shkeybag->algor); 862296465Sdelphij } 863296465Sdelphij if (options & NOKEYS) 864296465Sdelphij return 1; 865296465Sdelphij print_attribs(out, bag->attrib, "Bag Attributes"); 866296465Sdelphij if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 867296465Sdelphij return 0; 868296465Sdelphij if (!(pkey = EVP_PKCS82PKEY(p8))) { 869296465Sdelphij PKCS8_PRIV_KEY_INFO_free(p8); 870296465Sdelphij return 0; 871296465Sdelphij } 872296465Sdelphij print_attribs(out, p8->attributes, "Key Attributes"); 873296465Sdelphij PKCS8_PRIV_KEY_INFO_free(p8); 874296465Sdelphij PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); 875296465Sdelphij EVP_PKEY_free(pkey); 876296465Sdelphij break; 87755714Skris 878296465Sdelphij case NID_certBag: 879296465Sdelphij if (options & INFO) 880296465Sdelphij BIO_printf(bio_err, "Certificate bag\n"); 881296465Sdelphij if (options & NOCERTS) 882296465Sdelphij return 1; 883296465Sdelphij if (PKCS12_get_attr(bag, NID_localKeyID)) { 884296465Sdelphij if (options & CACERTS) 885296465Sdelphij return 1; 886296465Sdelphij } else if (options & CLCERTS) 887296465Sdelphij return 1; 888296465Sdelphij print_attribs(out, bag->attrib, "Bag Attributes"); 889296465Sdelphij if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) 890296465Sdelphij return 1; 891296465Sdelphij if (!(x509 = PKCS12_certbag2x509(bag))) 892296465Sdelphij return 0; 893296465Sdelphij dump_cert_text(out, x509); 894296465Sdelphij PEM_write_bio_X509(out, x509); 895296465Sdelphij X509_free(x509); 896296465Sdelphij break; 897296465Sdelphij 898296465Sdelphij case NID_safeContentsBag: 899296465Sdelphij if (options & INFO) 900296465Sdelphij BIO_printf(bio_err, "Safe Contents bag\n"); 901296465Sdelphij print_attribs(out, bag->attrib, "Bag Attributes"); 902296465Sdelphij return dump_certs_pkeys_bags(out, bag->value.safes, pass, 903296465Sdelphij passlen, options, pempass); 904296465Sdelphij 905296465Sdelphij default: 906296465Sdelphij BIO_printf(bio_err, "Warning unsupported bag type: "); 907296465Sdelphij i2a_ASN1_OBJECT(bio_err, bag->type); 908296465Sdelphij BIO_printf(bio_err, "\n"); 909296465Sdelphij return 1; 910296465Sdelphij break; 911296465Sdelphij } 912296465Sdelphij return 1; 91355714Skris} 91455714Skris 91555714Skris/* Given a single certificate return a verified chain or NULL if error */ 91655714Skris 91755714Skris/* Hope this is OK .... */ 91855714Skris 919296465Sdelphijint get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) 92055714Skris{ 921296465Sdelphij X509_STORE_CTX store_ctx; 922296465Sdelphij STACK_OF(X509) *chn; 923296465Sdelphij int i = 0; 92459191Skris 925296465Sdelphij /* 926296465Sdelphij * FIXME: Should really check the return status of X509_STORE_CTX_init 927296465Sdelphij * for an error, but how that fits into the return value of this function 928296465Sdelphij * is less obvious. 929296465Sdelphij */ 930296465Sdelphij X509_STORE_CTX_init(&store_ctx, store, cert, NULL); 931296465Sdelphij if (X509_verify_cert(&store_ctx) <= 0) { 932296465Sdelphij i = X509_STORE_CTX_get_error(&store_ctx); 933296465Sdelphij if (i == 0) 934296465Sdelphij /* 935296465Sdelphij * avoid returning 0 if X509_verify_cert() did not set an 936296465Sdelphij * appropriate error value in the context 937296465Sdelphij */ 938296465Sdelphij i = -1; 939296465Sdelphij chn = NULL; 940296465Sdelphij goto err; 941296465Sdelphij } else 942296465Sdelphij chn = X509_STORE_CTX_get1_chain(&store_ctx); 943296465Sdelphij err: 944296465Sdelphij X509_STORE_CTX_cleanup(&store_ctx); 945296465Sdelphij *chain = chn; 94655714Skris 947296465Sdelphij return i; 948296465Sdelphij} 949296465Sdelphij 950296465Sdelphijint alg_print(BIO *x, X509_ALGOR *alg) 95155714Skris{ 952296465Sdelphij PBEPARAM *pbe; 953296465Sdelphij const unsigned char *p; 954296465Sdelphij p = alg->parameter->value.sequence->data; 955296465Sdelphij pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); 956296465Sdelphij if (!pbe) 957296465Sdelphij return 1; 958296465Sdelphij BIO_printf(bio_err, "%s, Iteration %ld\n", 959296465Sdelphij OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), 960296465Sdelphij ASN1_INTEGER_get(pbe->iter)); 961296465Sdelphij PBEPARAM_free(pbe); 962296465Sdelphij return 1; 96355714Skris} 96455714Skris 96555714Skris/* Load all certificates from a given file */ 96655714Skris 96755714Skrisint cert_load(BIO *in, STACK_OF(X509) *sk) 96855714Skris{ 969296465Sdelphij int ret; 970296465Sdelphij X509 *cert; 971296465Sdelphij ret = 0; 972296465Sdelphij# ifdef CRYPTO_MDEBUG 973296465Sdelphij CRYPTO_push_info("cert_load(): reading one cert"); 974296465Sdelphij# endif 975296465Sdelphij while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) { 976296465Sdelphij# ifdef CRYPTO_MDEBUG 977296465Sdelphij CRYPTO_pop_info(); 978296465Sdelphij# endif 979296465Sdelphij ret = 1; 980296465Sdelphij sk_X509_push(sk, cert); 981296465Sdelphij# ifdef CRYPTO_MDEBUG 982296465Sdelphij CRYPTO_push_info("cert_load(): reading one cert"); 983296465Sdelphij# endif 984296465Sdelphij } 985296465Sdelphij# ifdef CRYPTO_MDEBUG 986296465Sdelphij CRYPTO_pop_info(); 987296465Sdelphij# endif 988296465Sdelphij if (ret) 989296465Sdelphij ERR_clear_error(); 990296465Sdelphij return ret; 99155714Skris} 99255714Skris 99355714Skris/* Generalised attribute print: handle PKCS#8 and bag attributes */ 99455714Skris 995296465Sdelphijint print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, 996296465Sdelphij const char *name) 99755714Skris{ 998296465Sdelphij X509_ATTRIBUTE *attr; 999296465Sdelphij ASN1_TYPE *av; 1000296465Sdelphij char *value; 1001296465Sdelphij int i, attr_nid; 1002296465Sdelphij if (!attrlst) { 1003296465Sdelphij BIO_printf(out, "%s: <No Attributes>\n", name); 1004296465Sdelphij return 1; 1005296465Sdelphij } 1006296465Sdelphij if (!sk_X509_ATTRIBUTE_num(attrlst)) { 1007296465Sdelphij BIO_printf(out, "%s: <Empty Attributes>\n", name); 1008296465Sdelphij return 1; 1009296465Sdelphij } 1010296465Sdelphij BIO_printf(out, "%s\n", name); 1011296465Sdelphij for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { 1012296465Sdelphij attr = sk_X509_ATTRIBUTE_value(attrlst, i); 1013296465Sdelphij attr_nid = OBJ_obj2nid(attr->object); 1014296465Sdelphij BIO_printf(out, " "); 1015296465Sdelphij if (attr_nid == NID_undef) { 1016296465Sdelphij i2a_ASN1_OBJECT(out, attr->object); 1017296465Sdelphij BIO_printf(out, ": "); 1018296465Sdelphij } else 1019296465Sdelphij BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); 102055714Skris 1021296465Sdelphij if (sk_ASN1_TYPE_num(attr->value.set)) { 1022296465Sdelphij av = sk_ASN1_TYPE_value(attr->value.set, 0); 1023296465Sdelphij switch (av->type) { 1024296465Sdelphij case V_ASN1_BMPSTRING: 1025296465Sdelphij value = uni2asc(av->value.bmpstring->data, 1026296465Sdelphij av->value.bmpstring->length); 1027296465Sdelphij BIO_printf(out, "%s\n", value); 1028296465Sdelphij OPENSSL_free(value); 1029296465Sdelphij break; 103055714Skris 1031296465Sdelphij case V_ASN1_OCTET_STRING: 1032296465Sdelphij hex_prin(out, av->value.octet_string->data, 1033296465Sdelphij av->value.octet_string->length); 1034296465Sdelphij BIO_printf(out, "\n"); 1035296465Sdelphij break; 103655714Skris 1037296465Sdelphij case V_ASN1_BIT_STRING: 1038296465Sdelphij hex_prin(out, av->value.bit_string->data, 1039296465Sdelphij av->value.bit_string->length); 1040296465Sdelphij BIO_printf(out, "\n"); 1041296465Sdelphij break; 104255714Skris 1043296465Sdelphij default: 1044296465Sdelphij BIO_printf(out, "<Unsupported tag %d>\n", av->type); 1045296465Sdelphij break; 1046296465Sdelphij } 1047296465Sdelphij } else 1048296465Sdelphij BIO_printf(out, "<No Values>\n"); 1049296465Sdelphij } 1050296465Sdelphij return 1; 105155714Skris} 105255714Skris 105355714Skrisvoid hex_prin(BIO *out, unsigned char *buf, int len) 105455714Skris{ 1055296465Sdelphij int i; 1056296465Sdelphij for (i = 0; i < len; i++) 1057296465Sdelphij BIO_printf(out, "%02X ", buf[i]); 105855714Skris} 105955714Skris 106055714Skris#endif 1061