1*f5b1c8a1SJohn Marino /* $OpenBSD: dsa.c,v 1.7 2015/10/17 07:51:10 semarie Exp $ */ 2*f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*f5b1c8a1SJohn Marino * All rights reserved. 4*f5b1c8a1SJohn Marino * 5*f5b1c8a1SJohn Marino * This package is an SSL implementation written 6*f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com). 7*f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL. 8*f5b1c8a1SJohn Marino * 9*f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as 10*f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions 11*f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA, 12*f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms 14*f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*f5b1c8a1SJohn Marino * 16*f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in 17*f5b1c8a1SJohn Marino * the code are not to be removed. 18*f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution 19*f5b1c8a1SJohn Marino * as the author of the parts of the library used. 20*f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or 21*f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package. 22*f5b1c8a1SJohn Marino * 23*f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 24*f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 25*f5b1c8a1SJohn Marino * are met: 26*f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright 27*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 28*f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 29*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the 30*f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution. 31*f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software 32*f5b1c8a1SJohn Marino * must display the following acknowledgement: 33*f5b1c8a1SJohn Marino * "This product includes cryptographic software written by 34*f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)" 35*f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library 36*f5b1c8a1SJohn Marino * being used are not cryptographic related :-). 37*f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from 38*f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement: 39*f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*f5b1c8a1SJohn Marino * 41*f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*f5b1c8a1SJohn Marino * SUCH DAMAGE. 52*f5b1c8a1SJohn Marino * 53*f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or 54*f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be 55*f5b1c8a1SJohn Marino * copied and put under another distribution licence 56*f5b1c8a1SJohn Marino * [including the GNU Public Licence.] 57*f5b1c8a1SJohn Marino */ 58*f5b1c8a1SJohn Marino 59*f5b1c8a1SJohn Marino #include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */ 60*f5b1c8a1SJohn Marino 61*f5b1c8a1SJohn Marino #include <ctype.h> 62*f5b1c8a1SJohn Marino #include <stdio.h> 63*f5b1c8a1SJohn Marino #include <stdlib.h> 64*f5b1c8a1SJohn Marino #include <time.h> 65*f5b1c8a1SJohn Marino #include <string.h> 66*f5b1c8a1SJohn Marino 67*f5b1c8a1SJohn Marino #include "apps.h" 68*f5b1c8a1SJohn Marino 69*f5b1c8a1SJohn Marino #include <openssl/bio.h> 70*f5b1c8a1SJohn Marino #include <openssl/bn.h> 71*f5b1c8a1SJohn Marino #include <openssl/dsa.h> 72*f5b1c8a1SJohn Marino #include <openssl/err.h> 73*f5b1c8a1SJohn Marino #include <openssl/evp.h> 74*f5b1c8a1SJohn Marino #include <openssl/pem.h> 75*f5b1c8a1SJohn Marino #include <openssl/x509.h> 76*f5b1c8a1SJohn Marino 77*f5b1c8a1SJohn Marino static struct { 78*f5b1c8a1SJohn Marino const EVP_CIPHER *enc; 79*f5b1c8a1SJohn Marino char *infile; 80*f5b1c8a1SJohn Marino int informat; 81*f5b1c8a1SJohn Marino int modulus; 82*f5b1c8a1SJohn Marino int noout; 83*f5b1c8a1SJohn Marino char *outfile; 84*f5b1c8a1SJohn Marino int outformat; 85*f5b1c8a1SJohn Marino char *passargin; 86*f5b1c8a1SJohn Marino char *passargout; 87*f5b1c8a1SJohn Marino int pubin; 88*f5b1c8a1SJohn Marino int pubout; 89*f5b1c8a1SJohn Marino int pvk_encr; 90*f5b1c8a1SJohn Marino int text; 91*f5b1c8a1SJohn Marino } dsa_config; 92*f5b1c8a1SJohn Marino 93*f5b1c8a1SJohn Marino static int 94*f5b1c8a1SJohn Marino dsa_opt_enc(int argc, char **argv, int *argsused) 95*f5b1c8a1SJohn Marino { 96*f5b1c8a1SJohn Marino char *name = argv[0]; 97*f5b1c8a1SJohn Marino 98*f5b1c8a1SJohn Marino if (*name++ != '-') 99*f5b1c8a1SJohn Marino return (1); 100*f5b1c8a1SJohn Marino 101*f5b1c8a1SJohn Marino if ((dsa_config.enc = EVP_get_cipherbyname(name)) != NULL) { 102*f5b1c8a1SJohn Marino *argsused = 1; 103*f5b1c8a1SJohn Marino return (0); 104*f5b1c8a1SJohn Marino } 105*f5b1c8a1SJohn Marino 106*f5b1c8a1SJohn Marino return (1); 107*f5b1c8a1SJohn Marino } 108*f5b1c8a1SJohn Marino 109*f5b1c8a1SJohn Marino static struct option dsa_options[] = { 110*f5b1c8a1SJohn Marino { 111*f5b1c8a1SJohn Marino .name = "in", 112*f5b1c8a1SJohn Marino .argname = "file", 113*f5b1c8a1SJohn Marino .desc = "Input file (default stdin)", 114*f5b1c8a1SJohn Marino .type = OPTION_ARG, 115*f5b1c8a1SJohn Marino .opt.arg = &dsa_config.infile, 116*f5b1c8a1SJohn Marino }, 117*f5b1c8a1SJohn Marino { 118*f5b1c8a1SJohn Marino .name = "inform", 119*f5b1c8a1SJohn Marino .argname = "format", 120*f5b1c8a1SJohn Marino .desc = "Input format (PEM (default) or any other supported" 121*f5b1c8a1SJohn Marino " format)", 122*f5b1c8a1SJohn Marino .type = OPTION_ARG_FORMAT, 123*f5b1c8a1SJohn Marino .opt.value = &dsa_config.informat, 124*f5b1c8a1SJohn Marino }, 125*f5b1c8a1SJohn Marino { 126*f5b1c8a1SJohn Marino .name = "noout", 127*f5b1c8a1SJohn Marino .desc = "No output", 128*f5b1c8a1SJohn Marino .type = OPTION_FLAG, 129*f5b1c8a1SJohn Marino .opt.flag = &dsa_config.noout, 130*f5b1c8a1SJohn Marino }, 131*f5b1c8a1SJohn Marino { 132*f5b1c8a1SJohn Marino .name = "out", 133*f5b1c8a1SJohn Marino .argname = "file", 134*f5b1c8a1SJohn Marino .desc = "Output file (default stdout)", 135*f5b1c8a1SJohn Marino .type = OPTION_ARG, 136*f5b1c8a1SJohn Marino .opt.arg = &dsa_config.outfile, 137*f5b1c8a1SJohn Marino }, 138*f5b1c8a1SJohn Marino { 139*f5b1c8a1SJohn Marino .name = "outform", 140*f5b1c8a1SJohn Marino .argname = "format", 141*f5b1c8a1SJohn Marino .desc = "Output format (DER, MSBLOB, PEM (default) or PVK)", 142*f5b1c8a1SJohn Marino .type = OPTION_ARG_FORMAT, 143*f5b1c8a1SJohn Marino .opt.value = &dsa_config.outformat, 144*f5b1c8a1SJohn Marino }, 145*f5b1c8a1SJohn Marino { 146*f5b1c8a1SJohn Marino .name = "passin", 147*f5b1c8a1SJohn Marino .argname = "source", 148*f5b1c8a1SJohn Marino .desc = "Input file passphrase source", 149*f5b1c8a1SJohn Marino .type = OPTION_ARG, 150*f5b1c8a1SJohn Marino .opt.arg = &dsa_config.passargin, 151*f5b1c8a1SJohn Marino }, 152*f5b1c8a1SJohn Marino { 153*f5b1c8a1SJohn Marino .name = "passout", 154*f5b1c8a1SJohn Marino .argname = "source", 155*f5b1c8a1SJohn Marino .desc = "Output file passphrase source", 156*f5b1c8a1SJohn Marino .type = OPTION_ARG, 157*f5b1c8a1SJohn Marino .opt.arg = &dsa_config.passargout, 158*f5b1c8a1SJohn Marino }, 159*f5b1c8a1SJohn Marino { 160*f5b1c8a1SJohn Marino .name = "pubin", 161*f5b1c8a1SJohn Marino .desc = "Read a public key from the input file instead of" 162*f5b1c8a1SJohn Marino " private key", 163*f5b1c8a1SJohn Marino .type = OPTION_FLAG, 164*f5b1c8a1SJohn Marino .opt.flag = &dsa_config.pubin, 165*f5b1c8a1SJohn Marino }, 166*f5b1c8a1SJohn Marino { 167*f5b1c8a1SJohn Marino .name = "pubout", 168*f5b1c8a1SJohn Marino .desc = "Output a public key instead of private key", 169*f5b1c8a1SJohn Marino .type = OPTION_FLAG, 170*f5b1c8a1SJohn Marino .opt.flag = &dsa_config.pubout, 171*f5b1c8a1SJohn Marino }, 172*f5b1c8a1SJohn Marino { 173*f5b1c8a1SJohn Marino .name = "pvk-none", 174*f5b1c8a1SJohn Marino .desc = "PVK encryption level", 175*f5b1c8a1SJohn Marino .type = OPTION_VALUE, 176*f5b1c8a1SJohn Marino .value = 0, 177*f5b1c8a1SJohn Marino .opt.value = &dsa_config.pvk_encr, 178*f5b1c8a1SJohn Marino }, 179*f5b1c8a1SJohn Marino { 180*f5b1c8a1SJohn Marino .name = "pvk-strong", 181*f5b1c8a1SJohn Marino .desc = "PVK encryption level (default)", 182*f5b1c8a1SJohn Marino .type = OPTION_VALUE, 183*f5b1c8a1SJohn Marino .value = 2, 184*f5b1c8a1SJohn Marino .opt.value = &dsa_config.pvk_encr, 185*f5b1c8a1SJohn Marino }, 186*f5b1c8a1SJohn Marino { 187*f5b1c8a1SJohn Marino .name = "pvk-weak", 188*f5b1c8a1SJohn Marino .desc = "PVK encryption level", 189*f5b1c8a1SJohn Marino .type = OPTION_VALUE, 190*f5b1c8a1SJohn Marino .value = 1, 191*f5b1c8a1SJohn Marino .opt.value = &dsa_config.pvk_encr, 192*f5b1c8a1SJohn Marino }, 193*f5b1c8a1SJohn Marino { 194*f5b1c8a1SJohn Marino .name = "text", 195*f5b1c8a1SJohn Marino .desc = "Print the key in text form", 196*f5b1c8a1SJohn Marino .type = OPTION_FLAG, 197*f5b1c8a1SJohn Marino .opt.flag = &dsa_config.text, 198*f5b1c8a1SJohn Marino }, 199*f5b1c8a1SJohn Marino { 200*f5b1c8a1SJohn Marino .name = NULL, 201*f5b1c8a1SJohn Marino .type = OPTION_ARGV_FUNC, 202*f5b1c8a1SJohn Marino .opt.argvfunc = dsa_opt_enc, 203*f5b1c8a1SJohn Marino }, 204*f5b1c8a1SJohn Marino { NULL }, 205*f5b1c8a1SJohn Marino }; 206*f5b1c8a1SJohn Marino 207*f5b1c8a1SJohn Marino static void 208*f5b1c8a1SJohn Marino show_ciphers(const OBJ_NAME *name, void *arg) 209*f5b1c8a1SJohn Marino { 210*f5b1c8a1SJohn Marino static int n; 211*f5b1c8a1SJohn Marino 212*f5b1c8a1SJohn Marino if (!islower((unsigned char)*name->name)) 213*f5b1c8a1SJohn Marino return; 214*f5b1c8a1SJohn Marino 215*f5b1c8a1SJohn Marino fprintf(stderr, " -%-24s%s", name->name, (++n % 3 ? "" : "\n")); 216*f5b1c8a1SJohn Marino } 217*f5b1c8a1SJohn Marino 218*f5b1c8a1SJohn Marino static void 219*f5b1c8a1SJohn Marino dsa_usage(void) 220*f5b1c8a1SJohn Marino { 221*f5b1c8a1SJohn Marino fprintf(stderr, 222*f5b1c8a1SJohn Marino "usage: dsa [-in file] [-inform format] [-noout]\n" 223*f5b1c8a1SJohn Marino " [-out file] [-outform format] [-passin src] [-passout src]\n" 224*f5b1c8a1SJohn Marino " [-pubin] [-pubout] [-pvk-none | -pvk-strong | -pvk-weak]\n" 225*f5b1c8a1SJohn Marino " [-text] [-ciphername]\n\n"); 226*f5b1c8a1SJohn Marino options_usage(dsa_options); 227*f5b1c8a1SJohn Marino fprintf(stderr, "\n"); 228*f5b1c8a1SJohn Marino 229*f5b1c8a1SJohn Marino fprintf(stderr, "Valid ciphername values:\n\n"); 230*f5b1c8a1SJohn Marino OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_ciphers, NULL); 231*f5b1c8a1SJohn Marino fprintf(stderr, "\n"); 232*f5b1c8a1SJohn Marino } 233*f5b1c8a1SJohn Marino 234*f5b1c8a1SJohn Marino int 235*f5b1c8a1SJohn Marino dsa_main(int argc, char **argv) 236*f5b1c8a1SJohn Marino { 237*f5b1c8a1SJohn Marino int ret = 1; 238*f5b1c8a1SJohn Marino DSA *dsa = NULL; 239*f5b1c8a1SJohn Marino int i; 240*f5b1c8a1SJohn Marino BIO *in = NULL, *out = NULL; 241*f5b1c8a1SJohn Marino char *passin = NULL, *passout = NULL; 242*f5b1c8a1SJohn Marino 243*f5b1c8a1SJohn Marino if (single_execution) { 244*f5b1c8a1SJohn Marino if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { 245*f5b1c8a1SJohn Marino perror("pledge"); 246*f5b1c8a1SJohn Marino exit(1); 247*f5b1c8a1SJohn Marino } 248*f5b1c8a1SJohn Marino } 249*f5b1c8a1SJohn Marino 250*f5b1c8a1SJohn Marino memset(&dsa_config, 0, sizeof(dsa_config)); 251*f5b1c8a1SJohn Marino 252*f5b1c8a1SJohn Marino dsa_config.pvk_encr = 2; 253*f5b1c8a1SJohn Marino dsa_config.informat = FORMAT_PEM; 254*f5b1c8a1SJohn Marino dsa_config.outformat = FORMAT_PEM; 255*f5b1c8a1SJohn Marino 256*f5b1c8a1SJohn Marino if (options_parse(argc, argv, dsa_options, NULL, NULL) != 0) { 257*f5b1c8a1SJohn Marino dsa_usage(); 258*f5b1c8a1SJohn Marino goto end; 259*f5b1c8a1SJohn Marino } 260*f5b1c8a1SJohn Marino 261*f5b1c8a1SJohn Marino if (!app_passwd(bio_err, dsa_config.passargin, dsa_config.passargout, 262*f5b1c8a1SJohn Marino &passin, &passout)) { 263*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error getting passwords\n"); 264*f5b1c8a1SJohn Marino goto end; 265*f5b1c8a1SJohn Marino } 266*f5b1c8a1SJohn Marino 267*f5b1c8a1SJohn Marino in = BIO_new(BIO_s_file()); 268*f5b1c8a1SJohn Marino out = BIO_new(BIO_s_file()); 269*f5b1c8a1SJohn Marino if (in == NULL || out == NULL) { 270*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 271*f5b1c8a1SJohn Marino goto end; 272*f5b1c8a1SJohn Marino } 273*f5b1c8a1SJohn Marino if (dsa_config.infile == NULL) 274*f5b1c8a1SJohn Marino BIO_set_fp(in, stdin, BIO_NOCLOSE); 275*f5b1c8a1SJohn Marino else { 276*f5b1c8a1SJohn Marino if (BIO_read_filename(in, dsa_config.infile) <= 0) { 277*f5b1c8a1SJohn Marino perror(dsa_config.infile); 278*f5b1c8a1SJohn Marino goto end; 279*f5b1c8a1SJohn Marino } 280*f5b1c8a1SJohn Marino } 281*f5b1c8a1SJohn Marino 282*f5b1c8a1SJohn Marino BIO_printf(bio_err, "read DSA key\n"); 283*f5b1c8a1SJohn Marino 284*f5b1c8a1SJohn Marino { 285*f5b1c8a1SJohn Marino EVP_PKEY *pkey; 286*f5b1c8a1SJohn Marino 287*f5b1c8a1SJohn Marino if (dsa_config.pubin) 288*f5b1c8a1SJohn Marino pkey = load_pubkey(bio_err, dsa_config.infile, 289*f5b1c8a1SJohn Marino dsa_config.informat, 1, passin, "Public Key"); 290*f5b1c8a1SJohn Marino else 291*f5b1c8a1SJohn Marino pkey = load_key(bio_err, dsa_config.infile, 292*f5b1c8a1SJohn Marino dsa_config.informat, 1, passin, "Private Key"); 293*f5b1c8a1SJohn Marino 294*f5b1c8a1SJohn Marino if (pkey) { 295*f5b1c8a1SJohn Marino dsa = EVP_PKEY_get1_DSA(pkey); 296*f5b1c8a1SJohn Marino EVP_PKEY_free(pkey); 297*f5b1c8a1SJohn Marino } 298*f5b1c8a1SJohn Marino } 299*f5b1c8a1SJohn Marino if (dsa == NULL) { 300*f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to load Key\n"); 301*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 302*f5b1c8a1SJohn Marino goto end; 303*f5b1c8a1SJohn Marino } 304*f5b1c8a1SJohn Marino if (dsa_config.outfile == NULL) { 305*f5b1c8a1SJohn Marino BIO_set_fp(out, stdout, BIO_NOCLOSE); 306*f5b1c8a1SJohn Marino } else { 307*f5b1c8a1SJohn Marino if (BIO_write_filename(out, dsa_config.outfile) <= 0) { 308*f5b1c8a1SJohn Marino perror(dsa_config.outfile); 309*f5b1c8a1SJohn Marino goto end; 310*f5b1c8a1SJohn Marino } 311*f5b1c8a1SJohn Marino } 312*f5b1c8a1SJohn Marino 313*f5b1c8a1SJohn Marino if (dsa_config.text) { 314*f5b1c8a1SJohn Marino if (!DSA_print(out, dsa, 0)) { 315*f5b1c8a1SJohn Marino perror(dsa_config.outfile); 316*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 317*f5b1c8a1SJohn Marino goto end; 318*f5b1c8a1SJohn Marino } 319*f5b1c8a1SJohn Marino } 320*f5b1c8a1SJohn Marino if (dsa_config.modulus) { 321*f5b1c8a1SJohn Marino fprintf(stdout, "Public Key="); 322*f5b1c8a1SJohn Marino BN_print(out, dsa->pub_key); 323*f5b1c8a1SJohn Marino fprintf(stdout, "\n"); 324*f5b1c8a1SJohn Marino } 325*f5b1c8a1SJohn Marino if (dsa_config.noout) 326*f5b1c8a1SJohn Marino goto end; 327*f5b1c8a1SJohn Marino BIO_printf(bio_err, "writing DSA key\n"); 328*f5b1c8a1SJohn Marino if (dsa_config.outformat == FORMAT_ASN1) { 329*f5b1c8a1SJohn Marino if (dsa_config.pubin || dsa_config.pubout) 330*f5b1c8a1SJohn Marino i = i2d_DSA_PUBKEY_bio(out, dsa); 331*f5b1c8a1SJohn Marino else 332*f5b1c8a1SJohn Marino i = i2d_DSAPrivateKey_bio(out, dsa); 333*f5b1c8a1SJohn Marino } else if (dsa_config.outformat == FORMAT_PEM) { 334*f5b1c8a1SJohn Marino if (dsa_config.pubin || dsa_config.pubout) 335*f5b1c8a1SJohn Marino i = PEM_write_bio_DSA_PUBKEY(out, dsa); 336*f5b1c8a1SJohn Marino else 337*f5b1c8a1SJohn Marino i = PEM_write_bio_DSAPrivateKey(out, dsa, dsa_config.enc, 338*f5b1c8a1SJohn Marino NULL, 0, NULL, passout); 339*f5b1c8a1SJohn Marino #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4) 340*f5b1c8a1SJohn Marino } else if (dsa_config.outformat == FORMAT_MSBLOB || 341*f5b1c8a1SJohn Marino dsa_config.outformat == FORMAT_PVK) { 342*f5b1c8a1SJohn Marino EVP_PKEY *pk; 343*f5b1c8a1SJohn Marino pk = EVP_PKEY_new(); 344*f5b1c8a1SJohn Marino EVP_PKEY_set1_DSA(pk, dsa); 345*f5b1c8a1SJohn Marino if (dsa_config.outformat == FORMAT_PVK) 346*f5b1c8a1SJohn Marino i = i2b_PVK_bio(out, pk, dsa_config.pvk_encr, 0, 347*f5b1c8a1SJohn Marino passout); 348*f5b1c8a1SJohn Marino else if (dsa_config.pubin || dsa_config.pubout) 349*f5b1c8a1SJohn Marino i = i2b_PublicKey_bio(out, pk); 350*f5b1c8a1SJohn Marino else 351*f5b1c8a1SJohn Marino i = i2b_PrivateKey_bio(out, pk); 352*f5b1c8a1SJohn Marino EVP_PKEY_free(pk); 353*f5b1c8a1SJohn Marino #endif 354*f5b1c8a1SJohn Marino } else { 355*f5b1c8a1SJohn Marino BIO_printf(bio_err, "bad output format specified for outfile\n"); 356*f5b1c8a1SJohn Marino goto end; 357*f5b1c8a1SJohn Marino } 358*f5b1c8a1SJohn Marino if (i <= 0) { 359*f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to write private key\n"); 360*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 361*f5b1c8a1SJohn Marino } else 362*f5b1c8a1SJohn Marino ret = 0; 363*f5b1c8a1SJohn Marino end: 364*f5b1c8a1SJohn Marino BIO_free(in); 365*f5b1c8a1SJohn Marino if (out != NULL) 366*f5b1c8a1SJohn Marino BIO_free_all(out); 367*f5b1c8a1SJohn Marino if (dsa != NULL) 368*f5b1c8a1SJohn Marino DSA_free(dsa); 369*f5b1c8a1SJohn Marino free(passin); 370*f5b1c8a1SJohn Marino free(passout); 371*f5b1c8a1SJohn Marino 372*f5b1c8a1SJohn Marino return (ret); 373*f5b1c8a1SJohn Marino } 374