1 /* $OpenBSD: enc.c,v 1.7 2015/09/11 14:30:23 bcook 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 hexidecimal 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 hexidecimal 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 hexidecimal 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 memset(&enc_config, 0, sizeof(enc_config)); 342 enc_config.enc = 1; 343 344 /* first check the program name */ 345 program_name(argv[0], pname, sizeof(pname)); 346 347 if (strcmp(pname, "base64") == 0) 348 enc_config.base64 = 1; 349 350 #ifdef ZLIB 351 if (strcmp(pname, "zlib") == 0) 352 enc_config.do_zlib = 1; 353 #endif 354 355 enc_config.cipher = EVP_get_cipherbyname(pname); 356 357 #ifdef ZLIB 358 if (!enc_config.do_zlib && !enc_config.base64 && 359 enc_config.cipher == NULL && strcmp(pname, "enc") != 0) 360 #else 361 if (!enc_config.base64 && enc_config.cipher == NULL && 362 strcmp(pname, "enc") != 0) 363 #endif 364 { 365 BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 366 goto end; 367 } 368 369 if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) { 370 enc_usage(); 371 goto end; 372 } 373 374 if (enc_config.keyfile != NULL) { 375 static char buf[128]; 376 FILE *infile; 377 378 infile = fopen(enc_config.keyfile, "r"); 379 if (infile == NULL) { 380 BIO_printf(bio_err, "unable to read key from '%s'\n", 381 enc_config.keyfile); 382 goto end; 383 } 384 buf[0] = '\0'; 385 if (!fgets(buf, sizeof buf, infile)) { 386 BIO_printf(bio_err, "unable to read key from '%s'\n", 387 enc_config.keyfile); 388 fclose(infile); 389 goto end; 390 } 391 fclose(infile); 392 i = strlen(buf); 393 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 394 buf[--i] = '\0'; 395 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 396 buf[--i] = '\0'; 397 if (i < 1) { 398 BIO_printf(bio_err, "zero length password\n"); 399 goto end; 400 } 401 enc_config.keystr = buf; 402 } 403 404 if (enc_config.md != NULL && 405 (dgst = EVP_get_digestbyname(enc_config.md)) == NULL) { 406 BIO_printf(bio_err, 407 "%s is an unsupported message digest type\n", 408 enc_config.md); 409 goto end; 410 } 411 if (dgst == NULL) { 412 dgst = EVP_md5(); /* XXX */ 413 } 414 415 if (enc_config.bufsize != NULL) { 416 char *p = enc_config.bufsize; 417 unsigned long n; 418 419 /* XXX - provide an OPTION_ARG_DISKUNIT. */ 420 for (n = 0; *p != '\0'; p++) { 421 i = *p; 422 if ((i <= '9') && (i >= '0')) 423 n = n * 10 + i - '0'; 424 else if (i == 'k') { 425 n *= 1024; 426 p++; 427 break; 428 } 429 } 430 if (*p != '\0') { 431 BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 432 goto end; 433 } 434 /* It must be large enough for a base64 encoded line. */ 435 if (enc_config.base64 && n < 80) 436 n = 80; 437 438 bsize = (int)n; 439 if (enc_config.verbose) 440 BIO_printf(bio_err, "bufsize=%d\n", bsize); 441 } 442 strbuf = malloc(SIZE); 443 buff = malloc(EVP_ENCODE_LENGTH(bsize)); 444 if ((buff == NULL) || (strbuf == NULL)) { 445 BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize)); 446 goto end; 447 } 448 in = BIO_new(BIO_s_file()); 449 out = BIO_new(BIO_s_file()); 450 if ((in == NULL) || (out == NULL)) { 451 ERR_print_errors(bio_err); 452 goto end; 453 } 454 if (enc_config.debug) { 455 BIO_set_callback(in, BIO_debug_callback); 456 BIO_set_callback(out, BIO_debug_callback); 457 BIO_set_callback_arg(in, (char *) bio_err); 458 BIO_set_callback_arg(out, (char *) bio_err); 459 } 460 if (enc_config.inf == NULL) { 461 if (enc_config.bufsize != NULL) 462 setvbuf(stdin, (char *) NULL, _IONBF, 0); 463 BIO_set_fp(in, stdin, BIO_NOCLOSE); 464 } else { 465 if (BIO_read_filename(in, enc_config.inf) <= 0) { 466 perror(enc_config.inf); 467 goto end; 468 } 469 } 470 471 if (!enc_config.keystr && enc_config.passarg) { 472 if (!app_passwd(bio_err, enc_config.passarg, NULL, 473 &pass, NULL)) { 474 BIO_printf(bio_err, "Error getting password\n"); 475 goto end; 476 } 477 enc_config.keystr = pass; 478 } 479 if (enc_config.keystr == NULL && enc_config.cipher != NULL && 480 enc_config.hkey == NULL) { 481 for (;;) { 482 char buf[200]; 483 int retval; 484 485 retval = snprintf(buf, sizeof buf, 486 "enter %s %s password:", 487 OBJ_nid2ln(EVP_CIPHER_nid(enc_config.cipher)), 488 enc_config.enc ? "encryption" : "decryption"); 489 if ((size_t)retval >= sizeof buf) { 490 BIO_printf(bio_err, 491 "Password prompt too long\n"); 492 goto end; 493 } 494 strbuf[0] = '\0'; 495 i = EVP_read_pw_string((char *)strbuf, SIZE, buf, 496 enc_config.enc); 497 if (i == 0) { 498 if (strbuf[0] == '\0') { 499 ret = 1; 500 goto end; 501 } 502 enc_config.keystr = strbuf; 503 break; 504 } 505 if (i < 0) { 506 BIO_printf(bio_err, "bad password read\n"); 507 goto end; 508 } 509 } 510 } 511 if (enc_config.outf == NULL) { 512 BIO_set_fp(out, stdout, BIO_NOCLOSE); 513 if (enc_config.bufsize != NULL) 514 setvbuf(stdout, (char *)NULL, _IONBF, 0); 515 } else { 516 if (BIO_write_filename(out, enc_config.outf) <= 0) { 517 perror(enc_config.outf); 518 goto end; 519 } 520 } 521 522 rbio = in; 523 wbio = out; 524 525 #ifdef ZLIB 526 if (do_zlib) { 527 if ((bzl = BIO_new(BIO_f_zlib())) == NULL) 528 goto end; 529 if (enc) 530 wbio = BIO_push(bzl, wbio); 531 else 532 rbio = BIO_push(bzl, rbio); 533 } 534 #endif 535 536 if (enc_config.base64) { 537 if ((b64 = BIO_new(BIO_f_base64())) == NULL) 538 goto end; 539 if (enc_config.debug) { 540 BIO_set_callback(b64, BIO_debug_callback); 541 BIO_set_callback_arg(b64, (char *) bio_err); 542 } 543 if (enc_config.olb64) 544 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 545 if (enc_config.enc) 546 wbio = BIO_push(b64, wbio); 547 else 548 rbio = BIO_push(b64, rbio); 549 } 550 if (enc_config.cipher != NULL) { 551 /* 552 * Note that keystr is NULL if a key was passed on the command 553 * line, so we get no salt in that case. Is this a bug? 554 */ 555 if (enc_config.keystr != NULL) { 556 /* 557 * Salt handling: if encrypting generate a salt and 558 * write to output BIO. If decrypting read salt from 559 * input BIO. 560 */ 561 unsigned char *sptr; 562 if (enc_config.nosalt) 563 sptr = NULL; 564 else { 565 if (enc_config.enc) { 566 if (enc_config.hsalt) { 567 if (!set_hex(enc_config.hsalt, salt, sizeof salt)) { 568 BIO_printf(bio_err, 569 "invalid hex salt value\n"); 570 goto end; 571 } 572 } else 573 arc4random_buf(salt, 574 sizeof(salt)); 575 /* 576 * If -P option then don't bother 577 * writing 578 */ 579 if ((enc_config.printkey != 2) 580 && (BIO_write(wbio, magic, 581 sizeof magic - 1) != sizeof magic - 1 582 || BIO_write(wbio, 583 (char *) salt, 584 sizeof salt) != sizeof salt)) { 585 BIO_printf(bio_err, "error writing output file\n"); 586 goto end; 587 } 588 } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf 589 || BIO_read(rbio, 590 (unsigned char *) salt, 591 sizeof salt) != sizeof salt) { 592 BIO_printf(bio_err, "error reading input file\n"); 593 goto end; 594 } else if (memcmp(mbuf, magic, sizeof magic - 1)) { 595 BIO_printf(bio_err, "bad magic number\n"); 596 goto end; 597 } 598 sptr = salt; 599 } 600 601 EVP_BytesToKey(enc_config.cipher, dgst, sptr, 602 (unsigned char *)enc_config.keystr, 603 strlen(enc_config.keystr), 1, key, iv); 604 /* 605 * zero the complete buffer or the string passed from 606 * the command line bug picked up by Larry J. Hughes 607 * Jr. <hughes@indiana.edu> 608 */ 609 if (enc_config.keystr == strbuf) 610 explicit_bzero(enc_config.keystr, SIZE); 611 else 612 explicit_bzero(enc_config.keystr, 613 strlen(enc_config.keystr)); 614 } 615 if (enc_config.hiv != NULL && 616 !set_hex(enc_config.hiv, iv, sizeof iv)) { 617 BIO_printf(bio_err, "invalid hex iv value\n"); 618 goto end; 619 } 620 if (enc_config.hiv == NULL && enc_config.keystr == NULL && 621 EVP_CIPHER_iv_length(enc_config.cipher) != 0) { 622 /* 623 * No IV was explicitly set and no IV was generated 624 * during EVP_BytesToKey. Hence the IV is undefined, 625 * making correct decryption impossible. 626 */ 627 BIO_printf(bio_err, "iv undefined\n"); 628 goto end; 629 } 630 if (enc_config.hkey != NULL && 631 !set_hex(enc_config.hkey, key, sizeof key)) { 632 BIO_printf(bio_err, "invalid hex key value\n"); 633 goto end; 634 } 635 if ((benc = BIO_new(BIO_f_cipher())) == NULL) 636 goto end; 637 638 /* 639 * Since we may be changing parameters work on the encryption 640 * context rather than calling BIO_set_cipher(). 641 */ 642 643 BIO_get_cipher_ctx(benc, &ctx); 644 645 if (!EVP_CipherInit_ex(ctx, enc_config.cipher, NULL, NULL, 646 NULL, enc_config.enc)) { 647 BIO_printf(bio_err, "Error setting cipher %s\n", 648 EVP_CIPHER_name(enc_config.cipher)); 649 ERR_print_errors(bio_err); 650 goto end; 651 } 652 if (enc_config.nopad) 653 EVP_CIPHER_CTX_set_padding(ctx, 0); 654 655 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 656 enc_config.enc)) { 657 BIO_printf(bio_err, "Error setting cipher %s\n", 658 EVP_CIPHER_name(enc_config.cipher)); 659 ERR_print_errors(bio_err); 660 goto end; 661 } 662 if (enc_config.debug) { 663 BIO_set_callback(benc, BIO_debug_callback); 664 BIO_set_callback_arg(benc, (char *) bio_err); 665 } 666 if (enc_config.printkey) { 667 if (!enc_config.nosalt) { 668 printf("salt="); 669 for (i = 0; i < (int) sizeof(salt); i++) 670 printf("%02X", salt[i]); 671 printf("\n"); 672 } 673 if (enc_config.cipher->key_len > 0) { 674 printf("key="); 675 for (i = 0; i < enc_config.cipher->key_len; i++) 676 printf("%02X", key[i]); 677 printf("\n"); 678 } 679 if (enc_config.cipher->iv_len > 0) { 680 printf("iv ="); 681 for (i = 0; i < enc_config.cipher->iv_len; i++) 682 printf("%02X", iv[i]); 683 printf("\n"); 684 } 685 if (enc_config.printkey == 2) { 686 ret = 0; 687 goto end; 688 } 689 } 690 } 691 /* Only encrypt/decrypt as we write the file */ 692 if (benc != NULL) 693 wbio = BIO_push(benc, wbio); 694 695 for (;;) { 696 inl = BIO_read(rbio, (char *) buff, bsize); 697 if (inl <= 0) 698 break; 699 if (BIO_write(wbio, (char *) buff, inl) != inl) { 700 BIO_printf(bio_err, "error writing output file\n"); 701 goto end; 702 } 703 } 704 if (!BIO_flush(wbio)) { 705 BIO_printf(bio_err, "bad decrypt\n"); 706 goto end; 707 } 708 ret = 0; 709 if (enc_config.verbose) { 710 BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 711 BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 712 } 713 end: 714 ERR_print_errors(bio_err); 715 free(strbuf); 716 free(buff); 717 BIO_free(in); 718 if (out != NULL) 719 BIO_free_all(out); 720 BIO_free(benc); 721 BIO_free(b64); 722 #ifdef ZLIB 723 BIO_free(bzl); 724 #endif 725 free(pass); 726 727 return (ret); 728 } 729 730 int 731 set_hex(char *in, unsigned char *out, int size) 732 { 733 int i, n; 734 unsigned char j; 735 736 n = strlen(in); 737 if (n > (size * 2)) { 738 BIO_printf(bio_err, "hex string is too long\n"); 739 return (0); 740 } 741 memset(out, 0, size); 742 for (i = 0; i < n; i++) { 743 j = (unsigned char) *in; 744 *(in++) = '\0'; 745 if (j == 0) 746 break; 747 if ((j >= '0') && (j <= '9')) 748 j -= '0'; 749 else if ((j >= 'A') && (j <= 'F')) 750 j = j - 'A' + 10; 751 else if ((j >= 'a') && (j <= 'f')) 752 j = j - 'a' + 10; 753 else { 754 BIO_printf(bio_err, "non-hex digit\n"); 755 return (0); 756 } 757 if (i & 1) 758 out[i / 2] |= j; 759 else 760 out[i / 2] = (j << 4); 761 } 762 return (1); 763 } 764