155714Skris/* apps/dgst.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <string.h> 6155714Skris#include <stdlib.h> 6255714Skris#include "apps.h" 6355714Skris#include <openssl/bio.h> 6455714Skris#include <openssl/err.h> 6555714Skris#include <openssl/evp.h> 6655714Skris#include <openssl/objects.h> 6755714Skris#include <openssl/x509.h> 6855714Skris#include <openssl/pem.h> 69167612Ssimon#include <openssl/hmac.h> 7055714Skris 7155714Skris#undef BUFSIZE 7255714Skris#define BUFSIZE 1024*8 7355714Skris 7455714Skris#undef PROG 7555714Skris#define PROG dgst_main 7655714Skris 77109998Smarkmint do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, 78238405Sjkim EVP_PKEY *key, unsigned char *sigin, int siglen, 79238405Sjkim const char *sig_name, const char *md_name, 80238405Sjkim const char *file,BIO *bmd); 8159191Skris 82238405Sjkimstatic void list_md_fn(const EVP_MD *m, 83238405Sjkim const char *from, const char *to, void *arg) 84238405Sjkim { 85238405Sjkim const char *mname; 86238405Sjkim /* Skip aliases */ 87238405Sjkim if (!m) 88238405Sjkim return; 89238405Sjkim mname = OBJ_nid2ln(EVP_MD_type(m)); 90238405Sjkim /* Skip shortnames */ 91238405Sjkim if (strcmp(from, mname)) 92238405Sjkim return; 93238405Sjkim /* Skip clones */ 94238405Sjkim if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST) 95238405Sjkim return; 96238405Sjkim if (strchr(mname, ' ')) 97238405Sjkim mname= EVP_MD_name(m); 98238405Sjkim BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n", 99238405Sjkim mname, mname); 100238405Sjkim } 101238405Sjkim 10259191Skrisint MAIN(int, char **); 10359191Skris 10455714Skrisint MAIN(int argc, char **argv) 10555714Skris { 106109998Smarkm ENGINE *e = NULL; 10755714Skris unsigned char *buf=NULL; 108194206Ssimon int i,err=1; 10955714Skris const EVP_MD *md=NULL,*m; 11055714Skris BIO *in=NULL,*inp; 11155714Skris BIO *bmd=NULL; 11268651Skris BIO *out = NULL; 113100928Snectar#define PROG_NAME_SIZE 39 114100928Snectar char pname[PROG_NAME_SIZE+1]; 11555714Skris int separator=0; 11655714Skris int debug=0; 117109998Smarkm int keyform=FORMAT_PEM; 11868651Skris const char *outfile = NULL, *keyfile = NULL; 11968651Skris const char *sigfile = NULL, *randfile = NULL; 12079998Skris int out_bin = -1, want_pub = 0, do_verify = 0; 12168651Skris EVP_PKEY *sigkey = NULL; 12268651Skris unsigned char *sigbuf = NULL; 12368651Skris int siglen = 0; 124160814Ssimon char *passargin = NULL, *passin = NULL; 125111147Snectar#ifndef OPENSSL_NO_ENGINE 126109998Smarkm char *engine=NULL; 127111147Snectar#endif 128167612Ssimon char *hmac_key=NULL; 129238405Sjkim char *mac_name=NULL; 130194206Ssimon int non_fips_allow = 0; 131238405Sjkim STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; 13255714Skris 13355714Skris apps_startup(); 134238405Sjkim 13568651Skris if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) 13655714Skris { 13755714Skris BIO_printf(bio_err,"out of memory\n"); 13855714Skris goto end; 13955714Skris } 14055714Skris if (bio_err == NULL) 14155714Skris if ((bio_err=BIO_new(BIO_s_file())) != NULL) 14255714Skris BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); 14355714Skris 144109998Smarkm if (!load_config(bio_err, NULL)) 145109998Smarkm goto end; 146109998Smarkm 14755714Skris /* first check the program name */ 148109998Smarkm program_name(argv[0],pname,sizeof pname); 14955714Skris 15055714Skris md=EVP_get_digestbyname(pname); 15155714Skris 15255714Skris argc--; 15355714Skris argv++; 15455714Skris while (argc > 0) 15555714Skris { 15655714Skris if ((*argv)[0] != '-') break; 15755714Skris if (strcmp(*argv,"-c") == 0) 15855714Skris separator=1; 159238405Sjkim else if (strcmp(*argv,"-r") == 0) 160238405Sjkim separator=2; 16168651Skris else if (strcmp(*argv,"-rand") == 0) 16268651Skris { 16368651Skris if (--argc < 1) break; 16468651Skris randfile=*(++argv); 16568651Skris } 16668651Skris else if (strcmp(*argv,"-out") == 0) 16768651Skris { 16868651Skris if (--argc < 1) break; 16968651Skris outfile=*(++argv); 17068651Skris } 17168651Skris else if (strcmp(*argv,"-sign") == 0) 17268651Skris { 17368651Skris if (--argc < 1) break; 17468651Skris keyfile=*(++argv); 17568651Skris } 176160814Ssimon else if (!strcmp(*argv,"-passin")) 177160814Ssimon { 178160814Ssimon if (--argc < 1) 179160814Ssimon break; 180160814Ssimon passargin=*++argv; 181160814Ssimon } 18268651Skris else if (strcmp(*argv,"-verify") == 0) 18368651Skris { 18468651Skris if (--argc < 1) break; 18568651Skris keyfile=*(++argv); 18668651Skris want_pub = 1; 18768651Skris do_verify = 1; 18868651Skris } 18968651Skris else if (strcmp(*argv,"-prverify") == 0) 19068651Skris { 19168651Skris if (--argc < 1) break; 19268651Skris keyfile=*(++argv); 19368651Skris do_verify = 1; 19468651Skris } 19568651Skris else if (strcmp(*argv,"-signature") == 0) 19668651Skris { 19768651Skris if (--argc < 1) break; 19868651Skris sigfile=*(++argv); 19968651Skris } 200109998Smarkm else if (strcmp(*argv,"-keyform") == 0) 201109998Smarkm { 202109998Smarkm if (--argc < 1) break; 203109998Smarkm keyform=str2fmt(*(++argv)); 204109998Smarkm } 205111147Snectar#ifndef OPENSSL_NO_ENGINE 206109998Smarkm else if (strcmp(*argv,"-engine") == 0) 207109998Smarkm { 208109998Smarkm if (--argc < 1) break; 209109998Smarkm engine= *(++argv); 210238405Sjkim e = setup_engine(bio_err, engine, 0); 211109998Smarkm } 212111147Snectar#endif 21368651Skris else if (strcmp(*argv,"-hex") == 0) 21468651Skris out_bin = 0; 21568651Skris else if (strcmp(*argv,"-binary") == 0) 21668651Skris out_bin = 1; 21755714Skris else if (strcmp(*argv,"-d") == 0) 21855714Skris debug=1; 219246772Sjkim else if (!strcmp(*argv,"-fips-fingerprint")) 220246772Sjkim hmac_key = "etaonrishdlcupfm"; 221194206Ssimon else if (strcmp(*argv,"-non-fips-allow") == 0) 222194206Ssimon non_fips_allow=1; 223167612Ssimon else if (!strcmp(*argv,"-hmac")) 224167612Ssimon { 225167612Ssimon if (--argc < 1) 226167612Ssimon break; 227167612Ssimon hmac_key=*++argv; 228167612Ssimon } 229238405Sjkim else if (!strcmp(*argv,"-mac")) 230238405Sjkim { 231238405Sjkim if (--argc < 1) 232238405Sjkim break; 233238405Sjkim mac_name=*++argv; 234238405Sjkim } 235238405Sjkim else if (strcmp(*argv,"-sigopt") == 0) 236238405Sjkim { 237238405Sjkim if (--argc < 1) 238238405Sjkim break; 239238405Sjkim if (!sigopts) 240238405Sjkim sigopts = sk_OPENSSL_STRING_new_null(); 241238405Sjkim if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) 242238405Sjkim break; 243238405Sjkim } 244238405Sjkim else if (strcmp(*argv,"-macopt") == 0) 245238405Sjkim { 246238405Sjkim if (--argc < 1) 247238405Sjkim break; 248238405Sjkim if (!macopts) 249238405Sjkim macopts = sk_OPENSSL_STRING_new_null(); 250238405Sjkim if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv))) 251238405Sjkim break; 252238405Sjkim } 25355714Skris else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL) 25455714Skris md=m; 25555714Skris else 25655714Skris break; 25755714Skris argc--; 25855714Skris argv++; 25955714Skris } 26055714Skris 26155714Skris 26268651Skris if(do_verify && !sigfile) { 26368651Skris BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); 26468651Skris goto end; 26568651Skris } 26668651Skris 26755714Skris if ((argc > 0) && (argv[0][0] == '-')) /* bad option */ 26855714Skris { 26955714Skris BIO_printf(bio_err,"unknown option '%s'\n",*argv); 27055714Skris BIO_printf(bio_err,"options are\n"); 27168651Skris BIO_printf(bio_err,"-c to output the digest with separating colons\n"); 272238405Sjkim BIO_printf(bio_err,"-r to output the digest in coreutils format\n"); 27368651Skris BIO_printf(bio_err,"-d to output debug info\n"); 27468651Skris BIO_printf(bio_err,"-hex output as hex dump\n"); 27568651Skris BIO_printf(bio_err,"-binary output in binary form\n"); 276279264Sdelphij BIO_printf(bio_err,"-hmac arg set the HMAC key to arg\n"); 277279264Sdelphij BIO_printf(bio_err,"-non-fips-allow allow use of non FIPS digest\n"); 27868651Skris BIO_printf(bio_err,"-sign file sign digest using private key in file\n"); 27968651Skris BIO_printf(bio_err,"-verify file verify a signature using public key in file\n"); 28068651Skris BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n"); 281109998Smarkm BIO_printf(bio_err,"-keyform arg key file format (PEM or ENGINE)\n"); 282238405Sjkim BIO_printf(bio_err,"-out filename output to filename rather than stdout\n"); 28368651Skris BIO_printf(bio_err,"-signature file signature to verify\n"); 284238405Sjkim BIO_printf(bio_err,"-sigopt nm:v signature parameter\n"); 285194206Ssimon BIO_printf(bio_err,"-hmac key create hashed MAC with key\n"); 286238405Sjkim BIO_printf(bio_err,"-mac algorithm create MAC (not neccessarily HMAC)\n"); 287238405Sjkim BIO_printf(bio_err,"-macopt nm:v MAC algorithm parameters or key\n"); 288111147Snectar#ifndef OPENSSL_NO_ENGINE 289109998Smarkm BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n"); 290111147Snectar#endif 29168651Skris 292238405Sjkim EVP_MD_do_all_sorted(list_md_fn, bio_err); 29355714Skris goto end; 29455714Skris } 29568651Skris 29655714Skris in=BIO_new(BIO_s_file()); 29755714Skris bmd=BIO_new(BIO_f_md()); 29855714Skris if (debug) 29955714Skris { 30055714Skris BIO_set_callback(in,BIO_debug_callback); 30155714Skris /* needed for windows 3.1 */ 302167612Ssimon BIO_set_callback_arg(in,(char *)bio_err); 30355714Skris } 30455714Skris 305160814Ssimon if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) 306160814Ssimon { 307160814Ssimon BIO_printf(bio_err, "Error getting password\n"); 308160814Ssimon goto end; 309160814Ssimon } 310160814Ssimon 31155714Skris if ((in == NULL) || (bmd == NULL)) 31255714Skris { 31355714Skris ERR_print_errors(bio_err); 31455714Skris goto end; 31555714Skris } 31655714Skris 31768651Skris if(out_bin == -1) { 318238405Sjkim if(keyfile) 319238405Sjkim out_bin = 1; 320238405Sjkim else 321238405Sjkim out_bin = 0; 32268651Skris } 32368651Skris 32468651Skris if(randfile) 32568651Skris app_RAND_load_file(randfile, bio_err, 0); 32668651Skris 32768651Skris if(outfile) { 32868651Skris if(out_bin) 32968651Skris out = BIO_new_file(outfile, "wb"); 33068651Skris else out = BIO_new_file(outfile, "w"); 33168651Skris } else { 33268651Skris out = BIO_new_fp(stdout, BIO_NOCLOSE); 333109998Smarkm#ifdef OPENSSL_SYS_VMS 33468651Skris { 33568651Skris BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 33668651Skris out = BIO_push(tmpbio, out); 33768651Skris } 33868651Skris#endif 33968651Skris } 34068651Skris 34168651Skris if(!out) { 34268651Skris BIO_printf(bio_err, "Error opening output file %s\n", 34368651Skris outfile ? outfile : "(stdout)"); 34468651Skris ERR_print_errors(bio_err); 34568651Skris goto end; 34668651Skris } 347238405Sjkim if ((!!mac_name + !!keyfile + !!hmac_key) > 1) 348238405Sjkim { 349238405Sjkim BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); 350238405Sjkim goto end; 351238405Sjkim } 35268651Skris 353109998Smarkm if(keyfile) 354109998Smarkm { 355109998Smarkm if (want_pub) 356109998Smarkm sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, 357109998Smarkm e, "key file"); 358109998Smarkm else 359160814Ssimon sigkey = load_key(bio_err, keyfile, keyform, 0, passin, 360109998Smarkm e, "key file"); 361109998Smarkm if (!sigkey) 362109998Smarkm { 363109998Smarkm /* load_[pub]key() has already printed an appropriate 364109998Smarkm message */ 36568651Skris goto end; 366109998Smarkm } 36768651Skris } 36868651Skris 369238405Sjkim if (mac_name) 370238405Sjkim { 371238405Sjkim EVP_PKEY_CTX *mac_ctx = NULL; 372238405Sjkim int r = 0; 373238405Sjkim if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0)) 374238405Sjkim goto mac_end; 375238405Sjkim if (macopts) 376238405Sjkim { 377238405Sjkim char *macopt; 378238405Sjkim for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) 379238405Sjkim { 380238405Sjkim macopt = sk_OPENSSL_STRING_value(macopts, i); 381238405Sjkim if (pkey_ctrl_string(mac_ctx, macopt) <= 0) 382238405Sjkim { 383238405Sjkim BIO_printf(bio_err, 384238405Sjkim "MAC parameter error \"%s\"\n", 385238405Sjkim macopt); 386238405Sjkim ERR_print_errors(bio_err); 387238405Sjkim goto mac_end; 388238405Sjkim } 389238405Sjkim } 390238405Sjkim } 391238405Sjkim if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) 392238405Sjkim { 393238405Sjkim BIO_puts(bio_err, "Error generating key\n"); 394238405Sjkim ERR_print_errors(bio_err); 395238405Sjkim goto mac_end; 396238405Sjkim } 397238405Sjkim r = 1; 398238405Sjkim mac_end: 399238405Sjkim if (mac_ctx) 400238405Sjkim EVP_PKEY_CTX_free(mac_ctx); 401238405Sjkim if (r == 0) 402238405Sjkim goto end; 403238405Sjkim } 404238405Sjkim 405238405Sjkim if (non_fips_allow) 406238405Sjkim { 407238405Sjkim EVP_MD_CTX *md_ctx; 408238405Sjkim BIO_get_md_ctx(bmd,&md_ctx); 409238405Sjkim EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); 410238405Sjkim } 411238405Sjkim 412238405Sjkim if (hmac_key) 413238405Sjkim { 414238405Sjkim sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e, 415238405Sjkim (unsigned char *)hmac_key, -1); 416238405Sjkim if (!sigkey) 417238405Sjkim goto end; 418238405Sjkim } 419238405Sjkim 420238405Sjkim if (sigkey) 421238405Sjkim { 422238405Sjkim EVP_MD_CTX *mctx = NULL; 423238405Sjkim EVP_PKEY_CTX *pctx = NULL; 424238405Sjkim int r; 425238405Sjkim if (!BIO_get_md_ctx(bmd, &mctx)) 426238405Sjkim { 427238405Sjkim BIO_printf(bio_err, "Error getting context\n"); 428238405Sjkim ERR_print_errors(bio_err); 429238405Sjkim goto end; 430238405Sjkim } 431238405Sjkim if (do_verify) 432279264Sdelphij r = EVP_DigestVerifyInit(mctx, &pctx, md, NULL, sigkey); 433238405Sjkim else 434279264Sdelphij r = EVP_DigestSignInit(mctx, &pctx, md, NULL, sigkey); 435238405Sjkim if (!r) 436238405Sjkim { 437238405Sjkim BIO_printf(bio_err, "Error setting context\n"); 438238405Sjkim ERR_print_errors(bio_err); 439238405Sjkim goto end; 440238405Sjkim } 441238405Sjkim if (sigopts) 442238405Sjkim { 443238405Sjkim char *sigopt; 444238405Sjkim for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) 445238405Sjkim { 446238405Sjkim sigopt = sk_OPENSSL_STRING_value(sigopts, i); 447238405Sjkim if (pkey_ctrl_string(pctx, sigopt) <= 0) 448238405Sjkim { 449238405Sjkim BIO_printf(bio_err, 450238405Sjkim "parameter error \"%s\"\n", 451238405Sjkim sigopt); 452238405Sjkim ERR_print_errors(bio_err); 453238405Sjkim goto end; 454238405Sjkim } 455238405Sjkim } 456238405Sjkim } 457238405Sjkim } 458238405Sjkim /* we use md as a filter, reading from 'in' */ 459238405Sjkim else 460238405Sjkim { 461238405Sjkim if (md == NULL) 462238405Sjkim md = EVP_md5(); 463238405Sjkim if (!BIO_set_md(bmd,md)) 464238405Sjkim { 465238405Sjkim BIO_printf(bio_err, "Error setting digest %s\n", pname); 466238405Sjkim ERR_print_errors(bio_err); 467238405Sjkim goto end; 468238405Sjkim } 469238405Sjkim } 470238405Sjkim 47168651Skris if(sigfile && sigkey) { 47268651Skris BIO *sigbio; 47368651Skris sigbio = BIO_new_file(sigfile, "rb"); 47468651Skris siglen = EVP_PKEY_size(sigkey); 47568651Skris sigbuf = OPENSSL_malloc(siglen); 47668651Skris if(!sigbio) { 47768651Skris BIO_printf(bio_err, "Error opening signature file %s\n", 47868651Skris sigfile); 47968651Skris ERR_print_errors(bio_err); 48068651Skris goto end; 48168651Skris } 48268651Skris siglen = BIO_read(sigbio, sigbuf, siglen); 48368651Skris BIO_free(sigbio); 48468651Skris if(siglen <= 0) { 48568651Skris BIO_printf(bio_err, "Error reading signature file %s\n", 48668651Skris sigfile); 48768651Skris ERR_print_errors(bio_err); 48868651Skris goto end; 48968651Skris } 49068651Skris } 491238405Sjkim inp=BIO_push(bmd,in); 49268651Skris 493238405Sjkim if (md == NULL) 494194206Ssimon { 495238405Sjkim EVP_MD_CTX *tctx; 496238405Sjkim BIO_get_md_ctx(bmd, &tctx); 497238405Sjkim md = EVP_MD_CTX_md(tctx); 498194206Ssimon } 499160814Ssimon 50055714Skris if (argc == 0) 50155714Skris { 50255714Skris BIO_set_fp(in,stdin,BIO_NOCLOSE); 503109998Smarkm err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, 504238405Sjkim siglen,NULL,NULL,"stdin",bmd); 50555714Skris } 50655714Skris else 50755714Skris { 508238405Sjkim const char *md_name = NULL, *sig_name = NULL; 509238405Sjkim if(!out_bin) 510238405Sjkim { 511238405Sjkim if (sigkey) 512238405Sjkim { 513238405Sjkim const EVP_PKEY_ASN1_METHOD *ameth; 514238405Sjkim ameth = EVP_PKEY_get0_asn1(sigkey); 515238405Sjkim if (ameth) 516238405Sjkim EVP_PKEY_asn1_get0_info(NULL, NULL, 517238405Sjkim NULL, NULL, &sig_name, ameth); 518238405Sjkim } 519238405Sjkim md_name = EVP_MD_name(md); 520238405Sjkim } 521194206Ssimon err = 0; 52255714Skris for (i=0; i<argc; i++) 52355714Skris { 524109998Smarkm int r; 52555714Skris if (BIO_read_filename(in,argv[i]) <= 0) 52655714Skris { 52755714Skris perror(argv[i]); 52855714Skris err++; 52955714Skris continue; 53055714Skris } 531109998Smarkm else 532109998Smarkm r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf, 533238405Sjkim siglen,sig_name,md_name, argv[i],bmd); 534109998Smarkm if(r) 535109998Smarkm err=r; 53655714Skris (void)BIO_reset(bmd); 53755714Skris } 53855714Skris } 53955714Skrisend: 54055714Skris if (buf != NULL) 54155714Skris { 542109998Smarkm OPENSSL_cleanse(buf,BUFSIZE); 54368651Skris OPENSSL_free(buf); 54455714Skris } 54555714Skris if (in != NULL) BIO_free(in); 546160814Ssimon if (passin) 547160814Ssimon OPENSSL_free(passin); 54868651Skris BIO_free_all(out); 54968651Skris EVP_PKEY_free(sigkey); 550238405Sjkim if (sigopts) 551238405Sjkim sk_OPENSSL_STRING_free(sigopts); 552238405Sjkim if (macopts) 553238405Sjkim sk_OPENSSL_STRING_free(macopts); 55468651Skris if(sigbuf) OPENSSL_free(sigbuf); 55555714Skris if (bmd != NULL) BIO_free(bmd); 556109998Smarkm apps_shutdown(); 557109998Smarkm OPENSSL_EXIT(err); 55855714Skris } 55955714Skris 560109998Smarkmint do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, 561238405Sjkim EVP_PKEY *key, unsigned char *sigin, int siglen, 562238405Sjkim const char *sig_name, const char *md_name, 563238405Sjkim const char *file,BIO *bmd) 56455714Skris { 565238405Sjkim size_t len; 56655714Skris int i; 56755714Skris 56855714Skris for (;;) 56955714Skris { 57055714Skris i=BIO_read(bp,(char *)buf,BUFSIZE); 571109998Smarkm if(i < 0) 572109998Smarkm { 573109998Smarkm BIO_printf(bio_err, "Read Error in %s\n",file); 574109998Smarkm ERR_print_errors(bio_err); 575109998Smarkm return 1; 576109998Smarkm } 577109998Smarkm if (i == 0) break; 57855714Skris } 57968651Skris if(sigin) 58068651Skris { 58168651Skris EVP_MD_CTX *ctx; 58268651Skris BIO_get_md_ctx(bp, &ctx); 583238405Sjkim i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); 584109998Smarkm if(i > 0) 585109998Smarkm BIO_printf(out, "Verified OK\n"); 586109998Smarkm else if(i == 0) 587109998Smarkm { 588109998Smarkm BIO_printf(out, "Verification Failure\n"); 589109998Smarkm return 1; 590109998Smarkm } 59168651Skris else 59268651Skris { 59368651Skris BIO_printf(bio_err, "Error Verifying Data\n"); 59468651Skris ERR_print_errors(bio_err); 595109998Smarkm return 1; 59668651Skris } 597109998Smarkm return 0; 59868651Skris } 59968651Skris if(key) 60068651Skris { 60168651Skris EVP_MD_CTX *ctx; 60268651Skris BIO_get_md_ctx(bp, &ctx); 603238405Sjkim len = BUFSIZE; 604238405Sjkim if(!EVP_DigestSignFinal(ctx, buf, &len)) 60568651Skris { 60668651Skris BIO_printf(bio_err, "Error Signing Data\n"); 60768651Skris ERR_print_errors(bio_err); 608109998Smarkm return 1; 60968651Skris } 61068651Skris } 611238405Sjkim else 612167612Ssimon { 613238405Sjkim len=BIO_gets(bp,(char *)buf,BUFSIZE); 614238405Sjkim if ((int)len <0) 615238405Sjkim { 616238405Sjkim ERR_print_errors(bio_err); 617238405Sjkim return 1; 618238405Sjkim } 619167612Ssimon } 62055714Skris 62168651Skris if(binout) BIO_write(out, buf, len); 622238405Sjkim else if (sep == 2) 623238405Sjkim { 624238405Sjkim for (i=0; i<(int)len; i++) 625238405Sjkim BIO_printf(out, "%02x",buf[i]); 626238405Sjkim BIO_printf(out, " *%s\n", file); 627238405Sjkim } 62868651Skris else 62955714Skris { 630238405Sjkim if (sig_name) 631238405Sjkim BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file); 632238405Sjkim else if (md_name) 633238405Sjkim BIO_printf(out, "%s(%s)= ", md_name, file); 634238405Sjkim else 635238405Sjkim BIO_printf(out, "(%s)= ", file); 636167612Ssimon for (i=0; i<(int)len; i++) 63768651Skris { 63868651Skris if (sep && (i != 0)) 63968651Skris BIO_printf(out, ":"); 64068651Skris BIO_printf(out, "%02x",buf[i]); 64168651Skris } 64268651Skris BIO_printf(out, "\n"); 64355714Skris } 644109998Smarkm return 0; 64555714Skris } 64655714Skris 647