os/ossrv/ssl/tsrc/topenssl/src/pkcs8.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/tsrc/topenssl/src/pkcs8.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,462 @@
     1.4 +/* pkcs8.c */
     1.5 +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
     1.6 + * project 1999-2004.
     1.7 + */
     1.8 +/* ====================================================================
     1.9 + * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
    1.10 + *
    1.11 + * Redistribution and use in source and binary forms, with or without
    1.12 + * modification, are permitted provided that the following conditions
    1.13 + * are met:
    1.14 + *
    1.15 + * 1. Redistributions of source code must retain the above copyright
    1.16 + *    notice, this list of conditions and the following disclaimer. 
    1.17 + *
    1.18 + * 2. Redistributions in binary form must reproduce the above copyright
    1.19 + *    notice, this list of conditions and the following disclaimer in
    1.20 + *    the documentation and/or other materials provided with the
    1.21 + *    distribution.
    1.22 + *
    1.23 + * 3. All advertising materials mentioning features or use of this
    1.24 + *    software must display the following acknowledgment:
    1.25 + *    "This product includes software developed by the OpenSSL Project
    1.26 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
    1.27 + *
    1.28 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    1.29 + *    endorse or promote products derived from this software without
    1.30 + *    prior written permission. For written permission, please contact
    1.31 + *    licensing@OpenSSL.org.
    1.32 + *
    1.33 + * 5. Products derived from this software may not be called "OpenSSL"
    1.34 + *    nor may "OpenSSL" appear in their names without prior written
    1.35 + *    permission of the OpenSSL Project.
    1.36 + *
    1.37 + * 6. Redistributions of any form whatsoever must retain the following
    1.38 + *    acknowledgment:
    1.39 + *    "This product includes software developed by the OpenSSL Project
    1.40 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
    1.41 + *
    1.42 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    1.43 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.44 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.45 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    1.46 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.47 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1.48 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    1.49 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.50 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    1.51 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.52 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    1.53 + * OF THE POSSIBILITY OF SUCH DAMAGE.
    1.54 + * ====================================================================
    1.55 + *
    1.56 + * This product includes cryptographic software written by Eric Young
    1.57 + * (eay@cryptsoft.com).  This product includes software written by Tim
    1.58 + * Hudson (tjh@cryptsoft.com).
    1.59 + *
    1.60 + */
    1.61 +#include <stdio.h>
    1.62 +#include <string.h>
    1.63 +#include "apps.h"
    1.64 +#include <openssl/pem.h>
    1.65 +#include <openssl/err.h>
    1.66 +#include <openssl/evp.h>
    1.67 +#include <openssl/pkcs12.h>
    1.68 +
    1.69 +#define PROG pkcs8_main
    1.70 +
    1.71 +
    1.72 +int MAIN(int, char **);
    1.73 +
    1.74 +int MAIN(int argc, char **argv)
    1.75 +	{
    1.76 +	ENGINE *e = NULL;
    1.77 +	char **args, *infile = NULL, *outfile = NULL;
    1.78 +	char *passargin = NULL, *passargout = NULL;
    1.79 +	BIO *in = NULL, *out = NULL;
    1.80 +	int topk8 = 0;
    1.81 +	int pbe_nid = -1;
    1.82 +	const EVP_CIPHER *cipher = NULL;
    1.83 +	int iter = PKCS12_DEFAULT_ITER;
    1.84 +	int informat, outformat;
    1.85 +	int p8_broken = PKCS8_OK;
    1.86 +	int nocrypt = 0;
    1.87 +	X509_SIG *p8;
    1.88 +	PKCS8_PRIV_KEY_INFO *p8inf;
    1.89 +	EVP_PKEY *pkey=NULL;
    1.90 +	char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
    1.91 +	int badarg = 0;
    1.92 +#ifndef OPENSSL_NO_ENGINE
    1.93 +	char *engine=NULL;
    1.94 +#endif
    1.95 +
    1.96 +	if (bio_err == NULL) 
    1.97 +	bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
    1.98 +	
    1.99 +
   1.100 +	if (!load_config(bio_err, NULL))
   1.101 +		goto end;
   1.102 +
   1.103 +	informat=FORMAT_PEM;
   1.104 +	outformat=FORMAT_PEM;
   1.105 +
   1.106 +	ERR_load_crypto_strings();
   1.107 +	OpenSSL_add_all_algorithms();
   1.108 +	args = argv + 1;
   1.109 +	while (!badarg && *args && *args[0] == '-')
   1.110 +		{
   1.111 +		if (!strcmp(*args,"-v2"))
   1.112 +			{
   1.113 +			if (args[1])
   1.114 +				{
   1.115 +				args++;
   1.116 +				cipher=EVP_get_cipherbyname(*args);
   1.117 +				if (!cipher)
   1.118 +					{
   1.119 +					BIO_printf(bio_err,
   1.120 +						 "Unknown cipher %s\n", *args);
   1.121 +					badarg = 1;
   1.122 +					}
   1.123 +				}
   1.124 +			else
   1.125 +				badarg = 1;
   1.126 +			}
   1.127 +		else if (!strcmp(*args,"-v1"))
   1.128 +			{
   1.129 +			if (args[1])
   1.130 +				{
   1.131 +				args++;
   1.132 +				pbe_nid=OBJ_txt2nid(*args);
   1.133 +				if (pbe_nid == NID_undef)
   1.134 +					{
   1.135 +					BIO_printf(bio_err,
   1.136 +						 "Unknown PBE algorithm %s\n", *args);
   1.137 +					badarg = 1;
   1.138 +					}
   1.139 +				}
   1.140 +			else
   1.141 +				badarg = 1;
   1.142 +			}
   1.143 +		else if (!strcmp(*args,"-inform"))
   1.144 +			{
   1.145 +			if (args[1])
   1.146 +				{
   1.147 +				args++;
   1.148 +				informat=str2fmt(*args);
   1.149 +				}
   1.150 +			else badarg = 1;
   1.151 +			}
   1.152 +		else if (!strcmp(*args,"-outform"))
   1.153 +			{
   1.154 +			if (args[1])
   1.155 +				{
   1.156 +				args++;
   1.157 +				outformat=str2fmt(*args);
   1.158 +				}
   1.159 +			else badarg = 1;
   1.160 +			}
   1.161 +		else if (!strcmp (*args, "-topk8"))
   1.162 +			topk8 = 1;
   1.163 +		else if (!strcmp (*args, "-noiter"))
   1.164 +			iter = 1;
   1.165 +		else if (!strcmp (*args, "-nocrypt"))
   1.166 +			nocrypt = 1;
   1.167 +		else if (!strcmp (*args, "-nooct"))
   1.168 +			p8_broken = PKCS8_NO_OCTET;
   1.169 +		else if (!strcmp (*args, "-nsdb"))
   1.170 +			p8_broken = PKCS8_NS_DB;
   1.171 +		else if (!strcmp (*args, "-embed"))
   1.172 +			p8_broken = PKCS8_EMBEDDED_PARAM;
   1.173 +		else if (!strcmp(*args,"-passin"))
   1.174 +			{
   1.175 +			if (!args[1]) goto bad;
   1.176 +			passargin= *(++args);
   1.177 +			}
   1.178 +		else if (!strcmp(*args,"-passout"))
   1.179 +			{
   1.180 +			if (!args[1]) goto bad;
   1.181 +			passargout= *(++args);
   1.182 +			}
   1.183 +#ifndef OPENSSL_NO_ENGINE
   1.184 +		else if (strcmp(*args,"-engine") == 0)
   1.185 +			{
   1.186 +			if (!args[1]) goto bad;
   1.187 +			engine= *(++args);
   1.188 +			}
   1.189 +#endif
   1.190 +		else if (!strcmp (*args, "-in"))
   1.191 +			{
   1.192 +			if (args[1])
   1.193 +				{
   1.194 +				args++;
   1.195 +				infile = *args;
   1.196 +				}
   1.197 +			else badarg = 1;
   1.198 +			}
   1.199 +		else if (!strcmp (*args, "-out"))
   1.200 +			{
   1.201 +			if (args[1])
   1.202 +				{
   1.203 +				args++;
   1.204 +				outfile = *args;
   1.205 +				}
   1.206 +			else badarg = 1;
   1.207 +			}
   1.208 +		else badarg = 1;
   1.209 +		args++;
   1.210 +		}
   1.211 +
   1.212 +	if (badarg)
   1.213 +		{
   1.214 +		bad:
   1.215 +		BIO_printf(bio_err, "Usage pkcs8 [options]\n");
   1.216 +		BIO_printf(bio_err, "where options are\n");
   1.217 +		BIO_printf(bio_err, "-in file        input file\n");
   1.218 +		BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
   1.219 +		BIO_printf(bio_err, "-passin arg     input file pass phrase source\n");
   1.220 +		BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
   1.221 +		BIO_printf(bio_err, "-out file       output file\n");
   1.222 +		BIO_printf(bio_err, "-passout arg    output file pass phrase source\n");
   1.223 +		BIO_printf(bio_err, "-topk8          output PKCS8 file\n");
   1.224 +		BIO_printf(bio_err, "-nooct          use (nonstandard) no octet format\n");
   1.225 +		BIO_printf(bio_err, "-embed          use (nonstandard) embedded DSA parameters format\n");
   1.226 +		BIO_printf(bio_err, "-nsdb           use (nonstandard) DSA Netscape DB format\n");
   1.227 +		BIO_printf(bio_err, "-noiter         use 1 as iteration count\n");
   1.228 +		BIO_printf(bio_err, "-nocrypt        use or expect unencrypted private key\n");
   1.229 +		BIO_printf(bio_err, "-v2 alg         use PKCS#5 v2.0 and cipher \"alg\"\n");
   1.230 +		BIO_printf(bio_err, "-v1 obj         use PKCS#5 v1.5 and cipher \"alg\"\n");
   1.231 +#ifndef OPENSSL_NO_ENGINE
   1.232 +		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
   1.233 +#endif
   1.234 +		return 1;
   1.235 +		}
   1.236 +
   1.237 +#ifndef OPENSSL_NO_ENGINE
   1.238 +        e = setup_engine(bio_err, engine, 0);
   1.239 +#endif
   1.240 +
   1.241 +	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
   1.242 +		{
   1.243 +		BIO_printf(bio_err, "Error getting passwords\n");
   1.244 +		return 1;
   1.245 +		}
   1.246 +
   1.247 +	if ((pbe_nid == -1) && !cipher)
   1.248 +		pbe_nid = NID_pbeWithMD5AndDES_CBC;
   1.249 +
   1.250 +	if (infile)
   1.251 +		{
   1.252 +		if (!(in = BIO_new_file(infile, "rb")))
   1.253 +			{
   1.254 +			BIO_printf(bio_err,
   1.255 +				 "Can't open input file %s\n", infile);
   1.256 +			return (1);
   1.257 +			}
   1.258 +		}
   1.259 +	else
   1.260 +		in = BIO_new_fp (stdin, BIO_NOCLOSE);
   1.261 +	if (outfile)
   1.262 +		{
   1.263 +		if (!(out = BIO_new_file (outfile, "wb")))
   1.264 +			{
   1.265 +			BIO_printf(bio_err,
   1.266 +				 "Can't open output file %s\n", outfile);
   1.267 +			return (1);
   1.268 +			}
   1.269 +		}
   1.270 +	else
   1.271 +		{
   1.272 +		out = BIO_new_fp (stdout, BIO_NOCLOSE);
   1.273 +#ifdef OPENSSL_SYS_VMS
   1.274 +			{
   1.275 +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
   1.276 +			out = BIO_push(tmpbio, out);
   1.277 +			}
   1.278 +#endif
   1.279 +		}
   1.280 +	if (topk8)
   1.281 +		{
   1.282 +		BIO_free(in); /* Not needed in this section */
   1.283 +		pkey = load_key(bio_err, infile, informat, 1,
   1.284 +			passin, e, "key");
   1.285 +		if (!pkey)
   1.286 +			{
   1.287 +			BIO_free_all(out);
   1.288 +			return 1;
   1.289 +			}
   1.290 +		if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
   1.291 +			{
   1.292 +			BIO_printf(bio_err, "Error converting key\n");
   1.293 +			ERR_print_errors(bio_err);
   1.294 +			EVP_PKEY_free(pkey);
   1.295 +			BIO_free_all(out);
   1.296 +			return 1;
   1.297 +			}
   1.298 +		if (nocrypt)
   1.299 +			{
   1.300 +			if (outformat == FORMAT_PEM) 
   1.301 +				PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
   1.302 +			else if (outformat == FORMAT_ASN1)
   1.303 +				i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
   1.304 +			else
   1.305 +				{
   1.306 +				BIO_printf(bio_err, "Bad format specified for key\n");
   1.307 +				PKCS8_PRIV_KEY_INFO_free(p8inf);
   1.308 +				EVP_PKEY_free(pkey);
   1.309 +				BIO_free_all(out);
   1.310 +				return (1);
   1.311 +				}
   1.312 +			}
   1.313 +		else
   1.314 +			{
   1.315 +			if (passout)
   1.316 +				p8pass = passout;
   1.317 +			else
   1.318 +				{
   1.319 +				p8pass = pass;
   1.320 +				if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
   1.321 +					{
   1.322 +					PKCS8_PRIV_KEY_INFO_free(p8inf);
   1.323 +					EVP_PKEY_free(pkey);
   1.324 +					BIO_free_all(out);
   1.325 +					return (1);
   1.326 +					}
   1.327 +				}
   1.328 +			app_RAND_load_file(NULL, bio_err, 0);
   1.329 +			if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
   1.330 +					p8pass, strlen(p8pass),
   1.331 +					NULL, 0, iter, p8inf)))
   1.332 +				{
   1.333 +				BIO_printf(bio_err, "Error encrypting key\n");
   1.334 +				ERR_print_errors(bio_err);
   1.335 +				PKCS8_PRIV_KEY_INFO_free(p8inf);
   1.336 +				EVP_PKEY_free(pkey);
   1.337 +				BIO_free_all(out);
   1.338 +				return (1);
   1.339 +				}
   1.340 +			app_RAND_write_file(NULL, bio_err);
   1.341 +			if (outformat == FORMAT_PEM) 
   1.342 +				PEM_write_bio_PKCS8(out, p8);
   1.343 +			else if (outformat == FORMAT_ASN1)
   1.344 +				i2d_PKCS8_bio(out, p8);
   1.345 +			else
   1.346 +				{
   1.347 +				BIO_printf(bio_err, "Bad format specified for key\n");
   1.348 +				PKCS8_PRIV_KEY_INFO_free(p8inf);
   1.349 +				EVP_PKEY_free(pkey);
   1.350 +				BIO_free_all(out);
   1.351 +				return (1);
   1.352 +				}
   1.353 +			X509_SIG_free(p8);
   1.354 +			}
   1.355 +
   1.356 +		PKCS8_PRIV_KEY_INFO_free (p8inf);
   1.357 +		EVP_PKEY_free(pkey);
   1.358 +		BIO_free_all(out);
   1.359 +		if (passin)
   1.360 +			OPENSSL_free(passin);
   1.361 +		if (passout)
   1.362 +			OPENSSL_free(passout);
   1.363 +		return (0);
   1.364 +		}
   1.365 +
   1.366 +	if (nocrypt)
   1.367 +		{
   1.368 +		if (informat == FORMAT_PEM) 
   1.369 +			p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
   1.370 +		else if (informat == FORMAT_ASN1)
   1.371 +			p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
   1.372 +		else
   1.373 +			{
   1.374 +			BIO_printf(bio_err, "Bad format specified for key\n");
   1.375 +			return (1);
   1.376 +			}
   1.377 +		}
   1.378 +	else
   1.379 +		{
   1.380 +		if (informat == FORMAT_PEM) 
   1.381 +			p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
   1.382 +		else if (informat == FORMAT_ASN1)
   1.383 +			p8 = d2i_PKCS8_bio(in, NULL);
   1.384 +		else
   1.385 +			{
   1.386 +			BIO_printf(bio_err, "Bad format specified for key\n");
   1.387 +			return (1);
   1.388 +			}
   1.389 +
   1.390 +		if (!p8)
   1.391 +			{
   1.392 +			BIO_printf (bio_err, "Error reading key\n");
   1.393 +			ERR_print_errors(bio_err);
   1.394 +			return (1);
   1.395 +			}
   1.396 +		if (passin)
   1.397 +			p8pass = passin;
   1.398 +		else
   1.399 +			{
   1.400 +			p8pass = pass;
   1.401 +			EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
   1.402 +			}
   1.403 +		p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
   1.404 +		X509_SIG_free(p8);
   1.405 +		}
   1.406 +
   1.407 +	if (!p8inf)
   1.408 +		{
   1.409 +		BIO_printf(bio_err, "Error decrypting key\n");
   1.410 +		ERR_print_errors(bio_err);
   1.411 +		return (1);
   1.412 +		}
   1.413 +
   1.414 +	if (!(pkey = EVP_PKCS82PKEY(p8inf)))
   1.415 +		{
   1.416 +		BIO_printf(bio_err, "Error converting key\n");
   1.417 +		ERR_print_errors(bio_err);
   1.418 +		return (1);
   1.419 +		}
   1.420 +	
   1.421 +	if (p8inf->broken)
   1.422 +		{
   1.423 +		BIO_printf(bio_err, "Warning: broken key encoding: ");
   1.424 +		switch (p8inf->broken)
   1.425 +			{
   1.426 +			case PKCS8_NO_OCTET:
   1.427 +			BIO_printf(bio_err, "No Octet String in PrivateKey\n");
   1.428 +			break;
   1.429 +
   1.430 +			case PKCS8_EMBEDDED_PARAM:
   1.431 +			BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
   1.432 +			break;
   1.433 +
   1.434 +			case PKCS8_NS_DB:
   1.435 +			BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
   1.436 +			break;
   1.437 +
   1.438 +			default:
   1.439 +			BIO_printf(bio_err, "Unknown broken type\n");
   1.440 +			break;
   1.441 +		}
   1.442 +	}
   1.443 +	
   1.444 +	PKCS8_PRIV_KEY_INFO_free(p8inf);
   1.445 +	if (outformat == FORMAT_PEM) 
   1.446 +		PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
   1.447 +	else if (outformat == FORMAT_ASN1)
   1.448 +		i2d_PrivateKey_bio(out, pkey);
   1.449 +	else
   1.450 +		{
   1.451 +		BIO_printf(bio_err, "Bad format specified for key\n");
   1.452 +			return (1);
   1.453 +		}
   1.454 +
   1.455 +	end:
   1.456 +	EVP_PKEY_free(pkey);
   1.457 +	BIO_free_all(out);
   1.458 +	BIO_free(in);
   1.459 +	if (passin)
   1.460 +		OPENSSL_free(passin);
   1.461 +	if (passout)
   1.462 +		OPENSSL_free(passout);
   1.463 +
   1.464 +	return (0);
   1.465 +	}