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