dgst.c revision 279264
164562Sgshapiro/* apps/dgst.c */ 264562Sgshapiro/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 364562Sgshapiro * All rights reserved. 464562Sgshapiro * 564562Sgshapiro * This package is an SSL implementation written 6111823Sgshapiro * by Eric Young (eay@cryptsoft.com). 764562Sgshapiro * The implementation was written so as to conform with Netscapes SSL. 864562Sgshapiro * 964562Sgshapiro * This library is free for commercial and non-commercial use as long as 1064562Sgshapiro * the following conditions are aheared to. The following conditions 1164562Sgshapiro * apply to all code found in this distribution, be it the RC4, RSA, 1264562Sgshapiro * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1364562Sgshapiro * included with this distribution is covered by the same copyright terms 1464562Sgshapiro * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1564562Sgshapiro * 1664562Sgshapiro * Copyright remains Eric Young's, and as such any Copyright notices in 17159609Sgshapiro * the code are not to be removed. 1864562Sgshapiro * If this package is used in a product, Eric Young should be given attribution 1964562Sgshapiro * as the author of the parts of the library used. 2064562Sgshapiro * This can be in the form of a textual message at program startup or 2164562Sgshapiro * in documentation (online or textual) provided with the package. 2264562Sgshapiro * 2364562Sgshapiro * Redistribution and use in source and binary forms, with or without 2464562Sgshapiro * modification, are permitted provided that the following conditions 2564562Sgshapiro * are met: 26159609Sgshapiro * 1. Redistributions of source code must retain the copyright 27159609Sgshapiro * notice, this list of conditions and the following disclaimer. 28159609Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright 29159609Sgshapiro * notice, this list of conditions and the following disclaimer in the 30159609Sgshapiro * documentation and/or other materials provided with the distribution. 31159609Sgshapiro * 3. All advertising materials mentioning features or use of this software 32159609Sgshapiro * must display the following acknowledgement: 33159609Sgshapiro * "This product includes cryptographic software written by 34159609Sgshapiro * Eric Young (eay@cryptsoft.com)" 35159609Sgshapiro * The word 'cryptographic' can be left out if the rouines from the library 36159609Sgshapiro * being used are not cryptographic related :-). 37159609Sgshapiro * 4. If you include any Windows specific code (or a derivative thereof) from 38159609Sgshapiro * the apps directory (application code) you must include an acknowledgement: 39159609Sgshapiro * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40159609Sgshapiro * 41159609Sgshapiro * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42159609Sgshapiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43159609Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44159609Sgshapiro * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45159609Sgshapiro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46159609Sgshapiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4780785Sgshapiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48159609Sgshapiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49159609Sgshapiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50159609Sgshapiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51159609Sgshapiro * SUCH DAMAGE. 52159609Sgshapiro * 53159609Sgshapiro * The licence and distribution terms for any publically available version or 54159609Sgshapiro * derivative of this code cannot be changed. i.e. this code cannot simply be 55159609Sgshapiro * copied and put under another distribution licence 56159609Sgshapiro * [including the GNU Public Licence.] 57159609Sgshapiro */ 58159609Sgshapiro 59159609Sgshapiro#include <stdio.h> 60159609Sgshapiro#include <string.h> 61159609Sgshapiro#include <stdlib.h> 62159609Sgshapiro#include "apps.h" 63159609Sgshapiro#include <openssl/bio.h> 64159609Sgshapiro#include <openssl/err.h> 65159609Sgshapiro#include <openssl/evp.h> 6680785Sgshapiro#include <openssl/objects.h> 67159609Sgshapiro#include <openssl/x509.h> 68159609Sgshapiro#include <openssl/pem.h> 69159609Sgshapiro#include <openssl/hmac.h> 70159609Sgshapiro 71159609Sgshapiro#undef BUFSIZE 72159609Sgshapiro#define BUFSIZE 1024*8 73159609Sgshapiro 74159609Sgshapiro#undef PROG 75159609Sgshapiro#define PROG dgst_main 76159609Sgshapiro 77159609Sgshapiroint do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, 78159609Sgshapiro EVP_PKEY *key, unsigned char *sigin, int siglen, 79159609Sgshapiro const char *sig_name, const char *md_name, 80159609Sgshapiro const char *file,BIO *bmd); 81159609Sgshapiro 82159609Sgshapirostatic void list_md_fn(const EVP_MD *m, 83159609Sgshapiro const char *from, const char *to, void *arg) 84159609Sgshapiro { 85159609Sgshapiro const char *mname; 86159609Sgshapiro /* Skip aliases */ 87159609Sgshapiro if (!m) 88159609Sgshapiro return; 89159609Sgshapiro mname = OBJ_nid2ln(EVP_MD_type(m)); 90159609Sgshapiro /* Skip shortnames */ 91159609Sgshapiro if (strcmp(from, mname)) 92159609Sgshapiro return; 93159609Sgshapiro /* Skip clones */ 94159609Sgshapiro if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST) 95159609Sgshapiro return; 96159609Sgshapiro if (strchr(mname, ' ')) 97159609Sgshapiro mname= EVP_MD_name(m); 98159609Sgshapiro BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n", 99159609Sgshapiro mname, mname); 100159609Sgshapiro } 101159609Sgshapiro 102159609Sgshapiroint MAIN(int, char **); 103159609Sgshapiro 104159609Sgshapiroint MAIN(int argc, char **argv) 105159609Sgshapiro { 106159609Sgshapiro ENGINE *e = NULL; 107159609Sgshapiro unsigned char *buf=NULL; 108159609Sgshapiro int i,err=1; 109159609Sgshapiro const EVP_MD *md=NULL,*m; 110159609Sgshapiro BIO *in=NULL,*inp; 111159609Sgshapiro BIO *bmd=NULL; 112159609Sgshapiro BIO *out = NULL; 113159609Sgshapiro#define PROG_NAME_SIZE 39 114159609Sgshapiro char pname[PROG_NAME_SIZE+1]; 115159609Sgshapiro int separator=0; 116159609Sgshapiro int debug=0; 117159609Sgshapiro int keyform=FORMAT_PEM; 118159609Sgshapiro const char *outfile = NULL, *keyfile = NULL; 119159609Sgshapiro const char *sigfile = NULL, *randfile = NULL; 120159609Sgshapiro int out_bin = -1, want_pub = 0, do_verify = 0; 121159609Sgshapiro EVP_PKEY *sigkey = NULL; 122159609Sgshapiro unsigned char *sigbuf = NULL; 123159609Sgshapiro int siglen = 0; 124159609Sgshapiro char *passargin = NULL, *passin = NULL; 125159609Sgshapiro#ifndef OPENSSL_NO_ENGINE 126159609Sgshapiro char *engine=NULL; 127159609Sgshapiro#endif 128159609Sgshapiro char *hmac_key=NULL; 129159609Sgshapiro char *mac_name=NULL; 130159609Sgshapiro int non_fips_allow = 0; 131159609Sgshapiro STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; 132159609Sgshapiro 133159609Sgshapiro apps_startup(); 134159609Sgshapiro 135159609Sgshapiro if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) 136159609Sgshapiro { 137159609Sgshapiro BIO_printf(bio_err,"out of memory\n"); 138159609Sgshapiro goto end; 139159609Sgshapiro } 140159609Sgshapiro if (bio_err == NULL) 141159609Sgshapiro if ((bio_err=BIO_new(BIO_s_file())) != NULL) 14264562Sgshapiro BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); 14364562Sgshapiro 14464562Sgshapiro if (!load_config(bio_err, NULL)) 145261370Sgshapiro goto end; 146261370Sgshapiro 147261370Sgshapiro /* first check the program name */ 148261370Sgshapiro program_name(argv[0],pname,sizeof pname); 149261370Sgshapiro 150261370Sgshapiro md=EVP_get_digestbyname(pname); 151261370Sgshapiro 152261370Sgshapiro argc--; 153261370Sgshapiro argv++; 154261370Sgshapiro while (argc > 0) 155261370Sgshapiro { 156261370Sgshapiro if ((*argv)[0] != '-') break; 157261370Sgshapiro if (strcmp(*argv,"-c") == 0) 158261370Sgshapiro separator=1; 159261370Sgshapiro else if (strcmp(*argv,"-r") == 0) 160261370Sgshapiro separator=2; 161261370Sgshapiro else if (strcmp(*argv,"-rand") == 0) 162261370Sgshapiro { 163261370Sgshapiro if (--argc < 1) break; 164261370Sgshapiro randfile=*(++argv); 165261370Sgshapiro } 166261370Sgshapiro else if (strcmp(*argv,"-out") == 0) 167261370Sgshapiro { 168261370Sgshapiro if (--argc < 1) break; 169261370Sgshapiro outfile=*(++argv); 170261370Sgshapiro } 171261370Sgshapiro else if (strcmp(*argv,"-sign") == 0) 172261370Sgshapiro { 173261370Sgshapiro if (--argc < 1) break; 174261370Sgshapiro keyfile=*(++argv); 175261370Sgshapiro } 176261370Sgshapiro else if (!strcmp(*argv,"-passin")) 177261370Sgshapiro { 178261370Sgshapiro if (--argc < 1) 179261370Sgshapiro break; 180261370Sgshapiro passargin=*++argv; 181261370Sgshapiro } 182261370Sgshapiro else if (strcmp(*argv,"-verify") == 0) 183261370Sgshapiro { 184261370Sgshapiro if (--argc < 1) break; 185261370Sgshapiro keyfile=*(++argv); 186261370Sgshapiro want_pub = 1; 187261370Sgshapiro do_verify = 1; 188261370Sgshapiro } 189261370Sgshapiro else if (strcmp(*argv,"-prverify") == 0) 190261370Sgshapiro { 191261370Sgshapiro if (--argc < 1) break; 192261370Sgshapiro keyfile=*(++argv); 193261370Sgshapiro do_verify = 1; 194261370Sgshapiro } 195261370Sgshapiro else if (strcmp(*argv,"-signature") == 0) 196261370Sgshapiro { 197261370Sgshapiro if (--argc < 1) break; 198261370Sgshapiro sigfile=*(++argv); 199261370Sgshapiro } 200261370Sgshapiro else if (strcmp(*argv,"-keyform") == 0) 201261370Sgshapiro { 202261370Sgshapiro if (--argc < 1) break; 203261370Sgshapiro keyform=str2fmt(*(++argv)); 204261370Sgshapiro } 205261370Sgshapiro#ifndef OPENSSL_NO_ENGINE 206261370Sgshapiro else if (strcmp(*argv,"-engine") == 0) 207261370Sgshapiro { 208261370Sgshapiro if (--argc < 1) break; 209261370Sgshapiro engine= *(++argv); 210261370Sgshapiro e = setup_engine(bio_err, engine, 0); 211261370Sgshapiro } 212261370Sgshapiro#endif 213261370Sgshapiro else if (strcmp(*argv,"-hex") == 0) 214261370Sgshapiro out_bin = 0; 215261370Sgshapiro else if (strcmp(*argv,"-binary") == 0) 216261370Sgshapiro out_bin = 1; 217261370Sgshapiro else if (strcmp(*argv,"-d") == 0) 218261370Sgshapiro debug=1; 219261370Sgshapiro else if (!strcmp(*argv,"-fips-fingerprint")) 220261370Sgshapiro hmac_key = "etaonrishdlcupfm"; 221261370Sgshapiro else if (strcmp(*argv,"-non-fips-allow") == 0) 222261370Sgshapiro non_fips_allow=1; 223261370Sgshapiro else if (!strcmp(*argv,"-hmac")) 224261370Sgshapiro { 225261370Sgshapiro if (--argc < 1) 226261370Sgshapiro break; 227261370Sgshapiro hmac_key=*++argv; 228261370Sgshapiro } 229261370Sgshapiro else if (!strcmp(*argv,"-mac")) 230261370Sgshapiro { 231261370Sgshapiro if (--argc < 1) 232261370Sgshapiro break; 233261370Sgshapiro mac_name=*++argv; 234261370Sgshapiro } 235261370Sgshapiro else if (strcmp(*argv,"-sigopt") == 0) 236261370Sgshapiro { 237261370Sgshapiro if (--argc < 1) 238261370Sgshapiro break; 239261370Sgshapiro if (!sigopts) 240261370Sgshapiro sigopts = sk_OPENSSL_STRING_new_null(); 241261370Sgshapiro if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) 242261370Sgshapiro break; 243261370Sgshapiro } 244261370Sgshapiro else if (strcmp(*argv,"-macopt") == 0) 245261370Sgshapiro { 246261370Sgshapiro if (--argc < 1) 247261370Sgshapiro break; 248261370Sgshapiro if (!macopts) 249261370Sgshapiro macopts = sk_OPENSSL_STRING_new_null(); 250261370Sgshapiro if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv))) 251261370Sgshapiro break; 252261370Sgshapiro } 253261370Sgshapiro else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL) 254261370Sgshapiro md=m; 255261370Sgshapiro else 256261370Sgshapiro break; 257261370Sgshapiro argc--; 258261370Sgshapiro argv++; 259261370Sgshapiro } 260261370Sgshapiro 261261370Sgshapiro 262261370Sgshapiro if(do_verify && !sigfile) { 263261370Sgshapiro BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); 264261370Sgshapiro goto end; 265261370Sgshapiro } 266261370Sgshapiro 267261370Sgshapiro if ((argc > 0) && (argv[0][0] == '-')) /* bad option */ 268261370Sgshapiro { 269261370Sgshapiro BIO_printf(bio_err,"unknown option '%s'\n",*argv); 270261370Sgshapiro BIO_printf(bio_err,"options are\n"); 271261370Sgshapiro BIO_printf(bio_err,"-c to output the digest with separating colons\n"); 272261370Sgshapiro BIO_printf(bio_err,"-r to output the digest in coreutils format\n"); 273261370Sgshapiro BIO_printf(bio_err,"-d to output debug info\n"); 274261370Sgshapiro BIO_printf(bio_err,"-hex output as hex dump\n"); 275261370Sgshapiro BIO_printf(bio_err,"-binary output in binary form\n"); 276261370Sgshapiro BIO_printf(bio_err,"-hmac arg set the HMAC key to arg\n"); 277261370Sgshapiro BIO_printf(bio_err,"-non-fips-allow allow use of non FIPS digest\n"); 278261370Sgshapiro BIO_printf(bio_err,"-sign file sign digest using private key in file\n"); 279261370Sgshapiro BIO_printf(bio_err,"-verify file verify a signature using public key in file\n"); 280261370Sgshapiro BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n"); 281261370Sgshapiro BIO_printf(bio_err,"-keyform arg key file format (PEM or ENGINE)\n"); 282261370Sgshapiro BIO_printf(bio_err,"-out filename output to filename rather than stdout\n"); 283261370Sgshapiro BIO_printf(bio_err,"-signature file signature to verify\n"); 284261370Sgshapiro BIO_printf(bio_err,"-sigopt nm:v signature parameter\n"); 285261370Sgshapiro BIO_printf(bio_err,"-hmac key create hashed MAC with key\n"); 286261370Sgshapiro BIO_printf(bio_err,"-mac algorithm create MAC (not neccessarily HMAC)\n"); 287261370Sgshapiro BIO_printf(bio_err,"-macopt nm:v MAC algorithm parameters or key\n"); 288261370Sgshapiro#ifndef OPENSSL_NO_ENGINE 289261370Sgshapiro BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n"); 290261370Sgshapiro#endif 291261370Sgshapiro 292261370Sgshapiro EVP_MD_do_all_sorted(list_md_fn, bio_err); 293261370Sgshapiro goto end; 294261370Sgshapiro } 295261370Sgshapiro 296261370Sgshapiro in=BIO_new(BIO_s_file()); 297261370Sgshapiro bmd=BIO_new(BIO_f_md()); 298261370Sgshapiro if (debug) 299261370Sgshapiro { 300261370Sgshapiro BIO_set_callback(in,BIO_debug_callback); 301261370Sgshapiro /* needed for windows 3.1 */ 302261370Sgshapiro BIO_set_callback_arg(in,(char *)bio_err); 303261370Sgshapiro } 304261370Sgshapiro 305261370Sgshapiro if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) 306261370Sgshapiro { 307261370Sgshapiro BIO_printf(bio_err, "Error getting password\n"); 308261370Sgshapiro goto end; 309261370Sgshapiro } 310261370Sgshapiro 311261370Sgshapiro if ((in == NULL) || (bmd == NULL)) 312261370Sgshapiro { 313261370Sgshapiro ERR_print_errors(bio_err); 314261370Sgshapiro goto end; 315261370Sgshapiro } 316261370Sgshapiro 317261370Sgshapiro if(out_bin == -1) { 318261370Sgshapiro if(keyfile) 319261370Sgshapiro out_bin = 1; 320261370Sgshapiro else 321261370Sgshapiro out_bin = 0; 322261370Sgshapiro } 323249865Sgshapiro 324249865Sgshapiro if(randfile) 325249865Sgshapiro app_RAND_load_file(randfile, bio_err, 0); 326249865Sgshapiro 327249865Sgshapiro if(outfile) { 328249865Sgshapiro if(out_bin) 329249865Sgshapiro out = BIO_new_file(outfile, "wb"); 330249865Sgshapiro else out = BIO_new_file(outfile, "w"); 331249865Sgshapiro } else { 332249865Sgshapiro out = BIO_new_fp(stdout, BIO_NOCLOSE); 333249865Sgshapiro#ifdef OPENSSL_SYS_VMS 334249865Sgshapiro { 335249865Sgshapiro BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 336249865Sgshapiro out = BIO_push(tmpbio, out); 337249865Sgshapiro } 338249865Sgshapiro#endif 339249865Sgshapiro } 340249865Sgshapiro 341249865Sgshapiro if(!out) { 342249865Sgshapiro BIO_printf(bio_err, "Error opening output file %s\n", 343249865Sgshapiro outfile ? outfile : "(stdout)"); 344249865Sgshapiro ERR_print_errors(bio_err); 345249865Sgshapiro goto end; 346249865Sgshapiro } 347249865Sgshapiro if ((!!mac_name + !!keyfile + !!hmac_key) > 1) 348249865Sgshapiro { 349249865Sgshapiro BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); 350249865Sgshapiro goto end; 351249865Sgshapiro } 352249865Sgshapiro 353249865Sgshapiro if(keyfile) 354249865Sgshapiro { 355249865Sgshapiro if (want_pub) 356249865Sgshapiro sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, 357249865Sgshapiro e, "key file"); 358249865Sgshapiro else 359249865Sgshapiro sigkey = load_key(bio_err, keyfile, keyform, 0, passin, 360249865Sgshapiro e, "key file"); 361249865Sgshapiro if (!sigkey) 362249865Sgshapiro { 363249865Sgshapiro /* load_[pub]key() has already printed an appropriate 364249865Sgshapiro message */ 365249865Sgshapiro goto end; 366249865Sgshapiro } 367249865Sgshapiro } 368249865Sgshapiro 369249865Sgshapiro if (mac_name) 370249865Sgshapiro { 371249865Sgshapiro EVP_PKEY_CTX *mac_ctx = NULL; 372249865Sgshapiro int r = 0; 373249865Sgshapiro if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0)) 374249865Sgshapiro goto mac_end; 375249865Sgshapiro if (macopts) 376249865Sgshapiro { 377249865Sgshapiro char *macopt; 378249865Sgshapiro for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) 379249865Sgshapiro { 380249865Sgshapiro macopt = sk_OPENSSL_STRING_value(macopts, i); 381249865Sgshapiro if (pkey_ctrl_string(mac_ctx, macopt) <= 0) 382249865Sgshapiro { 383249865Sgshapiro BIO_printf(bio_err, 384249865Sgshapiro "MAC parameter error \"%s\"\n", 385249865Sgshapiro macopt); 386249865Sgshapiro ERR_print_errors(bio_err); 387249865Sgshapiro goto mac_end; 388249865Sgshapiro } 389249865Sgshapiro } 390249865Sgshapiro } 391249865Sgshapiro if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) 392249865Sgshapiro { 393249865Sgshapiro BIO_puts(bio_err, "Error generating key\n"); 394249865Sgshapiro ERR_print_errors(bio_err); 395249865Sgshapiro goto mac_end; 396249865Sgshapiro } 397249865Sgshapiro r = 1; 398249865Sgshapiro mac_end: 399249865Sgshapiro if (mac_ctx) 400249865Sgshapiro EVP_PKEY_CTX_free(mac_ctx); 401249865Sgshapiro if (r == 0) 402249865Sgshapiro goto end; 403249865Sgshapiro } 404249865Sgshapiro 405249865Sgshapiro if (non_fips_allow) 406249865Sgshapiro { 407249865Sgshapiro EVP_MD_CTX *md_ctx; 408249865Sgshapiro BIO_get_md_ctx(bmd,&md_ctx); 409249865Sgshapiro EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); 410249865Sgshapiro } 411249865Sgshapiro 412249865Sgshapiro if (hmac_key) 413249865Sgshapiro { 414249865Sgshapiro sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e, 415249865Sgshapiro (unsigned char *)hmac_key, -1); 416249865Sgshapiro if (!sigkey) 417249865Sgshapiro goto end; 418249865Sgshapiro } 419249865Sgshapiro 420249865Sgshapiro if (sigkey) 421249865Sgshapiro { 422249865Sgshapiro EVP_MD_CTX *mctx = NULL; 423249865Sgshapiro EVP_PKEY_CTX *pctx = NULL; 424249865Sgshapiro int r; 425249865Sgshapiro if (!BIO_get_md_ctx(bmd, &mctx)) 426249865Sgshapiro { 427249865Sgshapiro BIO_printf(bio_err, "Error getting context\n"); 428249865Sgshapiro ERR_print_errors(bio_err); 429249865Sgshapiro goto end; 430249865Sgshapiro } 431249865Sgshapiro if (do_verify) 432249865Sgshapiro r = EVP_DigestVerifyInit(mctx, &pctx, md, NULL, sigkey); 433249865Sgshapiro else 434249865Sgshapiro r = EVP_DigestSignInit(mctx, &pctx, md, NULL, sigkey); 435249865Sgshapiro if (!r) 436249865Sgshapiro { 437249865Sgshapiro BIO_printf(bio_err, "Error setting context\n"); 438249865Sgshapiro ERR_print_errors(bio_err); 439249865Sgshapiro goto end; 440249865Sgshapiro } 441249865Sgshapiro if (sigopts) 442249865Sgshapiro { 443249865Sgshapiro char *sigopt; 444249865Sgshapiro for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) 445249865Sgshapiro { 446249865Sgshapiro sigopt = sk_OPENSSL_STRING_value(sigopts, i); 447249865Sgshapiro if (pkey_ctrl_string(pctx, sigopt) <= 0) 448249865Sgshapiro { 449249865Sgshapiro BIO_printf(bio_err, 450249865Sgshapiro "parameter error \"%s\"\n", 451249865Sgshapiro sigopt); 452249865Sgshapiro ERR_print_errors(bio_err); 453249865Sgshapiro goto end; 454249865Sgshapiro } 455249865Sgshapiro } 456249865Sgshapiro } 457249865Sgshapiro } 458249865Sgshapiro /* we use md as a filter, reading from 'in' */ 459249865Sgshapiro else 460244928Sgshapiro { 461244928Sgshapiro if (md == NULL) 462244928Sgshapiro md = EVP_md5(); 463244928Sgshapiro if (!BIO_set_md(bmd,md)) 464244928Sgshapiro { 465244928Sgshapiro BIO_printf(bio_err, "Error setting digest %s\n", pname); 466244928Sgshapiro ERR_print_errors(bio_err); 467244928Sgshapiro goto end; 468244928Sgshapiro } 469244928Sgshapiro } 470244928Sgshapiro 471244928Sgshapiro if(sigfile && sigkey) { 472244928Sgshapiro BIO *sigbio; 473244928Sgshapiro sigbio = BIO_new_file(sigfile, "rb"); 474244928Sgshapiro siglen = EVP_PKEY_size(sigkey); 475244928Sgshapiro sigbuf = OPENSSL_malloc(siglen); 476244928Sgshapiro if(!sigbio) { 477244928Sgshapiro BIO_printf(bio_err, "Error opening signature file %s\n", 478244928Sgshapiro sigfile); 479244928Sgshapiro ERR_print_errors(bio_err); 480244928Sgshapiro goto end; 481244928Sgshapiro } 482244928Sgshapiro siglen = BIO_read(sigbio, sigbuf, siglen); 483244928Sgshapiro BIO_free(sigbio); 484244928Sgshapiro if(siglen <= 0) { 485244928Sgshapiro BIO_printf(bio_err, "Error reading signature file %s\n", 486244928Sgshapiro sigfile); 487244928Sgshapiro ERR_print_errors(bio_err); 488244928Sgshapiro goto end; 489244928Sgshapiro } 490244928Sgshapiro } 491244928Sgshapiro inp=BIO_push(bmd,in); 492244928Sgshapiro 493244928Sgshapiro if (md == NULL) 494244928Sgshapiro { 495244928Sgshapiro EVP_MD_CTX *tctx; 496244928Sgshapiro BIO_get_md_ctx(bmd, &tctx); 497244928Sgshapiro md = EVP_MD_CTX_md(tctx); 498244928Sgshapiro } 499244928Sgshapiro 500244928Sgshapiro if (argc == 0) 501244928Sgshapiro { 502244928Sgshapiro BIO_set_fp(in,stdin,BIO_NOCLOSE); 503244928Sgshapiro err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, 504244928Sgshapiro siglen,NULL,NULL,"stdin",bmd); 505244928Sgshapiro } 506244928Sgshapiro else 507244928Sgshapiro { 508244928Sgshapiro const char *md_name = NULL, *sig_name = NULL; 509244928Sgshapiro if(!out_bin) 510244928Sgshapiro { 511244928Sgshapiro if (sigkey) 512244928Sgshapiro { 513244928Sgshapiro const EVP_PKEY_ASN1_METHOD *ameth; 514244928Sgshapiro ameth = EVP_PKEY_get0_asn1(sigkey); 515244928Sgshapiro if (ameth) 516244928Sgshapiro EVP_PKEY_asn1_get0_info(NULL, NULL, 517244928Sgshapiro NULL, NULL, &sig_name, ameth); 518244928Sgshapiro } 519244928Sgshapiro md_name = EVP_MD_name(md); 520244928Sgshapiro } 521244928Sgshapiro err = 0; 522244928Sgshapiro for (i=0; i<argc; i++) 523244928Sgshapiro { 524244928Sgshapiro int r; 525244928Sgshapiro if (BIO_read_filename(in,argv[i]) <= 0) 526244928Sgshapiro { 527244928Sgshapiro perror(argv[i]); 528244928Sgshapiro err++; 529244928Sgshapiro continue; 530244928Sgshapiro } 531244928Sgshapiro else 532244928Sgshapiro r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf, 533244928Sgshapiro siglen,sig_name,md_name, argv[i],bmd); 534244928Sgshapiro if(r) 535244928Sgshapiro err=r; 536244928Sgshapiro (void)BIO_reset(bmd); 537244928Sgshapiro } 538244928Sgshapiro } 539244928Sgshapiroend: 540244928Sgshapiro if (buf != NULL) 541244928Sgshapiro { 542244928Sgshapiro OPENSSL_cleanse(buf,BUFSIZE); 543244928Sgshapiro OPENSSL_free(buf); 544244928Sgshapiro } 545244928Sgshapiro if (in != NULL) BIO_free(in); 546244928Sgshapiro if (passin) 547244928Sgshapiro OPENSSL_free(passin); 548244928Sgshapiro BIO_free_all(out); 549244928Sgshapiro EVP_PKEY_free(sigkey); 550244928Sgshapiro if (sigopts) 551244928Sgshapiro sk_OPENSSL_STRING_free(sigopts); 552244928Sgshapiro if (macopts) 553244928Sgshapiro sk_OPENSSL_STRING_free(macopts); 554244928Sgshapiro if(sigbuf) OPENSSL_free(sigbuf); 555244928Sgshapiro if (bmd != NULL) BIO_free(bmd); 556244928Sgshapiro apps_shutdown(); 557244928Sgshapiro OPENSSL_EXIT(err); 558244928Sgshapiro } 559244928Sgshapiro 560244928Sgshapiroint do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, 561244928Sgshapiro EVP_PKEY *key, unsigned char *sigin, int siglen, 562244928Sgshapiro const char *sig_name, const char *md_name, 563244928Sgshapiro const char *file,BIO *bmd) 564244928Sgshapiro { 565244928Sgshapiro size_t len; 566244928Sgshapiro int i; 567244928Sgshapiro 568244928Sgshapiro for (;;) 569244928Sgshapiro { 570244928Sgshapiro i=BIO_read(bp,(char *)buf,BUFSIZE); 571244928Sgshapiro if(i < 0) 572244928Sgshapiro { 573244928Sgshapiro BIO_printf(bio_err, "Read Error in %s\n",file); 574244928Sgshapiro ERR_print_errors(bio_err); 575244928Sgshapiro return 1; 576244928Sgshapiro } 577244928Sgshapiro if (i == 0) break; 578244928Sgshapiro } 579244928Sgshapiro if(sigin) 580244928Sgshapiro { 581244928Sgshapiro EVP_MD_CTX *ctx; 582244928Sgshapiro BIO_get_md_ctx(bp, &ctx); 583244928Sgshapiro i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); 584244928Sgshapiro if(i > 0) 585244928Sgshapiro BIO_printf(out, "Verified OK\n"); 586244928Sgshapiro else if(i == 0) 587244928Sgshapiro { 588244928Sgshapiro BIO_printf(out, "Verification Failure\n"); 589244928Sgshapiro return 1; 590244928Sgshapiro } 591244928Sgshapiro else 592244928Sgshapiro { 593244928Sgshapiro BIO_printf(bio_err, "Error Verifying Data\n"); 594244928Sgshapiro ERR_print_errors(bio_err); 595244928Sgshapiro return 1; 596244928Sgshapiro } 597244928Sgshapiro return 0; 598244928Sgshapiro } 599244928Sgshapiro if(key) 600244928Sgshapiro { 601244928Sgshapiro EVP_MD_CTX *ctx; 602244928Sgshapiro BIO_get_md_ctx(bp, &ctx); 603223067Sgshapiro len = BUFSIZE; 604223067Sgshapiro if(!EVP_DigestSignFinal(ctx, buf, &len)) 605223067Sgshapiro { 606223067Sgshapiro BIO_printf(bio_err, "Error Signing Data\n"); 607223067Sgshapiro ERR_print_errors(bio_err); 608223067Sgshapiro return 1; 609223067Sgshapiro } 610223067Sgshapiro } 611223067Sgshapiro else 612223067Sgshapiro { 613223067Sgshapiro len=BIO_gets(bp,(char *)buf,BUFSIZE); 614223067Sgshapiro if ((int)len <0) 615223067Sgshapiro { 616223067Sgshapiro ERR_print_errors(bio_err); 617223067Sgshapiro return 1; 618223067Sgshapiro } 619223067Sgshapiro } 620223067Sgshapiro 621223067Sgshapiro if(binout) BIO_write(out, buf, len); 622223067Sgshapiro else if (sep == 2) 623223067Sgshapiro { 624223067Sgshapiro for (i=0; i<(int)len; i++) 625223067Sgshapiro BIO_printf(out, "%02x",buf[i]); 626223067Sgshapiro BIO_printf(out, " *%s\n", file); 627223067Sgshapiro } 628223067Sgshapiro else 629223067Sgshapiro { 630223067Sgshapiro if (sig_name) 631223067Sgshapiro BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file); 632223067Sgshapiro else if (md_name) 633223067Sgshapiro BIO_printf(out, "%s(%s)= ", md_name, file); 634223067Sgshapiro else 635223067Sgshapiro BIO_printf(out, "(%s)= ", file); 636223067Sgshapiro for (i=0; i<(int)len; i++) 637223067Sgshapiro { 638223067Sgshapiro if (sep && (i != 0)) 639223067Sgshapiro BIO_printf(out, ":"); 640223067Sgshapiro BIO_printf(out, "%02x",buf[i]); 641223067Sgshapiro } 642223067Sgshapiro BIO_printf(out, "\n"); 643223067Sgshapiro } 644223067Sgshapiro return 0; 645223067Sgshapiro } 646223067Sgshapiro 647223067Sgshapiro