[BACK]Return to enc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / openssl

Annotation of src/usr.bin/openssl/enc.c, Revision 1.1

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