Home | History | Annotate | Download | only in apps
      1 /* apps/enc.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 <stdlib.h>
     61 #include <string.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/rand.h>
     69 #include <openssl/pem.h>
     70 #include <openssl/comp.h>
     71 #include <ctype.h>
     72 
     73 int set_hex(char *in,unsigned char *out,int size);
     74 #undef SIZE
     75 #undef BSIZE
     76 #undef PROG
     77 
     78 #define SIZE	(512)
     79 #define BSIZE	(8*1024)
     80 #define	PROG	enc_main
     81 
     82 static void show_ciphers(const OBJ_NAME *name,void *bio_)
     83 	{
     84 	BIO *bio=bio_;
     85 	static int n;
     86 
     87 	if(!islower((unsigned char)*name->name))
     88 		return;
     89 
     90 	BIO_printf(bio,"-%-25s",name->name);
     91 	if(++n == 3)
     92 		{
     93 		BIO_printf(bio,"\n");
     94 		n=0;
     95 		}
     96 	else
     97 		BIO_printf(bio," ");
     98 	}
     99 
    100 int MAIN(int, char **);
    101 
    102 int MAIN(int argc, char **argv)
    103 	{
    104 	static const char magic[]="Salted__";
    105 	char mbuf[sizeof magic-1];
    106 	char *strbuf=NULL;
    107 	unsigned char *buff=NULL,*bufsize=NULL;
    108 	int bsize=BSIZE,verbose=0;
    109 	int ret=1,inl;
    110 	int nopad = 0;
    111 	unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
    112 	unsigned char salt[PKCS5_SALT_LEN];
    113 	char *str=NULL, *passarg = NULL, *pass = NULL;
    114 	char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
    115 	char *md=NULL;
    116 	int enc=1,printkey=0,i,base64=0;
    117 #ifdef ZLIB
    118 	int do_zlib=0;
    119 	BIO *bzl = NULL;
    120 #endif
    121 	int debug=0,olb64=0,nosalt=0;
    122 	const EVP_CIPHER *cipher=NULL,*c;
    123 	EVP_CIPHER_CTX *ctx = NULL;
    124 	char *inf=NULL,*outf=NULL;
    125 	BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
    126 #define PROG_NAME_SIZE  39
    127 	char pname[PROG_NAME_SIZE+1];
    128 #ifndef OPENSSL_NO_ENGINE
    129 	char *engine = NULL;
    130 #endif
    131 	const EVP_MD *dgst=NULL;
    132 
    133 	apps_startup();
    134 
    135 	if (bio_err == NULL)
    136 		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
    137 			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
    138 
    139 	if (!load_config(bio_err, NULL))
    140 		goto end;
    141 
    142 	/* first check the program name */
    143 	program_name(argv[0],pname,sizeof pname);
    144 	if (strcmp(pname,"base64") == 0)
    145 		base64=1;
    146 #ifdef ZLIB
    147 	if (strcmp(pname,"zlib") == 0)
    148 		do_zlib=1;
    149 #endif
    150 
    151 	cipher=EVP_get_cipherbyname(pname);
    152 #ifdef ZLIB
    153 	if (!do_zlib && !base64 && (cipher == NULL)
    154 				&& (strcmp(pname,"enc") != 0))
    155 #else
    156 	if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
    157 #endif
    158 		{
    159 		BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
    160 		goto bad;
    161 		}
    162 
    163 	argc--;
    164 	argv++;
    165 	while (argc >= 1)
    166 		{
    167 		if	(strcmp(*argv,"-e") == 0)
    168 			enc=1;
    169 		else if (strcmp(*argv,"-in") == 0)
    170 			{
    171 			if (--argc < 1) goto bad;
    172 			inf= *(++argv);
    173 			}
    174 		else if (strcmp(*argv,"-out") == 0)
    175 			{
    176 			if (--argc < 1) goto bad;
    177 			outf= *(++argv);
    178 			}
    179 		else if (strcmp(*argv,"-pass") == 0)
    180 			{
    181 			if (--argc < 1) goto bad;
    182 			passarg= *(++argv);
    183 			}
    184 #ifndef OPENSSL_NO_ENGINE
    185 		else if (strcmp(*argv,"-engine") == 0)
    186 			{
    187 			if (--argc < 1) goto bad;
    188 			engine= *(++argv);
    189 			}
    190 #endif
    191 		else if	(strcmp(*argv,"-d") == 0)
    192 			enc=0;
    193 		else if	(strcmp(*argv,"-p") == 0)
    194 			printkey=1;
    195 		else if	(strcmp(*argv,"-v") == 0)
    196 			verbose=1;
    197 		else if	(strcmp(*argv,"-nopad") == 0)
    198 			nopad=1;
    199 		else if	(strcmp(*argv,"-salt") == 0)
    200 			nosalt=0;
    201 		else if	(strcmp(*argv,"-nosalt") == 0)
    202 			nosalt=1;
    203 		else if	(strcmp(*argv,"-debug") == 0)
    204 			debug=1;
    205 		else if	(strcmp(*argv,"-P") == 0)
    206 			printkey=2;
    207 		else if	(strcmp(*argv,"-A") == 0)
    208 			olb64=1;
    209 		else if	(strcmp(*argv,"-a") == 0)
    210 			base64=1;
    211 		else if	(strcmp(*argv,"-base64") == 0)
    212 			base64=1;
    213 #ifdef ZLIB
    214 		else if	(strcmp(*argv,"-z") == 0)
    215 			do_zlib=1;
    216 #endif
    217 		else if (strcmp(*argv,"-bufsize") == 0)
    218 			{
    219 			if (--argc < 1) goto bad;
    220 			bufsize=(unsigned char *)*(++argv);
    221 			}
    222 		else if (strcmp(*argv,"-k") == 0)
    223 			{
    224 			if (--argc < 1) goto bad;
    225 			str= *(++argv);
    226 			}
    227 		else if (strcmp(*argv,"-kfile") == 0)
    228 			{
    229 			static char buf[128];
    230 			FILE *infile;
    231 			char *file;
    232 
    233 			if (--argc < 1) goto bad;
    234 			file= *(++argv);
    235 			infile=fopen(file,"r");
    236 			if (infile == NULL)
    237 				{
    238 				BIO_printf(bio_err,"unable to read key from '%s'\n",
    239 					file);
    240 				goto bad;
    241 				}
    242 			buf[0]='\0';
    243 			if (!fgets(buf,sizeof buf,infile))
    244 				{
    245 				BIO_printf(bio_err,"unable to read key from '%s'\n",
    246 					file);
    247 				goto bad;
    248 				}
    249 			fclose(infile);
    250 			i=strlen(buf);
    251 			if ((i > 0) &&
    252 				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
    253 				buf[--i]='\0';
    254 			if ((i > 0) &&
    255 				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
    256 				buf[--i]='\0';
    257 			if (i < 1)
    258 				{
    259 				BIO_printf(bio_err,"zero length password\n");
    260 				goto bad;
    261 				}
    262 			str=buf;
    263 			}
    264 		else if (strcmp(*argv,"-K") == 0)
    265 			{
    266 			if (--argc < 1) goto bad;
    267 			hkey= *(++argv);
    268 			}
    269 		else if (strcmp(*argv,"-S") == 0)
    270 			{
    271 			if (--argc < 1) goto bad;
    272 			hsalt= *(++argv);
    273 			}
    274 		else if (strcmp(*argv,"-iv") == 0)
    275 			{
    276 			if (--argc < 1) goto bad;
    277 			hiv= *(++argv);
    278 			}
    279 		else if (strcmp(*argv,"-md") == 0)
    280 			{
    281 			if (--argc < 1) goto bad;
    282 			md= *(++argv);
    283 			}
    284 		else if	((argv[0][0] == '-') &&
    285 			((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
    286 			{
    287 			cipher=c;
    288 			}
    289 		else if (strcmp(*argv,"-none") == 0)
    290 			cipher=NULL;
    291 		else
    292 			{
    293 			BIO_printf(bio_err,"unknown option '%s'\n",*argv);
    294 bad:
    295 			BIO_printf(bio_err,"options are\n");
    296 			BIO_printf(bio_err,"%-14s input file\n","-in <file>");
    297 			BIO_printf(bio_err,"%-14s output file\n","-out <file>");
    298 			BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
    299 			BIO_printf(bio_err,"%-14s encrypt\n","-e");
    300 			BIO_printf(bio_err,"%-14s decrypt\n","-d");
    301 			BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
    302 			BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
    303 			BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
    304 			BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
    305 			BIO_printf(bio_err,"%-14s   from a passphrase.  One of md2, md5, sha or sha1\n","");
    306 			BIO_printf(bio_err,"%-14s salt in hex is the next argument\n","-S");
    307 			BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
    308 			BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
    309 			BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
    310 			BIO_printf(bio_err,"%-14s disable standard block padding\n","-nopad");
    311 #ifndef OPENSSL_NO_ENGINE
    312 			BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
    313 #endif
    314 
    315 			BIO_printf(bio_err,"Cipher Types\n");
    316 			OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
    317 					       show_ciphers,
    318 					       bio_err);
    319 			BIO_printf(bio_err,"\n");
    320 
    321 			goto end;
    322 			}
    323 		argc--;
    324 		argv++;
    325 		}
    326 
    327 #ifndef OPENSSL_NO_ENGINE
    328         setup_engine(bio_err, engine, 0);
    329 #endif
    330 
    331 	if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
    332 		{
    333 		BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
    334 		goto end;
    335 		}
    336 
    337 	if (dgst == NULL)
    338 		{
    339 		dgst = EVP_md5();
    340 		}
    341 
    342 	if (bufsize != NULL)
    343 		{
    344 		unsigned long n;
    345 
    346 		for (n=0; *bufsize; bufsize++)
    347 			{
    348 			i= *bufsize;
    349 			if ((i <= '9') && (i >= '0'))
    350 				n=n*10+i-'0';
    351 			else if (i == 'k')
    352 				{
    353 				n*=1024;
    354 				bufsize++;
    355 				break;
    356 				}
    357 			}
    358 		if (*bufsize != '\0')
    359 			{
    360 			BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
    361 			goto end;
    362 			}
    363 
    364 		/* It must be large enough for a base64 encoded line */
    365 		if (base64 && n < 80) n=80;
    366 
    367 		bsize=(int)n;
    368 		if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
    369 		}
    370 
    371 	strbuf=OPENSSL_malloc(SIZE);
    372 	buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
    373 	if ((buff == NULL) || (strbuf == NULL))
    374 		{
    375 		BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
    376 		goto end;
    377 		}
    378 
    379 	in=BIO_new(BIO_s_file());
    380 	out=BIO_new(BIO_s_file());
    381 	if ((in == NULL) || (out == NULL))
    382 		{
    383 		ERR_print_errors(bio_err);
    384 		goto end;
    385 		}
    386 	if (debug)
    387 		{
    388 		BIO_set_callback(in,BIO_debug_callback);
    389 		BIO_set_callback(out,BIO_debug_callback);
    390 		BIO_set_callback_arg(in,(char *)bio_err);
    391 		BIO_set_callback_arg(out,(char *)bio_err);
    392 		}
    393 
    394 	if (inf == NULL)
    395 	        {
    396 #ifndef OPENSSL_NO_SETVBUF_IONBF
    397 		if (bufsize != NULL)
    398 			setvbuf(stdin, (char *)NULL, _IONBF, 0);
    399 #endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
    400 		BIO_set_fp(in,stdin,BIO_NOCLOSE);
    401 	        }
    402 	else
    403 		{
    404 		if (BIO_read_filename(in,inf) <= 0)
    405 			{
    406 			perror(inf);
    407 			goto end;
    408 			}
    409 		}
    410 
    411 	if(!str && passarg) {
    412 		if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
    413 			BIO_printf(bio_err, "Error getting password\n");
    414 			goto end;
    415 		}
    416 		str = pass;
    417 	}
    418 
    419 	if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
    420 		{
    421 		for (;;)
    422 			{
    423 			char buf[200];
    424 
    425 			BIO_snprintf(buf,sizeof buf,"enter %s %s password:",
    426 				     OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
    427 				     (enc)?"encryption":"decryption");
    428 			strbuf[0]='\0';
    429 			i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
    430 			if (i == 0)
    431 				{
    432 				if (strbuf[0] == '\0')
    433 					{
    434 					ret=1;
    435 					goto end;
    436 					}
    437 				str=strbuf;
    438 				break;
    439 				}
    440 			if (i < 0)
    441 				{
    442 				BIO_printf(bio_err,"bad password read\n");
    443 				goto end;
    444 				}
    445 			}
    446 		}
    447 
    448 
    449 	if (outf == NULL)
    450 		{
    451 		BIO_set_fp(out,stdout,BIO_NOCLOSE);
    452 #ifndef OPENSSL_NO_SETVBUF_IONBF
    453 		if (bufsize != NULL)
    454 			setvbuf(stdout, (char *)NULL, _IONBF, 0);
    455 #endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
    456 #ifdef OPENSSL_SYS_VMS
    457 		{
    458 		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
    459 		out = BIO_push(tmpbio, out);
    460 		}
    461 #endif
    462 		}
    463 	else
    464 		{
    465 		if (BIO_write_filename(out,outf) <= 0)
    466 			{
    467 			perror(outf);
    468 			goto end;
    469 			}
    470 		}
    471 
    472 	rbio=in;
    473 	wbio=out;
    474 
    475 #ifdef ZLIB
    476 
    477 	if (do_zlib)
    478 		{
    479 		if ((bzl=BIO_new(BIO_f_zlib())) == NULL)
    480 			goto end;
    481 		if (enc)
    482 			wbio=BIO_push(bzl,wbio);
    483 		else
    484 			rbio=BIO_push(bzl,rbio);
    485 		}
    486 #endif
    487 
    488 	if (base64)
    489 		{
    490 		if ((b64=BIO_new(BIO_f_base64())) == NULL)
    491 			goto end;
    492 		if (debug)
    493 			{
    494 			BIO_set_callback(b64,BIO_debug_callback);
    495 			BIO_set_callback_arg(b64,(char *)bio_err);
    496 			}
    497 		if (olb64)
    498 			BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
    499 		if (enc)
    500 			wbio=BIO_push(b64,wbio);
    501 		else
    502 			rbio=BIO_push(b64,rbio);
    503 		}
    504 
    505 	if (cipher != NULL)
    506 		{
    507 		/* Note that str is NULL if a key was passed on the command
    508 		 * line, so we get no salt in that case. Is this a bug?
    509 		 */
    510 		if (str != NULL)
    511 			{
    512 			/* Salt handling: if encrypting generate a salt and
    513 			 * write to output BIO. If decrypting read salt from
    514 			 * input BIO.
    515 			 */
    516 			unsigned char *sptr;
    517 			if(nosalt) sptr = NULL;
    518 			else {
    519 				if(enc) {
    520 					if(hsalt) {
    521 						if(!set_hex(hsalt,salt,sizeof salt)) {
    522 							BIO_printf(bio_err,
    523 								"invalid hex salt value\n");
    524 							goto end;
    525 						}
    526 					} else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
    527 						goto end;
    528 					/* If -P option then don't bother writing */
    529 					if((printkey != 2)
    530 					   && (BIO_write(wbio,magic,
    531 							 sizeof magic-1) != sizeof magic-1
    532 					       || BIO_write(wbio,
    533 							    (char *)salt,
    534 							    sizeof salt) != sizeof salt)) {
    535 						BIO_printf(bio_err,"error writing output file\n");
    536 						goto end;
    537 					}
    538 				} else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
    539 					  || BIO_read(rbio,
    540 						      (unsigned char *)salt,
    541 				    sizeof salt) != sizeof salt) {
    542 					BIO_printf(bio_err,"error reading input file\n");
    543 					goto end;
    544 				} else if(memcmp(mbuf,magic,sizeof magic-1)) {
    545 				    BIO_printf(bio_err,"bad magic number\n");
    546 				    goto end;
    547 				}
    548 
    549 				sptr = salt;
    550 			}
    551 
    552 			EVP_BytesToKey(cipher,dgst,sptr,
    553 				(unsigned char *)str,
    554 				strlen(str),1,key,iv);
    555 			/* zero the complete buffer or the string
    556 			 * passed from the command line
    557 			 * bug picked up by
    558 			 * Larry J. Hughes Jr. <hughes (at) indiana.edu> */
    559 			if (str == strbuf)
    560 				OPENSSL_cleanse(str,SIZE);
    561 			else
    562 				OPENSSL_cleanse(str,strlen(str));
    563 			}
    564 		if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
    565 			{
    566 			BIO_printf(bio_err,"invalid hex iv value\n");
    567 			goto end;
    568 			}
    569 		if ((hiv == NULL) && (str == NULL)
    570 		    && EVP_CIPHER_iv_length(cipher) != 0)
    571 			{
    572 			/* No IV was explicitly set and no IV was generated
    573 			 * during EVP_BytesToKey. Hence the IV is undefined,
    574 			 * making correct decryption impossible. */
    575 			BIO_printf(bio_err, "iv undefined\n");
    576 			goto end;
    577 			}
    578 		if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
    579 			{
    580 			BIO_printf(bio_err,"invalid hex key value\n");
    581 			goto end;
    582 			}
    583 
    584 		if ((benc=BIO_new(BIO_f_cipher())) == NULL)
    585 			goto end;
    586 
    587 		/* Since we may be changing parameters work on the encryption
    588 		 * context rather than calling BIO_set_cipher().
    589 		 */
    590 
    591 		BIO_get_cipher_ctx(benc, &ctx);
    592 		if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
    593 			{
    594 			BIO_printf(bio_err, "Error setting cipher %s\n",
    595 				EVP_CIPHER_name(cipher));
    596 			ERR_print_errors(bio_err);
    597 			goto end;
    598 			}
    599 
    600 		if (nopad)
    601 			EVP_CIPHER_CTX_set_padding(ctx, 0);
    602 
    603 		if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
    604 			{
    605 			BIO_printf(bio_err, "Error setting cipher %s\n",
    606 				EVP_CIPHER_name(cipher));
    607 			ERR_print_errors(bio_err);
    608 			goto end;
    609 			}
    610 
    611 		if (debug)
    612 			{
    613 			BIO_set_callback(benc,BIO_debug_callback);
    614 			BIO_set_callback_arg(benc,(char *)bio_err);
    615 			}
    616 
    617 		if (printkey)
    618 			{
    619 			if (!nosalt)
    620 				{
    621 				printf("salt=");
    622 				for (i=0; i<(int)sizeof(salt); i++)
    623 					printf("%02X",salt[i]);
    624 				printf("\n");
    625 				}
    626 			if (cipher->key_len > 0)
    627 				{
    628 				printf("key=");
    629 				for (i=0; i<cipher->key_len; i++)
    630 					printf("%02X",key[i]);
    631 				printf("\n");
    632 				}
    633 			if (cipher->iv_len > 0)
    634 				{
    635 				printf("iv =");
    636 				for (i=0; i<cipher->iv_len; i++)
    637 					printf("%02X",iv[i]);
    638 				printf("\n");
    639 				}
    640 			if (printkey == 2)
    641 				{
    642 				ret=0;
    643 				goto end;
    644 				}
    645 			}
    646 		}
    647 
    648 	/* Only encrypt/decrypt as we write the file */
    649 	if (benc != NULL)
    650 		wbio=BIO_push(benc,wbio);
    651 
    652 	for (;;)
    653 		{
    654 		inl=BIO_read(rbio,(char *)buff,bsize);
    655 		if (inl <= 0) break;
    656 		if (BIO_write(wbio,(char *)buff,inl) != inl)
    657 			{
    658 			BIO_printf(bio_err,"error writing output file\n");
    659 			goto end;
    660 			}
    661 		}
    662 	if (!BIO_flush(wbio))
    663 		{
    664 		BIO_printf(bio_err,"bad decrypt\n");
    665 		goto end;
    666 		}
    667 
    668 	ret=0;
    669 	if (verbose)
    670 		{
    671 		BIO_printf(bio_err,"bytes read   :%8ld\n",BIO_number_read(in));
    672 		BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
    673 		}
    674 end:
    675 	ERR_print_errors(bio_err);
    676 	if (strbuf != NULL) OPENSSL_free(strbuf);
    677 	if (buff != NULL) OPENSSL_free(buff);
    678 	if (in != NULL) BIO_free(in);
    679 	if (out != NULL) BIO_free_all(out);
    680 	if (benc != NULL) BIO_free(benc);
    681 	if (b64 != NULL) BIO_free(b64);
    682 #ifdef ZLIB
    683 	if (bzl != NULL) BIO_free(bzl);
    684 #endif
    685 	if(pass) OPENSSL_free(pass);
    686 	apps_shutdown();
    687 	OPENSSL_EXIT(ret);
    688 	}
    689 
    690 int set_hex(char *in, unsigned char *out, int size)
    691 	{
    692 	int i,n;
    693 	unsigned char j;
    694 
    695 	n=strlen(in);
    696 	if (n > (size*2))
    697 		{
    698 		BIO_printf(bio_err,"hex string is too long\n");
    699 		return(0);
    700 		}
    701 	memset(out,0,size);
    702 	for (i=0; i<n; i++)
    703 		{
    704 		j=(unsigned char)*in;
    705 		*(in++)='\0';
    706 		if (j == 0) break;
    707 		if ((j >= '0') && (j <= '9'))
    708 			j-='0';
    709 		else if ((j >= 'A') && (j <= 'F'))
    710 			j=j-'A'+10;
    711 		else if ((j >= 'a') && (j <= 'f'))
    712 			j=j-'a'+10;
    713 		else
    714 			{
    715 			BIO_printf(bio_err,"non-hex digit\n");
    716 			return(0);
    717 			}
    718 		if (i&1)
    719 			out[i/2]|=j;
    720 		else
    721 			out[i/2]=(j<<4);
    722 		}
    723 	return(1);
    724 	}
    725