X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=apps%2Fpkcs12.c;h=c22c00fce156147fe9e0b121f4cecdd0c93079ba;hb=68b64fb6102737bf84de9e25168abbf7e969b54b;hp=1697f6157ff5eb2245fb4fcfd6fd73d2eaaf7661;hpb=9a2601033dcf12c3c8075719264cfea4985a8562;p=openssl.git diff --git a/apps/pkcs12.c b/apps/pkcs12.c index 1697f6157f..c22c00fce1 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -1,11 +1,9 @@ /* pkcs12.c */ -#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) - /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL - * project 1999. + * project. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -58,6 +56,9 @@ * */ +#include +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) + #include #include #include @@ -83,7 +84,7 @@ int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int opti int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass, int passlen, int options, char *pempass); int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass); -int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, char *name); +int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name); void hex_prin(BIO *out, unsigned char *buf, int len); int alg_print(BIO *x, X509_ALGOR *alg); int cert_load(BIO *in, STACK_OF(X509) *sk); @@ -120,7 +121,9 @@ int MAIN(int argc, char **argv) char *passin = NULL, *passout = NULL; char *inrand = NULL; char *CApath = NULL, *CAfile = NULL; +#ifndef OPENSSL_NO_ENGINE char *engine=NULL; +#endif apps_startup(); @@ -164,10 +167,14 @@ int MAIN(int argc, char **argv) maciter = PKCS12_DEFAULT_ITER; else if (!strcmp (*args, "-nomaciter")) maciter = 1; + else if (!strcmp (*args, "-nomac")) + maciter = -1; else if (!strcmp (*args, "-nodes")) enc=NULL; else if (!strcmp (*args, "-certpbe")) { if (args[1]) { args++; + if (!strcmp(*args, "NONE")) + cert_pbe = -1; cert_pbe=OBJ_txt2nid(*args); if(cert_pbe == NID_undef) { BIO_printf(bio_err, @@ -178,7 +185,10 @@ int MAIN(int argc, char **argv) } else if (!strcmp (*args, "-keypbe")) { if (args[1]) { args++; - key_pbe=OBJ_txt2nid(*args); + if (!strcmp(*args, "NONE")) + key_pbe = -1; + else + key_pbe=OBJ_txt2nid(*args); if(key_pbe == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); @@ -252,11 +262,13 @@ int MAIN(int argc, char **argv) args++; CAfile = *args; } else badarg = 1; +#ifndef OPENSSL_NO_ENGINE } else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; +#endif } else badarg = 1; } else badarg = 1; @@ -304,14 +316,18 @@ int MAIN(int argc, char **argv) BIO_printf (bio_err, "-password p set import/export password source\n"); BIO_printf (bio_err, "-passin p input file pass phrase source\n"); BIO_printf (bio_err, "-passout p output file pass phrase source\n"); +#ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); +#endif BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); goto end; } +#ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); +#endif if(passarg) { if(export_cert) passargout = passarg; @@ -357,24 +373,6 @@ int MAIN(int argc, char **argv) goto end; } -#if 0 - if (certfile) { - if(!(certsin = BIO_new_file(certfile, "r"))) { - BIO_printf(bio_err, "Can't open certificate file %s\n", certfile); - perror (certfile); - goto end; - } - } - - if (keyname) { - if(!(inkey = BIO_new_file(keyname, "r"))) { - BIO_printf(bio_err, "Can't key certificate file %s\n", keyname); - perror (keyname); - goto end; - } - } -#endif - #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("write files"); @@ -399,7 +397,7 @@ int MAIN(int argc, char **argv) #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read MAC password"); #endif - if(EVP_read_pw_string (macpass, 50, "Enter MAC Password:", export_cert)) + if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { BIO_printf (bio_err, "Can't read Password\n"); goto end; @@ -411,27 +409,31 @@ int MAIN(int argc, char **argv) if (export_cert) { EVP_PKEY *key = NULL; - STACK_OF(PKCS12_SAFEBAG) *bags = NULL; - STACK_OF(PKCS7) *safes = NULL; - PKCS12_SAFEBAG *bag = NULL; - PKCS8_PRIV_KEY_INFO *p8 = NULL; - PKCS7 *authsafe = NULL; - X509 *ucert = NULL; + X509 *ucert = NULL, *x = NULL; STACK_OF(X509) *certs=NULL; - char *catmp = NULL; + unsigned char *catmp = NULL; int i; - unsigned char keyid[EVP_MAX_MD_SIZE]; - unsigned int keyidlen = 0; + + if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS)) + { + BIO_printf(bio_err, "Nothing to do!\n"); + goto export_end; + } + + if (options & NOCERTS) + chain = 0; #ifdef CRYPTO_MDEBUG CRYPTO_push_info("process -export_cert"); CRYPTO_push_info("reading private key"); #endif - key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1, - passin, e, "private key"); - if (!key) { - goto export_end; - } + if (!(options & NOKEYS)) + { + key = load_key(bio_err, keyname ? keyname : infile, + FORMAT_PEM, 1, passin, e, "private key"); + if (!key) + goto export_end; + } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); @@ -439,49 +441,61 @@ int MAIN(int argc, char **argv) #endif /* Load in all certs in input file */ - if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, - "certificates"))) { - goto export_end; - } + if(!(options & NOCERTS)) + { + certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, + "certificates"); + if (!certs) + goto export_end; -#ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("reading certs from input 2"); -#endif + if (key) + { + /* Look for matching private key */ + for(i = 0; i < sk_X509_num(certs); i++) + { + x = sk_X509_value(certs, i); + if(X509_check_private_key(x, key)) + { + ucert = x; + /* Zero keyid and alias */ + X509_keyid_set1(ucert, NULL, 0); + X509_alias_set1(ucert, NULL, 0); + /* Remove from list */ + sk_X509_delete(certs, i); + break; + } + } + if (!ucert) + { + BIO_printf(bio_err, "No certificate matches private key\n"); + goto export_end; + } + } - for(i = 0; i < sk_X509_num(certs); i++) { - ucert = sk_X509_value(certs, i); - if(X509_check_private_key(ucert, key)) { - X509_digest(ucert, EVP_sha1(), keyid, &keyidlen); - break; } - } - if(!keyidlen) { - ucert = NULL; - BIO_printf(bio_err, "No certificate matches private key\n"); - goto export_end; - } - + #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); - CRYPTO_push_info("reading certs from certfile"); + CRYPTO_push_info("reading certs from input 2"); #endif - bags = sk_PKCS12_SAFEBAG_new_null (); - /* Add any more certificates asked for */ - if (certfile) { + if(certfile) + { STACK_OF(X509) *morecerts=NULL; if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, NULL, e, - "certificates from certfile"))) { + "certificates from certfile"))) goto export_end; - } - while(sk_X509_num(morecerts) > 0) { + while(sk_X509_num(morecerts) > 0) sk_X509_push(certs, sk_X509_shift(morecerts)); - } sk_X509_free(morecerts); - } + } + +#ifdef CRYPTO_MDEBUG + CRYPTO_pop_info(); + CRYPTO_push_info("reading certs from certfile"); +#endif #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); @@ -518,100 +532,55 @@ int MAIN(int argc, char **argv) } } -#ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("building bags"); -#endif - - /* We now have loads of certificates: include them all */ - for(i = 0; i < sk_X509_num(certs); i++) { - X509 *cert = NULL; - cert = sk_X509_value(certs, i); - bag = PKCS12_x5092certbag(cert); - /* If it matches private key set id */ - if(cert == ucert) { - if(name) PKCS12_add_friendlyname(bag, name, -1); - PKCS12_add_localkeyid(bag, keyid, keyidlen); - } else if((catmp = sk_shift(canames))) - PKCS12_add_friendlyname(bag, catmp, -1); - sk_PKCS12_SAFEBAG_push(bags, bag); - } - sk_X509_pop_free(certs, X509_free); - certs = NULL; - -#ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("encrypting bags"); -#endif + /* Add any CA names */ - if(!noprompt && - EVP_read_pw_string(pass, 50, "Enter Export Password:", 1)) { - BIO_printf (bio_err, "Can't read Password\n"); - goto export_end; - } - if (!twopass) strcpy(macpass, pass); - /* Turn certbags into encrypted authsafe */ - authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0, - iter, bags); - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - bags = NULL; - - if (!authsafe) { - ERR_print_errors (bio_err); - goto export_end; - } - - safes = sk_PKCS7_new_null (); - sk_PKCS7_push (safes, authsafe); - -#ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("building shrouded key bag"); -#endif + for (i = 0; i < sk_num(canames); i++) + { + catmp = (unsigned char *)sk_value(canames, i); + X509_alias_set1(sk_X509_value(certs, i), catmp, -1); + } - /* Make a shrouded key bag */ - p8 = EVP_PKEY2PKCS8 (key); - if(keytype) PKCS8_add_keyusage(p8, keytype); - bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8); - PKCS8_PRIV_KEY_INFO_free(p8); - p8 = NULL; - if (name) PKCS12_add_friendlyname (bag, name, -1); - if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1); - PKCS12_add_localkeyid (bag, keyid, keyidlen); - bags = sk_PKCS12_SAFEBAG_new_null(); - sk_PKCS12_SAFEBAG_push (bags, bag); + if (csp_name && key) + EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, + MBSTRING_ASC, (unsigned char *)csp_name, -1); + #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); - CRYPTO_push_info("encrypting shrouded key bag"); + CRYPTO_push_info("reading password"); #endif - /* Turn it into unencrypted safe bag */ - authsafe = PKCS12_pack_p7data (bags); - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - bags = NULL; - sk_PKCS7_push (safes, authsafe); + if(!noprompt && + EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1)) + { + BIO_printf (bio_err, "Can't read Password\n"); + goto export_end; + } + if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); - CRYPTO_push_info("building pkcs12"); + CRYPTO_push_info("creating PKCS#12 structure"); #endif - p12 = PKCS12_init(NID_pkcs7_data); - - PKCS12_pack_authsafes(p12, safes); + p12 = PKCS12_create(cpass, name, key, ucert, certs, + key_pbe, cert_pbe, iter, -1, keytype); - sk_PKCS7_pop_free(safes, PKCS7_free); - safes = NULL; + if (!p12) + { + ERR_print_errors (bio_err); + goto export_end; + } - PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL); + if (maciter != -1) + PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("writing pkcs12"); #endif - i2d_PKCS12_bio (out, p12); + i2d_PKCS12_bio(out, p12); ret = 0; @@ -624,8 +593,7 @@ int MAIN(int argc, char **argv) if (key) EVP_PKEY_free(key); if (certs) sk_X509_pop_free(certs, X509_free); - if (safes) sk_PKCS7_pop_free(safes, PKCS7_free); - if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + if (ucert) X509_free(ucert); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); @@ -642,7 +610,7 @@ int MAIN(int argc, char **argv) #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read import password"); #endif - if(!noprompt && EVP_read_pw_string(pass, 50, "Enter Import Password:", 0)) { + if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) { BIO_printf (bio_err, "Can't read Password\n"); goto end; } @@ -650,7 +618,7 @@ int MAIN(int argc, char **argv) CRYPTO_pop_info(); #endif - if (!twopass) strcpy(macpass, pass); + if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); if(macver) { @@ -658,7 +626,7 @@ int MAIN(int argc, char **argv) CRYPTO_push_info("verify MAC"); #endif /* If we enter empty password try no password first */ - if(!macpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { + if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { /* If mac and crypto pass the same set it to NULL too */ if(!twopass) cpass = NULL; } else if (!PKCS12_verify_mac(p12, mpass, -1)) { @@ -696,15 +664,16 @@ int MAIN(int argc, char **argv) if(passin) OPENSSL_free(passin); if(passout) OPENSSL_free(passout); apps_shutdown(); - EXIT(ret); + OPENSSL_EXIT(ret); } int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass) { - STACK_OF(PKCS7) *asafes; + STACK_OF(PKCS7) *asafes = NULL; STACK_OF(PKCS12_SAFEBAG) *bags; int i, bagnid; + int ret = 0; PKCS7 *p7; if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0; @@ -722,16 +691,22 @@ int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass, } bags = PKCS12_unpack_p7encdata(p7, pass, passlen); } else continue; - if (!bags) return 0; + if (!bags) goto err; if (!dump_certs_pkeys_bags (out, bags, pass, passlen, options, pempass)) { sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free); - return 0; + goto err; } sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free); + bags = NULL; } - sk_PKCS7_pop_free (asafes, PKCS7_free); - return 1; + ret = 1; + + err: + + if (asafes) + sk_PKCS7_pop_free (asafes, PKCS7_free); + return ret; } int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, @@ -848,11 +823,12 @@ err: int alg_print (BIO *x, X509_ALGOR *alg) { PBEPARAM *pbe; - unsigned char *p; + const unsigned char *p; p = alg->parameter->value.sequence->data; pbe = d2i_PBEPARAM (NULL, &p, alg->parameter->value.sequence->length); - BIO_printf (bio_err, "%s, Iteration %d\n", - OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), ASN1_INTEGER_get(pbe->iter)); + BIO_printf (bio_err, "%s, Iteration %ld\n", + OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), + ASN1_INTEGER_get(pbe->iter)); PBEPARAM_free (pbe); return 0; } @@ -886,7 +862,7 @@ int cert_load(BIO *in, STACK_OF(X509) *sk) /* Generalised attribute print: handle PKCS#8 and bag attributes */ -int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, char *name) +int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name) { X509_ATTRIBUTE *attr; ASN1_TYPE *av;