X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fenc.c;h=e4d490f25848dd7ac84f65bb9ffd943e061f8118;hp=1739b7ec23aecf71ac35dbb7be17861cf69be58d;hb=8920a7cd04f43b1a090d0b0a8c9e16b94c6898d4;hpb=266483d2f56b0764849797f31866bfd84f9c3aa8 diff --git a/apps/enc.c b/apps/enc.c index 1739b7ec23..e4d490f258 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -1,4 +1,3 @@ -/* apps/enc.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -72,322 +71,251 @@ #endif #include -int set_hex(char *in, unsigned char *out, int size); #undef SIZE #undef BSIZE -#undef PROG - #define SIZE (512) #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) +static int set_hex(char *in, unsigned char *out, int size); +static void show_ciphers(const OBJ_NAME *name, void *bio_); + +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_E, OPT_IN, OPT_OUT, OPT_PASS, OPT_ENGINE, OPT_D, OPT_P, OPT_V, + OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A, + OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE, + OPT_UPPER_S, OPT_IV, OPT_MD, OPT_NON_FIPS_ALLOW, OPT_CIPHER +} OPTION_CHOICE; + +OPTIONS enc_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"pass", OPT_PASS, 's', "Passphrase source"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"e", OPT_E, '-', "Encrypt"}, + {"d", OPT_D, '-', "Decrypt"}, + {"p", OPT_P, '-', "Print the iv/key"}, + {"P", OPT_UPPER_P, '-', "Print the iv/key and exit"}, + {"v", OPT_V, '-'}, + {"nopad", OPT_NOPAD, '-', "Disable standard block padding"}, + {"salt", OPT_SALT, '-'}, + {"nosalt", OPT_NOSALT, '-'}, + {"debug", OPT_DEBUG, '-'}, + {"A", OPT_UPPER_A, '-'}, + {"a", OPT_A, '-', "base64 encode/decode, depending on encryption flag"}, + {"base64", OPT_A, '-', "Base64 output as a single line"}, +#ifdef ZLIB + {"z", OPT_Z, '-', "Use zlib as the 'encryption'"}, +#endif + {"bufsize", OPT_BUFSIZE, 's', "Buffer size"}, + {"k", OPT_K, 's', "Passphrase"}, + {"kfile", OPT_KFILE, '<', "Fead passphrase from file"}, + {"K", OPT_UPPER_K, 's', "Raw key, in hex"}, + {"S", OPT_UPPER_S, 's', "Salt, in hex"}, + {"iv", OPT_IV, 's', "IV in hex"}, + {"md", OPT_MD, 's', "Use specified digest to create key from passphrase"}, + {"non-fips-allow", OPT_NON_FIPS_ALLOW, '-'}, + {"none", OPT_NONE, '-', "Don't encrypt"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, + {NULL} +}; + +int enc_main(int argc, char **argv) { + static char buf[128]; static const char magic[] = "Salted__"; + BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = + NULL, *wbio = NULL; + EVP_CIPHER_CTX *ctx = NULL; + const EVP_CIPHER *cipher = NULL, *c; + const EVP_MD *dgst = NULL; + char *hkey = NULL, *hiv = NULL, *hsalt = NULL, *p; + char *infile = NULL, *outfile = NULL, *prog; + char *str = NULL, *passarg = NULL, *pass = NULL, *strbuf = NULL; char mbuf[sizeof magic - 1]; - char *strbuf = NULL; - unsigned char *buff = NULL, *bufsize = NULL; - int bsize = BSIZE, verbose = 0; - int ret = 1, inl; - int nopad = 0; + OPTION_CHOICE o; + int bsize = BSIZE, verbose = 0, debug = 0, olb64 = 0, nosalt = 0; + int enc = 1, printkey = 0, i, k, base64 = 0; + int ret = 1, inl, nopad = 0, non_fips_allow = 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; + unsigned char *buff = NULL, salt[PKCS5_SALT_LEN]; + unsigned long n; #ifdef ZLIB int do_zlib = 0; BIO *bzl = NULL; #endif - 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 - char pname[PROG_NAME_SIZE + 1]; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - const EVP_MD *dgst = NULL; - int non_fips_allow = 0; - - apps_startup(); - - if (bio_err == NULL) - 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, sizeof pname); - if (strcmp(pname, "base64") == 0) + prog = opt_progname(argv[0]); + if (strcmp(prog, "base64") == 0) base64 = 1; #ifdef ZLIB - if (strcmp(pname, "zlib") == 0) + else if (strcmp(prog, "zlib") == 0) do_zlib = 1; #endif - - cipher = EVP_get_cipherbyname(pname); -#ifdef ZLIB - if (!do_zlib && !base64 && (cipher == NULL) - && (strcmp(pname, "enc") != 0)) -#else - if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0)) -#endif - { - BIO_printf(bio_err, "%s is an unknown cipher\n", pname); - goto bad; + else { + cipher = EVP_get_cipherbyname(prog); + if (cipher == NULL && strcmp(prog, "enc") != 0) { + BIO_printf(bio_err, "%s is not a known cipher\n", prog); + goto end; + } } - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-e") == 0) + prog = opt_init(argc, argv, enc_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(enc_options); + ret = 0; + BIO_printf(bio_err, "Cipher Types\n"); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, + show_ciphers, bio_err); + BIO_printf(bio_err, "\n"); + goto end; + case OPT_E: enc = 1; - else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - inf = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - 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) + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_PASS: + passarg = opt_arg(); + break; + case OPT_ENGINE: + (void)setup_engine(opt_arg(), 0); + break; + case OPT_D: enc = 0; - else if (strcmp(*argv, "-p") == 0) + break; + case OPT_P: printkey = 1; - else if (strcmp(*argv, "-v") == 0) + break; + case OPT_V: verbose = 1; - else if (strcmp(*argv, "-nopad") == 0) + break; + case OPT_NOPAD: nopad = 1; - else if (strcmp(*argv, "-salt") == 0) + break; + case OPT_SALT: nosalt = 0; - else if (strcmp(*argv, "-nosalt") == 0) + break; + case OPT_NOSALT: nosalt = 1; - else if (strcmp(*argv, "-debug") == 0) + break; + case OPT_DEBUG: debug = 1; - else if (strcmp(*argv, "-P") == 0) + break; + case OPT_UPPER_P: printkey = 2; - else if (strcmp(*argv, "-A") == 0) + break; + case OPT_UPPER_A: olb64 = 1; - else if (strcmp(*argv, "-a") == 0) - base64 = 1; - else if (strcmp(*argv, "-base64") == 0) + break; + case OPT_A: base64 = 1; + break; + case OPT_Z: #ifdef ZLIB - else if (strcmp(*argv, "-z") == 0) do_zlib = 1; #endif - else if (strcmp(*argv, "-bufsize") == 0) { - if (--argc < 1) - goto bad; - bufsize = (unsigned char *)*(++argv); - } else if (strcmp(*argv, "-k") == 0) { - if (--argc < 1) - goto bad; - str = *(++argv); - } else if (strcmp(*argv, "-kfile") == 0) { - static char buf[128]; - FILE *infile; - char *file; - - if (--argc < 1) - goto bad; - file = *(++argv); - infile = fopen(file, "r"); - if (infile == NULL) { - BIO_printf(bio_err, "unable to read key from '%s'\n", file); - goto bad; - } - buf[0] = '\0'; - if (!fgets(buf, sizeof buf, infile)) { - BIO_printf(bio_err, "unable to read key from '%s'\n", file); - goto bad; + break; + case OPT_BUFSIZE: + p = opt_arg(); + i = (int)strlen(p) - 1; + k = i >= 1 && p[i] == 'k'; + if (k) + p[i] = '\0'; + if (!opt_ulong(opt_arg(), &n)) + goto opthelp; + if (k) + n *= 1024; + bsize = (int)n; + break; + case OPT_K: + str = opt_arg(); + break; + case OPT_KFILE: + in = bio_open_default(opt_arg(), "r"); + if (in == NULL) + goto opthelp; + i = BIO_gets(in, buf, sizeof buf); + BIO_free(in); + in = NULL; + if (i <= 0) { + BIO_printf(bio_err, + "%s Can't read key from %s\n", prog, opt_arg()); + goto opthelp; } - fclose(infile); - i = strlen(buf); - if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) - buf[--i] = '\0'; - if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) - buf[--i] = '\0'; - if (i < 1) { - BIO_printf(bio_err, "zero length password\n"); - goto bad; + while (--i > 0 && (buf[i] == '\r' || buf[i] == '\n')) + buf[i] = '\0'; + if (i <= 0) { + BIO_printf(bio_err, "%s: zero length password\n", prog); + goto opthelp; } str = buf; - } else if (strcmp(*argv, "-K") == 0) { - 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 (strcmp(*argv, "-non-fips-allow") == 0) + break; + case OPT_UPPER_K: + hkey = opt_arg(); + break; + case OPT_UPPER_S: + hsalt = opt_arg(); + break; + case OPT_IV: + hiv = opt_arg(); + break; + case OPT_MD: + if (!opt_md(opt_arg(), &dgst)) + goto opthelp; + break; + case OPT_NON_FIPS_ALLOW: non_fips_allow = 1; - else if ((argv[0][0] == '-') && - ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &c)) + goto opthelp; cipher = c; - } else if (strcmp(*argv, "-none") == 0) + break; + case OPT_NONE: cipher = NULL; - else { - BIO_printf(bio_err, "unknown option '%s'\n", *argv); - bad: - BIO_printf(bio_err, "options are\n"); - BIO_printf(bio_err, "%-14s input file\n", "-in "); - 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 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 salt in hex is the next argument\n", - "-S"); - 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 "); - BIO_printf(bio_err, "%-14s disable standard block padding\n", - "-nopad"); -#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"); - OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, - show_ciphers, bio_err); - BIO_printf(bio_err, "\n"); - - goto end; + break; } - argc--; - argv++; } - -#ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); -#endif + argc = opt_num_rest(); + argv = opt_rest(); if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { - BIO_printf(bio_err, - "AEAD ciphers not supported by the enc utility\n"); + BIO_printf(bio_err, "%s: AEAD ciphers not supported\n", prog); goto end; } if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) { - BIO_printf(bio_err, - "Ciphers in XTS mode are not supported by the enc utility\n"); + BIO_printf(bio_err, "%s XTS ciphers not supported\n", prog); goto end; } - 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) { + if (dgst == NULL) dgst = EVP_md5(); - } - - if (bufsize != NULL) { - unsigned long n; - for (n = 0; *bufsize; bufsize++) { - i = *bufsize; - if ((i <= '9') && (i >= '0')) - n = n * 10 + i - '0'; - else if (i == 'k') { - n *= 1024; - bufsize++; - break; - } - } - if (*bufsize != '\0') { - BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); - goto end; - } - - /* It must be large enough for a base64 encoded line */ - if (base64 && n < 80) - n = 80; - - bsize = (int)n; - if (verbose) - BIO_printf(bio_err, "bufsize=%d\n", bsize); - } + /* It must be large enough for a base64 encoded line */ + if (base64 && bsize < 80) + bsize = 80; + if (verbose) + BIO_printf(bio_err, "bufsize=%d\n", bsize); - strbuf = OPENSSL_malloc(SIZE); - buff = (unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); - if ((buff == NULL) || (strbuf == NULL)) { - BIO_printf(bio_err, "OPENSSL_malloc failure %ld\n", - (long)EVP_ENCODE_LENGTH(bsize)); - goto end; - } + strbuf = app_malloc(SIZE, "strbuf"); + buff = app_malloc(EVP_ENCODE_LENGTH(bsize), "evp buffer"); - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); - goto end; - } if (debug) { BIO_set_callback(in, BIO_debug_callback); BIO_set_callback(out, BIO_debug_callback); @@ -395,19 +323,16 @@ int MAIN(int argc, char **argv) BIO_set_callback_arg(out, (char *)bio_err); } - if (inf == NULL) { - if (bufsize != NULL) - setbuf(stdin, NULL); - BIO_set_fp(in, stdin, BIO_NOCLOSE); - } else { - if (BIO_read_filename(in, inf) <= 0) { - perror(inf); - goto end; - } - } + if (infile == NULL) { + unbuffer(stdin); + in = dup_bio_in(); + } else + in = bio_open_default(infile, "r"); + if (in == NULL) + goto end; if (!str && passarg) { - if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { + if (!app_passwd(passarg, NULL, &pass, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -416,13 +341,13 @@ int MAIN(int argc, char **argv) if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { for (;;) { - char buf[200]; + char prompt[200]; - BIO_snprintf(buf, sizeof buf, "enter %s %s password:", + BIO_snprintf(prompt, sizeof prompt, "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); + i = EVP_read_pw_string((char *)strbuf, SIZE, prompt, enc); if (i == 0) { if (strbuf[0] == '\0') { ret = 1; @@ -438,28 +363,14 @@ int MAIN(int argc, char **argv) } } - if (outf == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); - if (bufsize != NULL) - setbuf(stdin, NULL); /* don't do buffered reads */ -#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; - } - } + out = bio_open_default(outfile, "w"); + if (out == NULL) + goto end; rbio = in; wbio = out; #ifdef ZLIB - if (do_zlib) { if ((bzl = BIO_new(BIO_f_zlib())) == NULL) goto end; @@ -548,9 +459,14 @@ int MAIN(int argc, char **argv) else OPENSSL_cleanse(str, strlen(str)); } - if ((hiv != NULL) && !set_hex(hiv, iv, sizeof iv)) { - BIO_printf(bio_err, "invalid hex iv value\n"); - goto end; + if (hiv != NULL) { + int siz = EVP_CIPHER_iv_length(cipher); + if (siz == 0) { + BIO_printf(bio_err, "warning: iv not use by this cipher\n"); + } else if (!set_hex(hiv, iv, sizeof iv)) { + BIO_printf(bio_err, "invalid hex iv value\n"); + goto end; + } } if ((hiv == NULL) && (str == NULL) && EVP_CIPHER_iv_length(cipher) != 0) { @@ -562,7 +478,7 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "iv undefined\n"); goto end; } - if ((hkey != NULL) && !set_hex(hkey, key, sizeof key)) { + if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) { BIO_printf(bio_err, "invalid hex key value\n"); goto end; } @@ -653,29 +569,36 @@ int MAIN(int argc, char **argv) } end: 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_all(out); - if (benc != NULL) - BIO_free(benc); - if (b64 != NULL) - BIO_free(b64); + OPENSSL_free(strbuf); + OPENSSL_free(buff); + BIO_free(in); + BIO_free_all(out); + BIO_free(benc); + BIO_free(b64); #ifdef ZLIB - if (bzl != NULL) - BIO_free(bzl); + BIO_free(bzl); #endif - if (pass) - OPENSSL_free(pass); - apps_shutdown(); - OPENSSL_EXIT(ret); + OPENSSL_free(pass); + return (ret); +} + +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 set_hex(char *in, unsigned char *out, int size) +static int set_hex(char *in, unsigned char *out, int size) { int i, n; unsigned char j; @@ -691,16 +614,11 @@ int set_hex(char *in, unsigned char *out, int size) *(in++) = '\0'; if (j == 0) break; - if ((j >= '0') && (j <= '9')) - j -= '0'; - else if ((j >= 'A') && (j <= 'F')) - j = j - 'A' + 10; - else if ((j >= 'a') && (j <= 'f')) - j = j - 'a' + 10; - else { + if (!isxdigit(j)) { BIO_printf(bio_err, "non-hex digit\n"); return (0); } + j = (unsigned char)app_hex(j); if (i & 1) out[i / 2] |= j; else