Home | History | Annotate | Download | only in apps
      1 /* apps/dgst.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) cryptsoft.com).
      7  * The implementation was written so as to conform with Netscapes SSL.
      8  *
      9  * This library is free for commercial and non-commercial use as long as
     10  * the following conditions are aheared to.  The following conditions
     11  * apply to all code found in this distribution, be it the RC4, RSA,
     12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     13  * included with this distribution is covered by the same copyright terms
     14  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     15  *
     16  * Copyright remains Eric Young's, and as such any Copyright notices in
     17  * the code are not to be removed.
     18  * If this package is used in a product, Eric Young should be given attribution
     19  * as the author of the parts of the library used.
     20  * This can be in the form of a textual message at program startup or
     21  * in documentation (online or textual) provided with the package.
     22  *
     23  * Redistribution and use in source and binary forms, with or without
     24  * modification, are permitted provided that the following conditions
     25  * are met:
     26  * 1. Redistributions of source code must retain the copyright
     27  *    notice, this list of conditions and the following disclaimer.
     28  * 2. Redistributions in binary form must reproduce the above copyright
     29  *    notice, this list of conditions and the following disclaimer in the
     30  *    documentation and/or other materials provided with the distribution.
     31  * 3. All advertising materials mentioning features or use of this software
     32  *    must display the following acknowledgement:
     33  *    "This product includes cryptographic software written by
     34  *     Eric Young (eay (at) cryptsoft.com)"
     35  *    The word 'cryptographic' can be left out if the rouines from the library
     36  *    being used are not cryptographic related :-).
     37  * 4. If you include any Windows specific code (or a derivative thereof) from
     38  *    the apps directory (application code) you must include an acknowledgement:
     39  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     40  *
     41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     51  * SUCH DAMAGE.
     52  *
     53  * The licence and distribution terms for any publically available version or
     54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     55  * copied and put under another distribution licence
     56  * [including the GNU Public Licence.]
     57  */
     58 
     59 #include <stdio.h>
     60 #include <string.h>
     61 #include <stdlib.h>
     62 #include "apps.h"
     63 #include <openssl/bio.h>
     64 #include <openssl/err.h>
     65 #include <openssl/evp.h>
     66 #include <openssl/objects.h>
     67 #include <openssl/x509.h>
     68 #include <openssl/pem.h>
     69 #include <openssl/hmac.h>
     70 
     71 #undef BUFSIZE
     72 #define BUFSIZE	1024*8
     73 
     74 #undef PROG
     75 #define PROG	dgst_main
     76 
     77 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
     78 	  EVP_PKEY *key, unsigned char *sigin, int siglen,
     79 	  const char *sig_name, const char *md_name,
     80 	  const char *file,BIO *bmd);
     81 
     82 static void list_md_fn(const EVP_MD *m,
     83 			const char *from, const char *to, void *arg)
     84 	{
     85 	const char *mname;
     86 	/* Skip aliases */
     87 	if (!m)
     88 		return;
     89 	mname = OBJ_nid2ln(EVP_MD_type(m));
     90 	/* Skip shortnames */
     91 	if (strcmp(from, mname))
     92 		return;
     93 	/* Skip clones */
     94 	if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST)
     95 		return;
     96 	if (strchr(mname, ' '))
     97 		mname= EVP_MD_name(m);
     98 	BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n",
     99 			mname, mname);
    100 	}
    101 
    102 int MAIN(int, char **);
    103 
    104 int MAIN(int argc, char **argv)
    105 	{
    106 	ENGINE *e = NULL;
    107 	unsigned char *buf=NULL;
    108 	int i,err=1;
    109 	const EVP_MD *md=NULL,*m;
    110 	BIO *in=NULL,*inp;
    111 	BIO *bmd=NULL;
    112 	BIO *out = NULL;
    113 #define PROG_NAME_SIZE  39
    114 	char pname[PROG_NAME_SIZE+1];
    115 	int separator=0;
    116 	int debug=0;
    117 	int keyform=FORMAT_PEM;
    118 	const char *outfile = NULL, *keyfile = NULL;
    119 	const char *sigfile = NULL, *randfile = NULL;
    120 	int out_bin = -1, want_pub = 0, do_verify = 0;
    121 	EVP_PKEY *sigkey = NULL;
    122 	unsigned char *sigbuf = NULL;
    123 	int siglen = 0;
    124 	char *passargin = NULL, *passin = NULL;
    125 #ifndef OPENSSL_NO_ENGINE
    126 	char *engine=NULL;
    127 #endif
    128 	char *hmac_key=NULL;
    129 	char *mac_name=NULL;
    130 	STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
    131 
    132 	apps_startup();
    133 
    134 	if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
    135 		{
    136 		BIO_printf(bio_err,"out of memory\n");
    137 		goto end;
    138 		}
    139 	if (bio_err == NULL)
    140 		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
    141 			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
    142 
    143 	if (!load_config(bio_err, NULL))
    144 		goto end;
    145 
    146 	/* first check the program name */
    147 	program_name(argv[0],pname,sizeof pname);
    148 
    149 	md=EVP_get_digestbyname(pname);
    150 
    151 	argc--;
    152 	argv++;
    153 	while (argc > 0)
    154 		{
    155 		if ((*argv)[0] != '-') break;
    156 		if (strcmp(*argv,"-c") == 0)
    157 			separator=1;
    158 		else if (strcmp(*argv,"-r") == 0)
    159 			separator=2;
    160 		else if (strcmp(*argv,"-rand") == 0)
    161 			{
    162 			if (--argc < 1) break;
    163 			randfile=*(++argv);
    164 			}
    165 		else if (strcmp(*argv,"-out") == 0)
    166 			{
    167 			if (--argc < 1) break;
    168 			outfile=*(++argv);
    169 			}
    170 		else if (strcmp(*argv,"-sign") == 0)
    171 			{
    172 			if (--argc < 1) break;
    173 			keyfile=*(++argv);
    174 			}
    175 		else if (!strcmp(*argv,"-passin"))
    176 			{
    177 			if (--argc < 1)
    178 				break;
    179 			passargin=*++argv;
    180 			}
    181 		else if (strcmp(*argv,"-verify") == 0)
    182 			{
    183 			if (--argc < 1) break;
    184 			keyfile=*(++argv);
    185 			want_pub = 1;
    186 			do_verify = 1;
    187 			}
    188 		else if (strcmp(*argv,"-prverify") == 0)
    189 			{
    190 			if (--argc < 1) break;
    191 			keyfile=*(++argv);
    192 			do_verify = 1;
    193 			}
    194 		else if (strcmp(*argv,"-signature") == 0)
    195 			{
    196 			if (--argc < 1) break;
    197 			sigfile=*(++argv);
    198 			}
    199 		else if (strcmp(*argv,"-keyform") == 0)
    200 			{
    201 			if (--argc < 1) break;
    202 			keyform=str2fmt(*(++argv));
    203 			}
    204 #ifndef OPENSSL_NO_ENGINE
    205 		else if (strcmp(*argv,"-engine") == 0)
    206 			{
    207 			if (--argc < 1) break;
    208 			engine= *(++argv);
    209         		e = setup_engine(bio_err, engine, 0);
    210 			}
    211 #endif
    212 		else if (strcmp(*argv,"-hex") == 0)
    213 			out_bin = 0;
    214 		else if (strcmp(*argv,"-binary") == 0)
    215 			out_bin = 1;
    216 		else if (strcmp(*argv,"-d") == 0)
    217 			debug=1;
    218 		else if (!strcmp(*argv,"-hmac"))
    219 			{
    220 			if (--argc < 1)
    221 				break;
    222 			hmac_key=*++argv;
    223 			}
    224 		else if (!strcmp(*argv,"-mac"))
    225 			{
    226 			if (--argc < 1)
    227 				break;
    228 			mac_name=*++argv;
    229 			}
    230 		else if (strcmp(*argv,"-sigopt") == 0)
    231 			{
    232 			if (--argc < 1)
    233 				break;
    234 			if (!sigopts)
    235 				sigopts = sk_OPENSSL_STRING_new_null();
    236 			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
    237 				break;
    238 			}
    239 		else if (strcmp(*argv,"-macopt") == 0)
    240 			{
    241 			if (--argc < 1)
    242 				break;
    243 			if (!macopts)
    244 				macopts = sk_OPENSSL_STRING_new_null();
    245 			if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv)))
    246 				break;
    247 			}
    248 		else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
    249 			md=m;
    250 		else
    251 			break;
    252 		argc--;
    253 		argv++;
    254 		}
    255 
    256 
    257 	if(do_verify && !sigfile) {
    258 		BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
    259 		goto end;
    260 	}
    261 
    262 	if ((argc > 0) && (argv[0][0] == '-')) /* bad option */
    263 		{
    264 		BIO_printf(bio_err,"unknown option '%s'\n",*argv);
    265 		BIO_printf(bio_err,"options are\n");
    266 		BIO_printf(bio_err,"-c              to output the digest with separating colons\n");
    267 		BIO_printf(bio_err,"-r              to output the digest in coreutils format\n");
    268 		BIO_printf(bio_err,"-d              to output debug info\n");
    269 		BIO_printf(bio_err,"-hex            output as hex dump\n");
    270 		BIO_printf(bio_err,"-binary         output in binary form\n");
    271 		BIO_printf(bio_err,"-sign   file    sign digest using private key in file\n");
    272 		BIO_printf(bio_err,"-verify file    verify a signature using public key in file\n");
    273 		BIO_printf(bio_err,"-prverify file  verify a signature using private key in file\n");
    274 		BIO_printf(bio_err,"-keyform arg    key file format (PEM or ENGINE)\n");
    275 		BIO_printf(bio_err,"-out filename   output to filename rather than stdout\n");
    276 		BIO_printf(bio_err,"-signature file signature to verify\n");
    277 		BIO_printf(bio_err,"-sigopt nm:v    signature parameter\n");
    278 		BIO_printf(bio_err,"-hmac key       create hashed MAC with key\n");
    279 		BIO_printf(bio_err,"-mac algorithm  create MAC (not neccessarily HMAC)\n");
    280 		BIO_printf(bio_err,"-macopt nm:v    MAC algorithm parameters or key\n");
    281 #ifndef OPENSSL_NO_ENGINE
    282 		BIO_printf(bio_err,"-engine e       use engine e, possibly a hardware device.\n");
    283 #endif
    284 
    285 		EVP_MD_do_all_sorted(list_md_fn, bio_err);
    286 		goto end;
    287 		}
    288 
    289 	in=BIO_new(BIO_s_file());
    290 	bmd=BIO_new(BIO_f_md());
    291 	if (debug)
    292 		{
    293 		BIO_set_callback(in,BIO_debug_callback);
    294 		/* needed for windows 3.1 */
    295 		BIO_set_callback_arg(in,(char *)bio_err);
    296 		}
    297 
    298 	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
    299 		{
    300 		BIO_printf(bio_err, "Error getting password\n");
    301 		goto end;
    302 		}
    303 
    304 	if ((in == NULL) || (bmd == NULL))
    305 		{
    306 		ERR_print_errors(bio_err);
    307 		goto end;
    308 		}
    309 
    310 	if(out_bin == -1) {
    311 		if(keyfile)
    312 			out_bin = 1;
    313 		else
    314 			out_bin = 0;
    315 	}
    316 
    317 	if(randfile)
    318 		app_RAND_load_file(randfile, bio_err, 0);
    319 
    320 	if(outfile) {
    321 		if(out_bin)
    322 			out = BIO_new_file(outfile, "wb");
    323 		else    out = BIO_new_file(outfile, "w");
    324 	} else {
    325 		out = BIO_new_fp(stdout, BIO_NOCLOSE);
    326 #ifdef OPENSSL_SYS_VMS
    327 		{
    328 		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
    329 		out = BIO_push(tmpbio, out);
    330 		}
    331 #endif
    332 	}
    333 
    334 	if(!out) {
    335 		BIO_printf(bio_err, "Error opening output file %s\n",
    336 					outfile ? outfile : "(stdout)");
    337 		ERR_print_errors(bio_err);
    338 		goto end;
    339 	}
    340 	if ((!!mac_name + !!keyfile + !!hmac_key) > 1)
    341 		{
    342 		BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
    343 		goto end;
    344 		}
    345 
    346 	if(keyfile)
    347 		{
    348 		if (want_pub)
    349 			sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
    350 				e, "key file");
    351 		else
    352 			sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
    353 				e, "key file");
    354 		if (!sigkey)
    355 			{
    356 			/* load_[pub]key() has already printed an appropriate
    357 			   message */
    358 			goto end;
    359 			}
    360 		}
    361 
    362 	if (mac_name)
    363 		{
    364 		EVP_PKEY_CTX *mac_ctx = NULL;
    365 		int r = 0;
    366 		if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0))
    367 			goto mac_end;
    368 		if (macopts)
    369 			{
    370 			char *macopt;
    371 			for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++)
    372 				{
    373 				macopt = sk_OPENSSL_STRING_value(macopts, i);
    374 				if (pkey_ctrl_string(mac_ctx, macopt) <= 0)
    375 					{
    376 					BIO_printf(bio_err,
    377 						"MAC parameter error \"%s\"\n",
    378 						macopt);
    379 					ERR_print_errors(bio_err);
    380 					goto mac_end;
    381 					}
    382 				}
    383 			}
    384 		if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0)
    385 			{
    386 			BIO_puts(bio_err, "Error generating key\n");
    387 			ERR_print_errors(bio_err);
    388 			goto mac_end;
    389 			}
    390 		r = 1;
    391 		mac_end:
    392 		if (mac_ctx)
    393 			EVP_PKEY_CTX_free(mac_ctx);
    394 		if (r == 0)
    395 			goto end;
    396 		}
    397 
    398 	if (hmac_key)
    399 		{
    400 		sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e,
    401 					(unsigned char *)hmac_key, -1);
    402 		if (!sigkey)
    403 			goto end;
    404 		}
    405 
    406 	if (sigkey)
    407 		{
    408 		EVP_MD_CTX *mctx = NULL;
    409 		EVP_PKEY_CTX *pctx = NULL;
    410 		int r;
    411 		if (!BIO_get_md_ctx(bmd, &mctx))
    412 			{
    413 			BIO_printf(bio_err, "Error getting context\n");
    414 			ERR_print_errors(bio_err);
    415 			goto end;
    416 			}
    417 		if (do_verify)
    418 			r = EVP_DigestVerifyInit(mctx, &pctx, md, e, sigkey);
    419 		else
    420 			r = EVP_DigestSignInit(mctx, &pctx, md, e, sigkey);
    421 		if (!r)
    422 			{
    423 			BIO_printf(bio_err, "Error setting context\n");
    424 			ERR_print_errors(bio_err);
    425 			goto end;
    426 			}
    427 		if (sigopts)
    428 			{
    429 			char *sigopt;
    430 			for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
    431 				{
    432 				sigopt = sk_OPENSSL_STRING_value(sigopts, i);
    433 				if (pkey_ctrl_string(pctx, sigopt) <= 0)
    434 					{
    435 					BIO_printf(bio_err,
    436 						"parameter error \"%s\"\n",
    437 						sigopt);
    438 					ERR_print_errors(bio_err);
    439 					goto end;
    440 					}
    441 				}
    442 			}
    443 		}
    444 	/* we use md as a filter, reading from 'in' */
    445 	else
    446 		{
    447 		if (md == NULL)
    448 			md = EVP_md5();
    449 		if (!BIO_set_md(bmd,md))
    450 			{
    451 			BIO_printf(bio_err, "Error setting digest %s\n", pname);
    452 			ERR_print_errors(bio_err);
    453 			goto end;
    454 			}
    455 		}
    456 
    457 	if(sigfile && sigkey) {
    458 		BIO *sigbio;
    459 		sigbio = BIO_new_file(sigfile, "rb");
    460 		siglen = EVP_PKEY_size(sigkey);
    461 		sigbuf = OPENSSL_malloc(siglen);
    462 		if(!sigbio) {
    463 			BIO_printf(bio_err, "Error opening signature file %s\n",
    464 								sigfile);
    465 			ERR_print_errors(bio_err);
    466 			goto end;
    467 		}
    468 		siglen = BIO_read(sigbio, sigbuf, siglen);
    469 		BIO_free(sigbio);
    470 		if(siglen <= 0) {
    471 			BIO_printf(bio_err, "Error reading signature file %s\n",
    472 								sigfile);
    473 			ERR_print_errors(bio_err);
    474 			goto end;
    475 		}
    476 	}
    477 	inp=BIO_push(bmd,in);
    478 
    479 	if (md == NULL)
    480 		{
    481 		EVP_MD_CTX *tctx;
    482 		BIO_get_md_ctx(bmd, &tctx);
    483 		md = EVP_MD_CTX_md(tctx);
    484 		}
    485 
    486 	if (argc == 0)
    487 		{
    488 		BIO_set_fp(in,stdin,BIO_NOCLOSE);
    489 		err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
    490 			  siglen,NULL,NULL,"stdin",bmd);
    491 		}
    492 	else
    493 		{
    494 		const char *md_name = NULL, *sig_name = NULL;
    495 		if(!out_bin)
    496 			{
    497 			if (sigkey)
    498 				{
    499 				const EVP_PKEY_ASN1_METHOD *ameth;
    500 				ameth = EVP_PKEY_get0_asn1(sigkey);
    501 				if (ameth)
    502 					EVP_PKEY_asn1_get0_info(NULL, NULL,
    503 						NULL, NULL, &sig_name, ameth);
    504 				}
    505 			md_name = EVP_MD_name(md);
    506 			}
    507 		err = 0;
    508 		for (i=0; i<argc; i++)
    509 			{
    510 			int r;
    511 			if (BIO_read_filename(in,argv[i]) <= 0)
    512 				{
    513 				perror(argv[i]);
    514 				err++;
    515 				continue;
    516 				}
    517 			else
    518 			r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
    519 				siglen,sig_name,md_name, argv[i],bmd);
    520 			if(r)
    521 			    err=r;
    522 			(void)BIO_reset(bmd);
    523 			}
    524 		}
    525 end:
    526 	if (buf != NULL)
    527 		{
    528 		OPENSSL_cleanse(buf,BUFSIZE);
    529 		OPENSSL_free(buf);
    530 		}
    531 	if (in != NULL) BIO_free(in);
    532 	if (passin)
    533 		OPENSSL_free(passin);
    534 	BIO_free_all(out);
    535 	EVP_PKEY_free(sigkey);
    536 	if (sigopts)
    537 		sk_OPENSSL_STRING_free(sigopts);
    538 	if (macopts)
    539 		sk_OPENSSL_STRING_free(macopts);
    540 	if(sigbuf) OPENSSL_free(sigbuf);
    541 	if (bmd != NULL) BIO_free(bmd);
    542 	apps_shutdown();
    543 	OPENSSL_EXIT(err);
    544 	}
    545 
    546 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
    547 	  EVP_PKEY *key, unsigned char *sigin, int siglen,
    548 	  const char *sig_name, const char *md_name,
    549 	  const char *file,BIO *bmd)
    550 	{
    551 	size_t len;
    552 	int i;
    553 
    554 	for (;;)
    555 		{
    556 		i=BIO_read(bp,(char *)buf,BUFSIZE);
    557 		if(i < 0)
    558 			{
    559 			BIO_printf(bio_err, "Read Error in %s\n",file);
    560 			ERR_print_errors(bio_err);
    561 			return 1;
    562 			}
    563 		if (i == 0) break;
    564 		}
    565 	if(sigin)
    566 		{
    567 		EVP_MD_CTX *ctx;
    568 		BIO_get_md_ctx(bp, &ctx);
    569 		i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen);
    570 		if(i > 0)
    571 			BIO_printf(out, "Verified OK\n");
    572 		else if(i == 0)
    573 			{
    574 			BIO_printf(out, "Verification Failure\n");
    575 			return 1;
    576 			}
    577 		else
    578 			{
    579 			BIO_printf(bio_err, "Error Verifying Data\n");
    580 			ERR_print_errors(bio_err);
    581 			return 1;
    582 			}
    583 		return 0;
    584 		}
    585 	if(key)
    586 		{
    587 		EVP_MD_CTX *ctx;
    588 		BIO_get_md_ctx(bp, &ctx);
    589 		len = BUFSIZE;
    590 		if(!EVP_DigestSignFinal(ctx, buf, &len))
    591 			{
    592 			BIO_printf(bio_err, "Error Signing Data\n");
    593 			ERR_print_errors(bio_err);
    594 			return 1;
    595 			}
    596 		}
    597 	else
    598 		{
    599 		len=BIO_gets(bp,(char *)buf,BUFSIZE);
    600 		if ((int)len <0)
    601 			{
    602 			ERR_print_errors(bio_err);
    603 			return 1;
    604 			}
    605 		}
    606 
    607 	if(binout) BIO_write(out, buf, len);
    608 	else if (sep == 2)
    609 		{
    610 		for (i=0; i<(int)len; i++)
    611 			BIO_printf(out, "%02x",buf[i]);
    612 		BIO_printf(out, " *%s\n", file);
    613 		}
    614 	else
    615 		{
    616 		if (sig_name)
    617 			BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file);
    618 		else if (md_name)
    619 			BIO_printf(out, "%s(%s)= ", md_name, file);
    620 		else
    621 			BIO_printf(out, "(%s)= ", file);
    622 		for (i=0; i<(int)len; i++)
    623 			{
    624 			if (sep && (i != 0))
    625 				BIO_printf(out, ":");
    626 			BIO_printf(out, "%02x",buf[i]);
    627 			}
    628 		BIO_printf(out, "\n");
    629 		}
    630 	return 0;
    631 	}
    632 
    633