1 /* 2 * Copyright 1995-2025 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 <stdio.h> 11 #include <string.h> 12 #include <stdlib.h> 13 #include "apps.h" 14 #include "progs.h" 15 #include <openssl/bio.h> 16 #include <openssl/err.h> 17 #include <openssl/evp.h> 18 #include <openssl/objects.h> 19 #include <openssl/x509.h> 20 #include <openssl/pem.h> 21 #include <openssl/hmac.h> 22 #include <ctype.h> 23 24 #undef BUFSIZE 25 #define BUFSIZE 1024*8 26 27 static int do_fp_oneshot_sign(BIO *out, EVP_MD_CTX *ctx, BIO *in, int sep, int binout, 28 EVP_PKEY *key, unsigned char *sigin, int siglen, 29 const char *sig_name, const char *file); 30 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen, 31 EVP_PKEY *key, unsigned char *sigin, int siglen, 32 const char *sig_name, const char *md_name, 33 const char *file); 34 static void show_digests(const OBJ_NAME *name, void *bio_); 35 36 struct doall_dgst_digests { 37 BIO *bio; 38 int n; 39 }; 40 41 typedef enum OPTION_choice { 42 OPT_COMMON, 43 OPT_LIST, 44 OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY, 45 OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL, 46 OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT, 47 OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, OPT_XOFLEN, 48 OPT_DIGEST, 49 OPT_R_ENUM, OPT_PROV_ENUM 50 } OPTION_CHOICE; 51 52 const OPTIONS dgst_options[] = { 53 {OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"}, 54 55 OPT_SECTION("General"), 56 {"help", OPT_HELP, '-', "Display this summary"}, 57 {"list", OPT_LIST, '-', "List digests"}, 58 #ifndef OPENSSL_NO_ENGINE 59 {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, 60 {"engine_impl", OPT_ENGINE_IMPL, '-', 61 "Also use engine given by -engine for digest operations"}, 62 #endif 63 {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, 64 65 OPT_SECTION("Output"), 66 {"c", OPT_C, '-', "Print the digest with separating colons"}, 67 {"r", OPT_R, '-', "Print the digest in coreutils format"}, 68 {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, 69 {"keyform", OPT_KEYFORM, 'f', "Key file format (ENGINE, other values ignored)"}, 70 {"hex", OPT_HEX, '-', "Print as hex dump"}, 71 {"binary", OPT_BINARY, '-', "Print in binary form"}, 72 {"xoflen", OPT_XOFLEN, 'p', "Output length for XOF algorithms. To obtain the maximum security strength set this to 32 (or greater) for SHAKE128, and 64 (or greater) for SHAKE256"}, 73 {"d", OPT_DEBUG, '-', "Print debug info"}, 74 {"debug", OPT_DEBUG, '-', "Print debug info"}, 75 76 OPT_SECTION("Signing"), 77 {"sign", OPT_SIGN, 's', "Sign digest using private key"}, 78 {"verify", OPT_VERIFY, 's', "Verify a signature using public key"}, 79 {"prverify", OPT_PRVERIFY, 's', "Verify a signature using private key"}, 80 {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, 81 {"signature", OPT_SIGNATURE, '<', "File with signature to verify"}, 82 {"hmac", OPT_HMAC, 's', "Create hashed MAC with key"}, 83 {"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"}, 84 {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"}, 85 {"", OPT_DIGEST, '-', "Any supported digest"}, 86 {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-', 87 "Compute HMAC with the key used in OpenSSL-FIPS fingerprint"}, 88 89 OPT_R_OPTIONS, 90 OPT_PROV_OPTIONS, 91 92 OPT_PARAMETERS(), 93 {"file", 0, 0, "Files to digest (optional; default is stdin)"}, 94 {NULL} 95 }; 96 97 int dgst_main(int argc, char **argv) 98 { 99 BIO *in = NULL, *inp = NULL, *bmd = NULL, *out = NULL; 100 ENGINE *e = NULL, *impl = NULL; 101 EVP_PKEY *sigkey = NULL; 102 STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; 103 char *hmac_key = NULL; 104 char *mac_name = NULL, *digestname = NULL; 105 char *passinarg = NULL, *passin = NULL; 106 EVP_MD *md = NULL; 107 const char *outfile = NULL, *keyfile = NULL, *prog = NULL; 108 const char *sigfile = NULL; 109 const char *md_name = NULL; 110 OPTION_CHOICE o; 111 int separator = 0, debug = 0, keyform = FORMAT_UNDEF, siglen = 0; 112 int i, ret = EXIT_FAILURE, out_bin = -1, want_pub = 0, do_verify = 0; 113 int xoflen = 0; 114 unsigned char *buf = NULL, *sigbuf = NULL; 115 int engine_impl = 0; 116 struct doall_dgst_digests dec; 117 EVP_MD_CTX *signctx = NULL; 118 int oneshot_sign = 0; 119 120 buf = app_malloc(BUFSIZE, "I/O buffer"); 121 md = (EVP_MD *)EVP_get_digestbyname(argv[0]); 122 if (md != NULL) 123 digestname = argv[0]; 124 125 opt_set_unknown_name("digest"); 126 prog = opt_init(argc, argv, dgst_options); 127 while ((o = opt_next()) != OPT_EOF) { 128 switch (o) { 129 case OPT_EOF: 130 case OPT_ERR: 131 opthelp: 132 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 133 goto end; 134 case OPT_HELP: 135 opt_help(dgst_options); 136 ret = EXIT_SUCCESS; 137 goto end; 138 case OPT_LIST: 139 BIO_printf(bio_out, "Supported digests:\n"); 140 dec.bio = bio_out; 141 dec.n = 0; 142 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, 143 show_digests, &dec); 144 BIO_printf(bio_out, "\n"); 145 ret = EXIT_SUCCESS; 146 goto end; 147 case OPT_C: 148 separator = 1; 149 break; 150 case OPT_R: 151 separator = 2; 152 break; 153 case OPT_R_CASES: 154 if (!opt_rand(o)) 155 goto end; 156 break; 157 case OPT_OUT: 158 outfile = opt_arg(); 159 break; 160 case OPT_SIGN: 161 keyfile = opt_arg(); 162 break; 163 case OPT_PASSIN: 164 passinarg = opt_arg(); 165 break; 166 case OPT_VERIFY: 167 keyfile = opt_arg(); 168 want_pub = do_verify = 1; 169 break; 170 case OPT_PRVERIFY: 171 keyfile = opt_arg(); 172 do_verify = 1; 173 break; 174 case OPT_SIGNATURE: 175 sigfile = opt_arg(); 176 break; 177 case OPT_KEYFORM: 178 if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) 179 goto opthelp; 180 break; 181 case OPT_ENGINE: 182 e = setup_engine(opt_arg(), 0); 183 break; 184 case OPT_ENGINE_IMPL: 185 engine_impl = 1; 186 break; 187 case OPT_HEX: 188 out_bin = 0; 189 break; 190 case OPT_BINARY: 191 out_bin = 1; 192 break; 193 case OPT_XOFLEN: 194 xoflen = atoi(opt_arg()); 195 break; 196 case OPT_DEBUG: 197 debug = 1; 198 break; 199 case OPT_FIPS_FINGERPRINT: 200 hmac_key = "etaonrishdlcupfm"; 201 break; 202 case OPT_HMAC: 203 hmac_key = opt_arg(); 204 break; 205 case OPT_MAC: 206 mac_name = opt_arg(); 207 break; 208 case OPT_SIGOPT: 209 if (!sigopts) 210 sigopts = sk_OPENSSL_STRING_new_null(); 211 if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) 212 goto opthelp; 213 break; 214 case OPT_MACOPT: 215 if (!macopts) 216 macopts = sk_OPENSSL_STRING_new_null(); 217 if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg())) 218 goto opthelp; 219 break; 220 case OPT_DIGEST: 221 digestname = opt_unknown(); 222 break; 223 case OPT_PROV_CASES: 224 if (!opt_provider(o)) 225 goto end; 226 break; 227 } 228 } 229 230 /* Remaining args are files to digest. */ 231 argc = opt_num_rest(); 232 argv = opt_rest(); 233 if (keyfile != NULL && argc > 1) { 234 BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog); 235 goto end; 236 } 237 if (!app_RAND_load()) 238 goto end; 239 240 if (digestname != NULL) { 241 if (!opt_md(digestname, &md)) 242 goto opthelp; 243 } 244 245 if (do_verify && sigfile == NULL) { 246 BIO_printf(bio_err, 247 "No signature to verify: use the -signature option\n"); 248 goto end; 249 } 250 if (engine_impl) 251 impl = e; 252 253 in = BIO_new(BIO_s_file()); 254 bmd = BIO_new(BIO_f_md()); 255 if (in == NULL || bmd == NULL) 256 goto end; 257 258 if (debug) { 259 BIO_set_callback_ex(in, BIO_debug_callback_ex); 260 /* needed for windows 3.1 */ 261 BIO_set_callback_arg(in, (char *)bio_err); 262 } 263 264 if (!app_passwd(passinarg, NULL, &passin, NULL)) { 265 BIO_printf(bio_err, "Error getting password\n"); 266 goto end; 267 } 268 269 if (out_bin == -1) { 270 if (keyfile != NULL) 271 out_bin = 1; 272 else 273 out_bin = 0; 274 } 275 276 out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); 277 if (out == NULL) 278 goto end; 279 280 if ((!(mac_name == NULL) + !(keyfile == NULL) + !(hmac_key == NULL)) > 1) { 281 BIO_printf(bio_err, "MAC and signing key cannot both be specified\n"); 282 goto end; 283 } 284 285 if (keyfile != NULL) { 286 if (want_pub) 287 sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key"); 288 else 289 sigkey = load_key(keyfile, keyform, 0, passin, e, "private key"); 290 if (sigkey == NULL) { 291 /* 292 * load_[pub]key() has already printed an appropriate message 293 */ 294 goto end; 295 } 296 { 297 char def_md[80]; 298 299 if (EVP_PKEY_get_default_digest_name(sigkey, def_md, 300 sizeof(def_md)) == 2 301 && strcmp(def_md, "UNDEF") == 0) 302 oneshot_sign = 1; 303 signctx = EVP_MD_CTX_new(); 304 if (signctx == NULL) 305 goto end; 306 } 307 } 308 309 if (mac_name != NULL) { 310 EVP_PKEY_CTX *mac_ctx = NULL; 311 312 if (!init_gen_str(&mac_ctx, mac_name, impl, 0, NULL, NULL)) 313 goto end; 314 if (macopts != NULL) { 315 for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { 316 char *macopt = sk_OPENSSL_STRING_value(macopts, i); 317 318 if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { 319 EVP_PKEY_CTX_free(mac_ctx); 320 BIO_printf(bio_err, "MAC parameter error \"%s\"\n", macopt); 321 goto end; 322 } 323 } 324 } 325 326 sigkey = app_keygen(mac_ctx, mac_name, 0, 0 /* not verbose */); 327 /* Verbose output would make external-tests gost-engine fail */ 328 EVP_PKEY_CTX_free(mac_ctx); 329 if (sigkey == NULL) 330 goto end; 331 } 332 333 if (hmac_key != NULL) { 334 if (md == NULL) { 335 md = (EVP_MD *)EVP_sha256(); 336 digestname = SN_sha256; 337 } 338 sigkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, impl, 339 (unsigned char *)hmac_key, 340 strlen(hmac_key)); 341 if (sigkey == NULL) 342 goto end; 343 } 344 345 if (sigkey != NULL) { 346 EVP_MD_CTX *mctx = NULL; 347 EVP_PKEY_CTX *pctx = NULL; 348 int res; 349 350 if (oneshot_sign) { 351 mctx = signctx; 352 } else if (BIO_get_md_ctx(bmd, &mctx) <= 0) { 353 BIO_printf(bio_err, "Error getting context\n"); 354 goto end; 355 } 356 if (do_verify) 357 if (impl == NULL) 358 res = EVP_DigestVerifyInit_ex(mctx, &pctx, digestname, 359 app_get0_libctx(), 360 app_get0_propq(), sigkey, NULL); 361 else 362 res = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); 363 else 364 if (impl == NULL) 365 res = EVP_DigestSignInit_ex(mctx, &pctx, digestname, 366 app_get0_libctx(), 367 app_get0_propq(), sigkey, NULL); 368 else 369 res = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); 370 if (res == 0) { 371 BIO_printf(bio_err, "Error setting context\n"); 372 goto end; 373 } 374 if (sigopts != NULL) { 375 for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { 376 char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); 377 378 if (pkey_ctrl_string(pctx, sigopt) <= 0) { 379 BIO_printf(bio_err, "Signature parameter error \"%s\"\n", 380 sigopt); 381 goto end; 382 } 383 } 384 } 385 } 386 /* we use md as a filter, reading from 'in' */ 387 else { 388 EVP_MD_CTX *mctx = NULL; 389 390 if (oneshot_sign) { 391 BIO_printf(bio_err, "Oneshot algorithms don't use a digest\n"); 392 goto end; 393 } 394 if (BIO_get_md_ctx(bmd, &mctx) <= 0) { 395 BIO_printf(bio_err, "Error getting context\n"); 396 goto end; 397 } 398 if (md == NULL) 399 md = (EVP_MD *)EVP_sha256(); 400 if (!EVP_DigestInit_ex(mctx, md, impl)) { 401 BIO_printf(bio_err, "Error setting digest\n"); 402 goto end; 403 } 404 } 405 406 if (sigfile != NULL && sigkey != NULL) { 407 BIO *sigbio = BIO_new_file(sigfile, "rb"); 408 409 if (sigbio == NULL) { 410 BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); 411 goto end; 412 } 413 siglen = EVP_PKEY_get_size(sigkey); 414 sigbuf = app_malloc(siglen, "signature buffer"); 415 siglen = BIO_read(sigbio, sigbuf, siglen); 416 BIO_free(sigbio); 417 if (siglen <= 0) { 418 BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); 419 goto end; 420 } 421 } 422 if (!oneshot_sign) { 423 inp = BIO_push(bmd, in); 424 425 if (md == NULL) { 426 EVP_MD_CTX *tctx; 427 428 BIO_get_md_ctx(bmd, &tctx); 429 md = EVP_MD_CTX_get1_md(tctx); 430 } 431 if (md != NULL) 432 md_name = EVP_MD_get0_name(md); 433 } 434 if (xoflen > 0) { 435 if (!EVP_MD_xof(md)) { 436 BIO_printf(bio_err, "Length can only be specified for XOF\n"); 437 goto end; 438 } 439 /* 440 * Signing using XOF is not supported by any algorithms currently since 441 * each algorithm only calls EVP_DigestFinal_ex() in their sign_final 442 * and verify_final methods. 443 */ 444 if (sigkey != NULL) { 445 BIO_printf(bio_err, "Signing key cannot be specified for XOF\n"); 446 goto end; 447 } 448 } 449 450 if (argc == 0) { 451 BIO_set_fp(in, stdin, BIO_NOCLOSE); 452 if (oneshot_sign) 453 ret = do_fp_oneshot_sign(out, signctx, in, separator, out_bin, 454 sigkey, sigbuf, siglen, NULL, "stdin"); 455 else 456 ret = do_fp(out, buf, inp, separator, out_bin, xoflen, 457 sigkey, sigbuf, siglen, NULL, md_name, "stdin"); 458 } else { 459 const char *sig_name = NULL; 460 461 if (out_bin == 0) { 462 if (sigkey != NULL) 463 sig_name = EVP_PKEY_get0_type_name(sigkey); 464 } 465 ret = EXIT_SUCCESS; 466 for (i = 0; i < argc; i++) { 467 if (BIO_read_filename(in, argv[i]) <= 0) { 468 perror(argv[i]); 469 ret = EXIT_FAILURE; 470 continue; 471 } else { 472 if (oneshot_sign) { 473 if (do_fp_oneshot_sign(out, signctx, in, separator, out_bin, 474 sigkey, sigbuf, siglen, sig_name, 475 argv[i])) 476 ret = EXIT_FAILURE; 477 } else { 478 if (do_fp(out, buf, inp, separator, out_bin, xoflen, 479 sigkey, sigbuf, siglen, sig_name, md_name, argv[i])) 480 ret = EXIT_FAILURE; 481 } 482 } 483 (void)BIO_reset(bmd); 484 } 485 } 486 end: 487 if (ret != EXIT_SUCCESS) 488 ERR_print_errors(bio_err); 489 OPENSSL_clear_free(buf, BUFSIZE); 490 BIO_free(in); 491 OPENSSL_free(passin); 492 BIO_free_all(out); 493 EVP_MD_free(md); 494 EVP_PKEY_free(sigkey); 495 EVP_MD_CTX_free(signctx); 496 sk_OPENSSL_STRING_free(sigopts); 497 sk_OPENSSL_STRING_free(macopts); 498 OPENSSL_free(sigbuf); 499 BIO_free(bmd); 500 release_engine(e); 501 return ret; 502 } 503 504 static void show_digests(const OBJ_NAME *name, void *arg) 505 { 506 struct doall_dgst_digests *dec = (struct doall_dgst_digests *)arg; 507 EVP_MD *md = NULL; 508 509 /* Filter out signed digests (a.k.a signature algorithms) */ 510 if (strstr(name->name, "rsa") != NULL || strstr(name->name, "RSA") != NULL) 511 return; 512 513 if (!islower((unsigned char)*name->name)) 514 return; 515 516 /* Filter out message digests that we cannot use */ 517 md = EVP_MD_fetch(app_get0_libctx(), name->name, app_get0_propq()); 518 if (md == NULL) { 519 if (EVP_get_digestbyname(name->name) == NULL) 520 return; 521 } 522 523 BIO_printf(dec->bio, "-%-25s", name->name); 524 if (++dec->n == 3) { 525 BIO_printf(dec->bio, "\n"); 526 dec->n = 0; 527 } else { 528 BIO_printf(dec->bio, " "); 529 } 530 531 EVP_MD_free(md); 532 } 533 534 /* 535 * The newline_escape_filename function performs newline escaping for any 536 * filename that contains a newline. This function also takes a pointer 537 * to backslash. The backslash pointer is a flag to indicating whether a newline 538 * is present in the filename. If a newline is present, the backslash flag is 539 * set and the output format will contain a backslash at the beginning of the 540 * digest output. This output format is to replicate the output format found 541 * in the '*sum' checksum programs. This aims to preserve backward 542 * compatibility. 543 */ 544 static const char *newline_escape_filename(const char *file, int *backslash) 545 { 546 size_t i, e = 0, length = strlen(file), newline_count = 0, mem_len = 0; 547 char *file_cpy = NULL; 548 549 for (i = 0; i < length; i++) 550 if (file[i] == '\n') 551 newline_count++; 552 553 mem_len = length + newline_count + 1; 554 file_cpy = app_malloc(mem_len, file); 555 i = 0; 556 557 while (e < length) { 558 const char c = file[e]; 559 if (c == '\n') { 560 file_cpy[i++] = '\\'; 561 file_cpy[i++] = 'n'; 562 *backslash = 1; 563 } else { 564 file_cpy[i++] = c; 565 } 566 e++; 567 } 568 file_cpy[i] = '\0'; 569 return (const char*)file_cpy; 570 } 571 572 static void print_out(BIO *out, unsigned char *buf, size_t len, 573 int sep, int binout, 574 const char *sig_name, const char *md_name, const char *file) 575 { 576 int i, backslash = 0; 577 578 if (binout) { 579 BIO_write(out, buf, len); 580 } else if (sep == 2) { 581 file = newline_escape_filename(file, &backslash); 582 583 if (backslash == 1) 584 BIO_puts(out, "\\"); 585 586 for (i = 0; i < (int)len; i++) 587 BIO_printf(out, "%02x", buf[i]); 588 589 BIO_printf(out, " *%s\n", file); 590 OPENSSL_free((char *)file); 591 } else { 592 if (sig_name != NULL) { 593 BIO_puts(out, sig_name); 594 if (md_name != NULL) 595 BIO_printf(out, "-%s", md_name); 596 BIO_printf(out, "(%s)= ", file); 597 } else if (md_name != NULL) { 598 BIO_printf(out, "%s(%s)= ", md_name, file); 599 } else { 600 BIO_printf(out, "(%s)= ", file); 601 } 602 for (i = 0; i < (int)len; i++) { 603 if (sep && (i != 0)) 604 BIO_printf(out, ":"); 605 BIO_printf(out, "%02x", buf[i]); 606 } 607 BIO_printf(out, "\n"); 608 } 609 } 610 611 static void print_verify_result(BIO *out, int i) 612 { 613 if (i > 0) 614 BIO_printf(out, "Verified OK\n"); 615 else if (i == 0) 616 BIO_printf(out, "Verification failure\n"); 617 else 618 BIO_printf(bio_err, "Error verifying data\n"); 619 } 620 621 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen, 622 EVP_PKEY *key, unsigned char *sigin, int siglen, 623 const char *sig_name, const char *md_name, 624 const char *file) 625 { 626 size_t len = BUFSIZE; 627 int i, ret = EXIT_FAILURE; 628 unsigned char *allocated_buf = NULL; 629 630 while (BIO_pending(bp) || !BIO_eof(bp)) { 631 i = BIO_read(bp, (char *)buf, BUFSIZE); 632 if (i < 0) { 633 BIO_printf(bio_err, "Read error in %s\n", file); 634 goto end; 635 } 636 if (i == 0) 637 break; 638 } 639 if (sigin != NULL) { 640 EVP_MD_CTX *ctx; 641 BIO_get_md_ctx(bp, &ctx); 642 i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); 643 print_verify_result(out, i); 644 if (i > 0) 645 ret = EXIT_SUCCESS; 646 goto end; 647 } 648 if (key != NULL) { 649 EVP_MD_CTX *ctx; 650 size_t tmplen; 651 652 BIO_get_md_ctx(bp, &ctx); 653 if (!EVP_DigestSignFinal(ctx, NULL, &tmplen)) { 654 BIO_printf(bio_err, "Error getting maximum length of signed data\n"); 655 goto end; 656 } 657 if (tmplen > BUFSIZE) { 658 len = tmplen; 659 allocated_buf = app_malloc(len, "Signature buffer"); 660 buf = allocated_buf; 661 } 662 if (!EVP_DigestSignFinal(ctx, buf, &len)) { 663 BIO_printf(bio_err, "Error signing data\n"); 664 goto end; 665 } 666 } else if (xoflen > 0) { 667 EVP_MD_CTX *ctx; 668 669 len = xoflen; 670 if (len > BUFSIZE) { 671 allocated_buf = app_malloc(len, "Digest buffer"); 672 buf = allocated_buf; 673 } 674 675 BIO_get_md_ctx(bp, &ctx); 676 677 if (!EVP_DigestFinalXOF(ctx, buf, len)) { 678 BIO_printf(bio_err, "Error Digesting Data\n"); 679 goto end; 680 } 681 } else { 682 len = BIO_gets(bp, (char *)buf, BUFSIZE); 683 if ((int)len < 0) 684 goto end; 685 } 686 print_out(out, buf, len, sep, binout, sig_name, md_name, file); 687 ret = EXIT_SUCCESS; 688 end: 689 if (allocated_buf != NULL) 690 OPENSSL_clear_free(allocated_buf, len); 691 692 return ret; 693 } 694 695 /* 696 * Some new algorithms only support one shot operations. 697 * For these we need to buffer all input and then do the sign on the 698 * total buffered input. These algorithms set a NULL digest name which is 699 * then used inside EVP_DigestVerify() and EVP_DigestSign(). 700 */ 701 static int do_fp_oneshot_sign(BIO *out, EVP_MD_CTX *ctx, BIO *in, int sep, int binout, 702 EVP_PKEY *key, unsigned char *sigin, int siglen, 703 const char *sig_name, const char *file) 704 { 705 int res, ret = EXIT_FAILURE; 706 size_t len = 0; 707 int buflen = 0; 708 int maxlen = 16 * 1024 * 1024; 709 uint8_t *buf = NULL, *sig = NULL; 710 711 buflen = bio_to_mem(&buf, maxlen, in); 712 if (buflen <= 0) { 713 BIO_printf(bio_err, "Read error in %s\n", file); 714 return ret; 715 } 716 if (sigin != NULL) { 717 res = EVP_DigestVerify(ctx, sigin, siglen, buf, buflen); 718 print_verify_result(out, res); 719 if (res > 0) 720 ret = EXIT_SUCCESS; 721 goto end; 722 } 723 if (key != NULL) { 724 if (EVP_DigestSign(ctx, NULL, &len, buf, buflen) != 1) { 725 BIO_printf(bio_err, "Error getting maximum length of signed data\n"); 726 goto end; 727 } 728 sig = app_malloc(len, "Signature buffer"); 729 if (EVP_DigestSign(ctx, sig, &len, buf, buflen) != 1) { 730 BIO_printf(bio_err, "Error signing data\n"); 731 goto end; 732 } 733 print_out(out, sig, len, sep, binout, sig_name, NULL, file); 734 ret = EXIT_SUCCESS; 735 } else { 736 BIO_printf(bio_err, "key must be set for one-shot algorithms\n"); 737 goto end; 738 } 739 740 end: 741 OPENSSL_free(sig); 742 OPENSSL_clear_free(buf, buflen); 743 744 return ret; 745 } 746