diff options
author | inoguchi <> | 2019-02-17 15:01:08 +0000 |
---|---|---|
committer | inoguchi <> | 2019-02-17 15:01:08 +0000 |
commit | ee56f9d53d1b66936b9bda4bb0fc94e85370e540 (patch) | |
tree | c8631d6d3a0a500e27f49d9383b2aa1d5c944fc3 | |
parent | bdfe3c2f539bff3f9588062bc5ba83760a8025d8 (diff) | |
download | openbsd-ee56f9d53d1b66936b9bda4bb0fc94e85370e540.tar.gz openbsd-ee56f9d53d1b66936b9bda4bb0fc94e85370e540.tar.bz2 openbsd-ee56f9d53d1b66936b9bda4bb0fc94e85370e540.zip |
Convert openssl(1) pkeyutl to the newer style of option handling.
ok jsing@ tb@
-rw-r--r-- | src/usr.bin/openssl/pkeyutl.c | 476 |
1 files changed, 278 insertions, 198 deletions
diff --git a/src/usr.bin/openssl/pkeyutl.c b/src/usr.bin/openssl/pkeyutl.c index 87a9eeb6f5..b0800181b0 100644 --- a/src/usr.bin/openssl/pkeyutl.c +++ b/src/usr.bin/openssl/pkeyutl.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: pkeyutl.c,v 1.14 2018/02/07 05:47:55 jsing Exp $ */ | 1 | /* $OpenBSD: pkeyutl.c,v 1.15 2019/02/17 15:01:08 inoguchi 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 | */ |
@@ -68,31 +68,194 @@ | |||
68 | #define KEY_PUBKEY 2 | 68 | #define KEY_PUBKEY 2 |
69 | #define KEY_CERT 3 | 69 | #define KEY_CERT 3 |
70 | 70 | ||
71 | static void usage(void); | 71 | struct { |
72 | int asn1parse; | ||
73 | EVP_PKEY_CTX *ctx; | ||
74 | int hexdump; | ||
75 | char *infile; | ||
76 | int key_type; | ||
77 | int keyform; | ||
78 | int keysize; | ||
79 | char *outfile; | ||
80 | char *passargin; | ||
81 | int peerform; | ||
82 | int pkey_op; | ||
83 | int rev; | ||
84 | char *sigfile; | ||
85 | } pkeyutl_config; | ||
72 | 86 | ||
73 | static EVP_PKEY_CTX *init_ctx(int *pkeysize, | 87 | static void pkeyutl_usage(void); |
74 | char *keyfile, int keyform, int key_type, | ||
75 | char *passargin, int pkey_op); | ||
76 | 88 | ||
77 | static int setup_peer(BIO * err, EVP_PKEY_CTX * ctx, int peerform, | 89 | static int init_ctx(char *keyfile); |
78 | const char *file); | 90 | |
91 | static int setup_peer(char *file); | ||
92 | |||
93 | static int pkeyutl_pkeyopt(char *pkeyopt); | ||
79 | 94 | ||
80 | static int do_keyop(EVP_PKEY_CTX * ctx, int pkey_op, | 95 | static int do_keyop(EVP_PKEY_CTX * ctx, int pkey_op, |
81 | unsigned char *out, size_t * poutlen, | 96 | unsigned char *out, size_t * poutlen, |
82 | unsigned char *in, size_t inlen); | 97 | unsigned char *in, size_t inlen); |
83 | 98 | ||
99 | struct option pkeyutl_options[] = { | ||
100 | { | ||
101 | .name = "asn1parse", | ||
102 | .desc = "ASN.1 parse the output data", | ||
103 | .type = OPTION_FLAG, | ||
104 | .opt.flag = &pkeyutl_config.asn1parse, | ||
105 | }, | ||
106 | { | ||
107 | .name = "certin", | ||
108 | .desc = "Input is a certificate containing a public key", | ||
109 | .type = OPTION_VALUE, | ||
110 | .value = KEY_CERT, | ||
111 | .opt.value = &pkeyutl_config.key_type, | ||
112 | }, | ||
113 | { | ||
114 | .name = "decrypt", | ||
115 | .desc = "Decrypt the input data using a private key", | ||
116 | .type = OPTION_VALUE, | ||
117 | .value = EVP_PKEY_OP_DECRYPT, | ||
118 | .opt.value = &pkeyutl_config.pkey_op, | ||
119 | }, | ||
120 | { | ||
121 | .name = "derive", | ||
122 | .desc = "Derive a shared secret using the peer key", | ||
123 | .type = OPTION_VALUE, | ||
124 | .value = EVP_PKEY_OP_DERIVE, | ||
125 | .opt.value = &pkeyutl_config.pkey_op, | ||
126 | }, | ||
127 | { | ||
128 | .name = "encrypt", | ||
129 | .desc = "Encrypt the input data using a public key", | ||
130 | .type = OPTION_VALUE, | ||
131 | .value = EVP_PKEY_OP_ENCRYPT, | ||
132 | .opt.value = &pkeyutl_config.pkey_op, | ||
133 | }, | ||
134 | { | ||
135 | .name = "hexdump", | ||
136 | .desc = "Hex dump the output data", | ||
137 | .type = OPTION_FLAG, | ||
138 | .opt.flag = &pkeyutl_config.hexdump, | ||
139 | }, | ||
140 | { | ||
141 | .name = "in", | ||
142 | .argname = "file", | ||
143 | .desc = "Input file (default stdin)", | ||
144 | .type = OPTION_ARG, | ||
145 | .opt.arg = &pkeyutl_config.infile, | ||
146 | }, | ||
147 | { | ||
148 | .name = "inkey", | ||
149 | .argname = "file", | ||
150 | .desc = "Input key file", | ||
151 | .type = OPTION_ARG_FUNC, | ||
152 | .opt.argfunc = init_ctx, | ||
153 | }, | ||
154 | { | ||
155 | .name = "keyform", | ||
156 | .argname = "fmt", | ||
157 | .desc = "Input key format (DER or PEM (default))", | ||
158 | .type = OPTION_ARG_FORMAT, | ||
159 | .opt.value = &pkeyutl_config.keyform, | ||
160 | }, | ||
161 | { | ||
162 | .name = "out", | ||
163 | .argname = "file", | ||
164 | .desc = "Output file (default stdout)", | ||
165 | .type = OPTION_ARG, | ||
166 | .opt.arg = &pkeyutl_config.outfile, | ||
167 | }, | ||
168 | { | ||
169 | .name = "passin", | ||
170 | .argname = "arg", | ||
171 | .desc = "Key password source", | ||
172 | .type = OPTION_ARG, | ||
173 | .opt.arg = &pkeyutl_config.passargin, | ||
174 | }, | ||
175 | { | ||
176 | .name = "peerform", | ||
177 | .argname = "fmt", | ||
178 | .desc = "Input key format (DER or PEM (default))", | ||
179 | .type = OPTION_ARG_FORMAT, | ||
180 | .opt.value = &pkeyutl_config.peerform, | ||
181 | }, | ||
182 | { | ||
183 | .name = "peerkey", | ||
184 | .argname = "file", | ||
185 | .desc = "Peer key file", | ||
186 | .type = OPTION_ARG_FUNC, | ||
187 | .opt.argfunc = setup_peer, | ||
188 | }, | ||
189 | { | ||
190 | .name = "pkeyopt", | ||
191 | .argname = "opt:value", | ||
192 | .desc = "Public key options", | ||
193 | .type = OPTION_ARG_FUNC, | ||
194 | .opt.argfunc = pkeyutl_pkeyopt, | ||
195 | }, | ||
196 | { | ||
197 | .name = "pubin", | ||
198 | .desc = "Input is a public key", | ||
199 | .type = OPTION_VALUE, | ||
200 | .value = KEY_PUBKEY, | ||
201 | .opt.value = &pkeyutl_config.key_type, | ||
202 | }, | ||
203 | { | ||
204 | .name = "rev", | ||
205 | .desc = "Reverse the input data", | ||
206 | .type = OPTION_FLAG, | ||
207 | .opt.flag = &pkeyutl_config.rev, | ||
208 | }, | ||
209 | { | ||
210 | .name = "sigfile", | ||
211 | .argname = "file", | ||
212 | .desc = "Signature file (verify operation only)", | ||
213 | .type = OPTION_ARG, | ||
214 | .opt.arg = &pkeyutl_config.sigfile, | ||
215 | }, | ||
216 | { | ||
217 | .name = "sign", | ||
218 | .desc = "Sign the input data using private key", | ||
219 | .type = OPTION_VALUE, | ||
220 | .value = EVP_PKEY_OP_SIGN, | ||
221 | .opt.value = &pkeyutl_config.pkey_op, | ||
222 | }, | ||
223 | { | ||
224 | .name = "verify", | ||
225 | .desc = "Verify the input data using public key", | ||
226 | .type = OPTION_VALUE, | ||
227 | .value = EVP_PKEY_OP_VERIFY, | ||
228 | .opt.value = &pkeyutl_config.pkey_op, | ||
229 | }, | ||
230 | { | ||
231 | .name = "verifyrecover", | ||
232 | .desc = "Verify with public key, recover original data", | ||
233 | .type = OPTION_VALUE, | ||
234 | .value = EVP_PKEY_OP_VERIFYRECOVER, | ||
235 | .opt.value = &pkeyutl_config.pkey_op, | ||
236 | }, | ||
237 | |||
238 | {NULL}, | ||
239 | }; | ||
240 | |||
241 | static void | ||
242 | pkeyutl_usage() | ||
243 | { | ||
244 | fprintf(stderr, | ||
245 | "usage: pkeyutl [-asn1parse] [-certin] [-decrypt] [-derive] " | ||
246 | "[-encrypt]\n" | ||
247 | " [-hexdump] [-in file] [-inkey file] [-keyform fmt]\n" | ||
248 | " [-out file] [-passin arg] [-peerform fmt]\n" | ||
249 | " [-peerkey file] [-pkeyopt opt:value] [-pubin] [-rev]\n" | ||
250 | " [-sigfile file] [-sign] [-verify] [-verifyrecover]\n\n"); | ||
251 | options_usage(pkeyutl_options); | ||
252 | fprintf(stderr, "\n"); | ||
253 | } | ||
254 | |||
84 | int | 255 | int |
85 | pkeyutl_main(int argc, char **argv) | 256 | pkeyutl_main(int argc, char **argv) |
86 | { | 257 | { |
87 | BIO *in = NULL, *out = NULL; | 258 | BIO *in = NULL, *out = NULL; |
88 | char *infile = NULL, *outfile = NULL, *sigfile = NULL; | ||
89 | int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; | ||
90 | int keyform = FORMAT_PEM, peerform = FORMAT_PEM; | ||
91 | char badarg = 0, rev = 0; | ||
92 | char hexdump = 0, asn1parse = 0; | ||
93 | EVP_PKEY_CTX *ctx = NULL; | ||
94 | char *passargin = NULL; | ||
95 | int keysize = -1; | ||
96 | 259 | ||
97 | unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; | 260 | unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; |
98 | size_t buf_outlen = 0; | 261 | size_t buf_outlen = 0; |
@@ -107,120 +270,36 @@ pkeyutl_main(int argc, char **argv) | |||
107 | } | 270 | } |
108 | } | 271 | } |
109 | 272 | ||
110 | argc--; | 273 | memset(&pkeyutl_config, 0, sizeof(pkeyutl_config)); |
111 | argv++; | 274 | pkeyutl_config.pkey_op = EVP_PKEY_OP_SIGN; |
275 | pkeyutl_config.key_type = KEY_PRIVKEY; | ||
276 | pkeyutl_config.keyform = FORMAT_PEM; | ||
277 | pkeyutl_config.peerform = FORMAT_PEM; | ||
278 | pkeyutl_config.keysize = -1; | ||
112 | 279 | ||
113 | while (argc >= 1) { | 280 | if (options_parse(argc, argv, pkeyutl_options, NULL, NULL) != 0) { |
114 | if (!strcmp(*argv, "-in")) { | 281 | pkeyutl_usage(); |
115 | if (--argc < 1) | 282 | goto end; |
116 | badarg = 1; | ||
117 | else | ||
118 | infile = *(++argv); | ||
119 | } else if (!strcmp(*argv, "-out")) { | ||
120 | if (--argc < 1) | ||
121 | badarg = 1; | ||
122 | else | ||
123 | outfile = *(++argv); | ||
124 | } else if (!strcmp(*argv, "-sigfile")) { | ||
125 | if (--argc < 1) | ||
126 | badarg = 1; | ||
127 | else | ||
128 | sigfile = *(++argv); | ||
129 | } else if (!strcmp(*argv, "-inkey")) { | ||
130 | if (--argc < 1) | ||
131 | badarg = 1; | ||
132 | else { | ||
133 | ctx = init_ctx(&keysize, | ||
134 | *(++argv), keyform, key_type, | ||
135 | passargin, pkey_op); | ||
136 | if (!ctx) { | ||
137 | BIO_puts(bio_err, | ||
138 | "Error initializing context\n"); | ||
139 | ERR_print_errors(bio_err); | ||
140 | badarg = 1; | ||
141 | } | ||
142 | } | ||
143 | } else if (!strcmp(*argv, "-peerkey")) { | ||
144 | if (--argc < 1) | ||
145 | badarg = 1; | ||
146 | else if (!setup_peer(bio_err, ctx, peerform, *(++argv))) | ||
147 | badarg = 1; | ||
148 | } else if (!strcmp(*argv, "-passin")) { | ||
149 | if (--argc < 1) | ||
150 | badarg = 1; | ||
151 | else | ||
152 | passargin = *(++argv); | ||
153 | } else if (strcmp(*argv, "-peerform") == 0) { | ||
154 | if (--argc < 1) | ||
155 | badarg = 1; | ||
156 | else | ||
157 | peerform = str2fmt(*(++argv)); | ||
158 | } else if (strcmp(*argv, "-keyform") == 0) { | ||
159 | if (--argc < 1) | ||
160 | badarg = 1; | ||
161 | else | ||
162 | keyform = str2fmt(*(++argv)); | ||
163 | } | ||
164 | else if (!strcmp(*argv, "-pubin")) | ||
165 | key_type = KEY_PUBKEY; | ||
166 | else if (!strcmp(*argv, "-certin")) | ||
167 | key_type = KEY_CERT; | ||
168 | else if (!strcmp(*argv, "-asn1parse")) | ||
169 | asn1parse = 1; | ||
170 | else if (!strcmp(*argv, "-hexdump")) | ||
171 | hexdump = 1; | ||
172 | else if (!strcmp(*argv, "-sign")) | ||
173 | pkey_op = EVP_PKEY_OP_SIGN; | ||
174 | else if (!strcmp(*argv, "-verify")) | ||
175 | pkey_op = EVP_PKEY_OP_VERIFY; | ||
176 | else if (!strcmp(*argv, "-verifyrecover")) | ||
177 | pkey_op = EVP_PKEY_OP_VERIFYRECOVER; | ||
178 | else if (!strcmp(*argv, "-rev")) | ||
179 | rev = 1; | ||
180 | else if (!strcmp(*argv, "-encrypt")) | ||
181 | pkey_op = EVP_PKEY_OP_ENCRYPT; | ||
182 | else if (!strcmp(*argv, "-decrypt")) | ||
183 | pkey_op = EVP_PKEY_OP_DECRYPT; | ||
184 | else if (!strcmp(*argv, "-derive")) | ||
185 | pkey_op = EVP_PKEY_OP_DERIVE; | ||
186 | else if (strcmp(*argv, "-pkeyopt") == 0) { | ||
187 | if (--argc < 1) | ||
188 | badarg = 1; | ||
189 | else if (!ctx) { | ||
190 | BIO_puts(bio_err, | ||
191 | "-pkeyopt command before -inkey\n"); | ||
192 | badarg = 1; | ||
193 | } else if (pkey_ctrl_string(ctx, *(++argv)) <= 0) { | ||
194 | BIO_puts(bio_err, "parameter setting error\n"); | ||
195 | ERR_print_errors(bio_err); | ||
196 | goto end; | ||
197 | } | ||
198 | } else | ||
199 | badarg = 1; | ||
200 | if (badarg) { | ||
201 | usage(); | ||
202 | goto end; | ||
203 | } | ||
204 | argc--; | ||
205 | argv++; | ||
206 | } | 283 | } |
207 | 284 | ||
208 | if (!ctx) { | 285 | if (!pkeyutl_config.ctx) { |
209 | usage(); | 286 | pkeyutl_usage(); |
210 | goto end; | 287 | goto end; |
211 | } | 288 | } |
212 | if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) { | 289 | if (pkeyutl_config.sigfile && |
290 | (pkeyutl_config.pkey_op != EVP_PKEY_OP_VERIFY)) { | ||
213 | BIO_puts(bio_err, "Signature file specified for non verify\n"); | 291 | BIO_puts(bio_err, "Signature file specified for non verify\n"); |
214 | goto end; | 292 | goto end; |
215 | } | 293 | } |
216 | if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) { | 294 | if (!pkeyutl_config.sigfile && |
295 | (pkeyutl_config.pkey_op == EVP_PKEY_OP_VERIFY)) { | ||
217 | BIO_puts(bio_err, "No signature file specified for verify\n"); | 296 | BIO_puts(bio_err, "No signature file specified for verify\n"); |
218 | goto end; | 297 | goto end; |
219 | } | 298 | } |
220 | 299 | ||
221 | if (pkey_op != EVP_PKEY_OP_DERIVE) { | 300 | if (pkeyutl_config.pkey_op != EVP_PKEY_OP_DERIVE) { |
222 | if (infile) { | 301 | if (pkeyutl_config.infile) { |
223 | if (!(in = BIO_new_file(infile, "rb"))) { | 302 | if (!(in = BIO_new_file(pkeyutl_config.infile, "rb"))) { |
224 | BIO_puts(bio_err, | 303 | BIO_puts(bio_err, |
225 | "Error Opening Input File\n"); | 304 | "Error Opening Input File\n"); |
226 | ERR_print_errors(bio_err); | 305 | ERR_print_errors(bio_err); |
@@ -229,8 +308,8 @@ pkeyutl_main(int argc, char **argv) | |||
229 | } else | 308 | } else |
230 | in = BIO_new_fp(stdin, BIO_NOCLOSE); | 309 | in = BIO_new_fp(stdin, BIO_NOCLOSE); |
231 | } | 310 | } |
232 | if (outfile) { | 311 | if (pkeyutl_config.outfile) { |
233 | if (!(out = BIO_new_file(outfile, "wb"))) { | 312 | if (!(out = BIO_new_file(pkeyutl_config.outfile, "wb"))) { |
234 | BIO_printf(bio_err, "Error Creating Output File\n"); | 313 | BIO_printf(bio_err, "Error Creating Output File\n"); |
235 | ERR_print_errors(bio_err); | 314 | ERR_print_errors(bio_err); |
236 | goto end; | 315 | goto end; |
@@ -239,14 +318,14 @@ pkeyutl_main(int argc, char **argv) | |||
239 | out = BIO_new_fp(stdout, BIO_NOCLOSE); | 318 | out = BIO_new_fp(stdout, BIO_NOCLOSE); |
240 | } | 319 | } |
241 | 320 | ||
242 | if (sigfile) { | 321 | if (pkeyutl_config.sigfile) { |
243 | BIO *sigbio = BIO_new_file(sigfile, "rb"); | 322 | BIO *sigbio = BIO_new_file(pkeyutl_config.sigfile, "rb"); |
244 | if (!sigbio) { | 323 | if (!sigbio) { |
245 | BIO_printf(bio_err, "Can't open signature file %s\n", | 324 | BIO_printf(bio_err, "Can't open signature file %s\n", |
246 | sigfile); | 325 | pkeyutl_config.sigfile); |
247 | goto end; | 326 | goto end; |
248 | } | 327 | } |
249 | siglen = bio_to_mem(&sig, keysize * 10, sigbio); | 328 | siglen = bio_to_mem(&sig, pkeyutl_config.keysize * 10, sigbio); |
250 | BIO_free(sigbio); | 329 | BIO_free(sigbio); |
251 | if (siglen <= 0) { | 330 | if (siglen <= 0) { |
252 | BIO_printf(bio_err, "Error reading signature data\n"); | 331 | BIO_printf(bio_err, "Error reading signature data\n"); |
@@ -255,12 +334,12 @@ pkeyutl_main(int argc, char **argv) | |||
255 | } | 334 | } |
256 | if (in) { | 335 | if (in) { |
257 | /* Read the input data */ | 336 | /* Read the input data */ |
258 | buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); | 337 | buf_inlen = bio_to_mem(&buf_in, pkeyutl_config.keysize * 10, in); |
259 | if (buf_inlen <= 0) { | 338 | if (buf_inlen <= 0) { |
260 | BIO_printf(bio_err, "Error reading input Data\n"); | 339 | BIO_printf(bio_err, "Error reading input Data\n"); |
261 | exit(1); | 340 | exit(1); |
262 | } | 341 | } |
263 | if (rev) { | 342 | if (pkeyutl_config.rev) { |
264 | size_t i; | 343 | size_t i; |
265 | unsigned char ctmp; | 344 | unsigned char ctmp; |
266 | size_t l = (size_t) buf_inlen; | 345 | size_t l = (size_t) buf_inlen; |
@@ -271,8 +350,8 @@ pkeyutl_main(int argc, char **argv) | |||
271 | } | 350 | } |
272 | } | 351 | } |
273 | } | 352 | } |
274 | if (pkey_op == EVP_PKEY_OP_VERIFY) { | 353 | if (pkeyutl_config.pkey_op == EVP_PKEY_OP_VERIFY) { |
275 | rv = EVP_PKEY_verify(ctx, sig, (size_t) siglen, | 354 | rv = EVP_PKEY_verify(pkeyutl_config.ctx, sig, (size_t) siglen, |
276 | buf_in, (size_t) buf_inlen); | 355 | buf_in, (size_t) buf_inlen); |
277 | if (rv == 1) { | 356 | if (rv == 1) { |
278 | BIO_puts(out, "Signature Verified Successfully\n"); | 357 | BIO_puts(out, "Signature Verified Successfully\n"); |
@@ -282,14 +361,15 @@ pkeyutl_main(int argc, char **argv) | |||
282 | if (rv >= 0) | 361 | if (rv >= 0) |
283 | goto end; | 362 | goto end; |
284 | } else { | 363 | } else { |
285 | rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, | 364 | rv = do_keyop(pkeyutl_config.ctx, pkeyutl_config.pkey_op, NULL, |
286 | buf_in, (size_t) buf_inlen); | 365 | (size_t *)&buf_outlen, buf_in, (size_t) buf_inlen); |
287 | if (rv > 0) { | 366 | if (rv > 0) { |
288 | buf_out = malloc(buf_outlen); | 367 | buf_out = malloc(buf_outlen); |
289 | if (!buf_out) | 368 | if (!buf_out) |
290 | rv = -1; | 369 | rv = -1; |
291 | else | 370 | else |
292 | rv = do_keyop(ctx, pkey_op, | 371 | rv = do_keyop(pkeyutl_config.ctx, |
372 | pkeyutl_config.pkey_op, | ||
293 | buf_out, (size_t *) & buf_outlen, | 373 | buf_out, (size_t *) & buf_outlen, |
294 | buf_in, (size_t) buf_inlen); | 374 | buf_in, (size_t) buf_inlen); |
295 | } | 375 | } |
@@ -301,16 +381,16 @@ pkeyutl_main(int argc, char **argv) | |||
301 | goto end; | 381 | goto end; |
302 | } | 382 | } |
303 | ret = 0; | 383 | ret = 0; |
304 | if (asn1parse) { | 384 | if (pkeyutl_config.asn1parse) { |
305 | if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) | 385 | if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) |
306 | ERR_print_errors(bio_err); | 386 | ERR_print_errors(bio_err); |
307 | } else if (hexdump) | 387 | } else if (pkeyutl_config.hexdump) |
308 | BIO_dump(out, (char *) buf_out, buf_outlen); | 388 | BIO_dump(out, (char *) buf_out, buf_outlen); |
309 | else | 389 | else |
310 | BIO_write(out, buf_out, buf_outlen); | 390 | BIO_write(out, buf_out, buf_outlen); |
311 | 391 | ||
312 | end: | 392 | end: |
313 | EVP_PKEY_CTX_free(ctx); | 393 | EVP_PKEY_CTX_free(pkeyutl_config.ctx); |
314 | BIO_free(in); | 394 | BIO_free(in); |
315 | BIO_free_all(out); | 395 | BIO_free_all(out); |
316 | free(buf_in); | 396 | free(buf_in); |
@@ -320,145 +400,145 @@ pkeyutl_main(int argc, char **argv) | |||
320 | return ret; | 400 | return ret; |
321 | } | 401 | } |
322 | 402 | ||
323 | static void | 403 | static int |
324 | usage() | 404 | init_ctx(char *keyfile) |
325 | { | ||
326 | BIO_printf(bio_err, "Usage: pkeyutl [options]\n"); | ||
327 | BIO_printf(bio_err, "-in file input file\n"); | ||
328 | BIO_printf(bio_err, "-out file output file\n"); | ||
329 | BIO_printf(bio_err, "-sigfile file signature file (verify operation only)\n"); | ||
330 | BIO_printf(bio_err, "-inkey file input key\n"); | ||
331 | BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); | ||
332 | BIO_printf(bio_err, "-pubin input is a public key\n"); | ||
333 | BIO_printf(bio_err, "-certin input is a certificate carrying a public key\n"); | ||
334 | BIO_printf(bio_err, "-pkeyopt X:Y public key options\n"); | ||
335 | BIO_printf(bio_err, "-sign sign with private key\n"); | ||
336 | BIO_printf(bio_err, "-verify verify with public key\n"); | ||
337 | BIO_printf(bio_err, "-verifyrecover verify with public key, recover original data\n"); | ||
338 | BIO_printf(bio_err, "-encrypt encrypt with public key\n"); | ||
339 | BIO_printf(bio_err, "-decrypt decrypt with private key\n"); | ||
340 | BIO_printf(bio_err, "-derive derive shared secret\n"); | ||
341 | BIO_printf(bio_err, "-hexdump hex dump output\n"); | ||
342 | BIO_printf(bio_err, "-passin arg pass phrase source\n"); | ||
343 | |||
344 | } | ||
345 | |||
346 | static EVP_PKEY_CTX * | ||
347 | init_ctx(int *pkeysize, | ||
348 | char *keyfile, int keyform, int key_type, | ||
349 | char *passargin, int pkey_op) | ||
350 | { | 405 | { |
351 | EVP_PKEY *pkey = NULL; | 406 | EVP_PKEY *pkey = NULL; |
352 | EVP_PKEY_CTX *ctx = NULL; | ||
353 | char *passin = NULL; | 407 | char *passin = NULL; |
354 | int rv = -1; | 408 | int rv = -1; |
355 | X509 *x; | 409 | X509 *x; |
356 | if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) | 410 | |
357 | || (pkey_op == EVP_PKEY_OP_DERIVE)) | 411 | if (((pkeyutl_config.pkey_op == EVP_PKEY_OP_SIGN) |
358 | && (key_type != KEY_PRIVKEY)) { | 412 | || (pkeyutl_config.pkey_op == EVP_PKEY_OP_DECRYPT) |
359 | BIO_printf(bio_err, "A private key is needed for this operation\n"); | 413 | || (pkeyutl_config.pkey_op == EVP_PKEY_OP_DERIVE)) |
414 | && (pkeyutl_config.key_type != KEY_PRIVKEY)) { | ||
415 | BIO_printf(bio_err, | ||
416 | "A private key is needed for this operation\n"); | ||
360 | goto end; | 417 | goto end; |
361 | } | 418 | } |
362 | if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { | 419 | if (!app_passwd(bio_err, pkeyutl_config.passargin, NULL, &passin, |
420 | NULL)) { | ||
363 | BIO_printf(bio_err, "Error getting password\n"); | 421 | BIO_printf(bio_err, "Error getting password\n"); |
364 | goto end; | 422 | goto end; |
365 | } | 423 | } |
366 | switch (key_type) { | 424 | switch (pkeyutl_config.key_type) { |
367 | case KEY_PRIVKEY: | 425 | case KEY_PRIVKEY: |
368 | pkey = load_key(bio_err, keyfile, keyform, 0, | 426 | pkey = load_key(bio_err, keyfile, pkeyutl_config.keyform, 0, |
369 | passin, "Private Key"); | 427 | passin, "Private Key"); |
370 | break; | 428 | break; |
371 | 429 | ||
372 | case KEY_PUBKEY: | 430 | case KEY_PUBKEY: |
373 | pkey = load_pubkey(bio_err, keyfile, keyform, 0, | 431 | pkey = load_pubkey(bio_err, keyfile, pkeyutl_config.keyform, 0, |
374 | NULL, "Public Key"); | 432 | NULL, "Public Key"); |
375 | break; | 433 | break; |
376 | 434 | ||
377 | case KEY_CERT: | 435 | case KEY_CERT: |
378 | x = load_cert(bio_err, keyfile, keyform, | 436 | x = load_cert(bio_err, keyfile, pkeyutl_config.keyform, |
379 | NULL, "Certificate"); | 437 | NULL, "Certificate"); |
380 | if (x) { | 438 | if (x) { |
381 | pkey = X509_get_pubkey(x); | 439 | pkey = X509_get_pubkey(x); |
382 | X509_free(x); | 440 | X509_free(x); |
383 | } | 441 | } |
384 | break; | 442 | break; |
385 | |||
386 | } | 443 | } |
387 | 444 | ||
388 | *pkeysize = EVP_PKEY_size(pkey); | 445 | pkeyutl_config.keysize = EVP_PKEY_size(pkey); |
389 | 446 | ||
390 | if (!pkey) | 447 | if (!pkey) |
391 | goto end; | 448 | goto end; |
392 | 449 | ||
393 | ctx = EVP_PKEY_CTX_new(pkey, NULL); | 450 | pkeyutl_config.ctx = EVP_PKEY_CTX_new(pkey, NULL); |
394 | 451 | ||
395 | EVP_PKEY_free(pkey); | 452 | EVP_PKEY_free(pkey); |
396 | 453 | ||
397 | if (!ctx) | 454 | if (!pkeyutl_config.ctx) |
398 | goto end; | 455 | goto end; |
399 | 456 | ||
400 | switch (pkey_op) { | 457 | switch (pkeyutl_config.pkey_op) { |
401 | case EVP_PKEY_OP_SIGN: | 458 | case EVP_PKEY_OP_SIGN: |
402 | rv = EVP_PKEY_sign_init(ctx); | 459 | rv = EVP_PKEY_sign_init(pkeyutl_config.ctx); |
403 | break; | 460 | break; |
404 | 461 | ||
405 | case EVP_PKEY_OP_VERIFY: | 462 | case EVP_PKEY_OP_VERIFY: |
406 | rv = EVP_PKEY_verify_init(ctx); | 463 | rv = EVP_PKEY_verify_init(pkeyutl_config.ctx); |
407 | break; | 464 | break; |
408 | 465 | ||
409 | case EVP_PKEY_OP_VERIFYRECOVER: | 466 | case EVP_PKEY_OP_VERIFYRECOVER: |
410 | rv = EVP_PKEY_verify_recover_init(ctx); | 467 | rv = EVP_PKEY_verify_recover_init(pkeyutl_config.ctx); |
411 | break; | 468 | break; |
412 | 469 | ||
413 | case EVP_PKEY_OP_ENCRYPT: | 470 | case EVP_PKEY_OP_ENCRYPT: |
414 | rv = EVP_PKEY_encrypt_init(ctx); | 471 | rv = EVP_PKEY_encrypt_init(pkeyutl_config.ctx); |
415 | break; | 472 | break; |
416 | 473 | ||
417 | case EVP_PKEY_OP_DECRYPT: | 474 | case EVP_PKEY_OP_DECRYPT: |
418 | rv = EVP_PKEY_decrypt_init(ctx); | 475 | rv = EVP_PKEY_decrypt_init(pkeyutl_config.ctx); |
419 | break; | 476 | break; |
420 | 477 | ||
421 | case EVP_PKEY_OP_DERIVE: | 478 | case EVP_PKEY_OP_DERIVE: |
422 | rv = EVP_PKEY_derive_init(ctx); | 479 | rv = EVP_PKEY_derive_init(pkeyutl_config.ctx); |
423 | break; | 480 | break; |
424 | } | 481 | } |
425 | 482 | ||
426 | if (rv <= 0) { | 483 | if (rv <= 0) { |
427 | EVP_PKEY_CTX_free(ctx); | 484 | EVP_PKEY_CTX_free(pkeyutl_config.ctx); |
428 | ctx = NULL; | 485 | pkeyutl_config.ctx = NULL; |
429 | } | 486 | } |
430 | end: | ||
431 | 487 | ||
488 | end: | ||
432 | free(passin); | 489 | free(passin); |
433 | 490 | ||
434 | return ctx; | 491 | if (!pkeyutl_config.ctx) { |
435 | 492 | BIO_puts(bio_err, "Error initializing context\n"); | |
493 | ERR_print_errors(bio_err); | ||
494 | return (1); | ||
495 | } | ||
436 | 496 | ||
497 | return (0); | ||
437 | } | 498 | } |
438 | 499 | ||
439 | static int | 500 | static int |
440 | setup_peer(BIO * err, EVP_PKEY_CTX * ctx, int peerform, | 501 | setup_peer(char *file) |
441 | const char *file) | ||
442 | { | 502 | { |
443 | EVP_PKEY *peer = NULL; | 503 | EVP_PKEY *peer = NULL; |
444 | int ret; | 504 | int ret; |
445 | if (!ctx) { | 505 | |
446 | BIO_puts(err, "-peerkey command before -inkey\n"); | 506 | if (!pkeyutl_config.ctx) { |
447 | return 0; | 507 | BIO_puts(bio_err, "-peerkey command before -inkey\n"); |
508 | return (1); | ||
448 | } | 509 | } |
449 | peer = load_pubkey(bio_err, file, peerform, 0, NULL, "Peer Key"); | 510 | peer = load_pubkey(bio_err, file, pkeyutl_config.peerform, 0, NULL, |
511 | "Peer Key"); | ||
450 | 512 | ||
451 | if (!peer) { | 513 | if (!peer) { |
452 | BIO_printf(bio_err, "Error reading peer key %s\n", file); | 514 | BIO_printf(bio_err, "Error reading peer key %s\n", file); |
453 | ERR_print_errors(err); | 515 | ERR_print_errors(bio_err); |
454 | return 0; | 516 | return (1); |
455 | } | 517 | } |
456 | ret = EVP_PKEY_derive_set_peer(ctx, peer); | 518 | ret = EVP_PKEY_derive_set_peer(pkeyutl_config.ctx, peer); |
457 | 519 | ||
458 | EVP_PKEY_free(peer); | 520 | EVP_PKEY_free(peer); |
459 | if (ret <= 0) | 521 | if (ret <= 0) { |
460 | ERR_print_errors(err); | 522 | ERR_print_errors(bio_err); |
461 | return ret; | 523 | return (1); |
524 | } | ||
525 | |||
526 | return (0); | ||
527 | } | ||
528 | |||
529 | static int | ||
530 | pkeyutl_pkeyopt(char *pkeyopt) | ||
531 | { | ||
532 | if (!pkeyutl_config.ctx) { | ||
533 | BIO_puts(bio_err, "-pkeyopt command before -inkey\n"); | ||
534 | return (1); | ||
535 | } else if (pkey_ctrl_string(pkeyutl_config.ctx, pkeyopt) <= 0) { | ||
536 | BIO_puts(bio_err, "parameter setting error\n"); | ||
537 | ERR_print_errors(bio_err); | ||
538 | return (1); | ||
539 | } | ||
540 | |||
541 | return (0); | ||
462 | } | 542 | } |
463 | 543 | ||
464 | static int | 544 | static int |