summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2018-02-08 11:17:44 +0000
committerjsing <>2018-02-08 11:17:44 +0000
commitfc0438989e1c41cdad9328de2e6d0856c7e42063 (patch)
tree9b6b7eb8537d700c9622b9f248ac5a4b7f2392ad /src
parentb887e277164c221b3385ae6f15eabe4c6a356c04 (diff)
downloadopenbsd-fc0438989e1c41cdad9328de2e6d0856c7e42063.tar.gz
openbsd-fc0438989e1c41cdad9328de2e6d0856c7e42063.tar.bz2
openbsd-fc0438989e1c41cdad9328de2e6d0856c7e42063.zip
Convert option handling for openssl(1) genpkey.
ok beck@ inoguchi@
Diffstat (limited to 'src')
-rw-r--r--src/usr.bin/openssl/genpkey.c287
1 files changed, 177 insertions, 110 deletions
diff --git a/src/usr.bin/openssl/genpkey.c b/src/usr.bin/openssl/genpkey.c
index 9e8e08aef4..ef16a5e0da 100644
--- a/src/usr.bin/openssl/genpkey.c
+++ b/src/usr.bin/openssl/genpkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: genpkey.c,v 1.11 2018/02/07 05:47:55 jsing Exp $ */ 1/* $OpenBSD: genpkey.c,v 1.12 2018/02/08 11:17:44 jsing 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 2006 3 * project 2006
4 */ 4 */
@@ -65,27 +65,165 @@
65#include <openssl/evp.h> 65#include <openssl/evp.h>
66#include <openssl/pem.h> 66#include <openssl/pem.h>
67 67
68static int 68static int init_keygen_file(BIO * err, EVP_PKEY_CTX **pctx, const char *file);
69init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, const char *file);
70static int genpkey_cb(EVP_PKEY_CTX * ctx); 69static int genpkey_cb(EVP_PKEY_CTX * ctx);
71 70
71struct {
72 const EVP_CIPHER *cipher;
73 EVP_PKEY_CTX **ctx;
74 int do_param;
75 char *outfile;
76 int outformat;
77 char *passarg;
78 int text;
79} genpkey_config;
80
81static int
82genpkey_opt_algorithm(char *arg)
83{
84 if (!init_gen_str(bio_err, genpkey_config.ctx, arg,
85 genpkey_config.do_param))
86 return (1);
87
88 return (0);
89}
90
91static int
92genpkey_opt_cipher(int argc, char **argv, int *argsused)
93{
94 char *name = argv[0];
95
96 if (*name++ != '-')
97 return (1);
98
99 if (genpkey_config.do_param == 1)
100 return (1);
101
102 if (strcmp(name, "none") == 0) {
103 genpkey_config.cipher = NULL;
104 *argsused = 1;
105 return (0);
106 }
107
108 if ((genpkey_config.cipher = EVP_get_cipherbyname(name)) != NULL) {
109 *argsused = 1;
110 return (0);
111 }
112
113 return (1);
114}
115
116static int
117genpkey_opt_paramfile(char *arg)
118{
119 if (genpkey_config.do_param == 1)
120 return (1);
121 if (!init_keygen_file(bio_err, genpkey_config.ctx, arg))
122 return (1);
123
124 return (0);
125}
126
127static int
128genpkey_opt_pkeyopt(char *arg)
129{
130 if (*genpkey_config.ctx == NULL) {
131 BIO_puts(bio_err, "No keytype specified\n");
132 return (1);
133 }
134
135 if (pkey_ctrl_string(*genpkey_config.ctx, arg) <= 0) {
136 BIO_puts(bio_err, "parameter setting error\n");
137 ERR_print_errors(bio_err);
138 return (1);
139 }
140
141 return (0);
142}
143
144struct option genpkey_options[] = {
145 {
146 .name = "algorithm",
147 .argname = "name",
148 .desc = "Public key algorithm to use (must precede -pkeyopt)",
149 .type = OPTION_ARG_FUNC,
150 .opt.argfunc = genpkey_opt_algorithm,
151 },
152 {
153 .name = "genparam",
154 .desc = "Generate a set of parameters instead of a private key",
155 .type = OPTION_FLAG,
156 .opt.flag = &genpkey_config.do_param,
157 },
158 {
159 .name = "out",
160 .argname = "file",
161 .desc = "Output file to write to (default stdout)",
162 .type = OPTION_ARG,
163 .opt.arg = &genpkey_config.outfile,
164 },
165 {
166 .name = "outform",
167 .argname = "format",
168 .desc = "Output format (DER or PEM)",
169 .type = OPTION_ARG_FORMAT,
170 .opt.value = &genpkey_config.outformat,
171 },
172 {
173 .name = "paramfile",
174 .argname = "file",
175 .desc = "File to load public key algorithm parameters from\n"
176 "(must precede -pkeyopt)",
177 .type = OPTION_ARG_FUNC,
178 .opt.argfunc = genpkey_opt_paramfile,
179 },
180 {
181 .name = "pass",
182 .argname = "arg",
183 .desc = "Output file password source",
184 .type = OPTION_ARG,
185 .opt.arg = &genpkey_config.passarg,
186 },
187 {
188 .name = "pkeyopt",
189 .argname = "opt:value",
190 .desc = "Set public key algorithm option to the given value",
191 .type = OPTION_ARG_FUNC,
192 .opt.argfunc = genpkey_opt_pkeyopt,
193 },
194 {
195 .name = "text",
196 .desc = "Print the private/public key in human readable form",
197 .type = OPTION_FLAG,
198 .opt.flag = &genpkey_config.text,
199 },
200 {
201 .name = NULL,
202 .type = OPTION_ARGV_FUNC,
203 .opt.argvfunc = genpkey_opt_cipher,
204 },
205 {NULL},
206};
207
208static void
209genpkey_usage()
210{
211 fprintf(stderr,
212 "usage: genpkey [-algorithm alg] [cipher] [-genparam] [-out file]\n"
213 " [-outform der | pem] [-paramfile file] [-pass arg]\n"
214 " [-pkeyopt opt:value] [-text]\n\n");
215 options_usage(genpkey_options);
216}
217
72int 218int
73genpkey_main(int argc, char **argv) 219genpkey_main(int argc, char **argv)
74{ 220{
75 char **args, *outfile = NULL;
76 char *passarg = NULL;
77 BIO *in = NULL, *out = NULL; 221 BIO *in = NULL, *out = NULL;
78 const EVP_CIPHER *cipher = NULL;
79 int outformat;
80 int text = 0;
81 EVP_PKEY *pkey = NULL;
82 EVP_PKEY_CTX *ctx = NULL; 222 EVP_PKEY_CTX *ctx = NULL;
223 EVP_PKEY *pkey = NULL;
83 char *pass = NULL; 224 char *pass = NULL;
84 int badarg = 0;
85 int ret = 1, rv; 225 int ret = 1, rv;
86 226
87 int do_param = 0;
88
89 if (single_execution) { 227 if (single_execution) {
90 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 228 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
91 perror("pledge"); 229 perror("pledge");
@@ -93,98 +231,29 @@ genpkey_main(int argc, char **argv)
93 } 231 }
94 } 232 }
95 233
96 outformat = FORMAT_PEM; 234 memset(&genpkey_config, 0, sizeof(genpkey_config));
97 235 genpkey_config.ctx = &ctx;
98 args = argv + 1; 236 genpkey_config.outformat = FORMAT_PEM;
99 while (!badarg && *args && *args[0] == '-') { 237
100 if (!strcmp(*args, "-outform")) { 238 if (options_parse(argc, argv, genpkey_options, NULL, NULL) != 0) {
101 if (args[1]) { 239 genpkey_usage();
102 args++; 240 goto end;
103 outformat = str2fmt(*args);
104 } else
105 badarg = 1;
106 } else if (!strcmp(*args, "-pass")) {
107 if (!args[1])
108 goto bad;
109 passarg = *(++args);
110 }
111 else if (!strcmp(*args, "-paramfile")) {
112 if (!args[1])
113 goto bad;
114 args++;
115 if (do_param == 1)
116 goto bad;
117 if (!init_keygen_file(bio_err, &ctx, *args))
118 goto end;
119 } else if (!strcmp(*args, "-out")) {
120 if (args[1]) {
121 args++;
122 outfile = *args;
123 } else
124 badarg = 1;
125 } else if (strcmp(*args, "-algorithm") == 0) {
126 if (!args[1])
127 goto bad;
128 if (!init_gen_str(bio_err, &ctx, *(++args), do_param))
129 goto end;
130 } else if (strcmp(*args, "-pkeyopt") == 0) {
131 if (!args[1])
132 goto bad;
133 if (!ctx) {
134 BIO_puts(bio_err, "No keytype specified\n");
135 goto bad;
136 } else if (pkey_ctrl_string(ctx, *(++args)) <= 0) {
137 BIO_puts(bio_err, "parameter setting error\n");
138 ERR_print_errors(bio_err);
139 goto end;
140 }
141 } else if (strcmp(*args, "-genparam") == 0) {
142 if (ctx)
143 goto bad;
144 do_param = 1;
145 } else if (strcmp(*args, "-text") == 0)
146 text = 1;
147 else {
148 cipher = EVP_get_cipherbyname(*args + 1);
149 if (!cipher) {
150 BIO_printf(bio_err, "Unknown cipher %s\n",
151 *args + 1);
152 badarg = 1;
153 }
154 if (do_param == 1)
155 badarg = 1;
156 }
157 args++;
158 } 241 }
159 242
160 if (!ctx) 243 if (ctx == NULL) {
161 badarg = 1; 244 genpkey_usage();
162
163 if (badarg) {
164 bad:
165 BIO_printf(bio_err, "Usage: genpkey [options]\n");
166 BIO_printf(bio_err, "where options may be\n");
167 BIO_printf(bio_err, "-out file output file\n");
168 BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
169 BIO_printf(bio_err, "-pass arg output file pass phrase source\n");
170 BIO_printf(bio_err, "-<cipher> use cipher <cipher> to encrypt the key\n");
171 BIO_printf(bio_err, "-paramfile file parameters file\n");
172 BIO_printf(bio_err, "-algorithm alg the public key algorithm\n");
173 BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n"
174 " to value <value>\n");
175 BIO_printf(bio_err, "-genparam generate parameters, not key\n");
176 BIO_printf(bio_err, "-text print the in text\n");
177 BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n");
178 goto end; 245 goto end;
179 } 246 }
180 if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { 247
248 if (!app_passwd(bio_err, genpkey_config.passarg, NULL, &pass, NULL)) {
181 BIO_puts(bio_err, "Error getting password\n"); 249 BIO_puts(bio_err, "Error getting password\n");
182 goto end; 250 goto end;
183 } 251 }
184 if (outfile) { 252 if (genpkey_config.outfile != NULL) {
185 if (!(out = BIO_new_file(outfile, "wb"))) { 253 if ((out = BIO_new_file(genpkey_config.outfile, "wb")) ==
186 BIO_printf(bio_err, 254 NULL) {
187 "Can't open output file %s\n", outfile); 255 BIO_printf(bio_err, "Can't open output file %s\n",
256 genpkey_config.outfile);
188 goto end; 257 goto end;
189 } 258 }
190 } else { 259 } else {
@@ -194,7 +263,7 @@ genpkey_main(int argc, char **argv)
194 EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); 263 EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
195 EVP_PKEY_CTX_set_app_data(ctx, bio_err); 264 EVP_PKEY_CTX_set_app_data(ctx, bio_err);
196 265
197 if (do_param) { 266 if (genpkey_config.do_param) {
198 if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) { 267 if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) {
199 BIO_puts(bio_err, "Error generating parameters\n"); 268 BIO_puts(bio_err, "Error generating parameters\n");
200 ERR_print_errors(bio_err); 269 ERR_print_errors(bio_err);
@@ -208,12 +277,12 @@ genpkey_main(int argc, char **argv)
208 } 277 }
209 } 278 }
210 279
211 if (do_param) 280 if (genpkey_config.do_param)
212 rv = PEM_write_bio_Parameters(out, pkey); 281 rv = PEM_write_bio_Parameters(out, pkey);
213 else if (outformat == FORMAT_PEM) 282 else if (genpkey_config.outformat == FORMAT_PEM)
214 rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, 283 rv = PEM_write_bio_PrivateKey(out, pkey, genpkey_config.cipher,
215 NULL, pass); 284 NULL, 0, NULL, pass);
216 else if (outformat == FORMAT_ASN1) 285 else if (genpkey_config.outformat == FORMAT_ASN1)
217 rv = i2d_PrivateKey_bio(out, pkey); 286 rv = i2d_PrivateKey_bio(out, pkey);
218 else { 287 else {
219 BIO_printf(bio_err, "Bad format specified for key\n"); 288 BIO_printf(bio_err, "Bad format specified for key\n");
@@ -224,8 +293,8 @@ genpkey_main(int argc, char **argv)
224 BIO_puts(bio_err, "Error writing key\n"); 293 BIO_puts(bio_err, "Error writing key\n");
225 ERR_print_errors(bio_err); 294 ERR_print_errors(bio_err);
226 } 295 }
227 if (text) { 296 if (genpkey_config.text) {
228 if (do_param) 297 if (genpkey_config.do_param)
229 rv = EVP_PKEY_print_params(out, pkey, 0, NULL); 298 rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
230 else 299 else
231 rv = EVP_PKEY_print_private(out, pkey, 0, NULL); 300 rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
@@ -248,8 +317,7 @@ genpkey_main(int argc, char **argv)
248} 317}
249 318
250static int 319static int
251init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, 320init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, const char *file)
252 const char *file)
253{ 321{
254 BIO *pbio; 322 BIO *pbio;
255 EVP_PKEY *pkey = NULL; 323 EVP_PKEY *pkey = NULL;
@@ -289,11 +357,10 @@ init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx,
289} 357}
290 358
291int 359int
292init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx, 360init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx, const char *algname, int do_param)
293 const char *algname, int do_param)
294{ 361{
295 EVP_PKEY_CTX *ctx = NULL;
296 const EVP_PKEY_ASN1_METHOD *ameth; 362 const EVP_PKEY_ASN1_METHOD *ameth;
363 EVP_PKEY_CTX *ctx = NULL;
297 int pkey_id; 364 int pkey_id;
298 365
299 if (*pctx) { 366 if (*pctx) {