=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/openssl/pkcs12.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- src/usr.bin/openssl/pkcs12.c 2018/02/07 05:47:55 1.10 +++ src/usr.bin/openssl/pkcs12.c 2019/07/23 10:18:32 1.11 @@ -1,4 +1,4 @@ -/* $OpenBSD: pkcs12.c,v 1.10 2018/02/07 05:47:55 jsing Exp $ */ +/* $OpenBSD: pkcs12.c,v 1.11 2019/07/23 10:18:32 inoguchi Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ @@ -71,8 +71,6 @@ #include #include -const EVP_CIPHER *enc; - #define NOKEYS 0x1 #define NOCERTS 0x2 #define INFO 0x4 @@ -92,37 +90,46 @@ int cert_load(BIO * in, STACK_OF(X509) * sk); static int set_pbe(BIO * err, int *ppbe, const char *str); +static struct { + int add_lmk; + char *CAfile; + STACK_OF(OPENSSL_STRING) *canames; + char *CApath; + int cert_pbe; + char *certfile; + int chain; + char *csp_name; + const EVP_CIPHER *enc; + int export_cert; + int key_pbe; + char *keyname; + int keytype; + char *infile; + int iter; + char *macalg; + int maciter; + int macver; + char *name; + int noprompt; + int options; + char *outfile; + char *passarg; + char *passargin; + char *passargout; + int twopass; +} pkcs12_config; + int pkcs12_main(int argc, char **argv) { - char *infile = NULL, *outfile = NULL, *keyname = NULL; - char *certfile = NULL; BIO *in = NULL, *out = NULL; char **args; - char *name = NULL; - char *csp_name = NULL; - int add_lmk = 0; PKCS12 *p12 = NULL; char pass[50], macpass[50]; - int export_cert = 0; - int options = 0; - int chain = 0; int badarg = 0; - int iter = PKCS12_DEFAULT_ITER; - int maciter = PKCS12_DEFAULT_ITER; - int twopass = 0; - int keytype = 0; - int cert_pbe; - int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; int ret = 1; - int macver = 1; - int noprompt = 0; - STACK_OF(OPENSSL_STRING) * canames = NULL; char *cpass = NULL, *mpass = NULL; - char *passargin = NULL, *passargout = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL; - char *macalg = NULL; - char *CApath = NULL, *CAfile = NULL; if (single_execution) { if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { @@ -131,161 +138,165 @@ } } - cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; + memset(&pkcs12_config, 0, sizeof(pkcs12_config)); + pkcs12_config.cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; + pkcs12_config.enc = EVP_des_ede3_cbc(); + pkcs12_config.iter = PKCS12_DEFAULT_ITER; + pkcs12_config.key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + pkcs12_config.maciter = PKCS12_DEFAULT_ITER; + pkcs12_config.macver = 1; - enc = EVP_des_ede3_cbc(); - args = argv + 1; while (*args) { if (*args[0] == '-') { if (!strcmp(*args, "-nokeys")) - options |= NOKEYS; + pkcs12_config.options |= NOKEYS; else if (!strcmp(*args, "-keyex")) - keytype = KEY_EX; + pkcs12_config.keytype = KEY_EX; else if (!strcmp(*args, "-keysig")) - keytype = KEY_SIG; + pkcs12_config.keytype = KEY_SIG; else if (!strcmp(*args, "-nocerts")) - options |= NOCERTS; + pkcs12_config.options |= NOCERTS; else if (!strcmp(*args, "-clcerts")) - options |= CLCERTS; + pkcs12_config.options |= CLCERTS; else if (!strcmp(*args, "-cacerts")) - options |= CACERTS; + pkcs12_config.options |= CACERTS; else if (!strcmp(*args, "-noout")) - options |= (NOKEYS | NOCERTS); + pkcs12_config.options |= (NOKEYS | NOCERTS); else if (!strcmp(*args, "-info")) - options |= INFO; + pkcs12_config.options |= INFO; else if (!strcmp(*args, "-chain")) - chain = 1; + pkcs12_config.chain = 1; else if (!strcmp(*args, "-twopass")) - twopass = 1; + pkcs12_config.twopass = 1; else if (!strcmp(*args, "-nomacver")) - macver = 0; + pkcs12_config.macver = 0; else if (!strcmp(*args, "-descert")) - cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + pkcs12_config.cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; else if (!strcmp(*args, "-export")) - export_cert = 1; + pkcs12_config.export_cert = 1; else if (!strcmp(*args, "-des")) - enc = EVP_des_cbc(); + pkcs12_config.enc = EVP_des_cbc(); else if (!strcmp(*args, "-des3")) - enc = EVP_des_ede3_cbc(); + pkcs12_config.enc = EVP_des_ede3_cbc(); #ifndef OPENSSL_NO_IDEA else if (!strcmp(*args, "-idea")) - enc = EVP_idea_cbc(); + pkcs12_config.enc = EVP_idea_cbc(); #endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args, "-aes128")) - enc = EVP_aes_128_cbc(); + pkcs12_config.enc = EVP_aes_128_cbc(); else if (!strcmp(*args, "-aes192")) - enc = EVP_aes_192_cbc(); + pkcs12_config.enc = EVP_aes_192_cbc(); else if (!strcmp(*args, "-aes256")) - enc = EVP_aes_256_cbc(); + pkcs12_config.enc = EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (!strcmp(*args, "-camellia128")) - enc = EVP_camellia_128_cbc(); + pkcs12_config.enc = EVP_camellia_128_cbc(); else if (!strcmp(*args, "-camellia192")) - enc = EVP_camellia_192_cbc(); + pkcs12_config.enc = EVP_camellia_192_cbc(); else if (!strcmp(*args, "-camellia256")) - enc = EVP_camellia_256_cbc(); + pkcs12_config.enc = EVP_camellia_256_cbc(); #endif else if (!strcmp(*args, "-noiter")) - iter = 1; + pkcs12_config.iter = 1; else if (!strcmp(*args, "-maciter")) - maciter = PKCS12_DEFAULT_ITER; + pkcs12_config.maciter = PKCS12_DEFAULT_ITER; else if (!strcmp(*args, "-nomaciter")) - maciter = 1; + pkcs12_config.maciter = 1; else if (!strcmp(*args, "-nomac")) - maciter = -1; + pkcs12_config.maciter = -1; else if (!strcmp(*args, "-macalg")) if (args[1]) { args++; - macalg = *args; + pkcs12_config.macalg = *args; } else badarg = 1; else if (!strcmp(*args, "-nodes")) - enc = NULL; + pkcs12_config.enc = NULL; else if (!strcmp(*args, "-certpbe")) { - if (!set_pbe(bio_err, &cert_pbe, *++args)) + if (!set_pbe(bio_err, &pkcs12_config.cert_pbe, *++args)) badarg = 1; } else if (!strcmp(*args, "-keypbe")) { - if (!set_pbe(bio_err, &key_pbe, *++args)) + if (!set_pbe(bio_err, &pkcs12_config.key_pbe, *++args)) badarg = 1; } else if (!strcmp(*args, "-inkey")) { if (args[1]) { args++; - keyname = *args; + pkcs12_config.keyname = *args; } else badarg = 1; } else if (!strcmp(*args, "-certfile")) { if (args[1]) { args++; - certfile = *args; + pkcs12_config.certfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-name")) { if (args[1]) { args++; - name = *args; + pkcs12_config.name = *args; } else badarg = 1; } else if (!strcmp(*args, "-LMK")) - add_lmk = 1; + pkcs12_config.add_lmk = 1; else if (!strcmp(*args, "-CSP")) { if (args[1]) { args++; - csp_name = *args; + pkcs12_config.csp_name = *args; } else badarg = 1; } else if (!strcmp(*args, "-caname")) { if (args[1]) { args++; - if (!canames) - canames = sk_OPENSSL_STRING_new_null(); - sk_OPENSSL_STRING_push(canames, *args); + if (!pkcs12_config.canames) + pkcs12_config.canames = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(pkcs12_config.canames, *args); } else badarg = 1; } else if (!strcmp(*args, "-in")) { if (args[1]) { args++; - infile = *args; + pkcs12_config.infile = *args; } else badarg = 1; } else if (!strcmp(*args, "-out")) { if (args[1]) { args++; - outfile = *args; + pkcs12_config.outfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-passin")) { if (args[1]) { args++; - passargin = *args; + pkcs12_config.passargin = *args; } else badarg = 1; } else if (!strcmp(*args, "-passout")) { if (args[1]) { args++; - passargout = *args; + pkcs12_config.passargout = *args; } else badarg = 1; } else if (!strcmp(*args, "-password")) { if (args[1]) { args++; - passarg = *args; - noprompt = 1; + pkcs12_config.passarg = *args; + pkcs12_config.noprompt = 1; } else badarg = 1; } else if (!strcmp(*args, "-CApath")) { if (args[1]) { args++; - CApath = *args; + pkcs12_config.CApath = *args; } else badarg = 1; } else if (!strcmp(*args, "-CAfile")) { if (args[1]) { args++; - CAfile = *args; + pkcs12_config.CAfile = *args; } else badarg = 1; } else @@ -349,58 +360,58 @@ goto end; } - if (passarg) { - if (export_cert) - passargout = passarg; + if (pkcs12_config.passarg) { + if (pkcs12_config.export_cert) + pkcs12_config.passargout = pkcs12_config.passarg; else - passargin = passarg; + pkcs12_config.passargin = pkcs12_config.passarg; } - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(bio_err, pkcs12_config.passargin, pkcs12_config.passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if (!cpass) { - if (export_cert) + if (pkcs12_config.export_cert) cpass = passout; else cpass = passin; } if (cpass) { mpass = cpass; - noprompt = 1; + pkcs12_config.noprompt = 1; } else { cpass = pass; mpass = macpass; } - if (!infile) + if (!pkcs12_config.infile) in = BIO_new_fp(stdin, BIO_NOCLOSE); else - in = BIO_new_file(infile, "rb"); + in = BIO_new_file(pkcs12_config.infile, "rb"); if (!in) { BIO_printf(bio_err, "Error opening input file %s\n", - infile ? infile : ""); - perror(infile); + pkcs12_config.infile ? pkcs12_config.infile : ""); + perror(pkcs12_config.infile); goto end; } - if (!outfile) { + if (!pkcs12_config.outfile) { out = BIO_new_fp(stdout, BIO_NOCLOSE); } else - out = BIO_new_file(outfile, "wb"); + out = BIO_new_file(pkcs12_config.outfile, "wb"); if (!out) { BIO_printf(bio_err, "Error opening output file %s\n", - outfile ? outfile : ""); - perror(outfile); + pkcs12_config.outfile ? pkcs12_config.outfile : ""); + perror(pkcs12_config.outfile); goto end; } - if (twopass) { - if (EVP_read_pw_string(macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { + if (pkcs12_config.twopass) { + if (EVP_read_pw_string(macpass, sizeof macpass, "Enter MAC Password:", pkcs12_config.export_cert)) { BIO_printf(bio_err, "Can't read Password\n"); goto end; } } - if (export_cert) { + if (pkcs12_config.export_cert) { EVP_PKEY *key = NULL; X509 *ucert = NULL, *x = NULL; STACK_OF(X509) * certs = NULL; @@ -408,23 +419,23 @@ unsigned char *catmp = NULL; int i; - if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { + if ((pkcs12_config.options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { BIO_printf(bio_err, "Nothing to do!\n"); goto export_end; } - if (options & NOCERTS) - chain = 0; + if (pkcs12_config.options & NOCERTS) + pkcs12_config.chain = 0; - if (!(options & NOKEYS)) { - key = load_key(bio_err, keyname ? keyname : infile, + if (!(pkcs12_config.options & NOKEYS)) { + key = load_key(bio_err, pkcs12_config.keyname ? pkcs12_config.keyname : pkcs12_config.infile, FORMAT_PEM, 1, passin, "private key"); if (!key) goto export_end; } /* Load in all certs in input file */ - if (!(options & NOCERTS)) { - certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, + if (!(pkcs12_config.options & NOCERTS)) { + certs = load_certs(bio_err, pkcs12_config.infile, FORMAT_PEM, NULL, "certificates"); if (!certs) goto export_end; @@ -451,9 +462,9 @@ } /* Add any more certificates asked for */ - if (certfile) { + if (pkcs12_config.certfile) { STACK_OF(X509) * morecerts = NULL; - if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, + if (!(morecerts = load_certs(bio_err, pkcs12_config.certfile, FORMAT_PEM, NULL, "certificates from certfile"))) goto export_end; while (sk_X509_num(morecerts) > 0) @@ -463,7 +474,7 @@ /* If chaining get chain from user cert */ - if (chain) { + if (pkcs12_config.chain) { int vret; STACK_OF(X509) * chain2; X509_STORE *store = X509_STORE_new(); @@ -471,7 +482,7 @@ BIO_printf(bio_err, "Memory allocation error\n"); goto export_end; } - if (!X509_STORE_load_locations(store, CAfile, CApath)) + if (!X509_STORE_load_locations(store, pkcs12_config.CAfile, pkcs12_config.CApath)) X509_STORE_set_default_paths(store); vret = get_cert_chain(ucert, store, &chain2); @@ -495,44 +506,44 @@ } /* Add any CA names */ - for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) { - catmp = (unsigned char *) sk_OPENSSL_STRING_value(canames, i); + for (i = 0; i < sk_OPENSSL_STRING_num(pkcs12_config.canames); i++) { + catmp = (unsigned char *) sk_OPENSSL_STRING_value(pkcs12_config.canames, i); X509_alias_set1(sk_X509_value(certs, i), catmp, -1); } - if (csp_name && key) + if (pkcs12_config.csp_name && key) EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, - MBSTRING_ASC, (unsigned char *) csp_name, -1); + MBSTRING_ASC, (unsigned char *) pkcs12_config.csp_name, -1); - if (add_lmk && key) + if (pkcs12_config.add_lmk && key) EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); - if (!noprompt && + if (!pkcs12_config.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) + if (!pkcs12_config.twopass) strlcpy(macpass, pass, sizeof macpass); - p12 = PKCS12_create(cpass, name, key, ucert, certs, - key_pbe, cert_pbe, iter, -1, keytype); + p12 = PKCS12_create(cpass, pkcs12_config.name, key, ucert, certs, + pkcs12_config.key_pbe, pkcs12_config.cert_pbe, pkcs12_config.iter, -1, pkcs12_config.keytype); if (!p12) { ERR_print_errors(bio_err); goto export_end; } - if (macalg) { - macmd = EVP_get_digestbyname(macalg); + if (pkcs12_config.macalg) { + macmd = EVP_get_digestbyname(pkcs12_config.macalg); if (!macmd) { BIO_printf(bio_err, "Unknown digest algorithm %s\n", - macalg); + pkcs12_config.macalg); } } - if (maciter != -1) - PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); + if (pkcs12_config.maciter != -1) + PKCS12_set_mac(p12, mpass, -1, NULL, 0, pkcs12_config.maciter, macmd); i2d_PKCS12_bio(out, p12); @@ -555,21 +566,21 @@ ERR_print_errors(bio_err); goto end; } - if (!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) { + if (!pkcs12_config.noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) { BIO_printf(bio_err, "Can't read Password\n"); goto end; } - if (!twopass) + if (!pkcs12_config.twopass) strlcpy(macpass, pass, sizeof macpass); - if ((options & INFO) && p12->mac) + if ((pkcs12_config.options & INFO) && p12->mac) BIO_printf(bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1); - if (macver) { + if (pkcs12_config.macver) { /* If we enter empty password try no password first */ if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { /* If mac and crypto pass the same set it to NULL too */ - if (!twopass) + if (!pkcs12_config.twopass) cpass = NULL; } else if (!PKCS12_verify_mac(p12, mpass, -1)) { BIO_printf(bio_err, "Mac verify error: invalid password?\n"); @@ -578,7 +589,7 @@ } BIO_printf(bio_err, "MAC verified OK\n"); } - if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) { + if (!dump_certs_keys_p12(out, p12, cpass, -1, pkcs12_config.options, passout)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); ERR_print_errors(bio_err); goto end; @@ -589,8 +600,8 @@ PKCS12_free(p12); BIO_free(in); BIO_free_all(out); - if (canames) - sk_OPENSSL_STRING_free(canames); + if (pkcs12_config.canames) + sk_OPENSSL_STRING_free(pkcs12_config.canames); free(passin); free(passout); @@ -678,7 +689,7 @@ if (!(pkey = EVP_PKCS82PKEY(p8))) return 0; print_attribs(out, p8->attributes, "Key Attributes"); - PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); + PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); break; @@ -698,7 +709,7 @@ } print_attribs(out, p8->attributes, "Key Attributes"); PKCS8_PRIV_KEY_INFO_free(p8); - PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); + PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); break;