(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/apps/enc.c

    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: #include <ctype.h>
   71: 
   72: int set_hex(char *in,unsigned char *out,int size);
   73: #undef SIZE
   74: #undef BSIZE
   75: #undef PROG
   76: 
   77: #define SIZE    (512)
   78: #define BSIZE   (8*1024)
   79: #define PROG    enc_main
   80: 
   81: static void show_ciphers(const OBJ_NAME *name,void *bio_)
   82:         {
   83:         BIO *bio=bio_;
   84:         static int n;
   85: 
   86:         if(!islower((unsigned char)*name->name))
   87:                 return;
   88: 
   89:         BIO_printf(bio,"-%-25s",name->name);
   90:         if(++n == 3)
   91:                 {
   92:                 BIO_printf(bio,"\n");
   93:                 n=0;
   94:                 }
   95:         else
   96:                 BIO_printf(bio," ");
   97:         }
   98: 
   99: int MAIN(int, char **);
  100: 
  101: int MAIN(int argc, char **argv)
  102:         {
  103: #ifndef OPENSSL_NO_ENGINE
  104:         ENGINE *e = NULL;
  105: #endif
  106:         static const char magic[]="Salted__";
  107:         char mbuf[sizeof magic-1];
  108:         char *strbuf=NULL;
  109:         unsigned char *buff=NULL,*bufsize=NULL;
  110:         int bsize=BSIZE,verbose=0;
  111:         int ret=1,inl;
  112:         int nopad = 0;
  113:         unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
  114:         unsigned char salt[PKCS5_SALT_LEN];
  115:         char *str=NULL, *passarg = NULL, *pass = NULL;
  116:         char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
  117:         char *md=NULL;
  118:         int enc=1,printkey=0,i,base64=0;
  119:         int debug=0,olb64=0,nosalt=0;
  120:         const EVP_CIPHER *cipher=NULL,*c;
  121:         EVP_CIPHER_CTX *ctx = NULL;
  122:         char *inf=NULL,*outf=NULL;
  123:         BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
  124: #define PROG_NAME_SIZE  39
  125:         char pname[PROG_NAME_SIZE+1];
  126: #ifndef OPENSSL_NO_ENGINE
  127:         char *engine = NULL;
  128: #endif
  129:         const EVP_MD *dgst=NULL;
  130: 
  131:         apps_startup();
  132: 
  133:         if (bio_err == NULL)
  134:                 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
  135:                         BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
  136: 
  137:         if (!load_config(bio_err, NULL))
  138:                 goto end;
  139: 
  140:         /* first check the program name */
  141:         program_name(argv[0],pname,sizeof pname);
  142:         if (strcmp(pname,"base64") == 0)
  143:                 base64=1;
  144: 
  145:         cipher=EVP_get_cipherbyname(pname);
  146:         if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
  147:                 {
  148:                 BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
  149:                 goto bad;
  150:                 }
  151: 
  152:         argc--;
  153:         argv++;
  154:         while (argc >= 1)
  155:                 {
  156:                 if    (strcmp(*argv,"-e") == 0)
  157:                         enc=1;
  158:                 else if (strcmp(*argv,"-in") == 0)
  159:                         {
  160:                         if (--argc < 1) goto bad;
  161:                         inf= *(++argv);
  162:                         }
  163:                 else if (strcmp(*argv,"-out") == 0)
  164:                         {
  165:                         if (--argc < 1) goto bad;
  166:                         outf= *(++argv);
  167:                         }
  168:                 else if (strcmp(*argv,"-pass") == 0)
  169:                         {
  170:                         if (--argc < 1) goto bad;
  171:                         passarg= *(++argv);
  172:                         }
  173: #ifndef OPENSSL_NO_ENGINE
  174:                 else if (strcmp(*argv,"-engine") == 0)
  175:                         {
  176:                         if (--argc < 1) goto bad;
  177:                         engine= *(++argv);
  178:                         }
  179: #endif
  180:                 else if       (strcmp(*argv,"-d") == 0)
  181:                         enc=0;
  182:                 else if       (strcmp(*argv,"-p") == 0)
  183:                         printkey=1;
  184:                 else if       (strcmp(*argv,"-v") == 0)
  185:                         verbose=1;
  186:                 else if       (strcmp(*argv,"-nopad") == 0)
  187:                         nopad=1;
  188:                 else if       (strcmp(*argv,"-salt") == 0)
  189:                         nosalt=0;
  190:                 else if       (strcmp(*argv,"-nosalt") == 0)
  191:                         nosalt=1;
  192:                 else if       (strcmp(*argv,"-debug") == 0)
  193:                         debug=1;
  194:                 else if       (strcmp(*argv,"-P") == 0)
  195:                         printkey=2;
  196:                 else if       (strcmp(*argv,"-A") == 0)
  197:                         olb64=1;
  198:                 else if       (strcmp(*argv,"-a") == 0)
  199:                         base64=1;
  200:                 else if       (strcmp(*argv,"-base64") == 0)
  201:                         base64=1;
  202:                 else if (strcmp(*argv,"-bufsize") == 0)
  203:                         {
  204:                         if (--argc < 1) goto bad;
  205:                         bufsize=(unsigned char *)*(++argv);
  206:                         }
  207:                 else if (strcmp(*argv,"-k") == 0)
  208:                         {
  209:                         if (--argc < 1) goto bad;
  210:                         str= *(++argv);
  211:                         }
  212:                 else if (strcmp(*argv,"-kfile") == 0)
  213:                         {
  214:                         static char buf[128];
  215:                         FILE *infile;
  216:                         char *file;
  217: 
  218:                         if (--argc < 1) goto bad;
  219:                         file= *(++argv);
  220:                         infile=fopen(file,"r");
  221:                         if (infile == NULL)
  222:                                 {
  223:                                 BIO_printf(bio_err,"unable to read key from '%s'\n",
  224:                                         file);
  225:                                 goto bad;
  226:                                 }
  227:                         buf[0]='\0';
  228:                         fgets(buf,sizeof buf,infile);
  229:                         fclose(infile);
  230:                         i=strlen(buf);
  231:                         if ((i > 0) &&
  232:                                 ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
  233:                                 buf[--i]='\0';
  234:                         if ((i > 0) &&
  235:                                 ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
  236:                                 buf[--i]='\0';
  237:                         if (i < 1)
  238:                                 {
  239:                                 BIO_printf(bio_err,"zero length password\n");
  240:                                 goto bad;
  241:                                 }
  242:                         str=buf;
  243:                         }
  244:                 else if (strcmp(*argv,"-K") == 0)
  245:                         {
  246:                         if (--argc < 1) goto bad;
  247:                         hkey= *(++argv);
  248:                         }
  249:                 else if (strcmp(*argv,"-S") == 0)
  250:                         {
  251:                         if (--argc < 1) goto bad;
  252:                         hsalt= *(++argv);
  253:                         }
  254:                 else if (strcmp(*argv,"-iv") == 0)
  255:                         {
  256:                         if (--argc < 1) goto bad;
  257:                         hiv= *(++argv);
  258:                         }
  259:                 else if (strcmp(*argv,"-md") == 0)
  260:                         {
  261:                         if (--argc < 1) goto bad;
  262:                         md= *(++argv);
  263:                         }
  264:                 else if       ((argv[0][0] == '-') &&
  265:                         ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
  266:                         {
  267:                         cipher=c;
  268:                         }
  269:                 else if (strcmp(*argv,"-none") == 0)
  270:                         cipher=NULL;
  271:                 else
  272:                         {
  273:                         BIO_printf(bio_err,"unknown option '%s'\n",*argv);
  274: bad:
  275:                         BIO_printf(bio_err,"options are\n");
  276:                         BIO_printf(bio_err,"%-14s input file\n","-in <file>");
  277:                         BIO_printf(bio_err,"%-14s output file\n","-out <file>");
  278:                         BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
  279:                         BIO_printf(bio_err,"%-14s encrypt\n","-e");
  280:                         BIO_printf(bio_err,"%-14s decrypt\n","-d");
  281:                         BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
  282:                         BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
  283:                         BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
  284:                         BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
  285:                         BIO_printf(bio_err,"%-14s   from a passphrase.  One of md2, md5, sha or sha1\n","");
  286:                         BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
  287:                         BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
  288:                         BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
  289: #ifndef OPENSSL_NO_ENGINE
  290:                         BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
  291: #endif
  292: 
  293:                         BIO_printf(bio_err,"Cipher Types\n");
  294:                         OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
  295:                                                show_ciphers,
  296:                                                bio_err);
  297:                         BIO_printf(bio_err,"\n");
  298: 
  299:                         goto end;
  300:                         }
  301:                 argc--;
  302:                 argv++;
  303:                 }
  304: 
  305: #ifndef OPENSSL_NO_ENGINE
  306:         e = setup_engine(bio_err, engine, 0);
  307: #endif
  308: 
  309:         if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
  310:                 {
  311:                 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
  312:                 goto end;
  313:                 }
  314: 
  315:         if (dgst == NULL)
  316:                 {
  317:                 dgst = EVP_md5();
  318:                 }
  319: 
  320:         if (bufsize != NULL)
  321:                 {
  322:                 unsigned long n;
  323: 
  324:                 for (n=0; *bufsize; bufsize++)
  325:                         {
  326:                         i= *bufsize;
  327:                         if ((i <= '9') && (i >= '0'))
  328:                                 n=n*10+i-'0';
  329:                         else if (i == 'k')
  330:                                 {
  331:                                 n*=1024;
  332:                                 bufsize++;
  333:                                 break;
  334:                                 }
  335:                         }
  336:                 if (*bufsize != '\0')
  337:                         {
  338:                         BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
  339:                         goto end;
  340:                         }
  341: 
  342:                 /* It must be large enough for a base64 encoded line */
  343:                 if (base64 && n < 80) n=80;
  344: 
  345:                 bsize=(int)n;
  346:                 if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
  347:                 }
  348: 
  349:         strbuf=OPENSSL_malloc(SIZE);
  350:         buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
  351:         if ((buff == NULL) || (strbuf == NULL))
  352:                 {
  353:                 BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
  354:                 goto end;
  355:                 }
  356: 
  357:         in=BIO_new(BIO_s_file());
  358:         out=BIO_new(BIO_s_file());
  359:         if ((in == NULL) || (out == NULL))
  360:                 {
  361:                 ERR_print_errors(bio_err);
  362:                 goto end;
  363:                 }
  364:         if (debug)
  365:                 {
  366:                 BIO_set_callback(in,BIO_debug_callback);
  367:                 BIO_set_callback(out,BIO_debug_callback);
  368:                 BIO_set_callback_arg(in,(char *)bio_err);
  369:                 BIO_set_callback_arg(out,(char *)bio_err);
  370:                 }
  371: 
  372:         if (inf == NULL)
  373:                 {
  374:                 if (bufsize != NULL)
  375:                         setvbuf(stdin, (char *)NULL, _IONBF, 0);
  376:                 BIO_set_fp(in,stdin,BIO_NOCLOSE);
  377:                 }
  378:         else
  379:                 {
  380:                 if (BIO_read_filename(in,inf) <= 0)
  381:                         {
  382:                         perror(inf);
  383:                         goto end;
  384:                         }
  385:                 }
  386: 
  387:         if(!str && passarg) {
  388:                 if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
  389:                         BIO_printf(bio_err, "Error getting password\n");
  390:                         goto end;
  391:                 }
  392:                 str = pass;
  393:         }
  394: 
  395:         if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
  396:                 {
  397:                 for (;;)
  398:                         {
  399:                         char buf[200];
  400: 
  401:                         BIO_snprintf(buf,sizeof buf,"enter %s %s password:",
  402:                                      OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
  403:                                      (enc)?"encryption":"decryption");
  404:                         strbuf[0]='\0';
  405:                         i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
  406:                         if (i == 0)
  407:                                 {
  408:                                 if (strbuf[0] == '\0')
  409:                                         {
  410:                                         ret=1;
  411:                                         goto end;
  412:                                         }
  413:                                 str=strbuf;
  414:                                 break;
  415:                                 }
  416:                         if (i < 0)
  417:                                 {
  418:                                 BIO_printf(bio_err,"bad password read\n");
  419:                                 goto end;
  420:                                 }
  421:                         }
  422:                 }
  423: 
  424: 
  425:         if (outf == NULL)
  426:                 {
  427:                 BIO_set_fp(out,stdout,BIO_NOCLOSE);
  428:                 if (bufsize != NULL)
  429:                         setvbuf(stdout, (char *)NULL, _IONBF, 0);
  430: #ifdef OPENSSL_SYS_VMS
  431:                 {
  432:                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
  433:                 out = BIO_push(tmpbio, out);
  434:                 }
  435: #endif
  436:                 }
  437:         else
  438:                 {
  439:                 if (BIO_write_filename(out,outf) <= 0)
  440:                         {
  441:                         perror(outf);
  442:                         goto end;
  443:                         }
  444:                 }
  445: 
  446:         rbio=in;
  447:         wbio=out;
  448: 
  449:         if (base64)
  450:                 {
  451:                 if ((b64=BIO_new(BIO_f_base64())) == NULL)
  452:                         goto end;
  453:                 if (debug)
  454:                         {
  455:                         BIO_set_callback(b64,BIO_debug_callback);
  456:                         BIO_set_callback_arg(b64,(char *)bio_err);
  457:                         }
  458:                 if (olb64)
  459:                         BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
  460:                 if (enc)
  461:                         wbio=BIO_push(b64,wbio);
  462:                 else
  463:                         rbio=BIO_push(b64,rbio);
  464:                 }
  465: 
  466:         if (cipher != NULL)
  467:                 {
  468:                 /* Note that str is NULL if a key was passed on the command
  469:                  * line, so we get no salt in that case. Is this a bug?
  470:                  */
  471:                 if (str != NULL)
  472:                         {
  473:                         /* Salt handling: if encrypting generate a salt and
  474:                          * write to output BIO. If decrypting read salt from
  475:                          * input BIO.
  476:                          */
  477:                         unsigned char *sptr;
  478:                         if(nosalt) sptr = NULL;
  479:                         else {
  480:                                 if(enc) {
  481:                                         if(hsalt) {
  482:                                                 if(!set_hex(hsalt,salt,sizeof salt)) {
  483:                                                         BIO_printf(bio_err,
  484:                                                                 "invalid hex salt value\n");
  485:                                                         goto end;
  486:                                                 }
  487:                                         } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
  488:                                                 goto end;
  489:                                         /* If -P option then don't bother writing */
  490:                                         if((printkey != 2)
  491:                                            && (BIO_write(wbio,magic,
  492:                                                          sizeof magic-1) != sizeof magic-1
  493:                                                || BIO_write(wbio,
  494:                                                             (char *)salt,
  495:                                                             sizeof salt) != sizeof salt)) {
  496:                                                 BIO_printf(bio_err,"error writing output file\n");
  497:                                                 goto end;
  498:                                         }
  499:                                 } else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
  500:                                           || BIO_read(rbio,
  501:                                                       (unsigned char *)salt,
  502:                                     sizeof salt) != sizeof salt) {
  503:                                         BIO_printf(bio_err,"error reading input file\n");
  504:                                         goto end;
  505:                                 } else if(memcmp(mbuf,magic,sizeof magic-1)) {
  506:                                     BIO_printf(bio_err,"bad magic number\n");
  507:                                     goto end;
  508:                                 }
  509: 
  510:                                 sptr = salt;
  511:                         }
  512: 
  513:                         EVP_BytesToKey(cipher,dgst,sptr,
  514:                                 (unsigned char *)str,
  515:                                 strlen(str),1,key,iv);
  516:                         /* zero the complete buffer or the string
  517:                          * passed from the command line
  518:                          * bug picked up by
  519:                          * Larry J. Hughes Jr. <hughes@indiana.edu> */
  520:                         if (str == strbuf)
  521:                                 OPENSSL_cleanse(str,SIZE);
  522:                         else
  523:                                 OPENSSL_cleanse(str,strlen(str));
  524:                         }
  525:                 if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
  526:                         {
  527:                         BIO_printf(bio_err,"invalid hex iv value\n");
  528:                         goto end;
  529:                         }
  530:                 if ((hiv == NULL) && (str == NULL))
  531:                         {
  532:                         /* No IV was explicitly set and no IV was generated
  533:                          * during EVP_BytesToKey. Hence the IV is undefined,
  534:                          * making correct decryption impossible. */
  535:                         BIO_printf(bio_err, "iv undefined\n");
  536:                         goto end;
  537:                         }
  538:                 if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
  539:                         {
  540: