Buffer size handling fix for enc.
[openssl.git] / apps / enc.c
index 69f4bebcb911e6ef12d9937613c5d91cde4d146c..3e3e8eb4b8a74c4ab62aed3c8d94a946b61ab029 100644 (file)
@@ -114,9 +114,11 @@ int MAIN(int argc, char **argv)
        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,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  39
@@ -124,6 +126,7 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_ENGINE
        char *engine = NULL;
 #endif
+       const EVP_MD *dgst=NULL;
 
        apps_startup();
 
@@ -253,6 +256,11 @@ int MAIN(int argc, char **argv)
                        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))
                        {
@@ -271,8 +279,10 @@ bad:
                        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 <n>");
@@ -296,6 +306,17 @@ bad:
         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;
@@ -319,7 +340,7 @@ bad:
                        }
 
                /* It must be large enough for a base64 encoded line */
-               if (n < 80) n=80;
+               if (base64 && n < 80) n=80;
 
                bsize=(int)n;
                if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
@@ -349,7 +370,11 @@ bad:
                }
 
        if (inf == NULL)
+               {
+               if (bufsize != NULL)
+                       setvbuf(stdin, (char *)NULL, _IONBF, 0);
                BIO_set_fp(in,stdin,BIO_NOCLOSE);
+               }
        else
                {
                if (BIO_read_filename(in,inf) <= 0)
@@ -400,6 +425,8 @@ bad:
        if (outf == NULL)
                {
                BIO_set_fp(out,stdout,BIO_NOCLOSE);
+               if (bufsize != NULL)
+                       setvbuf(stdout, (char *)NULL, _IONBF, 0);
 #ifdef OPENSSL_SYS_VMS
                {
                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
@@ -483,7 +510,7 @@ bad:
                                sptr = salt;
                        }
 
-                       EVP_BytesToKey(cipher,EVP_md5(),sptr,
+                       EVP_BytesToKey(cipher,dgst,sptr,
                                (unsigned char *)str,
                                strlen(str),1,key,iv);
                        /* zero the complete buffer or the string
@@ -516,13 +543,31 @@ bad:
 
                if ((benc=BIO_new(BIO_f_cipher())) == NULL)
                        goto end;
-               BIO_set_cipher(benc,cipher,key,iv,enc);
-               if (nopad)
+
+               /* 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))
                        {
-                       EVP_CIPHER_CTX *ctx;
-                       BIO_get_cipher_ctx(benc, &ctx);
+                       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);