10Sstevel@tonic-gate /* apps/dgst.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
580Sstevel@tonic-gate
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include <string.h>
610Sstevel@tonic-gate #include <stdlib.h>
620Sstevel@tonic-gate #include "apps.h"
630Sstevel@tonic-gate #include <openssl/bio.h>
640Sstevel@tonic-gate #include <openssl/err.h>
650Sstevel@tonic-gate #include <openssl/evp.h>
660Sstevel@tonic-gate #include <openssl/objects.h>
670Sstevel@tonic-gate #include <openssl/x509.h>
680Sstevel@tonic-gate #include <openssl/pem.h>
690Sstevel@tonic-gate
700Sstevel@tonic-gate #undef BUFSIZE
710Sstevel@tonic-gate #define BUFSIZE 1024*8
720Sstevel@tonic-gate
730Sstevel@tonic-gate #undef PROG
740Sstevel@tonic-gate #define PROG dgst_main
750Sstevel@tonic-gate
760Sstevel@tonic-gate int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
770Sstevel@tonic-gate EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
780Sstevel@tonic-gate const char *file);
790Sstevel@tonic-gate
800Sstevel@tonic-gate int MAIN(int, char **);
810Sstevel@tonic-gate
MAIN(int argc,char ** argv)820Sstevel@tonic-gate int MAIN(int argc, char **argv)
830Sstevel@tonic-gate {
840Sstevel@tonic-gate ENGINE *e = NULL;
850Sstevel@tonic-gate unsigned char *buf=NULL;
860Sstevel@tonic-gate int i,err=0;
870Sstevel@tonic-gate const EVP_MD *md=NULL,*m;
880Sstevel@tonic-gate BIO *in=NULL,*inp;
890Sstevel@tonic-gate BIO *bmd=NULL;
900Sstevel@tonic-gate BIO *out = NULL;
910Sstevel@tonic-gate const char *name;
920Sstevel@tonic-gate #define PROG_NAME_SIZE 39
930Sstevel@tonic-gate char pname[PROG_NAME_SIZE+1];
940Sstevel@tonic-gate int separator=0;
950Sstevel@tonic-gate int debug=0;
960Sstevel@tonic-gate int keyform=FORMAT_PEM;
970Sstevel@tonic-gate const char *outfile = NULL, *keyfile = NULL;
980Sstevel@tonic-gate const char *sigfile = NULL, *randfile = NULL;
990Sstevel@tonic-gate int out_bin = -1, want_pub = 0, do_verify = 0;
1000Sstevel@tonic-gate EVP_PKEY *sigkey = NULL;
1010Sstevel@tonic-gate unsigned char *sigbuf = NULL;
1020Sstevel@tonic-gate int siglen = 0;
103*2139Sjp161948 char *passargin = NULL, *passin = NULL;
1040Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
1050Sstevel@tonic-gate char *engine=NULL;
1060Sstevel@tonic-gate #endif
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate apps_startup();
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
1110Sstevel@tonic-gate {
1120Sstevel@tonic-gate BIO_printf(bio_err,"out of memory\n");
1130Sstevel@tonic-gate goto end;
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate if (bio_err == NULL)
1160Sstevel@tonic-gate if ((bio_err=BIO_new(BIO_s_file())) != NULL)
1170Sstevel@tonic-gate BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate if (!load_config(bio_err, NULL))
1200Sstevel@tonic-gate goto end;
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate /* first check the program name */
1230Sstevel@tonic-gate program_name(argv[0],pname,sizeof pname);
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate md=EVP_get_digestbyname(pname);
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate argc--;
1280Sstevel@tonic-gate argv++;
1290Sstevel@tonic-gate while (argc > 0)
1300Sstevel@tonic-gate {
1310Sstevel@tonic-gate if ((*argv)[0] != '-') break;
1320Sstevel@tonic-gate if (strcmp(*argv,"-c") == 0)
1330Sstevel@tonic-gate separator=1;
1340Sstevel@tonic-gate else if (strcmp(*argv,"-rand") == 0)
1350Sstevel@tonic-gate {
1360Sstevel@tonic-gate if (--argc < 1) break;
1370Sstevel@tonic-gate randfile=*(++argv);
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate else if (strcmp(*argv,"-out") == 0)
1400Sstevel@tonic-gate {
1410Sstevel@tonic-gate if (--argc < 1) break;
1420Sstevel@tonic-gate outfile=*(++argv);
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate else if (strcmp(*argv,"-sign") == 0)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate if (--argc < 1) break;
1470Sstevel@tonic-gate keyfile=*(++argv);
1480Sstevel@tonic-gate }
149*2139Sjp161948 else if (!strcmp(*argv,"-passin"))
150*2139Sjp161948 {
151*2139Sjp161948 if (--argc < 1)
152*2139Sjp161948 break;
153*2139Sjp161948 passargin=*++argv;
154*2139Sjp161948 }
1550Sstevel@tonic-gate else if (strcmp(*argv,"-verify") == 0)
1560Sstevel@tonic-gate {
1570Sstevel@tonic-gate if (--argc < 1) break;
1580Sstevel@tonic-gate keyfile=*(++argv);
1590Sstevel@tonic-gate want_pub = 1;
1600Sstevel@tonic-gate do_verify = 1;
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate else if (strcmp(*argv,"-prverify") == 0)
1630Sstevel@tonic-gate {
1640Sstevel@tonic-gate if (--argc < 1) break;
1650Sstevel@tonic-gate keyfile=*(++argv);
1660Sstevel@tonic-gate do_verify = 1;
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate else if (strcmp(*argv,"-signature") == 0)
1690Sstevel@tonic-gate {
1700Sstevel@tonic-gate if (--argc < 1) break;
1710Sstevel@tonic-gate sigfile=*(++argv);
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate else if (strcmp(*argv,"-keyform") == 0)
1740Sstevel@tonic-gate {
1750Sstevel@tonic-gate if (--argc < 1) break;
1760Sstevel@tonic-gate keyform=str2fmt(*(++argv));
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
1790Sstevel@tonic-gate else if (strcmp(*argv,"-engine") == 0)
1800Sstevel@tonic-gate {
1810Sstevel@tonic-gate if (--argc < 1) break;
1820Sstevel@tonic-gate engine= *(++argv);
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate #endif
1850Sstevel@tonic-gate else if (strcmp(*argv,"-hex") == 0)
1860Sstevel@tonic-gate out_bin = 0;
1870Sstevel@tonic-gate else if (strcmp(*argv,"-binary") == 0)
1880Sstevel@tonic-gate out_bin = 1;
1890Sstevel@tonic-gate else if (strcmp(*argv,"-d") == 0)
1900Sstevel@tonic-gate debug=1;
1910Sstevel@tonic-gate else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
1920Sstevel@tonic-gate md=m;
1930Sstevel@tonic-gate else
1940Sstevel@tonic-gate break;
1950Sstevel@tonic-gate argc--;
1960Sstevel@tonic-gate argv++;
1970Sstevel@tonic-gate }
1980Sstevel@tonic-gate
1990Sstevel@tonic-gate if (md == NULL)
2000Sstevel@tonic-gate md=EVP_md5();
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate if(do_verify && !sigfile) {
2030Sstevel@tonic-gate BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
2040Sstevel@tonic-gate err = 1;
2050Sstevel@tonic-gate goto end;
2060Sstevel@tonic-gate }
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate if ((argc > 0) && (argv[0][0] == '-')) /* bad option */
2090Sstevel@tonic-gate {
2100Sstevel@tonic-gate BIO_printf(bio_err,"unknown option '%s'\n",*argv);
2110Sstevel@tonic-gate BIO_printf(bio_err,"options are\n");
2120Sstevel@tonic-gate BIO_printf(bio_err,"-c to output the digest with separating colons\n");
2130Sstevel@tonic-gate BIO_printf(bio_err,"-d to output debug info\n");
2140Sstevel@tonic-gate BIO_printf(bio_err,"-hex output as hex dump\n");
2150Sstevel@tonic-gate BIO_printf(bio_err,"-binary output in binary form\n");
2160Sstevel@tonic-gate BIO_printf(bio_err,"-sign file sign digest using private key in file\n");
2170Sstevel@tonic-gate BIO_printf(bio_err,"-verify file verify a signature using public key in file\n");
2180Sstevel@tonic-gate BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n");
2190Sstevel@tonic-gate BIO_printf(bio_err,"-keyform arg key file format (PEM or ENGINE)\n");
2200Sstevel@tonic-gate BIO_printf(bio_err,"-signature file signature to verify\n");
2210Sstevel@tonic-gate BIO_printf(bio_err,"-binary output in binary form\n");
2220Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2230Sstevel@tonic-gate BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n");
2240Sstevel@tonic-gate #endif
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate BIO_printf(bio_err,"-%3s to use the %s message digest algorithm (default)\n",
2270Sstevel@tonic-gate LN_md5,LN_md5);
2280Sstevel@tonic-gate BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
2290Sstevel@tonic-gate LN_md4,LN_md4);
2300Sstevel@tonic-gate BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
2310Sstevel@tonic-gate LN_md2,LN_md2);
232*2139Sjp161948 #ifndef OPENSSL_NO_SHA
2330Sstevel@tonic-gate BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
2340Sstevel@tonic-gate LN_sha1,LN_sha1);
2350Sstevel@tonic-gate BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
2360Sstevel@tonic-gate LN_sha,LN_sha);
237*2139Sjp161948 #ifndef OPENSSL_NO_SHA256
238*2139Sjp161948 BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
239*2139Sjp161948 LN_sha256,LN_sha256);
240*2139Sjp161948 #endif
241*2139Sjp161948 #ifndef OPENSSL_NO_SHA512
242*2139Sjp161948 BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
243*2139Sjp161948 LN_sha512,LN_sha512);
244*2139Sjp161948 #endif
245*2139Sjp161948 #endif
2460Sstevel@tonic-gate BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
2470Sstevel@tonic-gate LN_mdc2,LN_mdc2);
2480Sstevel@tonic-gate BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
2490Sstevel@tonic-gate LN_ripemd160,LN_ripemd160);
2500Sstevel@tonic-gate err=1;
2510Sstevel@tonic-gate goto end;
2520Sstevel@tonic-gate }
2530Sstevel@tonic-gate
2540Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2550Sstevel@tonic-gate e = setup_engine(bio_err, engine, 0);
2560Sstevel@tonic-gate #endif
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate in=BIO_new(BIO_s_file());
2590Sstevel@tonic-gate bmd=BIO_new(BIO_f_md());
2600Sstevel@tonic-gate if (debug)
2610Sstevel@tonic-gate {
2620Sstevel@tonic-gate BIO_set_callback(in,BIO_debug_callback);
2630Sstevel@tonic-gate /* needed for windows 3.1 */
2640Sstevel@tonic-gate BIO_set_callback_arg(in,bio_err);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate
267*2139Sjp161948 if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
268*2139Sjp161948 {
269*2139Sjp161948 BIO_printf(bio_err, "Error getting password\n");
270*2139Sjp161948 goto end;
271*2139Sjp161948 }
272*2139Sjp161948
2730Sstevel@tonic-gate if ((in == NULL) || (bmd == NULL))
2740Sstevel@tonic-gate {
2750Sstevel@tonic-gate ERR_print_errors(bio_err);
2760Sstevel@tonic-gate goto end;
2770Sstevel@tonic-gate }
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate if(out_bin == -1) {
2800Sstevel@tonic-gate if(keyfile) out_bin = 1;
2810Sstevel@tonic-gate else out_bin = 0;
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate if(randfile)
2850Sstevel@tonic-gate app_RAND_load_file(randfile, bio_err, 0);
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate if(outfile) {
2880Sstevel@tonic-gate if(out_bin)
2890Sstevel@tonic-gate out = BIO_new_file(outfile, "wb");
2900Sstevel@tonic-gate else out = BIO_new_file(outfile, "w");
2910Sstevel@tonic-gate } else {
2920Sstevel@tonic-gate out = BIO_new_fp(stdout, BIO_NOCLOSE);
2930Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS
2940Sstevel@tonic-gate {
2950Sstevel@tonic-gate BIO *tmpbio = BIO_new(BIO_f_linebuffer());
2960Sstevel@tonic-gate out = BIO_push(tmpbio, out);
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate #endif
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate if(!out) {
3020Sstevel@tonic-gate BIO_printf(bio_err, "Error opening output file %s\n",
3030Sstevel@tonic-gate outfile ? outfile : "(stdout)");
3040Sstevel@tonic-gate ERR_print_errors(bio_err);
3050Sstevel@tonic-gate goto end;
3060Sstevel@tonic-gate }
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate if(keyfile)
3090Sstevel@tonic-gate {
3100Sstevel@tonic-gate if (want_pub)
3110Sstevel@tonic-gate sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
3120Sstevel@tonic-gate e, "key file");
3130Sstevel@tonic-gate else
314*2139Sjp161948 sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
3150Sstevel@tonic-gate e, "key file");
3160Sstevel@tonic-gate if (!sigkey)
3170Sstevel@tonic-gate {
3180Sstevel@tonic-gate /* load_[pub]key() has already printed an appropriate
3190Sstevel@tonic-gate message */
3200Sstevel@tonic-gate goto end;
3210Sstevel@tonic-gate }
3220Sstevel@tonic-gate }
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate if(sigfile && sigkey) {
3250Sstevel@tonic-gate BIO *sigbio;
3260Sstevel@tonic-gate sigbio = BIO_new_file(sigfile, "rb");
3270Sstevel@tonic-gate siglen = EVP_PKEY_size(sigkey);
3280Sstevel@tonic-gate sigbuf = OPENSSL_malloc(siglen);
3290Sstevel@tonic-gate if(!sigbio) {
3300Sstevel@tonic-gate BIO_printf(bio_err, "Error opening signature file %s\n",
3310Sstevel@tonic-gate sigfile);
3320Sstevel@tonic-gate ERR_print_errors(bio_err);
3330Sstevel@tonic-gate goto end;
3340Sstevel@tonic-gate }
3350Sstevel@tonic-gate siglen = BIO_read(sigbio, sigbuf, siglen);
3360Sstevel@tonic-gate BIO_free(sigbio);
3370Sstevel@tonic-gate if(siglen <= 0) {
3380Sstevel@tonic-gate BIO_printf(bio_err, "Error reading signature file %s\n",
3390Sstevel@tonic-gate sigfile);
3400Sstevel@tonic-gate ERR_print_errors(bio_err);
3410Sstevel@tonic-gate goto end;
3420Sstevel@tonic-gate }
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate /* we use md as a filter, reading from 'in' */
348*2139Sjp161948 if (!BIO_set_md(bmd,md))
349*2139Sjp161948 {
350*2139Sjp161948 BIO_printf(bio_err, "Error setting digest %s\n", pname);
351*2139Sjp161948 ERR_print_errors(bio_err);
352*2139Sjp161948 goto end;
353*2139Sjp161948 }
354*2139Sjp161948
3550Sstevel@tonic-gate inp=BIO_push(bmd,in);
3560Sstevel@tonic-gate
3570Sstevel@tonic-gate if (argc == 0)
3580Sstevel@tonic-gate {
3590Sstevel@tonic-gate BIO_set_fp(in,stdin,BIO_NOCLOSE);
3600Sstevel@tonic-gate err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
3610Sstevel@tonic-gate siglen,"","(stdin)");
3620Sstevel@tonic-gate }
3630Sstevel@tonic-gate else
3640Sstevel@tonic-gate {
3650Sstevel@tonic-gate name=OBJ_nid2sn(md->type);
3660Sstevel@tonic-gate for (i=0; i<argc; i++)
3670Sstevel@tonic-gate {
3680Sstevel@tonic-gate char *tmp,*tofree=NULL;
3690Sstevel@tonic-gate int r;
3700Sstevel@tonic-gate
3710Sstevel@tonic-gate if (BIO_read_filename(in,argv[i]) <= 0)
3720Sstevel@tonic-gate {
3730Sstevel@tonic-gate perror(argv[i]);
3740Sstevel@tonic-gate err++;
3750Sstevel@tonic-gate continue;
3760Sstevel@tonic-gate }
3770Sstevel@tonic-gate if(!out_bin)
3780Sstevel@tonic-gate {
3790Sstevel@tonic-gate size_t len = strlen(name)+strlen(argv[i])+5;
3800Sstevel@tonic-gate tmp=tofree=OPENSSL_malloc(len);
3810Sstevel@tonic-gate BIO_snprintf(tmp,len,"%s(%s)= ",name,argv[i]);
3820Sstevel@tonic-gate }
3830Sstevel@tonic-gate else
3840Sstevel@tonic-gate tmp="";
3850Sstevel@tonic-gate r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
3860Sstevel@tonic-gate siglen,tmp,argv[i]);
3870Sstevel@tonic-gate if(r)
3880Sstevel@tonic-gate err=r;
3890Sstevel@tonic-gate if(tofree)
3900Sstevel@tonic-gate OPENSSL_free(tofree);
3910Sstevel@tonic-gate (void)BIO_reset(bmd);
3920Sstevel@tonic-gate }
3930Sstevel@tonic-gate }
3940Sstevel@tonic-gate end:
3950Sstevel@tonic-gate if (buf != NULL)
3960Sstevel@tonic-gate {
3970Sstevel@tonic-gate OPENSSL_cleanse(buf,BUFSIZE);
3980Sstevel@tonic-gate OPENSSL_free(buf);
3990Sstevel@tonic-gate }
4000Sstevel@tonic-gate if (in != NULL) BIO_free(in);
401*2139Sjp161948 if (passin)
402*2139Sjp161948 OPENSSL_free(passin);
4030Sstevel@tonic-gate BIO_free_all(out);
4040Sstevel@tonic-gate EVP_PKEY_free(sigkey);
4050Sstevel@tonic-gate if(sigbuf) OPENSSL_free(sigbuf);
4060Sstevel@tonic-gate if (bmd != NULL) BIO_free(bmd);
4070Sstevel@tonic-gate apps_shutdown();
4080Sstevel@tonic-gate OPENSSL_EXIT(err);
4090Sstevel@tonic-gate }
4100Sstevel@tonic-gate
do_fp(BIO * out,unsigned char * buf,BIO * bp,int sep,int binout,EVP_PKEY * key,unsigned char * sigin,int siglen,const char * title,const char * file)4110Sstevel@tonic-gate int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
4120Sstevel@tonic-gate EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
4130Sstevel@tonic-gate const char *file)
4140Sstevel@tonic-gate {
4150Sstevel@tonic-gate int len;
4160Sstevel@tonic-gate int i;
4170Sstevel@tonic-gate
4180Sstevel@tonic-gate for (;;)
4190Sstevel@tonic-gate {
4200Sstevel@tonic-gate i=BIO_read(bp,(char *)buf,BUFSIZE);
4210Sstevel@tonic-gate if(i < 0)
4220Sstevel@tonic-gate {
4230Sstevel@tonic-gate BIO_printf(bio_err, "Read Error in %s\n",file);
4240Sstevel@tonic-gate ERR_print_errors(bio_err);
4250Sstevel@tonic-gate return 1;
4260Sstevel@tonic-gate }
4270Sstevel@tonic-gate if (i == 0) break;
4280Sstevel@tonic-gate }
4290Sstevel@tonic-gate if(sigin)
4300Sstevel@tonic-gate {
4310Sstevel@tonic-gate EVP_MD_CTX *ctx;
4320Sstevel@tonic-gate BIO_get_md_ctx(bp, &ctx);
4330Sstevel@tonic-gate i = EVP_VerifyFinal(ctx, sigin, (unsigned int)siglen, key);
4340Sstevel@tonic-gate if(i > 0)
4350Sstevel@tonic-gate BIO_printf(out, "Verified OK\n");
4360Sstevel@tonic-gate else if(i == 0)
4370Sstevel@tonic-gate {
4380Sstevel@tonic-gate BIO_printf(out, "Verification Failure\n");
4390Sstevel@tonic-gate return 1;
4400Sstevel@tonic-gate }
4410Sstevel@tonic-gate else
4420Sstevel@tonic-gate {
4430Sstevel@tonic-gate BIO_printf(bio_err, "Error Verifying Data\n");
4440Sstevel@tonic-gate ERR_print_errors(bio_err);
4450Sstevel@tonic-gate return 1;
4460Sstevel@tonic-gate }
4470Sstevel@tonic-gate return 0;
4480Sstevel@tonic-gate }
4490Sstevel@tonic-gate if(key)
4500Sstevel@tonic-gate {
4510Sstevel@tonic-gate EVP_MD_CTX *ctx;
4520Sstevel@tonic-gate BIO_get_md_ctx(bp, &ctx);
4530Sstevel@tonic-gate if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key))
4540Sstevel@tonic-gate {
4550Sstevel@tonic-gate BIO_printf(bio_err, "Error Signing Data\n");
4560Sstevel@tonic-gate ERR_print_errors(bio_err);
4570Sstevel@tonic-gate return 1;
4580Sstevel@tonic-gate }
4590Sstevel@tonic-gate }
4600Sstevel@tonic-gate else
4610Sstevel@tonic-gate len=BIO_gets(bp,(char *)buf,BUFSIZE);
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate if(binout) BIO_write(out, buf, len);
4640Sstevel@tonic-gate else
4650Sstevel@tonic-gate {
4660Sstevel@tonic-gate BIO_write(out,title,strlen(title));
4670Sstevel@tonic-gate for (i=0; i<len; i++)
4680Sstevel@tonic-gate {
4690Sstevel@tonic-gate if (sep && (i != 0))
4700Sstevel@tonic-gate BIO_printf(out, ":");
4710Sstevel@tonic-gate BIO_printf(out, "%02x",buf[i]);
4720Sstevel@tonic-gate }
4730Sstevel@tonic-gate BIO_printf(out, "\n");
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate return 0;
4760Sstevel@tonic-gate }
4770Sstevel@tonic-gate
478