diff options
| author | jsing <> | 2018-02-08 11:17:44 +0000 |
|---|---|---|
| committer | jsing <> | 2018-02-08 11:17:44 +0000 |
| commit | 65ab7356a60597cf0c63882b8ed825bef112e719 (patch) | |
| tree | 9b6b7eb8537d700c9622b9f248ac5a4b7f2392ad /src | |
| parent | 1cdf8604761b93152a016438e63c11510e6d35bf (diff) | |
| download | openbsd-65ab7356a60597cf0c63882b8ed825bef112e719.tar.gz openbsd-65ab7356a60597cf0c63882b8ed825bef112e719.tar.bz2 openbsd-65ab7356a60597cf0c63882b8ed825bef112e719.zip | |
Convert option handling for openssl(1) genpkey.
ok beck@ inoguchi@
Diffstat (limited to '')
| -rw-r--r-- | src/usr.bin/openssl/genpkey.c | 287 |
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 | ||
| 68 | static int | 68 | static int init_keygen_file(BIO * err, EVP_PKEY_CTX **pctx, const char *file); |
| 69 | init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, const char *file); | ||
| 70 | static int genpkey_cb(EVP_PKEY_CTX * ctx); | 69 | static int genpkey_cb(EVP_PKEY_CTX * ctx); |
| 71 | 70 | ||
| 71 | struct { | ||
| 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 | |||
| 81 | static int | ||
| 82 | genpkey_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 | |||
| 91 | static int | ||
| 92 | genpkey_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 | |||
| 116 | static int | ||
| 117 | genpkey_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 | |||
| 127 | static int | ||
| 128 | genpkey_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 | |||
| 144 | struct 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 | |||
| 208 | static void | ||
| 209 | genpkey_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 | |||
| 72 | int | 218 | int |
| 73 | genpkey_main(int argc, char **argv) | 219 | genpkey_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 | ||
| 250 | static int | 319 | static int |
| 251 | init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, | 320 | init_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 | ||
| 291 | int | 359 | int |
| 292 | init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx, | 360 | init_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) { |
