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