#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
+#include <openssl/rand.h>
#ifndef NO_MD5
#include <openssl/md5.h>
#endif
#include <openssl/pem.h>
+#include <openssl/engine.h>
int set_hex(char *in,unsigned char *out,int size);
#undef SIZE
#define BSIZE (8*1024)
#define PROG enc_main
+int MAIN(int, char **);
+
int MAIN(int argc, char **argv)
{
+ ENGINE *e = NULL;
+ static const char magic[]="Salted__";
+ char mbuf[8]; /* should be 1 smaller than magic */
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;
+ 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;
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;
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];
+ char pname[PROG_NAME_SIZE];
+ char *engine = NULL;
apps_startup();
BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
/* first check the program name */
- program_name(argv[0],pname,PROG_NAME_SIZE);
+ program_name(argv[0],pname,PROG_NAME_SIZE);
if (strcmp(pname,"base64") == 0)
base64=1;
if (--argc < 1) goto bad;
outf= *(++argv);
}
+ else if (strcmp(*argv,"-pass") == 0)
+ {
+ if (--argc < 1) goto bad;
+ passarg= *(++argv);
+ }
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine= *(++argv);
+ }
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,"-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;
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;
bad:
BIO_printf(bio_err,"options are\n");
BIO_printf(bio_err,"%-14s input file\n","-in <file>");
- BIO_printf(bio_err,"%-14s output fileencrypt\n","-out <file>");
+ BIO_printf(bio_err,"%-14s output file\n","-out <file>");
+ BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
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/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>");
+ BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
BIO_printf(bio_err,"Cipher Types\n");
BIO_printf(bio_err,"des : 56 bit key DES encryption\n");
BIO_printf(bio_err,"rc2 :128 bit key RC2 encryption\n");
#endif
#ifndef NO_BF
- BIO_printf(bio_err,"bf :128 bit key BlowFish encryption\n");
+ 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_bf_cfb64, LN_bf_ofb64);
BIO_printf(bio_err," -%-4s (%s)\n","bf", LN_bf_cbc);
#endif
-#ifndef NO_BF
+#ifndef NO_CAST
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_BF
+#ifndef NO_RC5
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
+#ifndef NO_RIJNDAEL
+ BIO_printf(bio_err," -%-12s -%-12s -%-12s -%-12s\n",
+ LN_rijndael_ecb_k128_b128,"","","","");
+#endif
+
goto end;
}
argc--;
argv++;
}
+ if (engine != NULL)
+ {
+ if((e = ENGINE_by_id(engine)) == NULL)
+ {
+ BIO_printf(bio_err,"invalid engine \"%s\"\n",
+ engine);
+ goto end;
+ }
+ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+ {
+ BIO_printf(bio_err,"can't use that engine\n");
+ goto end;
+ }
+ BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
+ /* Free our "structural" reference. */
+ ENGINE_free(e);
+ }
+
if (bufsize != NULL)
{
unsigned long n;
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;
}
}
}
+ 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 (;;)
}
}
+
+ if (outf == NULL)
+ {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef 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)
{
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,PKCS5_SALT_LEN)) {
+ BIO_printf(bio_err,
+ "invalid hex salt value\n");
+ goto end;
+ }
+ } else if (RAND_pseudo_bytes(salt, PKCS5_SALT_LEN) < 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,
+ PKCS5_SALT_LEN) != PKCS5_SALT_LEN)) {
+ 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,
+ PKCS5_SALT_LEN) != PKCS5_SALT_LEN) {
+ 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,EVP_md5(),sptr,
(unsigned char *)str,
strlen(str),1,key,iv);
/* zero the complete buffer or the string
else
memset(str,0,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 ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
{
BIO_printf(bio_err,"invalid hex key value\n");
goto end;
if (printkey)
{
+ if (!nosalt)
+ {
+ printf("salt=");
+ for (i=0; i<PKCS5_SALT_LEN; i++)
+ printf("%02X",salt[i]);
+ printf("\n");
+ }
if (cipher->key_len > 0)
{
printf("key=");
}
}
-
- 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);
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);
+ if(pass) OPENSSL_free(pass);
EXIT(ret);
}