1 /* 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (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 23 #undef BUFSIZE 24 #define BUFSIZE 1024*8 25 26 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, 27 EVP_PKEY *key, unsigned char *sigin, int siglen, 28 const char *sig_name, const char *md_name, 29 const char *file); 30 31 typedef enum OPTION_choice { 32 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, 33 OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY, 34 OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL, 35 OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT, 36 OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, 37 OPT_DIGEST, 38 OPT_R_ENUM 39 } OPTION_CHOICE; 40 41 const OPTIONS dgst_options[] = { 42 {OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"}, 43 {OPT_HELP_STR, 1, '-', 44 " file... files to digest (default is stdin)\n"}, 45 {"help", OPT_HELP, '-', "Display this summary"}, 46 {"c", OPT_C, '-', "Print the digest with separating colons"}, 47 {"r", OPT_R, '-', "Print the digest in coreutils format"}, 48 {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, 49 {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, 50 {"sign", OPT_SIGN, 's', "Sign digest using private key"}, 51 {"verify", OPT_VERIFY, 's', 52 "Verify a signature using public key"}, 53 {"prverify", OPT_PRVERIFY, 's', 54 "Verify a signature using private key"}, 55 {"signature", OPT_SIGNATURE, '<', "File with signature to verify"}, 56 {"keyform", OPT_KEYFORM, 'f', "Key file format (PEM or ENGINE)"}, 57 {"hex", OPT_HEX, '-', "Print as hex dump"}, 58 {"binary", OPT_BINARY, '-', "Print in binary form"}, 59 {"d", OPT_DEBUG, '-', "Print debug info"}, 60 {"debug", OPT_DEBUG, '-', "Print debug info"}, 61 {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-', 62 "Compute HMAC with the key used in OpenSSL-FIPS fingerprint"}, 63 {"hmac", OPT_HMAC, 's', "Create hashed MAC with key"}, 64 {"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"}, 65 {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, 66 {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"}, 67 {"", OPT_DIGEST, '-', "Any supported digest"}, 68 OPT_R_OPTIONS, 69 #ifndef OPENSSL_NO_ENGINE 70 {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, 71 {"engine_impl", OPT_ENGINE_IMPL, '-', 72 "Also use engine given by -engine for digest operations"}, 73 #endif 74 {NULL} 75 }; 76 77 int dgst_main(int argc, char **argv) 78 { 79 BIO *in = NULL, *inp, *bmd = NULL, *out = NULL; 80 ENGINE *e = NULL, *impl = NULL; 81 EVP_PKEY *sigkey = NULL; 82 STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; 83 char *hmac_key = NULL; 84 char *mac_name = NULL; 85 char *passinarg = NULL, *passin = NULL; 86 const EVP_MD *md = NULL, *m; 87 const char *outfile = NULL, *keyfile = NULL, *prog = NULL; 88 const char *sigfile = NULL; 89 OPTION_CHOICE o; 90 int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; 91 int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0; 92 unsigned char *buf = NULL, *sigbuf = NULL; 93 int engine_impl = 0; 94 95 prog = opt_progname(argv[0]); 96 buf = app_malloc(BUFSIZE, "I/O buffer"); 97 md = EVP_get_digestbyname(prog); 98 99 prog = opt_init(argc, argv, dgst_options); 100 while ((o = opt_next()) != OPT_EOF) { 101 switch (o) { 102 case OPT_EOF: 103 case OPT_ERR: 104 opthelp: 105 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 106 goto end; 107 case OPT_HELP: 108 opt_help(dgst_options); 109 ret = 0; 110 goto end; 111 case OPT_C: 112 separator = 1; 113 break; 114 case OPT_R: 115 separator = 2; 116 break; 117 case OPT_R_CASES: 118 if (!opt_rand(o)) 119 goto end; 120 break; 121 case OPT_OUT: 122 outfile = opt_arg(); 123 break; 124 case OPT_SIGN: 125 keyfile = opt_arg(); 126 break; 127 case OPT_PASSIN: 128 passinarg = opt_arg(); 129 break; 130 case OPT_VERIFY: 131 keyfile = opt_arg(); 132 want_pub = do_verify = 1; 133 break; 134 case OPT_PRVERIFY: 135 keyfile = opt_arg(); 136 do_verify = 1; 137 break; 138 case OPT_SIGNATURE: 139 sigfile = opt_arg(); 140 break; 141 case OPT_KEYFORM: 142 if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) 143 goto opthelp; 144 break; 145 case OPT_ENGINE: 146 e = setup_engine(opt_arg(), 0); 147 break; 148 case OPT_ENGINE_IMPL: 149 engine_impl = 1; 150 break; 151 case OPT_HEX: 152 out_bin = 0; 153 break; 154 case OPT_BINARY: 155 out_bin = 1; 156 break; 157 case OPT_DEBUG: 158 debug = 1; 159 break; 160 case OPT_FIPS_FINGERPRINT: 161 hmac_key = "etaonrishdlcupfm"; 162 break; 163 case OPT_HMAC: 164 hmac_key = opt_arg(); 165 break; 166 case OPT_MAC: 167 mac_name = opt_arg(); 168 break; 169 case OPT_SIGOPT: 170 if (!sigopts) 171 sigopts = sk_OPENSSL_STRING_new_null(); 172 if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) 173 goto opthelp; 174 break; 175 case OPT_MACOPT: 176 if (!macopts) 177 macopts = sk_OPENSSL_STRING_new_null(); 178 if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg())) 179 goto opthelp; 180 break; 181 case OPT_DIGEST: 182 if (!opt_md(opt_unknown(), &m)) 183 goto opthelp; 184 md = m; 185 break; 186 } 187 } 188 argc = opt_num_rest(); 189 argv = opt_rest(); 190 if (keyfile != NULL && argc > 1) { 191 BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog); 192 goto end; 193 } 194 195 if (do_verify && sigfile == NULL) { 196 BIO_printf(bio_err, 197 "No signature to verify: use the -signature option\n"); 198 goto end; 199 } 200 if (engine_impl) 201 impl = e; 202 203 in = BIO_new(BIO_s_file()); 204 bmd = BIO_new(BIO_f_md()); 205 if ((in == NULL) || (bmd == NULL)) { 206 ERR_print_errors(bio_err); 207 goto end; 208 } 209 210 if (debug) { 211 BIO_set_callback(in, BIO_debug_callback); 212 /* needed for windows 3.1 */ 213 BIO_set_callback_arg(in, (char *)bio_err); 214 } 215 216 if (!app_passwd(passinarg, NULL, &passin, NULL)) { 217 BIO_printf(bio_err, "Error getting password\n"); 218 goto end; 219 } 220 221 if (out_bin == -1) { 222 if (keyfile != NULL) 223 out_bin = 1; 224 else 225 out_bin = 0; 226 } 227 228 out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); 229 if (out == NULL) 230 goto end; 231 232 if ((!(mac_name == NULL) + !(keyfile == NULL) + !(hmac_key == NULL)) > 1) { 233 BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); 234 goto end; 235 } 236 237 if (keyfile != NULL) { 238 int type; 239 240 if (want_pub) 241 sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); 242 else 243 sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); 244 if (sigkey == NULL) { 245 /* 246 * load_[pub]key() has already printed an appropriate message 247 */ 248 goto end; 249 } 250 type = EVP_PKEY_id(sigkey); 251 if (type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448) { 252 /* 253 * We implement PureEdDSA for these which doesn't have a separate 254 * digest, and only supports one shot. 255 */ 256 BIO_printf(bio_err, "Key type not supported for this operation\n"); 257 goto end; 258 } 259 } 260 261 if (mac_name != NULL) { 262 EVP_PKEY_CTX *mac_ctx = NULL; 263 int r = 0; 264 if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) 265 goto mac_end; 266 if (macopts != NULL) { 267 char *macopt; 268 for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { 269 macopt = sk_OPENSSL_STRING_value(macopts, i); 270 if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { 271 BIO_printf(bio_err, 272 "MAC parameter error \"%s\"\n", macopt); 273 ERR_print_errors(bio_err); 274 goto mac_end; 275 } 276 } 277 } 278 if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { 279 BIO_puts(bio_err, "Error generating key\n"); 280 ERR_print_errors(bio_err); 281 goto mac_end; 282 } 283 r = 1; 284 mac_end: 285 EVP_PKEY_CTX_free(mac_ctx); 286 if (r == 0) 287 goto end; 288 } 289 290 if (hmac_key != NULL) { 291 sigkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, impl, 292 (unsigned char *)hmac_key, -1); 293 if (sigkey == NULL) 294 goto end; 295 } 296 297 if (sigkey != NULL) { 298 EVP_MD_CTX *mctx = NULL; 299 EVP_PKEY_CTX *pctx = NULL; 300 int r; 301 if (!BIO_get_md_ctx(bmd, &mctx)) { 302 BIO_printf(bio_err, "Error getting context\n"); 303 ERR_print_errors(bio_err); 304 goto end; 305 } 306 if (do_verify) 307 r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); 308 else 309 r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); 310 if (!r) { 311 BIO_printf(bio_err, "Error setting context\n"); 312 ERR_print_errors(bio_err); 313 goto end; 314 } 315 if (sigopts != NULL) { 316 char *sigopt; 317 for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { 318 sigopt = sk_OPENSSL_STRING_value(sigopts, i); 319 if (pkey_ctrl_string(pctx, sigopt) <= 0) { 320 BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); 321 ERR_print_errors(bio_err); 322 goto end; 323 } 324 } 325 } 326 } 327 /* we use md as a filter, reading from 'in' */ 328 else { 329 EVP_MD_CTX *mctx = NULL; 330 if (!BIO_get_md_ctx(bmd, &mctx)) { 331 BIO_printf(bio_err, "Error getting context\n"); 332 ERR_print_errors(bio_err); 333 goto end; 334 } 335 if (md == NULL) 336 md = EVP_sha256(); 337 if (!EVP_DigestInit_ex(mctx, md, impl)) { 338 BIO_printf(bio_err, "Error setting digest\n"); 339 ERR_print_errors(bio_err); 340 goto end; 341 } 342 } 343 344 if (sigfile != NULL && sigkey != NULL) { 345 BIO *sigbio = BIO_new_file(sigfile, "rb"); 346 if (sigbio == NULL) { 347 BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); 348 ERR_print_errors(bio_err); 349 goto end; 350 } 351 siglen = EVP_PKEY_size(sigkey); 352 sigbuf = app_malloc(siglen, "signature buffer"); 353 siglen = BIO_read(sigbio, sigbuf, siglen); 354 BIO_free(sigbio); 355 if (siglen <= 0) { 356 BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); 357 ERR_print_errors(bio_err); 358 goto end; 359 } 360 } 361 inp = BIO_push(bmd, in); 362 363 if (md == NULL) { 364 EVP_MD_CTX *tctx; 365 BIO_get_md_ctx(bmd, &tctx); 366 md = EVP_MD_CTX_md(tctx); 367 } 368 369 if (argc == 0) { 370 BIO_set_fp(in, stdin, BIO_NOCLOSE); 371 ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, 372 siglen, NULL, NULL, "stdin"); 373 } else { 374 const char *md_name = NULL, *sig_name = NULL; 375 if (!out_bin) { 376 if (sigkey != NULL) { 377 const EVP_PKEY_ASN1_METHOD *ameth; 378 ameth = EVP_PKEY_get0_asn1(sigkey); 379 if (ameth) 380 EVP_PKEY_asn1_get0_info(NULL, NULL, 381 NULL, NULL, &sig_name, ameth); 382 } 383 if (md != NULL) 384 md_name = EVP_MD_name(md); 385 } 386 ret = 0; 387 for (i = 0; i < argc; i++) { 388 int r; 389 if (BIO_read_filename(in, argv[i]) <= 0) { 390 perror(argv[i]); 391 ret++; 392 continue; 393 } else { 394 r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, 395 siglen, sig_name, md_name, argv[i]); 396 } 397 if (r) 398 ret = r; 399 (void)BIO_reset(bmd); 400 } 401 } 402 end: 403 OPENSSL_clear_free(buf, BUFSIZE); 404 BIO_free(in); 405 OPENSSL_free(passin); 406 BIO_free_all(out); 407 EVP_PKEY_free(sigkey); 408 sk_OPENSSL_STRING_free(sigopts); 409 sk_OPENSSL_STRING_free(macopts); 410 OPENSSL_free(sigbuf); 411 BIO_free(bmd); 412 release_engine(e); 413 return ret; 414 } 415 416 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, 417 EVP_PKEY *key, unsigned char *sigin, int siglen, 418 const char *sig_name, const char *md_name, 419 const char *file) 420 { 421 size_t len; 422 int i; 423 424 for (;;) { 425 i = BIO_read(bp, (char *)buf, BUFSIZE); 426 if (i < 0) { 427 BIO_printf(bio_err, "Read Error in %s\n", file); 428 ERR_print_errors(bio_err); 429 return 1; 430 } 431 if (i == 0) 432 break; 433 } 434 if (sigin != NULL) { 435 EVP_MD_CTX *ctx; 436 BIO_get_md_ctx(bp, &ctx); 437 i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); 438 if (i > 0) { 439 BIO_printf(out, "Verified OK\n"); 440 } else if (i == 0) { 441 BIO_printf(out, "Verification Failure\n"); 442 return 1; 443 } else { 444 BIO_printf(bio_err, "Error Verifying Data\n"); 445 ERR_print_errors(bio_err); 446 return 1; 447 } 448 return 0; 449 } 450 if (key != NULL) { 451 EVP_MD_CTX *ctx; 452 BIO_get_md_ctx(bp, &ctx); 453 len = BUFSIZE; 454 if (!EVP_DigestSignFinal(ctx, buf, &len)) { 455 BIO_printf(bio_err, "Error Signing Data\n"); 456 ERR_print_errors(bio_err); 457 return 1; 458 } 459 } else { 460 len = BIO_gets(bp, (char *)buf, BUFSIZE); 461 if ((int)len < 0) { 462 ERR_print_errors(bio_err); 463 return 1; 464 } 465 } 466 467 if (binout) { 468 BIO_write(out, buf, len); 469 } else if (sep == 2) { 470 for (i = 0; i < (int)len; i++) 471 BIO_printf(out, "%02x", buf[i]); 472 BIO_printf(out, " *%s\n", file); 473 } else { 474 if (sig_name != NULL) { 475 BIO_puts(out, sig_name); 476 if (md_name != NULL) 477 BIO_printf(out, "-%s", md_name); 478 BIO_printf(out, "(%s)= ", file); 479 } else if (md_name != NULL) { 480 BIO_printf(out, "%s(%s)= ", md_name, file); 481 } else { 482 BIO_printf(out, "(%s)= ", file); 483 } 484 for (i = 0; i < (int)len; i++) { 485 if (sep && (i != 0)) 486 BIO_printf(out, ":"); 487 BIO_printf(out, "%02x", buf[i]); 488 } 489 BIO_printf(out, "\n"); 490 } 491 return 0; 492 } 493