OLD | NEW |
1 /* pkcs8.c */ | 1 /* pkcs8.c */ |
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 * project 1999-2004. | 3 * project 1999-2004. |
4 */ | 4 */ |
5 /* ==================================================================== | 5 /* ==================================================================== |
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | 6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 char **args, *infile = NULL, *outfile = NULL; | 73 char **args, *infile = NULL, *outfile = NULL; |
74 char *passargin = NULL, *passargout = NULL; | 74 char *passargin = NULL, *passargout = NULL; |
75 BIO *in = NULL, *out = NULL; | 75 BIO *in = NULL, *out = NULL; |
76 int topk8 = 0; | 76 int topk8 = 0; |
77 int pbe_nid = -1; | 77 int pbe_nid = -1; |
78 const EVP_CIPHER *cipher = NULL; | 78 const EVP_CIPHER *cipher = NULL; |
79 int iter = PKCS12_DEFAULT_ITER; | 79 int iter = PKCS12_DEFAULT_ITER; |
80 int informat, outformat; | 80 int informat, outformat; |
81 int p8_broken = PKCS8_OK; | 81 int p8_broken = PKCS8_OK; |
82 int nocrypt = 0; | 82 int nocrypt = 0; |
83 » X509_SIG *p8; | 83 » X509_SIG *p8 = NULL; |
84 » PKCS8_PRIV_KEY_INFO *p8inf; | 84 » PKCS8_PRIV_KEY_INFO *p8inf = NULL; |
85 EVP_PKEY *pkey=NULL; | 85 EVP_PKEY *pkey=NULL; |
86 char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; | 86 char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; |
87 int badarg = 0; | 87 int badarg = 0; |
| 88 int ret = 1; |
88 #ifndef OPENSSL_NO_ENGINE | 89 #ifndef OPENSSL_NO_ENGINE |
89 char *engine=NULL; | 90 char *engine=NULL; |
90 #endif | 91 #endif |
91 | 92 |
92 if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); | 93 if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); |
93 | 94 |
94 if (!load_config(bio_err, NULL)) | 95 if (!load_config(bio_err, NULL)) |
95 goto end; | 96 goto end; |
96 | 97 |
97 informat=FORMAT_PEM; | 98 informat=FORMAT_PEM; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 BIO_printf(bio_err, "-nooct use (nonstandard) no octet
format\n"); | 219 BIO_printf(bio_err, "-nooct use (nonstandard) no octet
format\n"); |
219 BIO_printf(bio_err, "-embed use (nonstandard) embedded
DSA parameters format\n"); | 220 BIO_printf(bio_err, "-embed use (nonstandard) embedded
DSA parameters format\n"); |
220 BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netsc
ape DB format\n"); | 221 BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netsc
ape DB format\n"); |
221 BIO_printf(bio_err, "-noiter use 1 as iteration count\n"
); | 222 BIO_printf(bio_err, "-noiter use 1 as iteration count\n"
); |
222 BIO_printf(bio_err, "-nocrypt use or expect unencrypted p
rivate key\n"); | 223 BIO_printf(bio_err, "-nocrypt use or expect unencrypted p
rivate key\n"); |
223 BIO_printf(bio_err, "-v2 alg use PKCS#5 v2.0 and cipher
\"alg\"\n"); | 224 BIO_printf(bio_err, "-v2 alg use PKCS#5 v2.0 and cipher
\"alg\"\n"); |
224 BIO_printf(bio_err, "-v1 obj use PKCS#5 v1.5 and cipher
\"alg\"\n"); | 225 BIO_printf(bio_err, "-v1 obj use PKCS#5 v1.5 and cipher
\"alg\"\n"); |
225 #ifndef OPENSSL_NO_ENGINE | 226 #ifndef OPENSSL_NO_ENGINE |
226 BIO_printf(bio_err," -engine e use engine e, possibly a ha
rdware device.\n"); | 227 BIO_printf(bio_err," -engine e use engine e, possibly a ha
rdware device.\n"); |
227 #endif | 228 #endif |
228 » » return 1; | 229 » » goto end; |
229 } | 230 } |
230 | 231 |
231 #ifndef OPENSSL_NO_ENGINE | 232 #ifndef OPENSSL_NO_ENGINE |
232 e = setup_engine(bio_err, engine, 0); | 233 e = setup_engine(bio_err, engine, 0); |
233 #endif | 234 #endif |
234 | 235 |
235 if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) | 236 if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) |
236 { | 237 { |
237 BIO_printf(bio_err, "Error getting passwords\n"); | 238 BIO_printf(bio_err, "Error getting passwords\n"); |
238 » » return 1; | 239 » » goto end; |
239 } | 240 } |
240 | 241 |
241 if ((pbe_nid == -1) && !cipher) | 242 if ((pbe_nid == -1) && !cipher) |
242 pbe_nid = NID_pbeWithMD5AndDES_CBC; | 243 pbe_nid = NID_pbeWithMD5AndDES_CBC; |
243 | 244 |
244 if (infile) | 245 if (infile) |
245 { | 246 { |
246 if (!(in = BIO_new_file(infile, "rb"))) | 247 if (!(in = BIO_new_file(infile, "rb"))) |
247 { | 248 { |
248 BIO_printf(bio_err, | 249 BIO_printf(bio_err, |
249 "Can't open input file %s\n", infile); | 250 "Can't open input file %s\n", infile); |
250 » » » return (1); | 251 » » » goto end; |
251 } | 252 } |
252 } | 253 } |
253 else | 254 else |
254 in = BIO_new_fp (stdin, BIO_NOCLOSE); | 255 in = BIO_new_fp (stdin, BIO_NOCLOSE); |
255 | 256 |
256 if (outfile) | 257 if (outfile) |
257 { | 258 { |
258 if (!(out = BIO_new_file (outfile, "wb"))) | 259 if (!(out = BIO_new_file (outfile, "wb"))) |
259 { | 260 { |
260 BIO_printf(bio_err, | 261 BIO_printf(bio_err, |
261 "Can't open output file %s\n", outfile); | 262 "Can't open output file %s\n", outfile); |
262 » » » return (1); | 263 » » » goto end; |
263 } | 264 } |
264 } | 265 } |
265 else | 266 else |
266 { | 267 { |
267 out = BIO_new_fp (stdout, BIO_NOCLOSE); | 268 out = BIO_new_fp (stdout, BIO_NOCLOSE); |
268 #ifdef OPENSSL_SYS_VMS | 269 #ifdef OPENSSL_SYS_VMS |
269 { | 270 { |
270 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); | 271 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); |
271 out = BIO_push(tmpbio, out); | 272 out = BIO_push(tmpbio, out); |
272 } | 273 } |
273 #endif | 274 #endif |
274 } | 275 } |
275 if (topk8) | 276 if (topk8) |
276 { | 277 { |
277 BIO_free(in); /* Not needed in this section */ | |
278 pkey = load_key(bio_err, infile, informat, 1, | 278 pkey = load_key(bio_err, infile, informat, 1, |
279 passin, e, "key"); | 279 passin, e, "key"); |
280 if (!pkey) | 280 if (!pkey) |
281 » » » { | 281 » » » goto end; |
282 » » » BIO_free_all(out); | |
283 » » » return 1; | |
284 » » » } | |
285 if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) | 282 if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) |
286 { | 283 { |
287 BIO_printf(bio_err, "Error converting key\n"); | 284 BIO_printf(bio_err, "Error converting key\n"); |
288 ERR_print_errors(bio_err); | 285 ERR_print_errors(bio_err); |
289 » » » EVP_PKEY_free(pkey); | 286 » » » goto end; |
290 » » » BIO_free_all(out); | |
291 » » » return 1; | |
292 } | 287 } |
293 if (nocrypt) | 288 if (nocrypt) |
294 { | 289 { |
295 if (outformat == FORMAT_PEM) | 290 if (outformat == FORMAT_PEM) |
296 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); | 291 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); |
297 else if (outformat == FORMAT_ASN1) | 292 else if (outformat == FORMAT_ASN1) |
298 i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); | 293 i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); |
299 else | 294 else |
300 { | 295 { |
301 BIO_printf(bio_err, "Bad format specified for ke
y\n"); | 296 BIO_printf(bio_err, "Bad format specified for ke
y\n"); |
302 » » » » PKCS8_PRIV_KEY_INFO_free(p8inf); | 297 » » » » goto end; |
303 » » » » EVP_PKEY_free(pkey); | |
304 » » » » BIO_free_all(out); | |
305 » » » » return (1); | |
306 } | 298 } |
307 } | 299 } |
308 else | 300 else |
309 { | 301 { |
310 if (passout) | 302 if (passout) |
311 p8pass = passout; | 303 p8pass = passout; |
312 else | 304 else |
313 { | 305 { |
314 p8pass = pass; | 306 p8pass = pass; |
315 if (EVP_read_pw_string(pass, sizeof pass, "Enter
Encryption Password:", 1)) | 307 if (EVP_read_pw_string(pass, sizeof pass, "Enter
Encryption Password:", 1)) |
316 » » » » » { | 308 » » » » » goto end; |
317 » » » » » PKCS8_PRIV_KEY_INFO_free(p8inf); | |
318 » » » » » EVP_PKEY_free(pkey); | |
319 » » » » » BIO_free_all(out); | |
320 » » » » » return (1); | |
321 » » » » » } | |
322 } | 309 } |
323 app_RAND_load_file(NULL, bio_err, 0); | 310 app_RAND_load_file(NULL, bio_err, 0); |
324 if (!(p8 = PKCS8_encrypt(pbe_nid, cipher, | 311 if (!(p8 = PKCS8_encrypt(pbe_nid, cipher, |
325 p8pass, strlen(p8pass), | 312 p8pass, strlen(p8pass), |
326 NULL, 0, iter, p8inf))) | 313 NULL, 0, iter, p8inf))) |
327 { | 314 { |
328 BIO_printf(bio_err, "Error encrypting key\n"); | 315 BIO_printf(bio_err, "Error encrypting key\n"); |
329 ERR_print_errors(bio_err); | 316 ERR_print_errors(bio_err); |
330 » » » » PKCS8_PRIV_KEY_INFO_free(p8inf); | 317 » » » » goto end; |
331 » » » » EVP_PKEY_free(pkey); | |
332 » » » » BIO_free_all(out); | |
333 » » » » return (1); | |
334 } | 318 } |
335 app_RAND_write_file(NULL, bio_err); | 319 app_RAND_write_file(NULL, bio_err); |
336 if (outformat == FORMAT_PEM) | 320 if (outformat == FORMAT_PEM) |
337 PEM_write_bio_PKCS8(out, p8); | 321 PEM_write_bio_PKCS8(out, p8); |
338 else if (outformat == FORMAT_ASN1) | 322 else if (outformat == FORMAT_ASN1) |
339 i2d_PKCS8_bio(out, p8); | 323 i2d_PKCS8_bio(out, p8); |
340 else | 324 else |
341 { | 325 { |
342 BIO_printf(bio_err, "Bad format specified for ke
y\n"); | 326 BIO_printf(bio_err, "Bad format specified for ke
y\n"); |
343 » » » » PKCS8_PRIV_KEY_INFO_free(p8inf); | 327 » » » » goto end; |
344 » » » » EVP_PKEY_free(pkey); | |
345 » » » » BIO_free_all(out); | |
346 » » » » return (1); | |
347 } | 328 } |
348 X509_SIG_free(p8); | |
349 } | 329 } |
350 | 330 |
351 » » PKCS8_PRIV_KEY_INFO_free (p8inf); | 331 » » ret = 0; |
352 » » EVP_PKEY_free(pkey); | 332 » » goto end; |
353 » » BIO_free_all(out); | |
354 » » if (passin) | |
355 » » » OPENSSL_free(passin); | |
356 » » if (passout) | |
357 » » » OPENSSL_free(passout); | |
358 » » return (0); | |
359 } | 333 } |
360 | 334 |
361 if (nocrypt) | 335 if (nocrypt) |
362 { | 336 { |
363 if (informat == FORMAT_PEM) | 337 if (informat == FORMAT_PEM) |
364 p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, N
ULL); | 338 p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, N
ULL); |
365 else if (informat == FORMAT_ASN1) | 339 else if (informat == FORMAT_ASN1) |
366 p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); | 340 p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); |
367 else | 341 else |
368 { | 342 { |
369 BIO_printf(bio_err, "Bad format specified for key\n"); | 343 BIO_printf(bio_err, "Bad format specified for key\n"); |
370 » » » return (1); | 344 » » » goto end; |
371 } | 345 } |
372 } | 346 } |
373 else | 347 else |
374 { | 348 { |
375 if (informat == FORMAT_PEM) | 349 if (informat == FORMAT_PEM) |
376 p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); | 350 p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); |
377 else if (informat == FORMAT_ASN1) | 351 else if (informat == FORMAT_ASN1) |
378 p8 = d2i_PKCS8_bio(in, NULL); | 352 p8 = d2i_PKCS8_bio(in, NULL); |
379 else | 353 else |
380 { | 354 { |
381 BIO_printf(bio_err, "Bad format specified for key\n"); | 355 BIO_printf(bio_err, "Bad format specified for key\n"); |
382 » » » return (1); | 356 » » » goto end; |
383 } | 357 } |
384 | 358 |
385 if (!p8) | 359 if (!p8) |
386 { | 360 { |
387 BIO_printf (bio_err, "Error reading key\n"); | 361 BIO_printf (bio_err, "Error reading key\n"); |
388 ERR_print_errors(bio_err); | 362 ERR_print_errors(bio_err); |
389 » » » return (1); | 363 » » » goto end; |
390 } | 364 } |
391 if (passin) | 365 if (passin) |
392 p8pass = passin; | 366 p8pass = passin; |
393 else | 367 else |
394 { | 368 { |
395 p8pass = pass; | 369 p8pass = pass; |
396 EVP_read_pw_string(pass, sizeof pass, "Enter Password:",
0); | 370 EVP_read_pw_string(pass, sizeof pass, "Enter Password:",
0); |
397 } | 371 } |
398 p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); | 372 p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); |
399 X509_SIG_free(p8); | |
400 } | 373 } |
401 | 374 |
402 if (!p8inf) | 375 if (!p8inf) |
403 { | 376 { |
404 BIO_printf(bio_err, "Error decrypting key\n"); | 377 BIO_printf(bio_err, "Error decrypting key\n"); |
405 ERR_print_errors(bio_err); | 378 ERR_print_errors(bio_err); |
406 » » return (1); | 379 » » goto end; |
407 } | 380 } |
408 | 381 |
409 if (!(pkey = EVP_PKCS82PKEY(p8inf))) | 382 if (!(pkey = EVP_PKCS82PKEY(p8inf))) |
410 { | 383 { |
411 BIO_printf(bio_err, "Error converting key\n"); | 384 BIO_printf(bio_err, "Error converting key\n"); |
412 ERR_print_errors(bio_err); | 385 ERR_print_errors(bio_err); |
413 » » return (1); | 386 » » goto end; |
414 } | 387 } |
415 | 388 |
416 if (p8inf->broken) | 389 if (p8inf->broken) |
417 { | 390 { |
418 BIO_printf(bio_err, "Warning: broken key encoding: "); | 391 BIO_printf(bio_err, "Warning: broken key encoding: "); |
419 switch (p8inf->broken) | 392 switch (p8inf->broken) |
420 { | 393 { |
421 case PKCS8_NO_OCTET: | 394 case PKCS8_NO_OCTET: |
422 BIO_printf(bio_err, "No Octet String in PrivateKey\n"); | 395 BIO_printf(bio_err, "No Octet String in PrivateKey\n"); |
423 break; | 396 break; |
424 | 397 |
425 case PKCS8_EMBEDDED_PARAM: | 398 case PKCS8_EMBEDDED_PARAM: |
426 BIO_printf(bio_err, "DSA parameters included in PrivateK
ey\n"); | 399 BIO_printf(bio_err, "DSA parameters included in PrivateK
ey\n"); |
427 break; | 400 break; |
428 | 401 |
429 case PKCS8_NS_DB: | 402 case PKCS8_NS_DB: |
430 BIO_printf(bio_err, "DSA public key include in PrivateKe
y\n"); | 403 BIO_printf(bio_err, "DSA public key include in PrivateKe
y\n"); |
431 break; | 404 break; |
432 | 405 |
| 406 case PKCS8_NEG_PRIVKEY: |
| 407 BIO_printf(bio_err, "DSA private key value is negative\n
"); |
| 408 break; |
| 409 |
433 default: | 410 default: |
434 BIO_printf(bio_err, "Unknown broken type\n"); | 411 BIO_printf(bio_err, "Unknown broken type\n"); |
435 break; | 412 break; |
436 } | 413 } |
437 } | 414 } |
438 | 415 |
439 PKCS8_PRIV_KEY_INFO_free(p8inf); | |
440 if (outformat == FORMAT_PEM) | 416 if (outformat == FORMAT_PEM) |
441 PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout
); | 417 PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout
); |
442 else if (outformat == FORMAT_ASN1) | 418 else if (outformat == FORMAT_ASN1) |
443 i2d_PrivateKey_bio(out, pkey); | 419 i2d_PrivateKey_bio(out, pkey); |
444 else | 420 else |
445 { | 421 { |
446 BIO_printf(bio_err, "Bad format specified for key\n"); | 422 BIO_printf(bio_err, "Bad format specified for key\n"); |
447 » » » return (1); | 423 » » » goto end; |
448 } | 424 } |
| 425 ret = 0; |
449 | 426 |
450 end: | 427 end: |
| 428 X509_SIG_free(p8); |
| 429 PKCS8_PRIV_KEY_INFO_free(p8inf); |
451 EVP_PKEY_free(pkey); | 430 EVP_PKEY_free(pkey); |
452 BIO_free_all(out); | 431 BIO_free_all(out); |
453 BIO_free(in); | 432 BIO_free(in); |
454 if (passin) | 433 if (passin) |
455 OPENSSL_free(passin); | 434 OPENSSL_free(passin); |
456 if (passout) | 435 if (passout) |
457 OPENSSL_free(passout); | 436 OPENSSL_free(passout); |
458 | 437 |
459 » return (0); | 438 » return ret; |
460 } | 439 } |
OLD | NEW |