00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <stdio.h>
00060 #include <stdlib.h>
00061 #include <string.h>
00062 #include "apps.h"
00063 #include <openssl/bio.h>
00064 #include <openssl/err.h>
00065 #include <openssl/evp.h>
00066 #include <openssl/objects.h>
00067 #include <openssl/x509.h>
00068 #include <openssl/rand.h>
00069 #include <openssl/pem.h>
00070 #include <ctype.h>
00071
00072 int set_hex(char *in,unsigned char *out,int size);
00073 #undef SIZE
00074 #undef BSIZE
00075 #undef PROG
00076
00077 #define SIZE (512)
00078 #define BSIZE (8*1024)
00079 #define PROG enc_main
00080
00081 static void show_ciphers(const OBJ_NAME *name,void *bio_)
00082 {
00083 BIO *bio=bio_;
00084 static int n;
00085
00086 if(!islower((unsigned char)*name->name))
00087 return;
00088
00089 BIO_printf(bio,"-%-25s",name->name);
00090 if(++n == 3)
00091 {
00092 BIO_printf(bio,"\n");
00093 n=0;
00094 }
00095 else
00096 BIO_printf(bio," ");
00097 }
00098
00099 int MAIN(int, char **);
00100
00101 int MAIN(int argc, char **argv)
00102 {
00103 #ifndef OPENSSL_NO_ENGINE
00104 ENGINE *e = NULL;
00105 #endif
00106 static const char magic[]="Salted__";
00107 char mbuf[sizeof magic-1];
00108 char *strbuf=NULL;
00109 unsigned char *buff=NULL,*bufsize=NULL;
00110 int bsize=BSIZE,verbose=0;
00111 int ret=1,inl;
00112 int nopad = 0;
00113 unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
00114 unsigned char salt[PKCS5_SALT_LEN];
00115 char *str=NULL, *passarg = NULL, *pass = NULL;
00116 char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
00117 char *md=NULL;
00118 int enc=1,printkey=0,i,base64=0;
00119 int debug=0,olb64=0,nosalt=0;
00120 const EVP_CIPHER *cipher=NULL,*c;
00121 EVP_CIPHER_CTX *ctx = NULL;
00122 char *inf=NULL,*outf=NULL;
00123 BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
00124 #define PROG_NAME_SIZE 39
00125 char pname[PROG_NAME_SIZE+1];
00126 #ifndef OPENSSL_NO_ENGINE
00127 char *engine = NULL;
00128 #endif
00129 const EVP_MD *dgst=NULL;
00130
00131 apps_startup();
00132
00133 if (bio_err == NULL)
00134 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
00135 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
00136
00137 if (!load_config(bio_err, NULL))
00138 goto end;
00139
00140
00141 program_name(argv[0],pname,sizeof pname);
00142 if (strcmp(pname,"base64") == 0)
00143 base64=1;
00144
00145 cipher=EVP_get_cipherbyname(pname);
00146 if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
00147 {
00148 BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
00149 goto bad;
00150 }
00151
00152 argc--;
00153 argv++;
00154 while (argc >= 1)
00155 {
00156 if (strcmp(*argv,"-e") == 0)
00157 enc=1;
00158 else if (strcmp(*argv,"-in") == 0)
00159 {
00160 if (--argc < 1) goto bad;
00161 inf= *(++argv);
00162 }
00163 else if (strcmp(*argv,"-out") == 0)
00164 {
00165 if (--argc < 1) goto bad;
00166 outf= *(++argv);
00167 }
00168 else if (strcmp(*argv,"-pass") == 0)
00169 {
00170 if (--argc < 1) goto bad;
00171 passarg= *(++argv);
00172 }
00173 #ifndef OPENSSL_NO_ENGINE
00174 else if (strcmp(*argv,"-engine") == 0)
00175 {
00176 if (--argc < 1) goto bad;
00177 engine= *(++argv);
00178 }
00179 #endif
00180 else if (strcmp(*argv,"-d") == 0)
00181 enc=0;
00182 else if (strcmp(*argv,"-p") == 0)
00183 printkey=1;
00184 else if (strcmp(*argv,"-v") == 0)
00185 verbose=1;
00186 else if (strcmp(*argv,"-nopad") == 0)
00187 nopad=1;
00188 else if (strcmp(*argv,"-salt") == 0)
00189 nosalt=0;
00190 else if (strcmp(*argv,"-nosalt") == 0)
00191 nosalt=1;
00192 else if (strcmp(*argv,"-debug") == 0)
00193 debug=1;
00194 else if (strcmp(*argv,"-P") == 0)
00195 printkey=2;
00196 else if (strcmp(*argv,"-A") == 0)
00197 olb64=1;
00198 else if (strcmp(*argv,"-a") == 0)
00199 base64=1;
00200 else if (strcmp(*argv,"-base64") == 0)
00201 base64=1;
00202 else if (strcmp(*argv,"-bufsize") == 0)
00203 {
00204 if (--argc < 1) goto bad;
00205 bufsize=(unsigned char *)*(++argv);
00206 }
00207 else if (strcmp(*argv,"-k") == 0)
00208 {
00209 if (--argc < 1) goto bad;
00210 str= *(++argv);
00211 }
00212 else if (strcmp(*argv,"-kfile") == 0)
00213 {
00214 static char buf[128];
00215 FILE *infile;
00216 char *file;
00217
00218 if (--argc < 1) goto bad;
00219 file= *(++argv);
00220 infile=fopen(file,"r");
00221 if (infile == NULL)
00222 {
00223 BIO_printf(bio_err,"unable to read key from '%s'\n",
00224 file);
00225 goto bad;
00226 }
00227 buf[0]='\0';
00228 fgets(buf,sizeof buf,infile);
00229 fclose(infile);
00230 i=strlen(buf);
00231 if ((i > 0) &&
00232 ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
00233 buf[--i]='\0';
00234 if ((i > 0) &&
00235 ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
00236 buf[--i]='\0';
00237 if (i < 1)
00238 {
00239 BIO_printf(bio_err,"zero length password\n");
00240 goto bad;
00241 }
00242 str=buf;
00243 }
00244 else if (strcmp(*argv,"-K") == 0)
00245 {
00246 if (--argc < 1) goto bad;
00247 hkey= *(++argv);
00248 }
00249 else if (strcmp(*argv,"-S") == 0)
00250 {
00251 if (--argc < 1) goto bad;
00252 hsalt= *(++argv);
00253 }
00254 else if (strcmp(*argv,"-iv") == 0)
00255 {
00256 if (--argc < 1) goto bad;
00257 hiv= *(++argv);
00258 }
00259 else if (strcmp(*argv,"-md") == 0)
00260 {
00261 if (--argc < 1) goto bad;
00262 md= *(++argv);
00263 }
00264 else if ((argv[0][0] == '-') &&
00265 ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
00266 {
00267 cipher=c;
00268 }
00269 else if (strcmp(*argv,"-none") == 0)
00270 cipher=NULL;
00271 else
00272 {
00273 BIO_printf(bio_err,"unknown option '%s'\n",*argv);
00274 bad:
00275 BIO_printf(bio_err,"options are\n");
00276 BIO_printf(bio_err,"%-14s input file\n","-in <file>");
00277 BIO_printf(bio_err,"%-14s output file\n","-out <file>");
00278 BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
00279 BIO_printf(bio_err,"%-14s encrypt\n","-e");
00280 BIO_printf(bio_err,"%-14s decrypt\n","-d");
00281 BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
00282 BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
00283 BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
00284 BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
00285 BIO_printf(bio_err,"%-14s from a passphrase. One of md2, md5, sha or sha1\n","");
00286 BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
00287 BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
00288 BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
00289 #ifndef OPENSSL_NO_ENGINE
00290 BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
00291 #endif
00292
00293 BIO_printf(bio_err,"Cipher Types\n");
00294 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
00295 show_ciphers,
00296 bio_err);
00297 BIO_printf(bio_err,"\n");
00298
00299 goto end;
00300 }
00301 argc--;
00302 argv++;
00303 }
00304
00305 #ifndef OPENSSL_NO_ENGINE
00306 e = setup_engine(bio_err, engine, 0);
00307 #endif
00308
00309 if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
00310 {
00311 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
00312 goto end;
00313 }
00314
00315 if (dgst == NULL)
00316 {
00317 dgst = EVP_md5();
00318 }
00319
00320 if (bufsize != NULL)
00321 {
00322 unsigned long n;
00323
00324 for (n=0; *bufsize; bufsize++)
00325 {
00326 i= *bufsize;
00327 if ((i <= '9') && (i >= '0'))
00328 n=n*10+i-'0';
00329 else if (i == 'k')
00330 {
00331 n*=1024;
00332 bufsize++;
00333 break;
00334 }
00335 }
00336 if (*bufsize != '\0')
00337 {
00338 BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
00339 goto end;
00340 }
00341
00342
00343 if (n < 80) n=80;
00344
00345 bsize=(int)n;
00346 if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
00347 }
00348
00349 strbuf=OPENSSL_malloc(SIZE);
00350 buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
00351 if ((buff == NULL) || (strbuf == NULL))
00352 {
00353 BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
00354 goto end;
00355 }
00356
00357 in=BIO_new(BIO_s_file());
00358 out=BIO_new(BIO_s_file());
00359 if ((in == NULL) || (out == NULL))
00360 {
00361 ERR_print_errors(bio_err);
00362 goto end;
00363 }
00364 if (debug)
00365 {
00366 BIO_set_callback(in,BIO_debug_callback);
00367 BIO_set_callback(out,BIO_debug_callback);
00368 BIO_set_callback_arg(in,bio_err);
00369 BIO_set_callback_arg(out,bio_err);
00370 }
00371
00372 if (inf == NULL)
00373 BIO_set_fp(in,stdin,BIO_NOCLOSE);
00374 else
00375 {
00376 if (BIO_read_filename(in,inf) <= 0)
00377 {
00378 perror(inf);
00379 goto end;
00380 }
00381 }
00382
00383 if(!str && passarg) {
00384 if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
00385 BIO_printf(bio_err, "Error getting password\n");
00386 goto end;
00387 }
00388 str = pass;
00389 }
00390
00391 if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
00392 {
00393 for (;;)
00394 {
00395 char buf[200];
00396
00397 BIO_snprintf(buf,sizeof buf,"enter %s %s password:",
00398 OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
00399 (enc)?"encryption":"decryption");
00400 strbuf[0]='\0';
00401 i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
00402 if (i == 0)
00403 {
00404 if (strbuf[0] == '\0')
00405 {
00406 ret=1;
00407 goto end;
00408 }
00409 str=strbuf;
00410 break;
00411 }
00412 if (i < 0)
00413 {
00414 BIO_printf(bio_err,"bad password read\n");
00415 goto end;
00416 }
00417 }
00418 }
00419
00420
00421 if (outf == NULL)
00422 {
00423 BIO_set_fp(out,stdout,BIO_NOCLOSE);
00424 #ifdef OPENSSL_SYS_VMS
00425 {
00426 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
00427 out = BIO_push(tmpbio, out);
00428 }
00429 #endif
00430 }
00431 else
00432 {
00433 if (BIO_write_filename(out,outf) <= 0)
00434 {
00435 perror(outf);
00436 goto end;
00437 }
00438 }
00439
00440 rbio=in;
00441 wbio=out;
00442
00443 if (base64)
00444 {
00445 if ((b64=BIO_new(BIO_f_base64())) == NULL)
00446 goto end;
00447 if (debug)
00448 {
00449 BIO_set_callback(b64,BIO_debug_callback);
00450 BIO_set_callback_arg(b64,bio_err);
00451 }
00452 if (olb64)
00453 BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
00454 if (enc)
00455 wbio=BIO_push(b64,wbio);
00456 else
00457 rbio=BIO_push(b64,rbio);
00458 }
00459
00460 if (cipher != NULL)
00461 {
00462
00463
00464
00465 if (str != NULL)
00466 {
00467
00468
00469
00470
00471 unsigned char *sptr;
00472 if(nosalt) sptr = NULL;
00473 else {
00474 if(enc) {
00475 if(hsalt) {
00476 if(!set_hex(hsalt,salt,sizeof salt)) {
00477 BIO_printf(bio_err,
00478 "invalid hex salt value\n");
00479 goto end;
00480 }
00481 } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
00482 goto end;
00483
00484 if((printkey != 2)
00485 && (BIO_write(wbio,magic,
00486 sizeof magic-1) != sizeof magic-1
00487 || BIO_write(wbio,
00488 (char *)salt,
00489 sizeof salt) != sizeof salt)) {
00490 BIO_printf(bio_err,"error writing output file\n");
00491 goto end;
00492 }
00493 } else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
00494 || BIO_read(rbio,
00495 (unsigned char *)salt,
00496 sizeof salt) != sizeof salt) {
00497 BIO_printf(bio_err,"error reading input file\n");
00498 goto end;
00499 } else if(memcmp(mbuf,magic,sizeof magic-1)) {
00500 BIO_printf(bio_err,"bad magic number\n");
00501 goto end;
00502 }
00503
00504 sptr = salt;
00505 }
00506
00507 EVP_BytesToKey(cipher,dgst,sptr,
00508 (unsigned char *)str,
00509 strlen(str),1,key,iv);
00510
00511
00512
00513
00514 if (str == strbuf)
00515 OPENSSL_cleanse(str,SIZE);
00516 else
00517 OPENSSL_cleanse(str,strlen(str));
00518 }
00519 if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
00520 {
00521 BIO_printf(bio_err,"invalid hex iv value\n");
00522 goto end;
00523 }
00524 if ((hiv == NULL) && (str == NULL))
00525 {
00526
00527
00528
00529 BIO_printf(bio_err, "iv undefined\n");
00530 goto end;
00531 }
00532 if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
00533 {
00534 BIO_printf(bio_err,"invalid hex key value\n");
00535 goto end;
00536 }
00537
00538 if ((benc=BIO_new(BIO_f_cipher())) == NULL)
00539 goto end;
00540
00541
00542
00543
00544
00545 BIO_get_cipher_ctx(benc, &ctx);
00546 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
00547 {
00548 BIO_printf(bio_err, "Error setting cipher %s\n",
00549 EVP_CIPHER_name(cipher));
00550 ERR_print_errors(bio_err);
00551 goto end;
00552 }
00553
00554 if (nopad)
00555 EVP_CIPHER_CTX_set_padding(ctx, 0);
00556
00557 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
00558 {
00559 BIO_printf(bio_err, "Error setting cipher %s\n",
00560 EVP_CIPHER_name(cipher));
00561 ERR_print_errors(bio_err);
00562 goto end;
00563 }
00564
00565 if (debug)
00566 {
00567 BIO_set_callback(benc,BIO_debug_callback);
00568 BIO_set_callback_arg(benc,bio_err);
00569 }
00570
00571 if (printkey)
00572 {
00573 if (!nosalt)
00574 {
00575 printf("salt=");
00576 for (i=0; i<(int)sizeof(salt); i++)
00577 printf("%02X",salt[i]);
00578 printf("\n");
00579 }
00580 if (cipher->key_len > 0)
00581 {
00582 printf("key=");
00583 for (i=0; i<cipher->key_len; i++)
00584 printf("%02X",key[i]);
00585 printf("\n");
00586 }
00587 if (cipher->iv_len > 0)
00588 {
00589 printf("iv =");
00590 for (i=0; i<cipher->iv_len; i++)
00591 printf("%02X",iv[i]);
00592 printf("\n");
00593 }
00594 if (printkey == 2)
00595 {
00596 ret=0;
00597 goto end;
00598 }
00599 }
00600 }
00601
00602
00603 if (benc != NULL)
00604 wbio=BIO_push(benc,wbio);
00605
00606 for (;;)
00607 {
00608 inl=BIO_read(rbio,(char *)buff,bsize);
00609 if (inl <= 0) break;
00610 if (BIO_write(wbio,(char *)buff,inl) != inl)
00611 {
00612 BIO_printf(bio_err,"error writing output file\n");
00613 goto end;
00614 }
00615 }
00616 if (!BIO_flush(wbio))
00617 {
00618 BIO_printf(bio_err,"bad decrypt\n");
00619 goto end;
00620 }
00621
00622 ret=0;
00623 if (verbose)
00624 {
00625 BIO_printf(bio_err,"bytes read :%8ld\n",BIO_number_read(in));
00626 BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
00627 }
00628 end:
00629 ERR_print_errors(bio_err);
00630 if (strbuf != NULL) OPENSSL_free(strbuf);
00631 if (buff != NULL) OPENSSL_free(buff);
00632 if (in != NULL) BIO_free(in);
00633 if (out != NULL) BIO_free_all(out);
00634 if (benc != NULL) BIO_free(benc);
00635 if (b64 != NULL) BIO_free(b64);
00636 if(pass) OPENSSL_free(pass);
00637 apps_shutdown();
00638 OPENSSL_EXIT(ret);
00639 }
00640
00641 int set_hex(char *in, unsigned char *out, int size)
00642 {
00643 int i,n;
00644 unsigned char j;
00645
00646 n=strlen(in);
00647 if (n > (size*2))
00648 {
00649 BIO_printf(bio_err,"hex string is too long\n");
00650 return(0);
00651 }
00652 memset(out,0,size);
00653 for (i=0; i<n; i++)
00654 {
00655 j=(unsigned char)*in;
00656 *(in++)='\0';
00657 if (j == 0) break;
00658 if ((j >= '0') && (j <= '9'))
00659 j-='0';
00660 else if ((j >= 'A') && (j <= 'F'))
00661 j=j-'A'+10;
00662 else if ((j >= 'a') && (j <= 'f'))
00663 j=j-'a'+10;
00664 else
00665 {
00666 BIO_printf(bio_err,"non-hex digit\n");
00667 return(0);
00668 }
00669 if (i&1)
00670 out[i/2]|=j;
00671 else
00672 out[i/2]=(j<<4);
00673 }
00674 return(1);
00675 }