00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include <stdio.h>
00059 #include <string.h>
00060 #include "apps.h"
00061 #include <openssl/pem.h>
00062 #include <openssl/err.h>
00063 #include <openssl/evp.h>
00064 #include <openssl/pkcs12.h>
00065
00066 #define PROG pkcs8_main
00067
00068 int MAIN(int, char **);
00069
00070 int MAIN(int argc, char **argv)
00071 {
00072 ENGINE *e = NULL;
00073 char **args, *infile = NULL, *outfile = NULL;
00074 char *passargin = NULL, *passargout = NULL;
00075 BIO *in = NULL, *out = NULL;
00076 int topk8 = 0;
00077 int pbe_nid = -1;
00078 const EVP_CIPHER *cipher = NULL;
00079 int iter = PKCS12_DEFAULT_ITER;
00080 int informat, outformat;
00081 int p8_broken = PKCS8_OK;
00082 int nocrypt = 0;
00083 X509_SIG *p8;
00084 PKCS8_PRIV_KEY_INFO *p8inf;
00085 EVP_PKEY *pkey=NULL;
00086 char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
00087 int badarg = 0;
00088 #ifndef OPENSSL_NO_ENGINE
00089 char *engine=NULL;
00090 #endif
00091
00092 if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
00093
00094 if (!load_config(bio_err, NULL))
00095 goto end;
00096
00097 informat=FORMAT_PEM;
00098 outformat=FORMAT_PEM;
00099
00100 ERR_load_crypto_strings();
00101 OpenSSL_add_all_algorithms();
00102 args = argv + 1;
00103 while (!badarg && *args && *args[0] == '-')
00104 {
00105 if (!strcmp(*args,"-v2"))
00106 {
00107 if (args[1])
00108 {
00109 args++;
00110 cipher=EVP_get_cipherbyname(*args);
00111 if (!cipher)
00112 {
00113 BIO_printf(bio_err,
00114 "Unknown cipher %s\n", *args);
00115 badarg = 1;
00116 }
00117 }
00118 else
00119 badarg = 1;
00120 }
00121 else if (!strcmp(*args,"-v1"))
00122 {
00123 if (args[1])
00124 {
00125 args++;
00126 pbe_nid=OBJ_txt2nid(*args);
00127 if (pbe_nid == NID_undef)
00128 {
00129 BIO_printf(bio_err,
00130 "Unknown PBE algorithm %s\n", *args);
00131 badarg = 1;
00132 }
00133 }
00134 else
00135 badarg = 1;
00136 }
00137 else if (!strcmp(*args,"-inform"))
00138 {
00139 if (args[1])
00140 {
00141 args++;
00142 informat=str2fmt(*args);
00143 }
00144 else badarg = 1;
00145 }
00146 else if (!strcmp(*args,"-outform"))
00147 {
00148 if (args[1])
00149 {
00150 args++;
00151 outformat=str2fmt(*args);
00152 }
00153 else badarg = 1;
00154 }
00155 else if (!strcmp (*args, "-topk8"))
00156 topk8 = 1;
00157 else if (!strcmp (*args, "-noiter"))
00158 iter = 1;
00159 else if (!strcmp (*args, "-nocrypt"))
00160 nocrypt = 1;
00161 else if (!strcmp (*args, "-nooct"))
00162 p8_broken = PKCS8_NO_OCTET;
00163 else if (!strcmp (*args, "-nsdb"))
00164 p8_broken = PKCS8_NS_DB;
00165 else if (!strcmp (*args, "-embed"))
00166 p8_broken = PKCS8_EMBEDDED_PARAM;
00167 else if (!strcmp(*args,"-passin"))
00168 {
00169 if (!args[1]) goto bad;
00170 passargin= *(++args);
00171 }
00172 else if (!strcmp(*args,"-passout"))
00173 {
00174 if (!args[1]) goto bad;
00175 passargout= *(++args);
00176 }
00177 #ifndef OPENSSL_NO_ENGINE
00178 else if (strcmp(*args,"-engine") == 0)
00179 {
00180 if (!args[1]) goto bad;
00181 engine= *(++args);
00182 }
00183 #endif
00184 else if (!strcmp (*args, "-in"))
00185 {
00186 if (args[1])
00187 {
00188 args++;
00189 infile = *args;
00190 }
00191 else badarg = 1;
00192 }
00193 else if (!strcmp (*args, "-out"))
00194 {
00195 if (args[1])
00196 {
00197 args++;
00198 outfile = *args;
00199 }
00200 else badarg = 1;
00201 }
00202 else badarg = 1;
00203 args++;
00204 }
00205
00206 if (badarg)
00207 {
00208 bad:
00209 BIO_printf(bio_err, "Usage pkcs8 [options]\n");
00210 BIO_printf(bio_err, "where options are\n");
00211 BIO_printf(bio_err, "-in file input file\n");
00212 BIO_printf(bio_err, "-inform X input format (DER or PEM)\n");
00213 BIO_printf(bio_err, "-passin arg input file pass phrase source\n");
00214 BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
00215 BIO_printf(bio_err, "-out file output file\n");
00216 BIO_printf(bio_err, "-passout arg output file pass phrase source\n");
00217 BIO_printf(bio_err, "-topk8 output PKCS8 file\n");
00218 BIO_printf(bio_err, "-nooct use (nonstandard) no octet format\n");
00219 BIO_printf(bio_err, "-embed use (nonstandard) embedded DSA parameters format\n");
00220 BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netscape DB format\n");
00221 BIO_printf(bio_err, "-noiter use 1 as iteration count\n");
00222 BIO_printf(bio_err, "-nocrypt use or expect unencrypted private key\n");
00223 BIO_printf(bio_err, "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n");
00224 BIO_printf(bio_err, "-v1 obj use PKCS#5 v1.5 and cipher \"alg\"\n");
00225 #ifndef OPENSSL_NO_ENGINE
00226 BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
00227 #endif
00228 return 1;
00229 }
00230
00231 #ifndef OPENSSL_NO_ENGINE
00232 e = setup_engine(bio_err, engine, 0);
00233 #endif
00234
00235 if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
00236 {
00237 BIO_printf(bio_err, "Error getting passwords\n");
00238 return 1;
00239 }
00240
00241 if ((pbe_nid == -1) && !cipher)
00242 pbe_nid = NID_pbeWithMD5AndDES_CBC;
00243
00244 if (infile)
00245 {
00246 if (!(in = BIO_new_file(infile, "rb")))
00247 {
00248 BIO_printf(bio_err,
00249 "Can't open input file %s\n", infile);
00250 return (1);
00251 }
00252 }
00253 else
00254 in = BIO_new_fp (stdin, BIO_NOCLOSE);
00255
00256 if (outfile)
00257 {
00258 if (!(out = BIO_new_file (outfile, "wb")))
00259 {
00260 BIO_printf(bio_err,
00261 "Can't open output file %s\n", outfile);
00262 return (1);
00263 }
00264 }
00265 else
00266 {
00267 out = BIO_new_fp (stdout, BIO_NOCLOSE);
00268 #ifdef OPENSSL_SYS_VMS
00269 {
00270 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
00271 out = BIO_push(tmpbio, out);
00272 }
00273 #endif
00274 }
00275 if (topk8)
00276 {
00277 BIO_free(in);
00278 pkey = load_key(bio_err, infile, informat, 1,
00279 passin, e, "key");
00280 if (!pkey)
00281 {
00282 BIO_free_all(out);
00283 return 1;
00284 }
00285 if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
00286 {
00287 BIO_printf(bio_err, "Error converting key\n");
00288 ERR_print_errors(bio_err);
00289 EVP_PKEY_free(pkey);
00290 BIO_free_all(out);
00291 return 1;
00292 }
00293 if (nocrypt)
00294 {
00295 if (outformat == FORMAT_PEM)
00296 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
00297 else if (outformat == FORMAT_ASN1)
00298 i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
00299 else
00300 {
00301 BIO_printf(bio_err, "Bad format specified for key\n");
00302 PKCS8_PRIV_KEY_INFO_free(p8inf);
00303 EVP_PKEY_free(pkey);
00304 BIO_free_all(out);
00305 return (1);
00306 }
00307 }
00308 else
00309 {
00310 if (passout)
00311 p8pass = passout;
00312 else
00313 {
00314 p8pass = pass;
00315 if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
00316 {
00317 PKCS8_PRIV_KEY_INFO_free(p8inf);
00318 EVP_PKEY_free(pkey);
00319 BIO_free_all(out);
00320 return (1);
00321 }
00322 }
00323 app_RAND_load_file(NULL, bio_err, 0);
00324 if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
00325 p8pass, strlen(p8pass),
00326 NULL, 0, iter, p8inf)))
00327 {
00328 BIO_printf(bio_err, "Error encrypting key\n");
00329 ERR_print_errors(bio_err);
00330 PKCS8_PRIV_KEY_INFO_free(p8inf);
00331 EVP_PKEY_free(pkey);
00332 BIO_free_all(out);
00333 return (1);
00334 }
00335 app_RAND_write_file(NULL, bio_err);
00336 if (outformat == FORMAT_PEM)
00337 PEM_write_bio_PKCS8(out, p8);
00338 else if (outformat == FORMAT_ASN1)
00339 i2d_PKCS8_bio(out, p8);
00340 else
00341 {
00342 BIO_printf(bio_err, "Bad format specified for key\n");
00343 PKCS8_PRIV_KEY_INFO_free(p8inf);
00344 EVP_PKEY_free(pkey);
00345 BIO_free_all(out);
00346 return (1);
00347 }
00348 X509_SIG_free(p8);
00349 }
00350
00351 PKCS8_PRIV_KEY_INFO_free (p8inf);
00352 EVP_PKEY_free(pkey);
00353 BIO_free_all(out);
00354 if (passin)
00355 OPENSSL_free(passin);
00356 if (passout)
00357 OPENSSL_free(passout);
00358 return (0);
00359 }
00360
00361 if (nocrypt)
00362 {
00363 if (informat == FORMAT_PEM)
00364 p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
00365 else if (informat == FORMAT_ASN1)
00366 p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
00367 else
00368 {
00369 BIO_printf(bio_err, "Bad format specified for key\n");
00370 return (1);
00371 }
00372 }
00373 else
00374 {
00375 if (informat == FORMAT_PEM)
00376 p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
00377 else if (informat == FORMAT_ASN1)
00378 p8 = d2i_PKCS8_bio(in, NULL);
00379 else
00380 {
00381 BIO_printf(bio_err, "Bad format specified for key\n");
00382 return (1);
00383 }
00384
00385 if (!p8)
00386 {
00387 BIO_printf (bio_err, "Error reading key\n");
00388 ERR_print_errors(bio_err);
00389 return (1);
00390 }
00391 if (passin)
00392 p8pass = passin;
00393 else
00394 {
00395 p8pass = pass;
00396 EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
00397 }
00398 p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
00399 X509_SIG_free(p8);
00400 }
00401
00402 if (!p8inf)
00403 {
00404 BIO_printf(bio_err, "Error decrypting key\n");
00405 ERR_print_errors(bio_err);
00406 return (1);
00407 }
00408
00409 if (!(pkey = EVP_PKCS82PKEY(p8inf)))
00410 {
00411 BIO_printf(bio_err, "Error converting key\n");
00412 ERR_print_errors(bio_err);
00413 return (1);
00414 }
00415
00416 if (p8inf->broken)
00417 {
00418 BIO_printf(bio_err, "Warning: broken key encoding: ");
00419 switch (p8inf->broken)
00420 {
00421 case PKCS8_NO_OCTET:
00422 BIO_printf(bio_err, "No Octet String in PrivateKey\n");
00423 break;
00424
00425 case PKCS8_EMBEDDED_PARAM:
00426 BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
00427 break;
00428
00429 case PKCS8_NS_DB:
00430 BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
00431 break;
00432
00433 default:
00434 BIO_printf(bio_err, "Unknown broken type\n");
00435 break;
00436 }
00437 }
00438
00439 PKCS8_PRIV_KEY_INFO_free(p8inf);
00440 if (outformat == FORMAT_PEM)
00441 PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
00442 else if (outformat == FORMAT_ASN1)
00443 i2d_PrivateKey_bio(out, pkey);
00444 else
00445 {
00446 BIO_printf(bio_err, "Bad format specified for key\n");
00447 return (1);
00448 }
00449
00450 end:
00451 EVP_PKEY_free(pkey);
00452 BIO_free_all(out);
00453 BIO_free(in);
00454 if (passin)
00455 OPENSSL_free(passin);
00456 if (passout)
00457 OPENSSL_free(passout);
00458
00459 return (0);
00460 }