1 /* 2 * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include "apps.h" 11 #include "progs.h" 12 #include <string.h> 13 #include <openssl/err.h> 14 #include <openssl/pem.h> 15 #include <openssl/evp.h> 16 #include <sys/stat.h> 17 18 #define KEY_NONE 0 19 #define KEY_PRIVKEY 1 20 #define KEY_PUBKEY 2 21 #define KEY_CERT 3 22 23 static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, 24 const char *keyfile, int keyform, int key_type, 25 char *passinarg, int pkey_op, ENGINE *e, 26 const int impl, int rawin, EVP_PKEY **ppkey, 27 EVP_MD_CTX *mctx, const char *digestname, 28 OSSL_LIB_CTX *libctx, const char *propq); 29 30 static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, 31 ENGINE *e); 32 33 static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, 34 unsigned char *out, size_t *poutlen, 35 const unsigned char *in, size_t inlen); 36 37 static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx, 38 EVP_PKEY *pkey, BIO *in, 39 int filesize, unsigned char *sig, int siglen, 40 unsigned char **out, size_t *poutlen); 41 42 typedef enum OPTION_choice { 43 OPT_COMMON, 44 OPT_ENGINE, OPT_ENGINE_IMPL, OPT_IN, OPT_OUT, 45 OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN, 46 OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, 47 OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN, 48 OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_PKEYOPT_PASSIN, OPT_KDF, 49 OPT_KDFLEN, OPT_R_ENUM, OPT_PROV_ENUM, 50 OPT_CONFIG, 51 OPT_RAWIN, OPT_DIGEST 52 } OPTION_CHOICE; 53 54 const OPTIONS pkeyutl_options[] = { 55 OPT_SECTION("General"), 56 {"help", OPT_HELP, '-', "Display this summary"}, 57 #ifndef OPENSSL_NO_ENGINE 58 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, 59 {"engine_impl", OPT_ENGINE_IMPL, '-', 60 "Also use engine given by -engine for crypto operations"}, 61 #endif 62 {"sign", OPT_SIGN, '-', "Sign input data with private key"}, 63 {"verify", OPT_VERIFY, '-', "Verify with public key"}, 64 {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, 65 {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, 66 {"derive", OPT_DERIVE, '-', "Derive shared secret"}, 67 OPT_CONFIG_OPTION, 68 69 OPT_SECTION("Input"), 70 {"in", OPT_IN, '<', "Input file - default stdin"}, 71 {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"}, 72 {"pubin", OPT_PUBIN, '-', "Input is a public key"}, 73 {"inkey", OPT_INKEY, 's', "Input private key file"}, 74 {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, 75 {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, 76 {"peerform", OPT_PEERFORM, 'E', "Peer key format (DER/PEM/P12/ENGINE)"}, 77 {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, 78 {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, 79 {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, 80 {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"}, 81 82 OPT_SECTION("Output"), 83 {"out", OPT_OUT, '>', "Output file - default stdout"}, 84 {"asn1parse", OPT_ASN1PARSE, '-', 85 "parse the output as ASN.1 data to check its DER encoding and print errors"}, 86 {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, 87 {"verifyrecover", OPT_VERIFYRECOVER, '-', 88 "Verify RSA signature, recovering original signature input data"}, 89 90 OPT_SECTION("Signing/Derivation"), 91 {"digest", OPT_DIGEST, 's', 92 "Specify the digest algorithm when signing the raw input data"}, 93 {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, 94 {"pkeyopt_passin", OPT_PKEYOPT_PASSIN, 's', 95 "Public key option that is read as a passphrase argument opt:passphrase"}, 96 {"kdf", OPT_KDF, 's', "Use KDF algorithm"}, 97 {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"}, 98 99 OPT_R_OPTIONS, 100 OPT_PROV_OPTIONS, 101 {NULL} 102 }; 103 104 int pkeyutl_main(int argc, char **argv) 105 { 106 CONF *conf = NULL; 107 BIO *in = NULL, *out = NULL; 108 ENGINE *e = NULL; 109 EVP_PKEY_CTX *ctx = NULL; 110 EVP_PKEY *pkey = NULL; 111 char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL; 112 char hexdump = 0, asn1parse = 0, rev = 0, *prog; 113 unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; 114 OPTION_CHOICE o; 115 int buf_inlen = 0, siglen = -1; 116 int keyform = FORMAT_UNDEF, peerform = FORMAT_UNDEF; 117 int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; 118 int engine_impl = 0; 119 int ret = 1, rv = -1; 120 size_t buf_outlen; 121 const char *inkey = NULL; 122 const char *peerkey = NULL; 123 const char *kdfalg = NULL, *digestname = NULL; 124 int kdflen = 0; 125 STACK_OF(OPENSSL_STRING) *pkeyopts = NULL; 126 STACK_OF(OPENSSL_STRING) *pkeyopts_passin = NULL; 127 int rawin = 0; 128 EVP_MD_CTX *mctx = NULL; 129 EVP_MD *md = NULL; 130 int filesize = -1; 131 OSSL_LIB_CTX *libctx = app_get0_libctx(); 132 133 prog = opt_init(argc, argv, pkeyutl_options); 134 while ((o = opt_next()) != OPT_EOF) { 135 switch (o) { 136 case OPT_EOF: 137 case OPT_ERR: 138 opthelp: 139 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 140 goto end; 141 case OPT_HELP: 142 opt_help(pkeyutl_options); 143 ret = 0; 144 goto end; 145 case OPT_IN: 146 infile = opt_arg(); 147 break; 148 case OPT_OUT: 149 outfile = opt_arg(); 150 break; 151 case OPT_SIGFILE: 152 sigfile = opt_arg(); 153 break; 154 case OPT_ENGINE_IMPL: 155 engine_impl = 1; 156 break; 157 case OPT_INKEY: 158 inkey = opt_arg(); 159 break; 160 case OPT_PEERKEY: 161 peerkey = opt_arg(); 162 break; 163 case OPT_PASSIN: 164 passinarg = opt_arg(); 165 break; 166 case OPT_PEERFORM: 167 if (!opt_format(opt_arg(), OPT_FMT_ANY, &peerform)) 168 goto opthelp; 169 break; 170 case OPT_KEYFORM: 171 if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) 172 goto opthelp; 173 break; 174 case OPT_R_CASES: 175 if (!opt_rand(o)) 176 goto end; 177 break; 178 case OPT_CONFIG: 179 conf = app_load_config_modules(opt_arg()); 180 if (conf == NULL) 181 goto end; 182 break; 183 case OPT_PROV_CASES: 184 if (!opt_provider(o)) 185 goto end; 186 break; 187 case OPT_ENGINE: 188 e = setup_engine(opt_arg(), 0); 189 break; 190 case OPT_PUBIN: 191 key_type = KEY_PUBKEY; 192 break; 193 case OPT_CERTIN: 194 key_type = KEY_CERT; 195 break; 196 case OPT_ASN1PARSE: 197 asn1parse = 1; 198 break; 199 case OPT_HEXDUMP: 200 hexdump = 1; 201 break; 202 case OPT_SIGN: 203 pkey_op = EVP_PKEY_OP_SIGN; 204 break; 205 case OPT_VERIFY: 206 pkey_op = EVP_PKEY_OP_VERIFY; 207 break; 208 case OPT_VERIFYRECOVER: 209 pkey_op = EVP_PKEY_OP_VERIFYRECOVER; 210 break; 211 case OPT_ENCRYPT: 212 pkey_op = EVP_PKEY_OP_ENCRYPT; 213 break; 214 case OPT_DECRYPT: 215 pkey_op = EVP_PKEY_OP_DECRYPT; 216 break; 217 case OPT_DERIVE: 218 pkey_op = EVP_PKEY_OP_DERIVE; 219 break; 220 case OPT_KDF: 221 pkey_op = EVP_PKEY_OP_DERIVE; 222 key_type = KEY_NONE; 223 kdfalg = opt_arg(); 224 break; 225 case OPT_KDFLEN: 226 kdflen = atoi(opt_arg()); 227 break; 228 case OPT_REV: 229 rev = 1; 230 break; 231 case OPT_PKEYOPT: 232 if ((pkeyopts == NULL && 233 (pkeyopts = sk_OPENSSL_STRING_new_null()) == NULL) || 234 sk_OPENSSL_STRING_push(pkeyopts, opt_arg()) == 0) { 235 BIO_puts(bio_err, "out of memory\n"); 236 goto end; 237 } 238 break; 239 case OPT_PKEYOPT_PASSIN: 240 if ((pkeyopts_passin == NULL && 241 (pkeyopts_passin = sk_OPENSSL_STRING_new_null()) == NULL) || 242 sk_OPENSSL_STRING_push(pkeyopts_passin, opt_arg()) == 0) { 243 BIO_puts(bio_err, "out of memory\n"); 244 goto end; 245 } 246 break; 247 case OPT_RAWIN: 248 rawin = 1; 249 break; 250 case OPT_DIGEST: 251 digestname = opt_arg(); 252 break; 253 } 254 } 255 256 /* No extra arguments. */ 257 argc = opt_num_rest(); 258 if (argc != 0) 259 goto opthelp; 260 261 if (!app_RAND_load()) 262 goto end; 263 264 if (rawin && pkey_op != EVP_PKEY_OP_SIGN && pkey_op != EVP_PKEY_OP_VERIFY) { 265 BIO_printf(bio_err, 266 "%s: -rawin can only be used with -sign or -verify\n", 267 prog); 268 goto opthelp; 269 } 270 271 if (digestname != NULL && !rawin) { 272 BIO_printf(bio_err, 273 "%s: -digest can only be used with -rawin\n", 274 prog); 275 goto opthelp; 276 } 277 278 if (rawin && rev) { 279 BIO_printf(bio_err, "%s: -rev cannot be used with raw input\n", 280 prog); 281 goto opthelp; 282 } 283 284 if (kdfalg != NULL) { 285 if (kdflen == 0) { 286 BIO_printf(bio_err, 287 "%s: no KDF length given (-kdflen parameter).\n", prog); 288 goto opthelp; 289 } 290 } else if (inkey == NULL) { 291 BIO_printf(bio_err, 292 "%s: no private key given (-inkey parameter).\n", prog); 293 goto opthelp; 294 } else if (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE) { 295 BIO_printf(bio_err, 296 "%s: no peer key given (-peerkey parameter).\n", prog); 297 goto opthelp; 298 } 299 300 if (rawin) { 301 if ((mctx = EVP_MD_CTX_new()) == NULL) { 302 BIO_printf(bio_err, "Error: out of memory\n"); 303 goto end; 304 } 305 } 306 ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type, 307 passinarg, pkey_op, e, engine_impl, rawin, &pkey, 308 mctx, digestname, libctx, app_get0_propq()); 309 if (ctx == NULL) { 310 BIO_printf(bio_err, "%s: Error initializing context\n", prog); 311 goto end; 312 } 313 if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) { 314 BIO_printf(bio_err, "%s: Error setting up peer key\n", prog); 315 goto end; 316 } 317 if (pkeyopts != NULL) { 318 int num = sk_OPENSSL_STRING_num(pkeyopts); 319 int i; 320 321 for (i = 0; i < num; ++i) { 322 const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i); 323 324 if (pkey_ctrl_string(ctx, opt) <= 0) { 325 BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n", 326 prog, opt); 327 goto end; 328 } 329 } 330 } 331 if (pkeyopts_passin != NULL) { 332 int num = sk_OPENSSL_STRING_num(pkeyopts_passin); 333 int i; 334 335 for (i = 0; i < num; i++) { 336 char *opt = sk_OPENSSL_STRING_value(pkeyopts_passin, i); 337 char *passin = strchr(opt, ':'); 338 char *passwd; 339 340 if (passin == NULL) { 341 /* Get password interactively */ 342 char passwd_buf[4096]; 343 int r; 344 345 BIO_snprintf(passwd_buf, sizeof(passwd_buf), "Enter %s: ", opt); 346 r = EVP_read_pw_string(passwd_buf, sizeof(passwd_buf) - 1, 347 passwd_buf, 0); 348 if (r < 0) { 349 if (r == -2) 350 BIO_puts(bio_err, "user abort\n"); 351 else 352 BIO_puts(bio_err, "entry failed\n"); 353 goto end; 354 } 355 passwd = OPENSSL_strdup(passwd_buf); 356 if (passwd == NULL) { 357 BIO_puts(bio_err, "out of memory\n"); 358 goto end; 359 } 360 } else { 361 /* Get password as a passin argument: First split option name 362 * and passphrase argument into two strings */ 363 *passin = 0; 364 passin++; 365 if (app_passwd(passin, NULL, &passwd, NULL) == 0) { 366 BIO_printf(bio_err, "failed to get '%s'\n", opt); 367 goto end; 368 } 369 } 370 371 if (EVP_PKEY_CTX_ctrl_str(ctx, opt, passwd) <= 0) { 372 BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n", 373 prog, opt); 374 goto end; 375 } 376 OPENSSL_free(passwd); 377 } 378 } 379 380 if (sigfile != NULL && (pkey_op != EVP_PKEY_OP_VERIFY)) { 381 BIO_printf(bio_err, 382 "%s: Signature file specified for non verify\n", prog); 383 goto end; 384 } 385 386 if (sigfile == NULL && (pkey_op == EVP_PKEY_OP_VERIFY)) { 387 BIO_printf(bio_err, 388 "%s: No signature file specified for verify\n", prog); 389 goto end; 390 } 391 392 if (pkey_op != EVP_PKEY_OP_DERIVE) { 393 in = bio_open_default(infile, 'r', FORMAT_BINARY); 394 if (infile != NULL) { 395 struct stat st; 396 397 if (stat(infile, &st) == 0 && st.st_size <= INT_MAX) 398 filesize = (int)st.st_size; 399 } 400 if (in == NULL) 401 goto end; 402 } 403 out = bio_open_default(outfile, 'w', FORMAT_BINARY); 404 if (out == NULL) 405 goto end; 406 407 if (sigfile != NULL) { 408 BIO *sigbio = BIO_new_file(sigfile, "rb"); 409 410 if (sigbio == NULL) { 411 BIO_printf(bio_err, "Can't open signature file %s\n", sigfile); 412 goto end; 413 } 414 siglen = bio_to_mem(&sig, keysize * 10, sigbio); 415 BIO_free(sigbio); 416 if (siglen < 0) { 417 BIO_printf(bio_err, "Error reading signature data\n"); 418 goto end; 419 } 420 } 421 422 /* Raw input data is handled elsewhere */ 423 if (in != NULL && !rawin) { 424 /* Read the input data */ 425 buf_inlen = bio_to_mem(&buf_in, -1, in); 426 if (buf_inlen < 0) { 427 BIO_printf(bio_err, "Error reading input Data\n"); 428 goto end; 429 } 430 if (rev) { 431 size_t i; 432 unsigned char ctmp; 433 size_t l = (size_t)buf_inlen; 434 for (i = 0; i < l / 2; i++) { 435 ctmp = buf_in[i]; 436 buf_in[i] = buf_in[l - 1 - i]; 437 buf_in[l - 1 - i] = ctmp; 438 } 439 } 440 } 441 442 /* Sanity check the input if the input is not raw */ 443 if (!rawin 444 && buf_inlen > EVP_MAX_MD_SIZE 445 && (pkey_op == EVP_PKEY_OP_SIGN 446 || pkey_op == EVP_PKEY_OP_VERIFY)) { 447 BIO_printf(bio_err, 448 "Error: The input data looks too long to be a hash\n"); 449 goto end; 450 } 451 452 if (pkey_op == EVP_PKEY_OP_VERIFY) { 453 if (rawin) { 454 rv = do_raw_keyop(pkey_op, mctx, pkey, in, filesize, sig, siglen, 455 NULL, 0); 456 } else { 457 rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, 458 buf_in, (size_t)buf_inlen); 459 } 460 if (rv == 1) { 461 BIO_puts(out, "Signature Verified Successfully\n"); 462 ret = 0; 463 } else { 464 BIO_puts(out, "Signature Verification Failure\n"); 465 } 466 goto end; 467 } 468 if (rawin) { 469 /* rawin allocates the buffer in do_raw_keyop() */ 470 rv = do_raw_keyop(pkey_op, mctx, pkey, in, filesize, NULL, 0, 471 &buf_out, (size_t *)&buf_outlen); 472 } else { 473 if (kdflen != 0) { 474 buf_outlen = kdflen; 475 rv = 1; 476 } else { 477 rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, 478 buf_in, (size_t)buf_inlen); 479 } 480 if (rv > 0 && buf_outlen != 0) { 481 buf_out = app_malloc(buf_outlen, "buffer output"); 482 rv = do_keyop(ctx, pkey_op, 483 buf_out, (size_t *)&buf_outlen, 484 buf_in, (size_t)buf_inlen); 485 } 486 } 487 if (rv <= 0) { 488 if (pkey_op != EVP_PKEY_OP_DERIVE) { 489 BIO_puts(bio_err, "Public Key operation error\n"); 490 } else { 491 BIO_puts(bio_err, "Key derivation failed\n"); 492 } 493 goto end; 494 } 495 ret = 0; 496 497 if (asn1parse) { 498 if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) 499 ERR_print_errors(bio_err); /* but still return success */ 500 } else if (hexdump) { 501 BIO_dump(out, (char *)buf_out, buf_outlen); 502 } else { 503 BIO_write(out, buf_out, buf_outlen); 504 } 505 506 end: 507 if (ret != 0) 508 ERR_print_errors(bio_err); 509 EVP_MD_CTX_free(mctx); 510 EVP_PKEY_CTX_free(ctx); 511 EVP_MD_free(md); 512 release_engine(e); 513 BIO_free(in); 514 BIO_free_all(out); 515 OPENSSL_free(buf_in); 516 OPENSSL_free(buf_out); 517 OPENSSL_free(sig); 518 sk_OPENSSL_STRING_free(pkeyopts); 519 sk_OPENSSL_STRING_free(pkeyopts_passin); 520 NCONF_free(conf); 521 return ret; 522 } 523 524 static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, 525 const char *keyfile, int keyform, int key_type, 526 char *passinarg, int pkey_op, ENGINE *e, 527 const int engine_impl, int rawin, 528 EVP_PKEY **ppkey, EVP_MD_CTX *mctx, const char *digestname, 529 OSSL_LIB_CTX *libctx, const char *propq) 530 { 531 EVP_PKEY *pkey = NULL; 532 EVP_PKEY_CTX *ctx = NULL; 533 ENGINE *impl = NULL; 534 char *passin = NULL; 535 int rv = -1; 536 X509 *x; 537 538 if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) 539 || (pkey_op == EVP_PKEY_OP_DERIVE)) 540 && (key_type != KEY_PRIVKEY && kdfalg == NULL)) { 541 BIO_printf(bio_err, "A private key is needed for this operation\n"); 542 goto end; 543 } 544 if (!app_passwd(passinarg, NULL, &passin, NULL)) { 545 BIO_printf(bio_err, "Error getting password\n"); 546 goto end; 547 } 548 switch (key_type) { 549 case KEY_PRIVKEY: 550 pkey = load_key(keyfile, keyform, 0, passin, e, "private key"); 551 break; 552 553 case KEY_PUBKEY: 554 pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key"); 555 break; 556 557 case KEY_CERT: 558 x = load_cert(keyfile, keyform, "Certificate"); 559 if (x) { 560 pkey = X509_get_pubkey(x); 561 X509_free(x); 562 } 563 break; 564 565 case KEY_NONE: 566 break; 567 568 } 569 570 #ifndef OPENSSL_NO_ENGINE 571 if (engine_impl) 572 impl = e; 573 #endif 574 575 if (kdfalg != NULL) { 576 int kdfnid = OBJ_sn2nid(kdfalg); 577 578 if (kdfnid == NID_undef) { 579 kdfnid = OBJ_ln2nid(kdfalg); 580 if (kdfnid == NID_undef) { 581 BIO_printf(bio_err, "The given KDF \"%s\" is unknown.\n", 582 kdfalg); 583 goto end; 584 } 585 } 586 if (impl != NULL) 587 ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); 588 else 589 ctx = EVP_PKEY_CTX_new_from_name(libctx, kdfalg, propq); 590 } else { 591 if (pkey == NULL) 592 goto end; 593 594 *pkeysize = EVP_PKEY_get_size(pkey); 595 if (impl != NULL) 596 ctx = EVP_PKEY_CTX_new(pkey, impl); 597 else 598 ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); 599 if (ppkey != NULL) 600 *ppkey = pkey; 601 EVP_PKEY_free(pkey); 602 } 603 604 if (ctx == NULL) 605 goto end; 606 607 if (rawin) { 608 EVP_MD_CTX_set_pkey_ctx(mctx, ctx); 609 610 switch (pkey_op) { 611 case EVP_PKEY_OP_SIGN: 612 rv = EVP_DigestSignInit_ex(mctx, NULL, digestname, libctx, propq, 613 pkey, NULL); 614 break; 615 616 case EVP_PKEY_OP_VERIFY: 617 rv = EVP_DigestVerifyInit_ex(mctx, NULL, digestname, libctx, propq, 618 pkey, NULL); 619 break; 620 } 621 622 } else { 623 switch (pkey_op) { 624 case EVP_PKEY_OP_SIGN: 625 rv = EVP_PKEY_sign_init(ctx); 626 break; 627 628 case EVP_PKEY_OP_VERIFY: 629 rv = EVP_PKEY_verify_init(ctx); 630 break; 631 632 case EVP_PKEY_OP_VERIFYRECOVER: 633 rv = EVP_PKEY_verify_recover_init(ctx); 634 break; 635 636 case EVP_PKEY_OP_ENCRYPT: 637 rv = EVP_PKEY_encrypt_init(ctx); 638 break; 639 640 case EVP_PKEY_OP_DECRYPT: 641 rv = EVP_PKEY_decrypt_init(ctx); 642 break; 643 644 case EVP_PKEY_OP_DERIVE: 645 rv = EVP_PKEY_derive_init(ctx); 646 break; 647 } 648 } 649 650 if (rv <= 0) { 651 EVP_PKEY_CTX_free(ctx); 652 ctx = NULL; 653 } 654 655 end: 656 OPENSSL_free(passin); 657 return ctx; 658 659 } 660 661 static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, 662 ENGINE *e) 663 { 664 EVP_PKEY *peer = NULL; 665 ENGINE *engine = NULL; 666 int ret; 667 668 if (peerform == FORMAT_ENGINE) 669 engine = e; 670 peer = load_pubkey(file, peerform, 0, NULL, engine, "peer key"); 671 if (peer == NULL) { 672 BIO_printf(bio_err, "Error reading peer key %s\n", file); 673 return 0; 674 } 675 676 ret = EVP_PKEY_derive_set_peer(ctx, peer) > 0; 677 678 EVP_PKEY_free(peer); 679 return ret; 680 } 681 682 static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, 683 unsigned char *out, size_t *poutlen, 684 const unsigned char *in, size_t inlen) 685 { 686 int rv = 0; 687 switch (pkey_op) { 688 case EVP_PKEY_OP_VERIFYRECOVER: 689 rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen); 690 break; 691 692 case EVP_PKEY_OP_SIGN: 693 rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen); 694 break; 695 696 case EVP_PKEY_OP_ENCRYPT: 697 rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen); 698 break; 699 700 case EVP_PKEY_OP_DECRYPT: 701 rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen); 702 break; 703 704 case EVP_PKEY_OP_DERIVE: 705 rv = EVP_PKEY_derive(ctx, out, poutlen); 706 break; 707 708 } 709 return rv; 710 } 711 712 #define TBUF_MAXSIZE 2048 713 714 static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx, 715 EVP_PKEY *pkey, BIO *in, 716 int filesize, unsigned char *sig, int siglen, 717 unsigned char **out, size_t *poutlen) 718 { 719 int rv = 0; 720 unsigned char tbuf[TBUF_MAXSIZE]; 721 unsigned char *mbuf = NULL; 722 int buf_len = 0; 723 724 /* Some algorithms only support oneshot digests */ 725 if (EVP_PKEY_get_id(pkey) == EVP_PKEY_ED25519 726 || EVP_PKEY_get_id(pkey) == EVP_PKEY_ED448) { 727 if (filesize < 0) { 728 BIO_printf(bio_err, 729 "Error: unable to determine file size for oneshot operation\n"); 730 goto end; 731 } 732 mbuf = app_malloc(filesize, "oneshot sign/verify buffer"); 733 switch(pkey_op) { 734 case EVP_PKEY_OP_VERIFY: 735 buf_len = BIO_read(in, mbuf, filesize); 736 if (buf_len != filesize) { 737 BIO_printf(bio_err, "Error reading raw input data\n"); 738 goto end; 739 } 740 rv = EVP_DigestVerify(mctx, sig, (size_t)siglen, mbuf, buf_len); 741 break; 742 case EVP_PKEY_OP_SIGN: 743 buf_len = BIO_read(in, mbuf, filesize); 744 if (buf_len != filesize) { 745 BIO_printf(bio_err, "Error reading raw input data\n"); 746 goto end; 747 } 748 rv = EVP_DigestSign(mctx, NULL, poutlen, mbuf, buf_len); 749 if (rv == 1 && out != NULL) { 750 *out = app_malloc(*poutlen, "buffer output"); 751 rv = EVP_DigestSign(mctx, *out, poutlen, mbuf, buf_len); 752 } 753 break; 754 } 755 goto end; 756 } 757 758 switch(pkey_op) { 759 case EVP_PKEY_OP_VERIFY: 760 for (;;) { 761 buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); 762 if (buf_len == 0) 763 break; 764 if (buf_len < 0) { 765 BIO_printf(bio_err, "Error reading raw input data\n"); 766 goto end; 767 } 768 rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)buf_len); 769 if (rv != 1) { 770 BIO_printf(bio_err, "Error verifying raw input data\n"); 771 goto end; 772 } 773 } 774 rv = EVP_DigestVerifyFinal(mctx, sig, (size_t)siglen); 775 break; 776 case EVP_PKEY_OP_SIGN: 777 for (;;) { 778 buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); 779 if (buf_len == 0) 780 break; 781 if (buf_len < 0) { 782 BIO_printf(bio_err, "Error reading raw input data\n"); 783 goto end; 784 } 785 rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)buf_len); 786 if (rv != 1) { 787 BIO_printf(bio_err, "Error signing raw input data\n"); 788 goto end; 789 } 790 } 791 rv = EVP_DigestSignFinal(mctx, NULL, poutlen); 792 if (rv == 1 && out != NULL) { 793 *out = app_malloc(*poutlen, "buffer output"); 794 rv = EVP_DigestSignFinal(mctx, *out, poutlen); 795 } 796 break; 797 } 798 799 end: 800 OPENSSL_free(mbuf); 801 return rv; 802 } 803