summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordoug <>2015-01-08 11:06:12 +0000
committerdoug <>2015-01-08 11:06:12 +0000
commit7c309d18930478afab0b16bd74eca4338e8b6bdf (patch)
tree9943e7aed41baa761c9d90297fac00b26bd05ce1
parent4d5a9de6c466235cf933ddcfc21e3a9e50c41f7c (diff)
downloadopenbsd-7c309d18930478afab0b16bd74eca4338e8b6bdf.tar.gz
openbsd-7c309d18930478afab0b16bd74eca4338e8b6bdf.tar.bz2
openbsd-7c309d18930478afab0b16bd74eca4338e8b6bdf.zip
Convert pkcs8.c to the new option handling code.
Minor KNF in a few places too. input + ok jsing@
-rw-r--r--src/usr.bin/openssl/pkcs8.c377
1 files changed, 220 insertions, 157 deletions
diff --git a/src/usr.bin/openssl/pkcs8.c b/src/usr.bin/openssl/pkcs8.c
index 25ffb363ee..b226a00ce6 100644
--- a/src/usr.bin/openssl/pkcs8.c
+++ b/src/usr.bin/openssl/pkcs8.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: pkcs8.c,v 1.3 2014/08/28 14:25:48 jsing Exp $ */ 1/* $OpenBSD: pkcs8.c,v 1.4 2015/01/08 11:06:12 doug Exp $ */
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 */
@@ -66,185 +66,241 @@
66#include <openssl/pem.h> 66#include <openssl/pem.h>
67#include <openssl/pkcs12.h> 67#include <openssl/pkcs12.h>
68 68
69int pkcs8_main(int, char **); 69static struct {
70 const EVP_CIPHER *cipher;
71#ifndef OPENSSL_NO_ENGINE
72 char *engine;
73#endif
74 char *infile;
75 int informat;
76 int iter;
77 int nocrypt;
78 char *outfile;
79 int outformat;
80 int p8_broken;
81 char *passargin;
82 char *passargout;
83 int pbe_nid;
84 int topk8;
85} pkcs8_config;
86
87static int
88pkcs8_opt_v1(char *arg)
89{
90 if ((pkcs8_config.pbe_nid = OBJ_txt2nid(arg)) == NID_undef) {
91 fprintf(stderr, "Unknown PBE algorithm '%s'\n", arg);
92 return (1);
93 }
94
95 return (0);
96}
97
98static int
99pkcs8_opt_v2(char *arg)
100{
101 if ((pkcs8_config.cipher = EVP_get_cipherbyname(arg)) == NULL) {
102 fprintf(stderr, "Unknown cipher '%s'\n", arg);
103 return (1);
104 }
105
106 return (0);
107}
108
109static struct option pkcs8_options[] = {
110 {
111 .name = "embed",
112 .desc = "Generate DSA keys in a broken format",
113 .type = OPTION_VALUE,
114 .value = PKCS8_EMBEDDED_PARAM,
115 .opt.value = &pkcs8_config.p8_broken,
116 },
117#ifndef OPENSSL_NO_ENGINE
118 {
119 .name = "engine",
120 .argname = "id",
121 .desc = "Use the engine specified by the given identifier",
122 .type = OPTION_ARG,
123 .opt.arg = &pkcs8_config.engine,
124 },
125#endif
126 {
127 .name = "in",
128 .argname = "file",
129 .desc = "Input file (default stdin)",
130 .type = OPTION_ARG,
131 .opt.arg = &pkcs8_config.infile,
132 },
133 {
134 .name = "inform",
135 .argname = "format",
136 .desc = "Input format (DER or PEM (default))",
137 .type = OPTION_ARG_FORMAT,
138 .opt.value = &pkcs8_config.informat,
139 },
140 {
141 .name = "nocrypt",
142 .desc = "Use or expect unencrypted private key",
143 .type = OPTION_FLAG,
144 .opt.flag = &pkcs8_config.nocrypt,
145 },
146 {
147 .name = "noiter",
148 .desc = "Use 1 as iteration count",
149 .type = OPTION_VALUE,
150 .value = 1,
151 .opt.value = &pkcs8_config.iter,
152 },
153 {
154 .name = "nooct",
155 .desc = "Generate RSA keys in a broken format (no octet)",
156 .type = OPTION_VALUE,
157 .value = PKCS8_NO_OCTET,
158 .opt.value = &pkcs8_config.p8_broken,
159 },
160 {
161 .name = "nsdb",
162 .desc = "Generate DSA keys in the broken Netscape DB format",
163 .type = OPTION_VALUE,
164 .value = PKCS8_NS_DB,
165 .opt.value = &pkcs8_config.p8_broken,
166 },
167 {
168 .name = "out",
169 .argname = "file",
170 .desc = "Output file (default stdout)",
171 .type = OPTION_ARG,
172 .opt.arg = &pkcs8_config.outfile,
173 },
174 {
175 .name = "outform",
176 .argname = "format",
177 .desc = "Output format (DER or PEM (default))",
178 .type = OPTION_ARG_FORMAT,
179 .opt.value = &pkcs8_config.outformat,
180 },
181 {
182 .name = "passin",
183 .argname = "source",
184 .desc = "Input file passphrase source",
185 .type = OPTION_ARG,
186 .opt.arg = &pkcs8_config.passargin,
187 },
188 {
189 .name = "passout",
190 .argname = "source",
191 .desc = "Output file passphrase source",
192 .type = OPTION_ARG,
193 .opt.arg = &pkcs8_config.passargout,
194 },
195 {
196 .name = "topk8",
197 .desc = "Read traditional format key and write PKCS#8 format"
198 " key",
199 .type = OPTION_FLAG,
200 .opt.flag = &pkcs8_config.topk8,
201 },
202 {
203 .name = "v1",
204 .argname = "algorithm",
205 .desc = "Use PKCS#5 v1.5 or PKCS#12 with given algorithm",
206 .type = OPTION_ARG_FUNC,
207 .opt.argfunc = pkcs8_opt_v1,
208 },
209 {
210 .name = "v2",
211 .argname = "cipher",
212 .desc = "Use PKCS#5 v2.0 with given cipher",
213 .type = OPTION_ARG_FUNC,
214 .opt.argfunc = pkcs8_opt_v2,
215 },
216 { NULL },
217};
218
219static void
220pkcs8_usage()
221{
222 fprintf(stderr, "usage: pkcs8 [-embed] [-engine id] [-in file] "
223 "[-inform fmt] [-nocrypt]\n"
224 " [-noiter] [-nooct] [-nsdb] [-out file] [-outform fmt] "
225 "[-passin src]\n"
226 " [-passout src] [-topk8] [-v1 alg] [-v2 alg]\n\n");
227 options_usage(pkcs8_options);
228}
70 229
71int 230int
72pkcs8_main(int argc, char **argv) 231pkcs8_main(int argc, char **argv)
73{ 232{
74 ENGINE *e = NULL; 233 ENGINE *e = NULL;
75 char **args, *infile = NULL, *outfile = NULL;
76 char *passargin = NULL, *passargout = NULL;
77 BIO *in = NULL, *out = NULL; 234 BIO *in = NULL, *out = NULL;
78 int topk8 = 0;
79 int pbe_nid = -1;
80 const EVP_CIPHER *cipher = NULL;
81 int iter = PKCS12_DEFAULT_ITER;
82 int informat, outformat;
83 int p8_broken = PKCS8_OK;
84 int nocrypt = 0;
85 X509_SIG *p8 = NULL; 235 X509_SIG *p8 = NULL;
86 PKCS8_PRIV_KEY_INFO *p8inf = NULL; 236 PKCS8_PRIV_KEY_INFO *p8inf = NULL;
87 EVP_PKEY *pkey = NULL; 237 EVP_PKEY *pkey = NULL;
88 char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; 238 char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
89 int badarg = 0;
90 int ret = 1; 239 int ret = 1;
91#ifndef OPENSSL_NO_ENGINE
92 char *engine = NULL;
93#endif
94 240
95 informat = FORMAT_PEM; 241 memset(&pkcs8_config, 0, sizeof(pkcs8_config));
96 outformat = FORMAT_PEM;
97 242
98 args = argv + 1; 243 pkcs8_config.iter = PKCS12_DEFAULT_ITER;
99 while (!badarg && *args && *args[0] == '-') { 244 pkcs8_config.informat = FORMAT_PEM;
100 if (!strcmp(*args, "-v2")) { 245 pkcs8_config.outformat = FORMAT_PEM;
101 if (args[1]) { 246 pkcs8_config.p8_broken = PKCS8_OK;
102 args++; 247 pkcs8_config.pbe_nid = -1;
103 cipher = EVP_get_cipherbyname(*args);
104 if (!cipher) {
105 BIO_printf(bio_err,
106 "Unknown cipher %s\n", *args);
107 badarg = 1;
108 }
109 } else
110 badarg = 1;
111 } else if (!strcmp(*args, "-v1")) {
112 if (args[1]) {
113 args++;
114 pbe_nid = OBJ_txt2nid(*args);
115 if (pbe_nid == NID_undef) {
116 BIO_printf(bio_err,
117 "Unknown PBE algorithm %s\n", *args);
118 badarg = 1;
119 }
120 } else
121 badarg = 1;
122 } else if (!strcmp(*args, "-inform")) {
123 if (args[1]) {
124 args++;
125 informat = str2fmt(*args);
126 } else
127 badarg = 1;
128 } else if (!strcmp(*args, "-outform")) {
129 if (args[1]) {
130 args++;
131 outformat = str2fmt(*args);
132 } else
133 badarg = 1;
134 } else if (!strcmp(*args, "-topk8"))
135 topk8 = 1;
136 else if (!strcmp(*args, "-noiter"))
137 iter = 1;
138 else if (!strcmp(*args, "-nocrypt"))
139 nocrypt = 1;
140 else if (!strcmp(*args, "-nooct"))
141 p8_broken = PKCS8_NO_OCTET;
142 else if (!strcmp(*args, "-nsdb"))
143 p8_broken = PKCS8_NS_DB;
144 else if (!strcmp(*args, "-embed"))
145 p8_broken = PKCS8_EMBEDDED_PARAM;
146 else if (!strcmp(*args, "-passin")) {
147 if (!args[1])
148 goto bad;
149 passargin = *(++args);
150 } else if (!strcmp(*args, "-passout")) {
151 if (!args[1])
152 goto bad;
153 passargout = *(++args);
154 }
155#ifndef OPENSSL_NO_ENGINE
156 else if (strcmp(*args, "-engine") == 0) {
157 if (!args[1])
158 goto bad;
159 engine = *(++args);
160 }
161#endif
162 else if (!strcmp(*args, "-in")) {
163 if (args[1]) {
164 args++;
165 infile = *args;
166 } else
167 badarg = 1;
168 } else if (!strcmp(*args, "-out")) {
169 if (args[1]) {
170 args++;
171 outfile = *args;
172 } else
173 badarg = 1;
174 } else
175 badarg = 1;
176 args++;
177 }
178 248
179 if (badarg) { 249 if (options_parse(argc, argv, pkcs8_options, NULL, NULL) != 0) {
180bad: 250 pkcs8_usage();
181 BIO_printf(bio_err, "Usage pkcs8 [options]\n"); 251 return (1);
182 BIO_printf(bio_err, "where options are\n");
183 BIO_printf(bio_err, "-in file input file\n");
184 BIO_printf(bio_err, "-inform X input format (DER or PEM)\n");
185 BIO_printf(bio_err, "-passin arg input file pass phrase source\n");
186 BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
187 BIO_printf(bio_err, "-out file output file\n");
188 BIO_printf(bio_err, "-passout arg output file pass phrase source\n");
189 BIO_printf(bio_err, "-topk8 output PKCS8 file\n");
190 BIO_printf(bio_err, "-nooct use (nonstandard) no octet format\n");
191 BIO_printf(bio_err, "-embed use (nonstandard) embedded DSA parameters format\n");
192 BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netscape DB format\n");
193 BIO_printf(bio_err, "-noiter use 1 as iteration count\n");
194 BIO_printf(bio_err, "-nocrypt use or expect unencrypted private key\n");
195 BIO_printf(bio_err, "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n");
196 BIO_printf(bio_err, "-v1 obj use PKCS#5 v1.5 and cipher \"alg\"\n");
197#ifndef OPENSSL_NO_ENGINE
198 BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n");
199#endif
200 goto end;
201 } 252 }
253
202#ifndef OPENSSL_NO_ENGINE 254#ifndef OPENSSL_NO_ENGINE
203 e = setup_engine(bio_err, engine, 0); 255 e = setup_engine(bio_err, pkcs8_config.engine, 0);
204#endif 256#endif
205 257
206 if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 258 if (!app_passwd(bio_err, pkcs8_config.passargin,
259 pkcs8_config.passargout, &passin, &passout)) {
207 BIO_printf(bio_err, "Error getting passwords\n"); 260 BIO_printf(bio_err, "Error getting passwords\n");
208 goto end; 261 goto end;
209 } 262 }
210 if ((pbe_nid == -1) && !cipher) 263 if ((pkcs8_config.pbe_nid == -1) && !pkcs8_config.cipher)
211 pbe_nid = NID_pbeWithMD5AndDES_CBC; 264 pkcs8_config.pbe_nid = NID_pbeWithMD5AndDES_CBC;
212 265
213 if (infile) { 266 if (pkcs8_config.infile) {
214 if (!(in = BIO_new_file(infile, "rb"))) { 267 if (!(in = BIO_new_file(pkcs8_config.infile, "rb"))) {
215 BIO_printf(bio_err, 268 BIO_printf(bio_err,
216 "Can't open input file %s\n", infile); 269 "Can't open input file '%s'\n",
270 pkcs8_config.infile);
217 goto end; 271 goto end;
218 } 272 }
219 } else 273 } else
220 in = BIO_new_fp(stdin, BIO_NOCLOSE); 274 in = BIO_new_fp(stdin, BIO_NOCLOSE);
221 275
222 if (outfile) { 276 if (pkcs8_config.outfile) {
223 if (!(out = BIO_new_file(outfile, "wb"))) { 277 if (!(out = BIO_new_file(pkcs8_config.outfile, "wb"))) {
224 BIO_printf(bio_err, 278 BIO_printf(bio_err, "Can't open output file '%s'\n",
225 "Can't open output file %s\n", outfile); 279 pkcs8_config.outfile);
226 goto end; 280 goto end;
227 } 281 }
228 } else { 282 } else {
229 out = BIO_new_fp(stdout, BIO_NOCLOSE); 283 out = BIO_new_fp(stdout, BIO_NOCLOSE);
230 } 284 }
231 if (topk8) { 285 if (pkcs8_config.topk8) {
232 pkey = load_key(bio_err, infile, informat, 1, 286 pkey = load_key(bio_err, pkcs8_config.infile,
233 passin, e, "key"); 287 pkcs8_config.informat, 1, passin, e, "key");
234 if (!pkey) 288 if (!pkey)
235 goto end; 289 goto end;
236 if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) { 290 if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey,
291 pkcs8_config.p8_broken))) {
237 BIO_printf(bio_err, "Error converting key\n"); 292 BIO_printf(bio_err, "Error converting key\n");
238 ERR_print_errors(bio_err); 293 ERR_print_errors(bio_err);
239 goto end; 294 goto end;
240 } 295 }
241 if (nocrypt) { 296 if (pkcs8_config.nocrypt) {
242 if (outformat == FORMAT_PEM) 297 if (pkcs8_config.outformat == FORMAT_PEM)
243 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); 298 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
244 else if (outformat == FORMAT_ASN1) 299 else if (pkcs8_config.outformat == FORMAT_ASN1)
245 i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); 300 i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
246 else { 301 else {
247 BIO_printf(bio_err, "Bad format specified for key\n"); 302 BIO_printf(bio_err,
303 "Bad format specified for key\n");
248 goto end; 304 goto end;
249 } 305 }
250 } else { 306 } else {
@@ -252,22 +308,24 @@ bad:
252 p8pass = passout; 308 p8pass = passout;
253 else { 309 else {
254 p8pass = pass; 310 p8pass = pass;
255 if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1)) 311 if (EVP_read_pw_string(pass, sizeof pass,
312 "Enter Encryption Password:", 1))
256 goto end; 313 goto end;
257 } 314 }
258 if (!(p8 = PKCS8_encrypt(pbe_nid, cipher, 315 if (!(p8 = PKCS8_encrypt(pkcs8_config.pbe_nid,
259 p8pass, strlen(p8pass), 316 pkcs8_config.cipher, p8pass, strlen(p8pass),
260 NULL, 0, iter, p8inf))) { 317 NULL, 0, pkcs8_config.iter, p8inf))) {
261 BIO_printf(bio_err, "Error encrypting key\n"); 318 BIO_printf(bio_err, "Error encrypting key\n");
262 ERR_print_errors(bio_err); 319 ERR_print_errors(bio_err);
263 goto end; 320 goto end;
264 } 321 }
265 if (outformat == FORMAT_PEM) 322 if (pkcs8_config.outformat == FORMAT_PEM)
266 PEM_write_bio_PKCS8(out, p8); 323 PEM_write_bio_PKCS8(out, p8);
267 else if (outformat == FORMAT_ASN1) 324 else if (pkcs8_config.outformat == FORMAT_ASN1)
268 i2d_PKCS8_bio(out, p8); 325 i2d_PKCS8_bio(out, p8);
269 else { 326 else {
270 BIO_printf(bio_err, "Bad format specified for key\n"); 327 BIO_printf(bio_err,
328 "Bad format specified for key\n");
271 goto end; 329 goto end;
272 } 330 }
273 } 331 }
@@ -275,19 +333,20 @@ bad:
275 ret = 0; 333 ret = 0;
276 goto end; 334 goto end;
277 } 335 }
278 if (nocrypt) { 336 if (pkcs8_config.nocrypt) {
279 if (informat == FORMAT_PEM) 337 if (pkcs8_config.informat == FORMAT_PEM)
280 p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL, NULL, NULL); 338 p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL,
281 else if (informat == FORMAT_ASN1) 339 NULL, NULL);
340 else if (pkcs8_config.informat == FORMAT_ASN1)
282 p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); 341 p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
283 else { 342 else {
284 BIO_printf(bio_err, "Bad format specified for key\n"); 343 BIO_printf(bio_err, "Bad format specified for key\n");
285 goto end; 344 goto end;
286 } 345 }
287 } else { 346 } else {
288 if (informat == FORMAT_PEM) 347 if (pkcs8_config.informat == FORMAT_PEM)
289 p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); 348 p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
290 else if (informat == FORMAT_ASN1) 349 else if (pkcs8_config.informat == FORMAT_ASN1)
291 p8 = d2i_PKCS8_bio(in, NULL); 350 p8 = d2i_PKCS8_bio(in, NULL);
292 else { 351 else {
293 BIO_printf(bio_err, "Bad format specified for key\n"); 352 BIO_printf(bio_err, "Bad format specified for key\n");
@@ -303,7 +362,8 @@ bad:
303 p8pass = passin; 362 p8pass = passin;
304 else { 363 else {
305 p8pass = pass; 364 p8pass = pass;
306 EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0); 365 EVP_read_pw_string(pass, sizeof pass,
366 "Enter Password:", 0);
307 } 367 }
308 p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); 368 p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
309 } 369 }
@@ -326,11 +386,13 @@ bad:
326 break; 386 break;
327 387
328 case PKCS8_EMBEDDED_PARAM: 388 case PKCS8_EMBEDDED_PARAM:
329 BIO_printf(bio_err, "DSA parameters included in PrivateKey\n"); 389 BIO_printf(bio_err,
390 "DSA parameters included in PrivateKey\n");
330 break; 391 break;
331 392
332 case PKCS8_NS_DB: 393 case PKCS8_NS_DB:
333 BIO_printf(bio_err, "DSA public key include in PrivateKey\n"); 394 BIO_printf(bio_err,
395 "DSA public key include in PrivateKey\n");
334 break; 396 break;
335 397
336 case PKCS8_NEG_PRIVKEY: 398 case PKCS8_NEG_PRIVKEY:
@@ -342,9 +404,10 @@ bad:
342 break; 404 break;
343 } 405 }
344 } 406 }
345 if (outformat == FORMAT_PEM) 407 if (pkcs8_config.outformat == FORMAT_PEM)
346 PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); 408 PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL,
347 else if (outformat == FORMAT_ASN1) 409 passout);
410 else if (pkcs8_config.outformat == FORMAT_ASN1)
348 i2d_PrivateKey_bio(out, pkey); 411 i2d_PrivateKey_bio(out, pkey);
349 else { 412 else {
350 BIO_printf(bio_err, "Bad format specified for key\n"); 413 BIO_printf(bio_err, "Bad format specified for key\n");