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