summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/usr.bin/openssl/ecparam.c412
1 files changed, 215 insertions, 197 deletions
diff --git a/src/usr.bin/openssl/ecparam.c b/src/usr.bin/openssl/ecparam.c
index 782069a8e5..7336360b35 100644
--- a/src/usr.bin/openssl/ecparam.c
+++ b/src/usr.bin/openssl/ecparam.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecparam.c,v 1.2 2014/08/28 14:23:52 jsing Exp $ */ 1/* $OpenBSD: ecparam.c,v 1.3 2014/09/01 14:26:01 jsing Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project. 3 * Written by Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -87,179 +87,198 @@
87#include <openssl/pem.h> 87#include <openssl/pem.h>
88#include <openssl/x509.h> 88#include <openssl/x509.h>
89 89
90/* -inform arg - input format - default PEM (DER or PEM) 90static int ecparam_print_var(BIO *, BIGNUM *, const char *, int,
91 * -outform arg - output format - default PEM 91 unsigned char *);
92 * -in arg - input file - default stdin 92
93 * -out arg - output file - default stdout 93static struct {
94 * -noout - do not print the ec parameter 94 int C;
95 * -text - print the ec parameters in text form 95 int asn1_flag;
96 * -check - validate the ec parameters 96 int check;
97 * -C - print a 'C' function creating the parameters 97 char *curve_name;
98 * -name arg - use the ec parameters with 'short name' name 98 char *engine;
99 * -list_curves - prints a list of all currently available curve 'short names' 99 point_conversion_form_t form;
100 * -conv_form arg - specifies the point conversion form 100 int genkey;
101 * - possible values: compressed 101 char *infile;
102 * uncompressed (default) 102 int informat;
103 * hybrid 103 int list_curves;
104 * -param_enc arg - specifies the way the ec parameters are encoded 104 int new_asn1_flag;
105 * in the asn1 der encoding 105 int new_form;
106 * possible values: named_curve (default) 106 int no_seed;
107 * explicit 107 int noout;
108 * -no_seed - if 'explicit' parameters are chosen do not use the seed 108 char *outfile;
109 * -genkey - generate ec key 109 int outformat;
110 * -engine e - use engine e, possibly a hardware device 110 int text;
111 */ 111} ecparam_config;
112 112
113static int
114ecparam_opt_form(struct option *opt, char *arg)
115{
116 if (strcmp(arg, "compressed") == 0)
117 ecparam_config.form = POINT_CONVERSION_COMPRESSED;
118 else if (strcmp(arg, "uncompressed") == 0)
119 ecparam_config.form = POINT_CONVERSION_UNCOMPRESSED;
120 else if (strcmp(arg, "hybrid") == 0)
121 ecparam_config.form = POINT_CONVERSION_HYBRID;
122 else
123 return (1);
124
125 ecparam_config.new_form = 1;
126 return (0);
127}
113 128
114static int ecparam_print_var(BIO *, BIGNUM *, const char *, int, unsigned char *); 129static int
130ecparam_opt_enctype(struct option *opt, char *arg)
131{
132 if (strcmp(arg, "explicit") == 0)
133 ecparam_config.asn1_flag = 0;
134 else if (strcmp(arg, "named_curve") == 0)
135 ecparam_config.asn1_flag = OPENSSL_EC_NAMED_CURVE;
136 else
137 return (1);
138
139 ecparam_config.new_asn1_flag = 1;
140 return (0);
141}
142
143struct option ecparam_options[] = {
144 {
145 .name = "C",
146 .desc = "Convert the EC parameters into C code",
147 .type = OPTION_FLAG,
148 .opt.flag = &ecparam_config.C,
149 },
150 {
151 .name = "check",
152 .desc = "Validate the elliptic curve parameters",
153 .type = OPTION_FLAG,
154 .opt.flag = &ecparam_config.check,
155 },
156 {
157 .name = "conv_form",
158 .argname = "form",
159 .desc = "Specify point conversion form:\n"
160 " compressed, uncompressed (default), hybrid",
161 .type = OPTION_ARG_FUNC,
162 .func = ecparam_opt_form,
163 },
164#ifndef OPENSSL_NO_ENGINE
165 {
166 .name = "engine",
167 .argname = "id",
168 .desc = "Use the engine specified by the given identifier",
169 .type = OPTION_ARG,
170 .opt.arg = &ecparam_config.engine,
171 },
172#endif
173 {
174 .name = "genkey",
175 .desc = "Generate an EC private key using the specified "
176 "parameters",
177 .type = OPTION_FLAG,
178 .opt.flag = &ecparam_config.genkey,
179 },
180 {
181 .name = "in",
182 .argname = "file",
183 .desc = "Input file to read parameters from (default stdin)",
184 .type = OPTION_ARG,
185 .opt.arg = &ecparam_config.infile,
186 },
187 {
188 .name = "inform",
189 .argname = "format",
190 .desc = "Input format (DER or PEM)",
191 .type = OPTION_ARG_FORMAT,
192 .opt.value = &ecparam_config.informat,
193 },
194 {
195 .name = "list_curves",
196 .desc = "Print list of all currently implemented EC "
197 "parameter names",
198 .type = OPTION_FLAG,
199 .opt.flag = &ecparam_config.list_curves,
200 },
201 {
202 .name = "name",
203 .argname = "curve",
204 .desc = "Use the EC parameters with the specified name",
205 .type = OPTION_ARG,
206 .opt.arg = &ecparam_config.curve_name,
207 },
208 {
209 .name = "no_seed",
210 .desc = "Do not output seed with explicit parameter encoding",
211 .type = OPTION_FLAG,
212 .opt.flag = &ecparam_config.no_seed,
213 },
214 {
215 .name = "noout",
216 .desc = "Do not output encoded version of EC parameters",
217 .type = OPTION_FLAG,
218 .opt.flag = &ecparam_config.noout,
219 },
220 {
221 .name = "out",
222 .argname = "file",
223 .desc = "Output file to write parameters to (default stdout)",
224 .type = OPTION_ARG,
225 .opt.arg = &ecparam_config.outfile,
226 },
227 {
228 .name = "outform",
229 .argname = "format",
230 .desc = "Output format (DER or PEM)",
231 .type = OPTION_ARG_FORMAT,
232 .opt.value = &ecparam_config.outformat,
233 },
234 {
235 .name = "param_enc",
236 .argname = "type",
237 .desc = "Specify EC parameter ASN.1 encoding type:\n"
238 " explicit, named_curve (default)",
239 .type = OPTION_ARG_FUNC,
240 .func = ecparam_opt_enctype,
241 },
242 {
243 .name = "text",
244 .desc = "Print out the EC parameters in human readable form",
245 .type = OPTION_FLAG,
246 .opt.flag = &ecparam_config.text,
247 },
248 {},
249};
250
251static void
252ecparam_usage(void)
253{
254 fprintf(stderr, "usage: ecparam [-C] [-check] [-conv_form arg] "
255 "[-engine id] [-genkey]\n"
256 " [-in file] [-inform DER | PEM] [-list_curves] [-name arg]\n"
257 " [-no_seed] [-noout] [-out file] [-outform DER | PEM]\n"
258 " [-param_enc arg] [-text]\n\n");
259 options_usage(ecparam_options);
260}
115 261
116int ecparam_main(int, char **); 262int ecparam_main(int, char **);
117 263
118int 264int
119ecparam_main(int argc, char **argv) 265ecparam_main(int argc, char **argv)
120{ 266{
267 BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL;
268 BIGNUM *ec_order = NULL, *ec_cofactor = NULL;
121 EC_GROUP *group = NULL; 269 EC_GROUP *group = NULL;
122 point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
123 int new_form = 0;
124 int asn1_flag = OPENSSL_EC_NAMED_CURVE;
125 int new_asn1_flag = 0;
126 char *curve_name = NULL;
127 int list_curves = 0, no_seed = 0, check = 0, badops = 0, text = 0,
128 i, genkey = 0;
129 char *infile = NULL, *outfile = NULL, *prog;
130 BIO *in = NULL, *out = NULL;
131 int informat, outformat, noout = 0, C = 0, ret = 1;
132 char *engine = NULL;
133
134 BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL,
135 *ec_order = NULL, *ec_cofactor = NULL;
136 unsigned char *buffer = NULL; 270 unsigned char *buffer = NULL;
271 BIO *in = NULL, *out = NULL;
272 int i, ret = 1;
137 273
138 informat = FORMAT_PEM; 274 memset(&ecparam_config, 0, sizeof(ecparam_config));
139 outformat = FORMAT_PEM; 275 ecparam_config.asn1_flag = OPENSSL_EC_NAMED_CURVE;
140 276 ecparam_config.form = POINT_CONVERSION_UNCOMPRESSED;
141 prog = argv[0]; 277 ecparam_config.informat = FORMAT_PEM;
142 argc--; 278 ecparam_config.outformat = FORMAT_PEM;
143 argv++;
144 while (argc >= 1) {
145 if (strcmp(*argv, "-inform") == 0) {
146 if (--argc < 1)
147 goto bad;
148 informat = str2fmt(*(++argv));
149 } else if (strcmp(*argv, "-outform") == 0) {
150 if (--argc < 1)
151 goto bad;
152 outformat = str2fmt(*(++argv));
153 } else if (strcmp(*argv, "-in") == 0) {
154 if (--argc < 1)
155 goto bad;
156 infile = *(++argv);
157 } else if (strcmp(*argv, "-out") == 0) {
158 if (--argc < 1)
159 goto bad;
160 outfile = *(++argv);
161 } else if (strcmp(*argv, "-text") == 0)
162 text = 1;
163 else if (strcmp(*argv, "-C") == 0)
164 C = 1;
165 else if (strcmp(*argv, "-check") == 0)
166 check = 1;
167 else if (strcmp(*argv, "-name") == 0) {
168 if (--argc < 1)
169 goto bad;
170 curve_name = *(++argv);
171 } else if (strcmp(*argv, "-list_curves") == 0)
172 list_curves = 1;
173 else if (strcmp(*argv, "-conv_form") == 0) {
174 if (--argc < 1)
175 goto bad;
176 ++argv;
177 new_form = 1;
178 if (strcmp(*argv, "compressed") == 0)
179 form = POINT_CONVERSION_COMPRESSED;
180 else if (strcmp(*argv, "uncompressed") == 0)
181 form = POINT_CONVERSION_UNCOMPRESSED;
182 else if (strcmp(*argv, "hybrid") == 0)
183 form = POINT_CONVERSION_HYBRID;
184 else
185 goto bad;
186 } else if (strcmp(*argv, "-param_enc") == 0) {
187 if (--argc < 1)
188 goto bad;
189 ++argv;
190 new_asn1_flag = 1;
191 if (strcmp(*argv, "named_curve") == 0)
192 asn1_flag = OPENSSL_EC_NAMED_CURVE;
193 else if (strcmp(*argv, "explicit") == 0)
194 asn1_flag = 0;
195 else
196 goto bad;
197 } else if (strcmp(*argv, "-no_seed") == 0)
198 no_seed = 1;
199 else if (strcmp(*argv, "-noout") == 0)
200 noout = 1;
201 else if (strcmp(*argv, "-genkey") == 0) {
202 genkey = 1;
203 } else if (strcmp(*argv, "-engine") == 0) {
204 if (--argc < 1)
205 goto bad;
206 engine = *(++argv);
207 } else {
208 BIO_printf(bio_err, "unknown option %s\n", *argv);
209 badops = 1;
210 break;
211 }
212 argc--;
213 argv++;
214 }
215 279
216 if (badops) { 280 if (options_parse(argc, argv, ecparam_options, NULL) != 0) {
217bad: 281 ecparam_usage();
218 BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
219 BIO_printf(bio_err, "where options are\n");
220 BIO_printf(bio_err, " -inform arg input format - "
221 "default PEM (DER or PEM)\n");
222 BIO_printf(bio_err, " -outform arg output format - "
223 "default PEM\n");
224 BIO_printf(bio_err, " -in arg input file - "
225 "default stdin\n");
226 BIO_printf(bio_err, " -out arg output file - "
227 "default stdout\n");
228 BIO_printf(bio_err, " -noout do not print the "
229 "ec parameter\n");
230 BIO_printf(bio_err, " -text print the ec "
231 "parameters in text form\n");
232 BIO_printf(bio_err, " -check validate the ec "
233 "parameters\n");
234 BIO_printf(bio_err, " -C print a 'C' "
235 "function creating the parameters\n");
236 BIO_printf(bio_err, " -name arg use the "
237 "ec parameters with 'short name' name\n");
238 BIO_printf(bio_err, " -list_curves prints a list of "
239 "all currently available curve 'short names'\n");
240 BIO_printf(bio_err, " -conv_form arg specifies the "
241 "point conversion form \n");
242 BIO_printf(bio_err, " possible values:"
243 " compressed\n");
244 BIO_printf(bio_err, " "
245 " uncompressed (default)\n");
246 BIO_printf(bio_err, " "
247 " hybrid\n");
248 BIO_printf(bio_err, " -param_enc arg specifies the way"
249 " the ec parameters are encoded\n");
250 BIO_printf(bio_err, " in the asn1 der "
251 "encoding\n");
252 BIO_printf(bio_err, " possible values:"
253 " named_curve (default)\n");
254 BIO_printf(bio_err, " "
255 " explicit\n");
256 BIO_printf(bio_err, " -no_seed if 'explicit'"
257 " parameters are chosen do not"
258 " use the seed\n");
259 BIO_printf(bio_err, " -genkey generate ec"
260 " key\n");
261 BIO_printf(bio_err, " -engine e use engine e, "
262 "possibly a hardware device\n");
263 goto end; 282 goto end;
264 } 283 }
265 284
@@ -269,28 +288,28 @@ bad:
269 ERR_print_errors(bio_err); 288 ERR_print_errors(bio_err);
270 goto end; 289 goto end;
271 } 290 }
272 if (infile == NULL) 291 if (ecparam_config.infile == NULL)
273 BIO_set_fp(in, stdin, BIO_NOCLOSE); 292 BIO_set_fp(in, stdin, BIO_NOCLOSE);
274 else { 293 else {
275 if (BIO_read_filename(in, infile) <= 0) { 294 if (BIO_read_filename(in, ecparam_config.infile) <= 0) {
276 perror(infile); 295 perror(ecparam_config.infile);
277 goto end; 296 goto end;
278 } 297 }
279 } 298 }
280 if (outfile == NULL) { 299 if (ecparam_config.outfile == NULL) {
281 BIO_set_fp(out, stdout, BIO_NOCLOSE); 300 BIO_set_fp(out, stdout, BIO_NOCLOSE);
282 } else { 301 } else {
283 if (BIO_write_filename(out, outfile) <= 0) { 302 if (BIO_write_filename(out, ecparam_config.outfile) <= 0) {
284 perror(outfile); 303 perror(ecparam_config.outfile);
285 goto end; 304 goto end;
286 } 305 }
287 } 306 }
288 307
289#ifndef OPENSSL_NO_ENGINE 308#ifndef OPENSSL_NO_ENGINE
290 setup_engine(bio_err, engine, 0); 309 setup_engine(bio_err, ecparam_config.engine, 0);
291#endif 310#endif
292 311
293 if (list_curves) { 312 if (ecparam_config.list_curves) {
294 EC_builtin_curve *curves = NULL; 313 EC_builtin_curve *curves = NULL;
295 size_t crv_len = 0; 314 size_t crv_len = 0;
296 size_t n = 0; 315 size_t n = 0;
@@ -298,7 +317,6 @@ bad:
298 crv_len = EC_get_builtin_curves(NULL, 0); 317 crv_len = EC_get_builtin_curves(NULL, 0);
299 318
300 curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve)); 319 curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve));
301
302 if (curves == NULL) 320 if (curves == NULL)
303 goto end; 321 goto end;
304 322
@@ -324,7 +342,7 @@ bad:
324 ret = 0; 342 ret = 0;
325 goto end; 343 goto end;
326 } 344 }
327 if (curve_name != NULL) { 345 if (ecparam_config.curve_name != NULL) {
328 int nid; 346 int nid;
329 347
330 /* 348 /*
@@ -332,33 +350,33 @@ bad:
332 * secp256r1 (which are the same as the curves prime192v1 and 350 * secp256r1 (which are the same as the curves prime192v1 and
333 * prime256v1 defined in X9.62) 351 * prime256v1 defined in X9.62)
334 */ 352 */
335 if (!strcmp(curve_name, "secp192r1")) { 353 if (!strcmp(ecparam_config.curve_name, "secp192r1")) {
336 BIO_printf(bio_err, "using curve name prime192v1 " 354 BIO_printf(bio_err, "using curve name prime192v1 "
337 "instead of secp192r1\n"); 355 "instead of secp192r1\n");
338 nid = NID_X9_62_prime192v1; 356 nid = NID_X9_62_prime192v1;
339 } else if (!strcmp(curve_name, "secp256r1")) { 357 } else if (!strcmp(ecparam_config.curve_name, "secp256r1")) {
340 BIO_printf(bio_err, "using curve name prime256v1 " 358 BIO_printf(bio_err, "using curve name prime256v1 "
341 "instead of secp256r1\n"); 359 "instead of secp256r1\n");
342 nid = NID_X9_62_prime256v1; 360 nid = NID_X9_62_prime256v1;
343 } else 361 } else
344 nid = OBJ_sn2nid(curve_name); 362 nid = OBJ_sn2nid(ecparam_config.curve_name);
345 363
346 if (nid == 0) { 364 if (nid == 0) {
347 BIO_printf(bio_err, "unknown curve name (%s)\n", 365 BIO_printf(bio_err, "unknown curve name (%s)\n",
348 curve_name); 366 ecparam_config.curve_name);
349 goto end; 367 goto end;
350 } 368 }
351 group = EC_GROUP_new_by_curve_name(nid); 369 group = EC_GROUP_new_by_curve_name(nid);
352 if (group == NULL) { 370 if (group == NULL) {
353 BIO_printf(bio_err, "unable to create curve (%s)\n", 371 BIO_printf(bio_err, "unable to create curve (%s)\n",
354 curve_name); 372 ecparam_config.curve_name);
355 goto end; 373 goto end;
356 } 374 }
357 EC_GROUP_set_asn1_flag(group, asn1_flag); 375 EC_GROUP_set_asn1_flag(group, ecparam_config.asn1_flag);
358 EC_GROUP_set_point_conversion_form(group, form); 376 EC_GROUP_set_point_conversion_form(group, ecparam_config.form);
359 } else if (informat == FORMAT_ASN1) { 377 } else if (ecparam_config.informat == FORMAT_ASN1) {
360 group = d2i_ECPKParameters_bio(in, NULL); 378 group = d2i_ECPKParameters_bio(in, NULL);
361 } else if (informat == FORMAT_PEM) { 379 } else if (ecparam_config.informat == FORMAT_PEM) {
362 group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); 380 group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
363 } else { 381 } else {
364 BIO_printf(bio_err, "bad input format specified\n"); 382 BIO_printf(bio_err, "bad input format specified\n");
@@ -371,20 +389,20 @@ bad:
371 ERR_print_errors(bio_err); 389 ERR_print_errors(bio_err);
372 goto end; 390 goto end;
373 } 391 }
374 if (new_form) 392 if (ecparam_config.new_form)
375 EC_GROUP_set_point_conversion_form(group, form); 393 EC_GROUP_set_point_conversion_form(group, ecparam_config.form);
376 394
377 if (new_asn1_flag) 395 if (ecparam_config.new_asn1_flag)
378 EC_GROUP_set_asn1_flag(group, asn1_flag); 396 EC_GROUP_set_asn1_flag(group, ecparam_config.asn1_flag);
379 397
380 if (no_seed) { 398 if (ecparam_config.no_seed)
381 EC_GROUP_set_seed(group, NULL, 0); 399 EC_GROUP_set_seed(group, NULL, 0);
382 } 400
383 if (text) { 401 if (ecparam_config.text) {
384 if (!ECPKParameters_print(out, group, 0)) 402 if (!ECPKParameters_print(out, group, 0))
385 goto end; 403 goto end;
386 } 404 }
387 if (check) { 405 if (ecparam_config.check) {
388 if (group == NULL) 406 if (group == NULL)
389 BIO_printf(bio_err, "no elliptic curve parameters\n"); 407 BIO_printf(bio_err, "no elliptic curve parameters\n");
390 BIO_printf(bio_err, "checking elliptic curve parameters: "); 408 BIO_printf(bio_err, "checking elliptic curve parameters: ");
@@ -395,7 +413,7 @@ bad:
395 BIO_printf(bio_err, "ok\n"); 413 BIO_printf(bio_err, "ok\n");
396 414
397 } 415 }
398 if (C) { 416 if (ecparam_config.C) {
399 size_t buf_len = 0, tmp_len = 0; 417 size_t buf_len = 0, tmp_len = 0;
400 const EC_POINT *point; 418 const EC_POINT *point;
401 int is_prime, len = 0; 419 int is_prime, len = 0;
@@ -413,7 +431,7 @@ bad:
413 431
414 if (is_prime) { 432 if (is_prime) {
415 if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, 433 if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
416 ec_b, NULL)) 434 ec_b, NULL))
417 goto end; 435 goto end;
418 } else { 436 } else {
419 /* TODO */ 437 /* TODO */
@@ -517,10 +535,10 @@ bad:
517 BIO_printf(out, "\t\t}\n"); 535 BIO_printf(out, "\t\t}\n");
518 BIO_printf(out, "\treturn(group);\n\t}\n"); 536 BIO_printf(out, "\treturn(group);\n\t}\n");
519 } 537 }
520 if (!noout) { 538 if (!ecparam_config.noout) {
521 if (outformat == FORMAT_ASN1) 539 if (ecparam_config.outformat == FORMAT_ASN1)
522 i = i2d_ECPKParameters_bio(out, group); 540 i = i2d_ECPKParameters_bio(out, group);
523 else if (outformat == FORMAT_PEM) 541 else if (ecparam_config.outformat == FORMAT_PEM)
524 i = PEM_write_bio_ECPKParameters(out, group); 542 i = PEM_write_bio_ECPKParameters(out, group);
525 else { 543 else {
526 BIO_printf(bio_err, "bad output format specified for" 544 BIO_printf(bio_err, "bad output format specified for"
@@ -534,7 +552,7 @@ bad:
534 goto end; 552 goto end;
535 } 553 }
536 } 554 }
537 if (genkey) { 555 if (ecparam_config.genkey) {
538 EC_KEY *eckey = EC_KEY_new(); 556 EC_KEY *eckey = EC_KEY_new();
539 557
540 if (eckey == NULL) 558 if (eckey == NULL)
@@ -549,9 +567,9 @@ bad:
549 EC_KEY_free(eckey); 567 EC_KEY_free(eckey);
550 goto end; 568 goto end;
551 } 569 }
552 if (outformat == FORMAT_ASN1) 570 if (ecparam_config.outformat == FORMAT_ASN1)
553 i = i2d_ECPrivateKey_bio(out, eckey); 571 i = i2d_ECPrivateKey_bio(out, eckey);
554 else if (outformat == FORMAT_PEM) 572 else if (ecparam_config.outformat == FORMAT_PEM)
555 i = PEM_write_bio_ECPrivateKey(out, eckey, NULL, 573 i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
556 NULL, 0, NULL, NULL); 574 NULL, 0, NULL, NULL);
557 else { 575 else {