X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=apps%2Fenc.c;h=ea948f8d101b3d958861584c5bb65106fe779b58;hb=1a5e414863a1c29bc6f88e4ae1d662f2e71e4969;hp=84a81ffb2306e49df0f3135a8f726bae5c98e045;hpb=ec577822f95a8bca0023c5c77cef1a4916822d4a;p=oweals%2Fopenssl.git diff --git a/apps/enc.c b/apps/enc.c index 84a81ffb23..ea948f8d10 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -65,17 +65,11 @@ #include #include #include -#ifdef NO_MD5 -#include -#endif +#include #include +#include -#ifndef NOPROTO int set_hex(char *in,unsigned char *out,int size); -#else -int set_hex(); -#endif - #undef SIZE #undef BSIZE #undef PROG @@ -84,22 +78,55 @@ int set_hex(); #define BSIZE (8*1024) #define PROG enc_main +static void show_ciphers(const OBJ_NAME *name,void *bio_) + { + BIO *bio=bio_; + static int n; + + if(!islower((unsigned char)*name->name)) + return; + + BIO_printf(bio,"-%-25s",name->name); + if(++n == 3) + { + BIO_printf(bio,"\n"); + n=0; + } + else + BIO_printf(bio," "); + } + +int MAIN(int, char **); + int MAIN(int argc, char **argv) { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e = NULL; +#endif + static const char magic[]="Salted__"; + char mbuf[sizeof magic-1]; char *strbuf=NULL; unsigned char *buff=NULL,*bufsize=NULL; int bsize=BSIZE,verbose=0; int ret=1,inl; - unsigned char key[24],iv[MD5_DIGEST_LENGTH]; - char *str=NULL; - char *hkey=NULL,*hiv=NULL; + int nopad = 0; + unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH]; + unsigned char salt[PKCS5_SALT_LEN]; + char *str=NULL, *passarg = NULL, *pass = NULL; + char *hkey=NULL,*hiv=NULL,*hsalt = NULL; + char *md=NULL; int enc=1,printkey=0,i,base64=0; - int debug=0,olb64=0; + int debug=0,olb64=0,nosalt=0; const EVP_CIPHER *cipher=NULL,*c; + EVP_CIPHER_CTX *ctx = NULL; char *inf=NULL,*outf=NULL; BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL; -#define PROG_NAME_SIZE 16 - char pname[PROG_NAME_SIZE]; +#define PROG_NAME_SIZE 39 + char pname[PROG_NAME_SIZE+1]; +#ifndef OPENSSL_NO_ENGINE + char *engine = NULL; +#endif + const EVP_MD *dgst=NULL; apps_startup(); @@ -107,8 +134,11 @@ int MAIN(int argc, char **argv) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); + if (!load_config(bio_err, NULL)) + goto end; + /* first check the program name */ - program_name(argv[0],pname,PROG_NAME_SIZE); + program_name(argv[0],pname,sizeof pname); if (strcmp(pname,"base64") == 0) base64=1; @@ -135,14 +165,31 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; outf= *(++argv); } + else if (strcmp(*argv,"-pass") == 0) + { + if (--argc < 1) goto bad; + passarg= *(++argv); + } +#ifndef OPENSSL_NO_ENGINE + else if (strcmp(*argv,"-engine") == 0) + { + if (--argc < 1) goto bad; + engine= *(++argv); + } +#endif else if (strcmp(*argv,"-d") == 0) enc=0; else if (strcmp(*argv,"-p") == 0) printkey=1; else if (strcmp(*argv,"-v") == 0) verbose=1; - else if ((strcmp(*argv,"-debug") == 0) || - (strcmp(*argv,"-d") == 0)) + else if (strcmp(*argv,"-nopad") == 0) + nopad=1; + else if (strcmp(*argv,"-salt") == 0) + nosalt=0; + else if (strcmp(*argv,"-nosalt") == 0) + nosalt=1; + else if (strcmp(*argv,"-debug") == 0) debug=1; else if (strcmp(*argv,"-P") == 0) printkey=2; @@ -178,7 +225,7 @@ int MAIN(int argc, char **argv) goto bad; } buf[0]='\0'; - fgets(buf,128,infile); + fgets(buf,sizeof buf,infile); fclose(infile); i=strlen(buf); if ((i > 0) && @@ -199,11 +246,21 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; hkey= *(++argv); } + else if (strcmp(*argv,"-S") == 0) + { + if (--argc < 1) goto bad; + hsalt= *(++argv); + } else if (strcmp(*argv,"-iv") == 0) { if (--argc < 1) goto bad; hiv= *(++argv); } + else if (strcmp(*argv,"-md") == 0) + { + if (--argc < 1) goto bad; + md= *(++argv); + } else if ((argv[0][0] == '-') && ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { @@ -217,88 +274,49 @@ int MAIN(int argc, char **argv) bad: BIO_printf(bio_err,"options are\n"); BIO_printf(bio_err,"%-14s input file\n","-in "); - BIO_printf(bio_err,"%-14s output fileencrypt\n","-out "); + BIO_printf(bio_err,"%-14s output file\n","-out "); + BIO_printf(bio_err,"%-14s pass phrase source\n","-pass "); BIO_printf(bio_err,"%-14s encrypt\n","-e"); BIO_printf(bio_err,"%-14s decrypt\n","-d"); BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64"); - BIO_printf(bio_err,"%-14s key is the next argument\n","-k"); - BIO_printf(bio_err,"%-14s key is the first line of the file argument\n","-kfile"); + BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k"); + BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile"); + BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md"); + BIO_printf(bio_err,"%-14s from a passphrase. One of md2, md5, sha or sha1\n",""); BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv"); BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]"); BIO_printf(bio_err,"%-14s buffer size\n","-bufsize "); +#ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e"); +#endif BIO_printf(bio_err,"Cipher Types\n"); - BIO_printf(bio_err,"des : 56 bit key DES encryption\n"); - BIO_printf(bio_err,"des_ede :112 bit key ede DES encryption\n"); - BIO_printf(bio_err,"des_ede3:168 bit key ede DES encryption\n"); -#ifndef NO_IDEA - BIO_printf(bio_err,"idea :128 bit key IDEA encryption\n"); -#endif -#ifndef NO_RC4 - BIO_printf(bio_err,"rc2 :128 bit key RC2 encryption\n"); -#endif -#ifndef NO_BLOWFISH - BIO_printf(bio_err,"bf :128 bit key BlowFish encryption\n"); -#endif -#ifndef NO_RC4 - BIO_printf(bio_err," -%-5s :128 bit key RC4 encryption\n", - LN_rc4); -#endif + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, + show_ciphers, + bio_err); + BIO_printf(bio_err,"\n"); - BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s", - LN_des_ecb,LN_des_cbc, - LN_des_cfb64,LN_des_ofb64); - BIO_printf(bio_err," -%-4s (%s)\n", - "des", LN_des_cbc); - - BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s", - LN_des_ede,LN_des_ede_cbc, - LN_des_ede_cfb64,LN_des_ede_ofb64); - BIO_printf(bio_err," -desx -none\n"); - - - BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s", - LN_des_ede3,LN_des_ede3_cbc, - LN_des_ede3_cfb64,LN_des_ede3_ofb64); - BIO_printf(bio_err," -%-4s (%s)\n", - "des3", LN_des_ede3_cbc); - -#ifndef NO_IDEA - BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s", - LN_idea_ecb, LN_idea_cbc, - LN_idea_cfb64, LN_idea_ofb64); - BIO_printf(bio_err," -%-4s (%s)\n","idea",LN_idea_cbc); -#endif -#ifndef NO_RC2 - BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s", - LN_rc2_ecb, LN_rc2_cbc, - LN_rc2_cfb64, LN_rc2_ofb64); - BIO_printf(bio_err," -%-4s (%s)\n","rc2", LN_rc2_cbc); -#endif -#ifndef NO_BLOWFISH - BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s", - LN_bf_ecb, LN_bf_cbc, - LN_bf_cfb64, LN_bf_ofb64); - BIO_printf(bio_err," -%-4s (%s)\n","bf", LN_bf_cbc); -#endif -#ifndef NO_BLOWFISH - BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s", - LN_cast5_ecb, LN_cast5_cbc, - LN_cast5_cfb64, LN_cast5_ofb64); - BIO_printf(bio_err," -%-4s (%s)\n","cast", LN_cast5_cbc); -#endif -#ifndef NO_BLOWFISH - BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s", - LN_rc5_ecb, LN_rc5_cbc, - LN_rc5_cfb64, LN_rc5_ofb64); - BIO_printf(bio_err," -%-4s (%s)\n","rc5", LN_rc5_cbc); -#endif goto end; } argc--; argv++; } +#ifndef OPENSSL_NO_ENGINE + e = setup_engine(bio_err, engine, 0); +#endif + + if (md && (dgst=EVP_get_digestbyname(md)) == NULL) + { + BIO_printf(bio_err,"%s is an unsupported message digest type\n",md); + goto end; + } + + if (dgst == NULL) + { + dgst = EVP_md5(); + } + if (bufsize != NULL) { unsigned long n; @@ -328,11 +346,11 @@ bad: if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize); } - strbuf=Malloc(SIZE); - buff=(unsigned char *)Malloc(EVP_ENCODE_LENGTH(bsize)); + strbuf=OPENSSL_malloc(SIZE); + buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); if ((buff == NULL) || (strbuf == NULL)) { - BIO_printf(bio_err,"Malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize)); + BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize)); goto end; } @@ -362,15 +380,23 @@ bad: } } + if(!str && passarg) { + if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + str = pass; + } + if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { for (;;) { char buf[200]; - sprintf(buf,"enter %s %s password:", - OBJ_nid2ln(EVP_CIPHER_nid(cipher)), - (enc)?"encryption":"decryption"); + BIO_snprintf(buf,sizeof buf,"enter %s %s password:", + OBJ_nid2ln(EVP_CIPHER_nid(cipher)), + (enc)?"encryption":"decryption"); strbuf[0]='\0'; i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc); if (i == 0) @@ -391,11 +417,94 @@ bad: } } + + if (outf == NULL) + { + BIO_set_fp(out,stdout,BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif + } + else + { + if (BIO_write_filename(out,outf) <= 0) + { + perror(outf); + goto end; + } + } + + rbio=in; + wbio=out; + + if (base64) + { + if ((b64=BIO_new(BIO_f_base64())) == NULL) + goto end; + if (debug) + { + BIO_set_callback(b64,BIO_debug_callback); + BIO_set_callback_arg(b64,bio_err); + } + if (olb64) + BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL); + if (enc) + wbio=BIO_push(b64,wbio); + else + rbio=BIO_push(b64,rbio); + } + if (cipher != NULL) { + /* Note that str is NULL if a key was passed on the command + * line, so we get no salt in that case. Is this a bug? + */ if (str != NULL) { - EVP_BytesToKey(cipher,EVP_md5(),NULL, + /* Salt handling: if encrypting generate a salt and + * write to output BIO. If decrypting read salt from + * input BIO. + */ + unsigned char *sptr; + if(nosalt) sptr = NULL; + else { + if(enc) { + if(hsalt) { + if(!set_hex(hsalt,salt,sizeof salt)) { + BIO_printf(bio_err, + "invalid hex salt value\n"); + goto end; + } + } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0) + goto end; + /* If -P option then don't bother writing */ + if((printkey != 2) + && (BIO_write(wbio,magic, + sizeof magic-1) != sizeof magic-1 + || BIO_write(wbio, + (char *)salt, + sizeof salt) != sizeof salt)) { + BIO_printf(bio_err,"error writing output file\n"); + goto end; + } + } else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf + || BIO_read(rbio, + (unsigned char *)salt, + sizeof salt) != sizeof salt) { + BIO_printf(bio_err,"error reading input file\n"); + goto end; + } else if(memcmp(mbuf,magic,sizeof magic-1)) { + BIO_printf(bio_err,"bad magic number\n"); + goto end; + } + + sptr = salt; + } + + EVP_BytesToKey(cipher,dgst,sptr, (unsigned char *)str, strlen(str),1,key,iv); /* zero the complete buffer or the string @@ -403,16 +512,24 @@ bad: * bug picked up by * Larry J. Hughes Jr. */ if (str == strbuf) - memset(str,0,SIZE); + OPENSSL_cleanse(str,SIZE); else - memset(str,0,strlen(str)); + OPENSSL_cleanse(str,strlen(str)); } - if ((hiv != NULL) && !set_hex(hiv,iv,8)) + if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv)) { BIO_printf(bio_err,"invalid hex iv value\n"); goto end; } - if ((hkey != NULL) && !set_hex(hkey,key,24)) + if ((hiv == NULL) && (str == NULL)) + { + /* No IV was explicitly set and no IV was generated + * during EVP_BytesToKey. Hence the IV is undefined, + * making correct decryption impossible. */ + BIO_printf(bio_err, "iv undefined\n"); + goto end; + } + if ((hkey != NULL) && !set_hex(hkey,key,sizeof key)) { BIO_printf(bio_err,"invalid hex key value\n"); goto end; @@ -420,7 +537,31 @@ bad: if ((benc=BIO_new(BIO_f_cipher())) == NULL) goto end; - BIO_set_cipher(benc,cipher,key,iv,enc); + + /* Since we may be changing parameters work on the encryption + * context rather than calling BIO_set_cipher(). + */ + + BIO_get_cipher_ctx(benc, &ctx); + if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) + { + BIO_printf(bio_err, "Error setting cipher %s\n", + EVP_CIPHER_name(cipher)); + ERR_print_errors(bio_err); + goto end; + } + + if (nopad) + EVP_CIPHER_CTX_set_padding(ctx, 0); + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) + { + BIO_printf(bio_err, "Error setting cipher %s\n", + EVP_CIPHER_name(cipher)); + ERR_print_errors(bio_err); + goto end; + } + if (debug) { BIO_set_callback(benc,BIO_debug_callback); @@ -429,6 +570,13 @@ bad: if (printkey) { + if (!nosalt) + { + printf("salt="); + for (i=0; i<(int)sizeof(salt); i++) + printf("%02X",salt[i]); + printf("\n"); + } if (cipher->key_len > 0) { printf("key="); @@ -451,38 +599,6 @@ bad: } } - - if (outf == NULL) - BIO_set_fp(out,stdout,BIO_NOCLOSE); - else - { - if (BIO_write_filename(out,outf) <= 0) - { - perror(outf); - goto end; - } - } - - rbio=in; - wbio=out; - - if (base64) - { - if ((b64=BIO_new(BIO_f_base64())) == NULL) - goto end; - if (debug) - { - BIO_set_callback(b64,BIO_debug_callback); - BIO_set_callback_arg(b64,bio_err); - } - if (olb64) - BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL); - if (enc) - wbio=BIO_push(b64,wbio); - else - rbio=BIO_push(b64,rbio); - } - /* Only encrypt/decrypt as we write the file */ if (benc != NULL) wbio=BIO_push(benc,wbio); @@ -510,13 +626,16 @@ bad: BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out)); } end: - if (strbuf != NULL) Free(strbuf); - if (buff != NULL) Free(buff); + ERR_print_errors(bio_err); + if (strbuf != NULL) OPENSSL_free(strbuf); + if (buff != NULL) OPENSSL_free(buff); if (in != NULL) BIO_free(in); - if (out != NULL) BIO_free(out); + if (out != NULL) BIO_free_all(out); if (benc != NULL) BIO_free(benc); if (b64 != NULL) BIO_free(b64); - EXIT(ret); + if(pass) OPENSSL_free(pass); + apps_shutdown(); + OPENSSL_EXIT(ret); } int set_hex(char *in, unsigned char *out, int size)