diff options
Diffstat (limited to 'src')
| -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 |
