xref: /onnv-gate/usr/src/common/openssl/apps/pkcs8.c (revision 2139:6243c3338933)
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