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