10Sstevel@tonic-gate /* pkcs8.c */
20Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3*2139Sjp161948 * project 1999-2004.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate /* ====================================================================
60Sstevel@tonic-gate * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate * are met:
110Sstevel@tonic-gate *
120Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate * the documentation and/or other materials provided with the
180Sstevel@tonic-gate * distribution.
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate * software must display the following acknowledgment:
220Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate * endorse or promote products derived from this software without
270Sstevel@tonic-gate * prior written permission. For written permission, please contact
280Sstevel@tonic-gate * licensing@OpenSSL.org.
290Sstevel@tonic-gate *
300Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate * permission of the OpenSSL Project.
330Sstevel@tonic-gate *
340Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate * acknowledgment:
360Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate *
390Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate * ====================================================================
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
550Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate *
570Sstevel@tonic-gate */
580Sstevel@tonic-gate #include <stdio.h>
590Sstevel@tonic-gate #include <string.h>
600Sstevel@tonic-gate #include "apps.h"
610Sstevel@tonic-gate #include <openssl/pem.h>
620Sstevel@tonic-gate #include <openssl/err.h>
630Sstevel@tonic-gate #include <openssl/evp.h>
640Sstevel@tonic-gate #include <openssl/pkcs12.h>
650Sstevel@tonic-gate
660Sstevel@tonic-gate #define PROG pkcs8_main
670Sstevel@tonic-gate
680Sstevel@tonic-gate int MAIN(int, char **);
690Sstevel@tonic-gate
MAIN(int argc,char ** argv)700Sstevel@tonic-gate int MAIN(int argc, char **argv)
71*2139Sjp161948 {
720Sstevel@tonic-gate ENGINE *e = NULL;
730Sstevel@tonic-gate char **args, *infile = NULL, *outfile = NULL;
740Sstevel@tonic-gate char *passargin = NULL, *passargout = NULL;
750Sstevel@tonic-gate BIO *in = NULL, *out = NULL;
760Sstevel@tonic-gate int topk8 = 0;
770Sstevel@tonic-gate int pbe_nid = -1;
780Sstevel@tonic-gate const EVP_CIPHER *cipher = NULL;
790Sstevel@tonic-gate int iter = PKCS12_DEFAULT_ITER;
800Sstevel@tonic-gate int informat, outformat;
810Sstevel@tonic-gate int p8_broken = PKCS8_OK;
820Sstevel@tonic-gate int nocrypt = 0;
830Sstevel@tonic-gate X509_SIG *p8;
840Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO *p8inf;
850Sstevel@tonic-gate EVP_PKEY *pkey=NULL;
860Sstevel@tonic-gate char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
870Sstevel@tonic-gate int badarg = 0;
880Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
890Sstevel@tonic-gate char *engine=NULL;
900Sstevel@tonic-gate #endif
910Sstevel@tonic-gate
920Sstevel@tonic-gate if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
930Sstevel@tonic-gate
940Sstevel@tonic-gate if (!load_config(bio_err, NULL))
950Sstevel@tonic-gate goto end;
960Sstevel@tonic-gate
970Sstevel@tonic-gate informat=FORMAT_PEM;
980Sstevel@tonic-gate outformat=FORMAT_PEM;
990Sstevel@tonic-gate
1000Sstevel@tonic-gate ERR_load_crypto_strings();
1010Sstevel@tonic-gate OpenSSL_add_all_algorithms();
1020Sstevel@tonic-gate args = argv + 1;
103*2139Sjp161948 while (!badarg && *args && *args[0] == '-')
104*2139Sjp161948 {
105*2139Sjp161948 if (!strcmp(*args,"-v2"))
106*2139Sjp161948 {
107*2139Sjp161948 if (args[1])
108*2139Sjp161948 {
1090Sstevel@tonic-gate args++;
1100Sstevel@tonic-gate cipher=EVP_get_cipherbyname(*args);
111*2139Sjp161948 if (!cipher)
112*2139Sjp161948 {
1130Sstevel@tonic-gate BIO_printf(bio_err,
1140Sstevel@tonic-gate "Unknown cipher %s\n", *args);
1150Sstevel@tonic-gate badarg = 1;
116*2139Sjp161948 }
1170Sstevel@tonic-gate }
118*2139Sjp161948 else
119*2139Sjp161948 badarg = 1;
120*2139Sjp161948 }
121*2139Sjp161948 else if (!strcmp(*args,"-v1"))
122*2139Sjp161948 {
123*2139Sjp161948 if (args[1])
124*2139Sjp161948 {
1250Sstevel@tonic-gate args++;
1260Sstevel@tonic-gate pbe_nid=OBJ_txt2nid(*args);
127*2139Sjp161948 if (pbe_nid == NID_undef)
128*2139Sjp161948 {
1290Sstevel@tonic-gate BIO_printf(bio_err,
1300Sstevel@tonic-gate "Unknown PBE algorithm %s\n", *args);
1310Sstevel@tonic-gate badarg = 1;
132*2139Sjp161948 }
1330Sstevel@tonic-gate }
134*2139Sjp161948 else
135*2139Sjp161948 badarg = 1;
136*2139Sjp161948 }
137*2139Sjp161948 else if (!strcmp(*args,"-inform"))
138*2139Sjp161948 {
139*2139Sjp161948 if (args[1])
140*2139Sjp161948 {
1410Sstevel@tonic-gate args++;
1420Sstevel@tonic-gate informat=str2fmt(*args);
143*2139Sjp161948 }
144*2139Sjp161948 else badarg = 1;
145*2139Sjp161948 }
146*2139Sjp161948 else if (!strcmp(*args,"-outform"))
147*2139Sjp161948 {
148*2139Sjp161948 if (args[1])
149*2139Sjp161948 {
1500Sstevel@tonic-gate args++;
1510Sstevel@tonic-gate outformat=str2fmt(*args);
152*2139Sjp161948 }
153*2139Sjp161948 else badarg = 1;
154*2139Sjp161948 }
155*2139Sjp161948 else if (!strcmp (*args, "-topk8"))
156*2139Sjp161948 topk8 = 1;
157*2139Sjp161948 else if (!strcmp (*args, "-noiter"))
158*2139Sjp161948 iter = 1;
159*2139Sjp161948 else if (!strcmp (*args, "-nocrypt"))
160*2139Sjp161948 nocrypt = 1;
161*2139Sjp161948 else if (!strcmp (*args, "-nooct"))
162*2139Sjp161948 p8_broken = PKCS8_NO_OCTET;
163*2139Sjp161948 else if (!strcmp (*args, "-nsdb"))
164*2139Sjp161948 p8_broken = PKCS8_NS_DB;
165*2139Sjp161948 else if (!strcmp (*args, "-embed"))
166*2139Sjp161948 p8_broken = PKCS8_EMBEDDED_PARAM;
1670Sstevel@tonic-gate else if (!strcmp(*args,"-passin"))
1680Sstevel@tonic-gate {
1690Sstevel@tonic-gate if (!args[1]) goto bad;
1700Sstevel@tonic-gate passargin= *(++args);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate else if (!strcmp(*args,"-passout"))
1730Sstevel@tonic-gate {
1740Sstevel@tonic-gate if (!args[1]) goto bad;
1750Sstevel@tonic-gate passargout= *(++args);
1760Sstevel@tonic-gate }
1770Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
1780Sstevel@tonic-gate else if (strcmp(*args,"-engine") == 0)
1790Sstevel@tonic-gate {
1800Sstevel@tonic-gate if (!args[1]) goto bad;
1810Sstevel@tonic-gate engine= *(++args);
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate #endif
184*2139Sjp161948 else if (!strcmp (*args, "-in"))
185*2139Sjp161948 {
186*2139Sjp161948 if (args[1])
187*2139Sjp161948 {
1880Sstevel@tonic-gate args++;
1890Sstevel@tonic-gate infile = *args;
190*2139Sjp161948 }
191*2139Sjp161948 else badarg = 1;
192*2139Sjp161948 }
193*2139Sjp161948 else if (!strcmp (*args, "-out"))
194*2139Sjp161948 {
195*2139Sjp161948 if (args[1])
196*2139Sjp161948 {
1970Sstevel@tonic-gate args++;
1980Sstevel@tonic-gate outfile = *args;
199*2139Sjp161948 }
200*2139Sjp161948 else badarg = 1;
201*2139Sjp161948 }
202*2139Sjp161948 else badarg = 1;
2030Sstevel@tonic-gate args++;
204*2139Sjp161948 }
2050Sstevel@tonic-gate
206*2139Sjp161948 if (badarg)
207*2139Sjp161948 {
2080Sstevel@tonic-gate bad:
2090Sstevel@tonic-gate BIO_printf(bio_err, "Usage pkcs8 [options]\n");
2100Sstevel@tonic-gate BIO_printf(bio_err, "where options are\n");
2110Sstevel@tonic-gate BIO_printf(bio_err, "-in file input file\n");
2120Sstevel@tonic-gate BIO_printf(bio_err, "-inform X input format (DER or PEM)\n");
2130Sstevel@tonic-gate BIO_printf(bio_err, "-passin arg input file pass phrase source\n");
2140Sstevel@tonic-gate BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
2150Sstevel@tonic-gate BIO_printf(bio_err, "-out file output file\n");
2160Sstevel@tonic-gate BIO_printf(bio_err, "-passout arg output file pass phrase source\n");
2170Sstevel@tonic-gate BIO_printf(bio_err, "-topk8 output PKCS8 file\n");
2180Sstevel@tonic-gate BIO_printf(bio_err, "-nooct use (nonstandard) no octet format\n");
2190Sstevel@tonic-gate BIO_printf(bio_err, "-embed use (nonstandard) embedded DSA parameters format\n");
2200Sstevel@tonic-gate BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netscape DB format\n");
2210Sstevel@tonic-gate BIO_printf(bio_err, "-noiter use 1 as iteration count\n");
2220Sstevel@tonic-gate BIO_printf(bio_err, "-nocrypt use or expect unencrypted private key\n");
2230Sstevel@tonic-gate BIO_printf(bio_err, "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n");
2240Sstevel@tonic-gate BIO_printf(bio_err, "-v1 obj use PKCS#5 v1.5 and cipher \"alg\"\n");
2250Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2260Sstevel@tonic-gate BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
2270Sstevel@tonic-gate #endif
228*2139Sjp161948 return 1;
229*2139Sjp161948 }
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2320Sstevel@tonic-gate e = setup_engine(bio_err, engine, 0);
2330Sstevel@tonic-gate #endif
2340Sstevel@tonic-gate
235*2139Sjp161948 if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
236*2139Sjp161948 {
2370Sstevel@tonic-gate BIO_printf(bio_err, "Error getting passwords\n");
238*2139Sjp161948 return 1;
239*2139Sjp161948 }
2400Sstevel@tonic-gate
241*2139Sjp161948 if ((pbe_nid == -1) && !cipher)
242*2139Sjp161948 pbe_nid = NID_pbeWithMD5AndDES_CBC;
2430Sstevel@tonic-gate
244*2139Sjp161948 if (infile)
245*2139Sjp161948 {
246*2139Sjp161948 if (!(in = BIO_new_file(infile, "rb")))
247*2139Sjp161948 {
2480Sstevel@tonic-gate BIO_printf(bio_err,
2490Sstevel@tonic-gate "Can't open input file %s\n", infile);
2500Sstevel@tonic-gate return (1);
251*2139Sjp161948 }
2520Sstevel@tonic-gate }
253*2139Sjp161948 else
254*2139Sjp161948 in = BIO_new_fp (stdin, BIO_NOCLOSE);
2550Sstevel@tonic-gate
256*2139Sjp161948 if (outfile)
257*2139Sjp161948 {
258*2139Sjp161948 if (!(out = BIO_new_file (outfile, "wb")))
259*2139Sjp161948 {
2600Sstevel@tonic-gate BIO_printf(bio_err,
2610Sstevel@tonic-gate "Can't open output file %s\n", outfile);
2620Sstevel@tonic-gate return (1);
263*2139Sjp161948 }
2640Sstevel@tonic-gate }
265*2139Sjp161948 else
266*2139Sjp161948 {
2670Sstevel@tonic-gate out = BIO_new_fp (stdout, BIO_NOCLOSE);
2680Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS
269*2139Sjp161948 {
2700Sstevel@tonic-gate BIO *tmpbio = BIO_new(BIO_f_linebuffer());
2710Sstevel@tonic-gate out = BIO_push(tmpbio, out);
272*2139Sjp161948 }
2730Sstevel@tonic-gate #endif
274*2139Sjp161948 }
2750Sstevel@tonic-gate if (topk8)
2760Sstevel@tonic-gate {
2770Sstevel@tonic-gate BIO_free(in); /* Not needed in this section */
2780Sstevel@tonic-gate pkey = load_key(bio_err, infile, informat, 1,
2790Sstevel@tonic-gate passin, e, "key");
280*2139Sjp161948 if (!pkey)
281*2139Sjp161948 {
282*2139Sjp161948 BIO_free_all(out);
283*2139Sjp161948 return 1;
284*2139Sjp161948 }
285*2139Sjp161948 if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
286*2139Sjp161948 {
2870Sstevel@tonic-gate BIO_printf(bio_err, "Error converting key\n");
2880Sstevel@tonic-gate ERR_print_errors(bio_err);
289*2139Sjp161948 EVP_PKEY_free(pkey);
290*2139Sjp161948 BIO_free_all(out);
291*2139Sjp161948 return 1;
292*2139Sjp161948 }
293*2139Sjp161948 if (nocrypt)
294*2139Sjp161948 {
295*2139Sjp161948 if (outformat == FORMAT_PEM)
2960Sstevel@tonic-gate PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
297*2139Sjp161948 else if (outformat == FORMAT_ASN1)
2980Sstevel@tonic-gate i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
299*2139Sjp161948 else
300*2139Sjp161948 {
3010Sstevel@tonic-gate BIO_printf(bio_err, "Bad format specified for key\n");
302*2139Sjp161948 PKCS8_PRIV_KEY_INFO_free(p8inf);
303*2139Sjp161948 EVP_PKEY_free(pkey);
304*2139Sjp161948 BIO_free_all(out);
3050Sstevel@tonic-gate return (1);
306*2139Sjp161948 }
3070Sstevel@tonic-gate }
308*2139Sjp161948 else
309*2139Sjp161948 {
310*2139Sjp161948 if (passout)
311*2139Sjp161948 p8pass = passout;
312*2139Sjp161948 else
313*2139Sjp161948 {
3140Sstevel@tonic-gate p8pass = pass;
3150Sstevel@tonic-gate if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
316*2139Sjp161948 {
317*2139Sjp161948 PKCS8_PRIV_KEY_INFO_free(p8inf);
318*2139Sjp161948 EVP_PKEY_free(pkey);
319*2139Sjp161948 BIO_free_all(out);
3200Sstevel@tonic-gate return (1);
321*2139Sjp161948 }
322*2139Sjp161948 }
3230Sstevel@tonic-gate app_RAND_load_file(NULL, bio_err, 0);
3240Sstevel@tonic-gate if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
3250Sstevel@tonic-gate p8pass, strlen(p8pass),
326*2139Sjp161948 NULL, 0, iter, p8inf)))
327*2139Sjp161948 {
3280Sstevel@tonic-gate BIO_printf(bio_err, "Error encrypting key\n");
3290Sstevel@tonic-gate ERR_print_errors(bio_err);
330*2139Sjp161948 PKCS8_PRIV_KEY_INFO_free(p8inf);
331*2139Sjp161948 EVP_PKEY_free(pkey);
332*2139Sjp161948 BIO_free_all(out);
3330Sstevel@tonic-gate return (1);
334*2139Sjp161948 }
3350Sstevel@tonic-gate app_RAND_write_file(NULL, bio_err);
336*2139Sjp161948 if (outformat == FORMAT_PEM)
3370Sstevel@tonic-gate PEM_write_bio_PKCS8(out, p8);
338*2139Sjp161948 else if (outformat == FORMAT_ASN1)
3390Sstevel@tonic-gate i2d_PKCS8_bio(out, p8);
340*2139Sjp161948 else
341*2139Sjp161948 {
3420Sstevel@tonic-gate BIO_printf(bio_err, "Bad format specified for key\n");
343*2139Sjp161948 PKCS8_PRIV_KEY_INFO_free(p8inf);
344*2139Sjp161948 EVP_PKEY_free(pkey);
345*2139Sjp161948 BIO_free_all(out);
3460Sstevel@tonic-gate return (1);
347*2139Sjp161948 }
3480Sstevel@tonic-gate X509_SIG_free(p8);
349*2139Sjp161948 }
350*2139Sjp161948
3510Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO_free (p8inf);
3520Sstevel@tonic-gate EVP_PKEY_free(pkey);
3530Sstevel@tonic-gate BIO_free_all(out);
354*2139Sjp161948 if (passin)
355*2139Sjp161948 OPENSSL_free(passin);
356*2139Sjp161948 if (passout)
357*2139Sjp161948 OPENSSL_free(passout);
3580Sstevel@tonic-gate return (0);
359*2139Sjp161948 }
3600Sstevel@tonic-gate
361*2139Sjp161948 if (nocrypt)
362*2139Sjp161948 {
363*2139Sjp161948 if (informat == FORMAT_PEM)
3640Sstevel@tonic-gate p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
365*2139Sjp161948 else if (informat == FORMAT_ASN1)
3660Sstevel@tonic-gate p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
367*2139Sjp161948 else
368*2139Sjp161948 {
3690Sstevel@tonic-gate BIO_printf(bio_err, "Bad format specified for key\n");
3700Sstevel@tonic-gate return (1);
371*2139Sjp161948 }
3720Sstevel@tonic-gate }
373*2139Sjp161948 else
374*2139Sjp161948 {
375*2139Sjp161948 if (informat == FORMAT_PEM)
3760Sstevel@tonic-gate p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
377*2139Sjp161948 else if (informat == FORMAT_ASN1)
3780Sstevel@tonic-gate p8 = d2i_PKCS8_bio(in, NULL);
379*2139Sjp161948 else
380*2139Sjp161948 {
3810Sstevel@tonic-gate BIO_printf(bio_err, "Bad format specified for key\n");
3820Sstevel@tonic-gate return (1);
383*2139Sjp161948 }
3840Sstevel@tonic-gate
385*2139Sjp161948 if (!p8)
386*2139Sjp161948 {
3870Sstevel@tonic-gate BIO_printf (bio_err, "Error reading key\n");
3880Sstevel@tonic-gate ERR_print_errors(bio_err);
3890Sstevel@tonic-gate return (1);
390*2139Sjp161948 }
391*2139Sjp161948 if (passin)
392*2139Sjp161948 p8pass = passin;
393*2139Sjp161948 else
394*2139Sjp161948 {
3950Sstevel@tonic-gate p8pass = pass;
3960Sstevel@tonic-gate EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
397*2139Sjp161948 }
3980Sstevel@tonic-gate p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
3990Sstevel@tonic-gate X509_SIG_free(p8);
400*2139Sjp161948 }
4010Sstevel@tonic-gate
402*2139Sjp161948 if (!p8inf)
403*2139Sjp161948 {
4040Sstevel@tonic-gate BIO_printf(bio_err, "Error decrypting key\n");
4050Sstevel@tonic-gate ERR_print_errors(bio_err);
4060Sstevel@tonic-gate return (1);
407*2139Sjp161948 }
4080Sstevel@tonic-gate
409*2139Sjp161948 if (!(pkey = EVP_PKCS82PKEY(p8inf)))
410*2139Sjp161948 {
4110Sstevel@tonic-gate BIO_printf(bio_err, "Error converting key\n");
4120Sstevel@tonic-gate ERR_print_errors(bio_err);
4130Sstevel@tonic-gate return (1);
414*2139Sjp161948 }
4150Sstevel@tonic-gate
416*2139Sjp161948 if (p8inf->broken)
417*2139Sjp161948 {
4180Sstevel@tonic-gate BIO_printf(bio_err, "Warning: broken key encoding: ");
419*2139Sjp161948 switch (p8inf->broken)
420*2139Sjp161948 {
4210Sstevel@tonic-gate case PKCS8_NO_OCTET:
4220Sstevel@tonic-gate BIO_printf(bio_err, "No Octet String in PrivateKey\n");
4230Sstevel@tonic-gate break;
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate case PKCS8_EMBEDDED_PARAM:
4260Sstevel@tonic-gate BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
4270Sstevel@tonic-gate break;
4280Sstevel@tonic-gate
4290Sstevel@tonic-gate case PKCS8_NS_DB:
4300Sstevel@tonic-gate BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
4310Sstevel@tonic-gate break;
4320Sstevel@tonic-gate
4330Sstevel@tonic-gate default:
4340Sstevel@tonic-gate BIO_printf(bio_err, "Unknown broken type\n");
4350Sstevel@tonic-gate break;
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate
4390Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO_free(p8inf);
440*2139Sjp161948 if (outformat == FORMAT_PEM)
4410Sstevel@tonic-gate PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
442*2139Sjp161948 else if (outformat == FORMAT_ASN1)
4430Sstevel@tonic-gate i2d_PrivateKey_bio(out, pkey);
444*2139Sjp161948 else
445*2139Sjp161948 {
4460Sstevel@tonic-gate BIO_printf(bio_err, "Bad format specified for key\n");
4470Sstevel@tonic-gate return (1);
448*2139Sjp161948 }
4490Sstevel@tonic-gate
4500Sstevel@tonic-gate end:
4510Sstevel@tonic-gate EVP_PKEY_free(pkey);
4520Sstevel@tonic-gate BIO_free_all(out);
4530Sstevel@tonic-gate BIO_free(in);
454*2139Sjp161948 if (passin)
455*2139Sjp161948 OPENSSL_free(passin);
456*2139Sjp161948 if (passout)
457*2139Sjp161948 OPENSSL_free(passout);
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate return (0);
460*2139Sjp161948 }
461