1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58: #include <stdio.h>
59: #include <string.h>
60: #include "apps.h"
61: #include <openssl/pem.h>
62: #include <openssl/err.h>
63: #include <openssl/evp.h>
64: #include <openssl/pkcs12.h>
65:
66: #define PROG pkcs8_main
67:
68: int MAIN(int, char **);
69:
70: int MAIN(int argc, char **argv)
71: {
72: ENGINE *e = NULL;
73: char **args, *infile = NULL, *outfile = NULL;
74: char *passargin = NULL, *passargout = NULL;
75: BIO *in = NULL, *out = NULL;
76: int topk8 = 0;
77: int pbe_nid = -1;
78: const EVP_CIPHER *cipher = NULL;
79: int iter = PKCS12_DEFAULT_ITER;
80: int informat, outformat;
81: int p8_broken = PKCS8_OK;
82: int nocrypt = 0;
83: X509_SIG *p8;
84: PKCS8_PRIV_KEY_INFO *p8inf;
85: EVP_PKEY *pkey=NULL;
86: char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
87: int badarg = 0;
88: #ifndef OPENSSL_NO_ENGINE
89: char *engine=NULL;
90: #endif
91:
92: if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
93:
94: if (!load_config(bio_err, NULL))
95: goto end;
96:
97: informat=FORMAT_PEM;
98: outformat=FORMAT_PEM;
99:
100: ERR_load_crypto_strings();
101: OpenSSL_add_all_algorithms();
102: args = argv + 1;
103: while (!badarg && *args && *args[0] == '-')
104: {
105: if (!strcmp(*args,"-v2"))
106: {
107: if (args[1])
108: {
109: args++;
110: cipher=EVP_get_cipherbyname(*args);
111: if (!cipher)
112: {
113: BIO_printf(bio_err,
114: "Unknown cipher %s\n", *args);
115: badarg = 1;
116: }
117: }
118: else
119: badarg = 1;
120: }
121: else if (!strcmp(*args,"-v1"))
122: {
123: if (args[1])
124: {
125: args++;
126: pbe_nid=OBJ_txt2nid(*args);
127: if (pbe_nid == NID_undef)
128: {
129: BIO_printf(bio_err,
130: "Unknown PBE algorithm %s\n", *args);
131: badarg = 1;
132: }
133: }
134: else
135: badarg = 1;
136: }
137: else if (!strcmp(*args,"-inform"))
138: {
139: if (args[1])
140: {
141: args++;
142: informat=str2fmt(*args);
143: }
144: else badarg = 1;
145: }
146: else if (!strcmp(*args,"-outform"))
147: {
148: if (args[1])
149: {
150: args++;
151: outformat=str2fmt(*args);
152: }
153: else badarg = 1;
154: }
155: else if (!strcmp (*args, "-topk8"))
156: topk8 = 1;
157: else if (!strcmp (*args, "-noiter"))
158: iter = 1;
159: else if (!strcmp (*args, "-nocrypt"))
160: nocrypt = 1;
161: else if (!strcmp (*args, "-nooct"))
162: p8_broken = PKCS8_NO_OCTET;
163: else if (!strcmp (*args, "-nsdb"))
164: p8_broken = PKCS8_NS_DB;
165: else if (!strcmp (*args, "-embed"))
166: p8_broken = PKCS8_EMBEDDED_PARAM;
167: else if (!strcmp(*args,"-passin"))
168: {
169: if (!args[1]) goto bad;
170: passargin= *(++args);
171: }
172: else if (!strcmp(*args,"-passout"))
173: {
174: if (!args[1]) goto bad;
175: passargout= *(++args);
176: }
177: #ifndef OPENSSL_NO_ENGINE
178: else if (strcmp(*args,"-engine") == 0)
179: {
180: if (!args[1]) goto bad;
181: engine= *(++args);
182: }
183: #endif
184: else if (!strcmp (*args, "-in"))
185: {
186: if (args[1])
187: {
188: args++;
189: infile = *args;
190: }
191: else badarg = 1;
192: }
193: else if (!strcmp (*args, "-out"))
194: {
195: if (args[1])
196: {
197: args++;
198: outfile = *args;
199: }
200: else badarg = 1;
201: }
202: else badarg = 1;
203: args++;
204: }
205:
206: if (badarg)
207: {
208: bad:
209: BIO_printf(bio_err, "Usage pkcs8 [options]\n");
210: BIO_printf(bio_err, "where options are\n");
211: BIO_printf(bio_err, "-in file input file\n");
212: BIO_printf(bio_err, "-inform X input format (DER or PEM)\n");
213: BIO_printf(bio_err, "-passin arg input file pass phrase source\n");
214: BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
215: BIO_printf(bio_err, "-out file output file\n");
216: BIO_printf(bio_err, "-passout arg output file pass phrase source\n");
217: BIO_printf(bio_err, "-topk8 output PKCS8 file\n");
218: 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, "-nsdb use (nonstandard) DSA Netscape DB format\n");
221: BIO_printf(bio_err, "-noiter use 1 as iteration count\n");
222: BIO_printf(bio_err, "-nocrypt use or expect unencrypted private key\n");
223: 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: #ifndef OPENSSL_NO_ENGINE
226: BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
227: #endif
228: return 1;
229: }
230:
231: #ifndef OPENSSL_NO_ENGINE
232: e = setup_engine(bio_err, engine, 0);
233: #endif
234:
235: if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
236: {
237: BIO_printf(bio_err, "Error getting passwords\n");
238: return 1;
239: }
240:
241: if ((pbe_nid == -1) && !cipher)
242: pbe_nid = NID_pbeWithMD5AndDES_CBC;
243:
244: if (infile)
245: {
246: if (!(in = BIO_new_file(infile, "rb")))
247: {
248: BIO_printf(bio_err,
249: "Can't open input file %s\n", infile);
250: return (1);
251: }
252: }
253: else
254: in = BIO_new_fp (stdin, BIO_NOCLOSE);
255:
256: if (outfile)
257: {
258: if (!(out = BIO_new_file (outfile, "wb")))
259: {
260: BIO_printf(bio_err,
261: "Can't open output file %s\n", outfile);
262: return (1);
263: }
264: }
265: else
266: {
267: out = BIO_new_fp (stdout, BIO_NOCLOSE);
268: #ifdef OPENSSL_SYS_VMS
269: {
270: BIO *tmpbio = BIO_new(BIO_f_linebuffer());
271: out = BIO_push(tmpbio, out);
272: }
273: #endif
274: }
275: if (topk8)
276: {
277: BIO_free(in);
278: pkey = load_key(bio_err, infile, informat, 1,
279: passin, e, "key");
280: if (!pkey)
281: {
282: BIO_free_all(out);
283: return 1;
284: }
285: if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
286: {
287: BIO_printf(bio_err, "Error converting key\n");
288: ERR_print_errors(bio_err);
289: EVP_PKEY_free(pkey);
290: BIO_free_all(out);
291: return 1;
292: }
293: if (nocrypt)
294: {
295: if (outformat == FORMAT_PEM)
296: PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
297: else if (outformat == FORMAT_ASN1)
298: i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
299: else
300: {
301: BIO_printf(bio_err, "Bad format specified for key\n");
302: PKCS8_PRIV_KEY_INFO_free(p8inf);
303: EVP_PKEY_free(pkey);
304: BIO_free_all(out);
305: return (1);
306: }
307: }
308: else
309: {
310: if (passout)
311: p8pass = passout;
312: else
313: {
314: p8pass = pass;
315: if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
316: {
317: PKCS8_PRIV_KEY_INFO_free(p8inf);
318: EVP_PKEY_free(pkey);
319: BIO_free_all(out);
320: return (1);
321: }
322: }
323: app_RAND_load_file(NULL, bio_err, 0);
324: if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
325: p8pass, strlen(p8pass),
326: NULL, 0, iter, p8inf)))
327: {
328: BIO_printf(bio_err, "Error encrypting key\n");
329: ERR_print_errors(bio_err);
330: PKCS8_PRIV_KEY_INFO_free(p8inf);
331: EVP_PKEY_free(pkey);
332: BIO_free_all(out);
333: return (1);
334: }
335: app_RAND_write_file(NULL, bio_err);
336: if (outformat == FORMAT_PEM)
337: PEM_write_bio_PKCS8(out, p8);
338: else if (outformat == FORMAT_ASN1)
339: i2d_PKCS8_bio(out, p8);
340: else
341: {
342: BIO_printf(bio_err, "Bad format specified for key\n");
343: PKCS8_PRIV_KEY_INFO_free(p8inf);
344: EVP_PKEY_free(pkey);
345: BIO_free_all(out);
346: return (1);
347: }
348: X509_SIG_free(p8);
349: }
350:
351: PKCS8_PRIV_KEY_INFO_free (p8inf);
352: EVP_PKEY_free(pkey);
353: BIO_free_all(out);
354: if (passin)
355: OPENSSL_free(passin);
356: if (passout)
357: OPENSSL_free(passout);
358: return (0);
359: }
360:
361: if (nocrypt)
362: {
363: if (informat == FORMAT_PEM)
364: p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
365: else if (informat == FORMAT_ASN1)
366: p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
367: else
368: {
369: BIO_printf(bio_err, "Bad format specified for key\n");
370: return (1);
371: }
372: }
373: else
374: {
375: if (informat == FORMAT_PEM)
376: p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
377: else if (informat == FORMAT_ASN1)
378: p8 = d2i_PKCS8_bio(in, NULL);
379: else
380: {
381: BIO_printf(bio_err, "Bad format specified for key\n");
382: return (1);
383: }
384:
385: if (!p8)
386: {
387: BIO_printf (bio_err, "Error reading key\n");
388: ERR_print_errors(bio_err);
389: return (1);
390: }
391: if (passin)
392: p8pass = passin;
393: else
394: {
395: p8pass = pass;
396: EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
397: }
398: p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
399: X509_SIG_free(p8);
400: }
401:
402: if (!p8inf)
403: {
404: BIO_printf(bio_err, "Error decrypting key\n");
405: ERR_print_errors(bio_err);
406: return (1);
407: }
408:
409: if (!(pkey = EVP_PKCS82PKEY(p8inf)))
410: {
411: BIO_printf(bio_err, "Error converting key\n");
412: ERR_print_errors(bio_err);
413: return (1);
414: }
415:
416: if (p8inf->broken)
417: {
418: BIO_printf(bio_err, "Warning: broken key encoding: ");
419: switch (p8inf->broken)
420: {
421: case PKCS8_NO_OCTET:
422: BIO_printf(bio_err, "No Octet String in PrivateKey\n");
423: break;
424:
425: case PKCS8_EMBEDDED_PARAM:
426: BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
427: break;
428:
429: case PKCS8_NS_DB:
430: BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
431: break;
432:
433: default:
434: BIO_printf(bio_err, "Unknown broken type\n");
435: break;
436: }
437: }
438:
439: PKCS8_PRIV_KEY_INFO_free(p8inf);
440: if (outformat == FORMAT_PEM)
441: PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
442: else if (outformat == FORMAT_ASN1)
443: i2d_PrivateKey_bio(out, pkey);
444: else
445: {
446: BIO_printf(bio_err, "Bad format specified for key\n");
447: return (1);
448: }
449:
450: end:
451: EVP_PKEY_free(pkey);
452: BIO_free_all(out);
453: BIO_free(in);
454: if (passin)
455: OPENSSL_free(passin);
456: if (passout)
457: OPENSSL_free(passout);
458:
459: return (0);
460: }