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 + }