0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};
+typedef enum {
+ passwd_unset = 0,
+ passwd_crypt,
+ passwd_md5,
+ passwd_apr1,
+ passwd_sha256,
+ passwd_sha512,
+ passwd_aixmd5
+} passwd_modes;
+
static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
char *passwd, BIO *out, int quiet, int table,
- int reverse, size_t pw_maxlen, int usecrypt, int use1,
- int useapr1, int use5, int use6);
+ int reverse, size_t pw_maxlen, passwd_modes mode);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_IN,
OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1,
- OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_SALT, OPT_STDIN
+ OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_AIXMD5, OPT_SALT, OPT_STDIN
} OPTION_CHOICE;
-OPTIONS passwd_options[] = {
+const OPTIONS passwd_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
- {"in", OPT_IN, '<', "Pead passwords from file"},
+ {"in", OPT_IN, '<', "Read passwords from file"},
{"noverify", OPT_NOVERIFY, '-',
"Never verify when reading password from terminal"},
{"quiet", OPT_QUIET, '-', "No warnings"},
# ifndef NO_MD5CRYPT_1
{"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"},
{"1", OPT_1, '-', "MD5-based password algorithm"},
+ {"aixmd5", OPT_AIXMD5, '-', "AIX MD5-based password algorithm"},
# endif
# ifndef OPENSSL_NO_DES
{"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"},
char *salt_malloc = NULL, *passwd_malloc = NULL, *prog;
OPTION_CHOICE o;
int in_stdin = 0, pw_source_defined = 0;
-#ifndef OPENSSL_NO_UI
+# ifndef OPENSSL_NO_UI
int in_noverify = 0;
-#endif
+# endif
int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
- int ret = 1, usecrypt = 0, use1 = 0, useapr1 = 0, use5 = 0, use6 = 0;
- size_t passwd_malloc_size = 0, pw_maxlen = 256;
+ int ret = 1;
+ passwd_modes mode = passwd_unset;
+ size_t passwd_malloc_size = 0;
+ size_t pw_maxlen = 256; /* arbitrary limit, should be enough for most
+ * passwords */
prog = opt_init(argc, argv, passwd_options);
while ((o = opt_next()) != OPT_EOF) {
pw_source_defined = 1;
break;
case OPT_NOVERIFY:
-#ifndef OPENSSL_NO_UI
+# ifndef OPENSSL_NO_UI
in_noverify = 1;
-#endif
+# endif
break;
case OPT_QUIET:
quiet = 1;
case OPT_REVERSE:
reverse = 1;
break;
+ case OPT_1:
+ if (mode != passwd_unset)
+ goto opthelp;
+ mode = passwd_md5;
+ break;
case OPT_5:
- use5 = 1;
+ if (mode != passwd_unset)
+ goto opthelp;
+ mode = passwd_sha256;
break;
case OPT_6:
- use6 = 1;
- break;
- case OPT_1:
- use1 = 1;
+ if (mode != passwd_unset)
+ goto opthelp;
+ mode = passwd_sha512;
break;
case OPT_APR1:
- useapr1 = 1;
+ if (mode != passwd_unset)
+ goto opthelp;
+ mode = passwd_apr1;
+ break;
+ case OPT_AIXMD5:
+ if (mode != passwd_unset)
+ goto opthelp;
+ mode = passwd_aixmd5;
break;
case OPT_CRYPT:
- usecrypt = 1;
+ if (mode != passwd_unset)
+ goto opthelp;
+ mode = passwd_crypt;
break;
case OPT_SALT:
passed_salt = 1;
passwds = argv;
}
- if (!usecrypt && !use5 && !use6 && !use1 && !useapr1) {
+ if (mode == passwd_unset) {
/* use default */
- usecrypt = 1;
- }
- if (usecrypt + use5 + use6 + use1 + useapr1 > 1) {
- /* conflict */
- goto opthelp;
+ mode = passwd_crypt;
}
# ifdef OPENSSL_NO_DES
- if (usecrypt)
+ if (mode == passwd_crypt)
goto opthelp;
# endif
# ifdef NO_MD5CRYPT_1
- if (use1 || useapr1)
+ if (mode == passwd_md5 || mode == passwd_apr1 || mode == passwd_aixmd5)
goto opthelp;
# endif
# ifdef NO_SHACRYPT
- if (use5 || use6)
+ if (mode == passwd_sha256 || mode == passwd_sha512)
goto opthelp;
# endif
goto end;
}
- if (usecrypt)
+ if (mode == passwd_crypt)
pw_maxlen = 8;
- else if (use1 || useapr1)
- pw_maxlen = 256; /* arbitrary limit, should be enough for most
- * passwords */
if (passwds == NULL) {
/* no passwords on the command line */
}
if ((in == NULL) && (passwds == NULL)) {
+ /*
+ * we use the following method to make sure what
+ * in the 'else' section is always compiled, to
+ * avoid rot of not-frequently-used code.
+ */
if (1) {
-#ifndef OPENSSL_NO_UI
+# ifndef OPENSSL_NO_UI
/* build a null-terminated list */
static char *passwds_static[2] = { NULL, NULL };
passwds = passwds_static;
- if (in == NULL)
+ if (in == NULL) {
if (EVP_read_pw_string
(passwd_malloc, passwd_malloc_size, "Password: ",
!(passed_salt || in_noverify)) != 0)
goto end;
+ }
passwds[0] = passwd_malloc;
} else {
-#endif
+# endif
BIO_printf(bio_err, "password required\n");
goto end;
}
}
-
if (in == NULL) {
assert(passwds != NULL);
assert(*passwds != NULL);
do { /* loop over list of passwords */
passwd = *passwds++;
if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, bio_out,
- quiet, table, reverse, pw_maxlen, usecrypt, use1,
- useapr1, use5, use6))
+ quiet, table, reverse, pw_maxlen, mode))
goto end;
- }
- while (*passwds != NULL);
- } else
+ } while (*passwds != NULL);
+ } else {
/* in != NULL */
- {
int done;
assert(passwd != NULL);
int r = BIO_gets(in, passwd, pw_maxlen + 1);
if (r > 0) {
char *c = (strchr(passwd, '\n'));
- if (c != NULL)
+ if (c != NULL) {
*c = 0; /* truncate at newline */
- else {
+ } else {
/* ignore rest of line */
char trash[BUFSIZ];
do
if (!do_passwd
(passed_salt, &salt, &salt_malloc, passwd, bio_out, quiet,
- table, reverse, pw_maxlen, usecrypt, use1, useapr1,
- use5, use6))
+ table, reverse, pw_maxlen, mode))
goto end;
}
done = (r <= 0);
- }
- while (!done);
+ } while (!done);
}
ret = 0;
size_t passwd_len, salt_len, magic_len;
passwd_len = strlen(passwd);
- out_buf[0] = '$';
- out_buf[1] = 0;
+
+ out_buf[0] = 0;
magic_len = strlen(magic);
- if (magic_len > 4) /* assert it's "1" or "apr1" */
- return NULL;
+ if (magic_len > 0) {
+ out_buf[0] = '$';
+ out_buf[1] = 0;
+
+ if (magic_len > 4) /* assert it's "1" or "apr1" */
+ return NULL;
+
+ OPENSSL_strlcat(out_buf, magic, sizeof out_buf);
+ OPENSSL_strlcat(out_buf, "$", sizeof out_buf);
+ }
- OPENSSL_strlcat(out_buf, magic, sizeof out_buf);
- OPENSSL_strlcat(out_buf, "$", sizeof out_buf);
OPENSSL_strlcat(out_buf, salt, sizeof out_buf);
if (strlen(out_buf) > 6 + 8) /* assert "$apr1$..salt.." */
return NULL;
- salt_out = out_buf + 2 + magic_len;
+ salt_out = out_buf;
+ if (magic_len > 0)
+ salt_out += 2 + magic_len;
salt_len = strlen(salt_out);
if (salt_len > 8)
md = EVP_MD_CTX_new();
if (md == NULL
|| !EVP_DigestInit_ex(md, EVP_md5(), NULL)
- || !EVP_DigestUpdate(md, passwd, passwd_len)
- || !EVP_DigestUpdate(md, "$", 1)
- || !EVP_DigestUpdate(md, magic, magic_len)
- || !EVP_DigestUpdate(md, "$", 1)
- || !EVP_DigestUpdate(md, salt_out, salt_len))
+ || !EVP_DigestUpdate(md, passwd, passwd_len))
+ goto err;
+
+ if (magic_len > 0)
+ if (!EVP_DigestUpdate(md, "$", 1)
+ || !EVP_DigestUpdate(md, magic, magic_len)
+ || !EVP_DigestUpdate(md, "$", 1))
+ goto err;
+
+ if (!EVP_DigestUpdate(md, salt_out, salt_len))
goto err;
md2 = EVP_MD_CTX_new();
/* Prefix for optional rounds specification. */
static const char rounds_prefix[] = "rounds=";
/* Maximum salt string length. */
-#define SALT_LEN_MAX 16
+# define SALT_LEN_MAX 16
/* Default number of rounds if not explicitly specified. */
-#define ROUNDS_DEFAULT 5000
+# define ROUNDS_DEFAULT 5000
/* Minimum number of rounds. */
-#define ROUNDS_MIN 1000
+# define ROUNDS_MIN 1000
/* Maximum number of rounds. */
-#define ROUNDS_MAX 999999999
+# define ROUNDS_MAX 999999999
/* "$6$rounds=<N>$......salt......$...shahash(up to 86 chars)...\0" */
static char out_buf[3 + 17 + 17 + 86 + 1];
EVP_MD_CTX *md = NULL, *md2 = NULL;
const EVP_MD *sha = NULL;
size_t passwd_len, salt_len, magic_len;
- size_t rounds = 5000; /* Default */
+ unsigned int rounds = 5000; /* Default */
char rounds_custom = 0;
char *p_bytes = NULL;
char *s_bytes = NULL;
else if (srounds < ROUNDS_MIN)
rounds = ROUNDS_MIN;
else
- rounds = srounds;
+ rounds = (unsigned int)srounds;
rounds_custom = 1;
} else {
return NULL;
OPENSSL_strlcat(out_buf, magic, sizeof out_buf);
OPENSSL_strlcat(out_buf, "$", sizeof out_buf);
if (rounds_custom) {
- char tmp_buf[7 + 9 + 1]; /* "rounds=999999999" */
- sprintf(tmp_buf, "rounds=%lu", rounds);
+ char tmp_buf[80]; /* "rounds=999999999" */
+ sprintf(tmp_buf, "rounds=%u", rounds);
OPENSSL_strlcat(out_buf, tmp_buf, sizeof out_buf);
OPENSSL_strlcat(out_buf, "$", sizeof out_buf);
}
cp = out_buf + strlen(out_buf);
*cp++ = '$';
-#define b64_from_24bit(B2, B1, B0, N) \
+# define b64_from_24bit(B2, B1, B0, N) \
do { \
unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
int i = (N); \
static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
char *passwd, BIO *out, int quiet, int table,
- int reverse, size_t pw_maxlen, int usecrypt, int use1,
- int useapr1, int use5, int use6)
+ int reverse, size_t pw_maxlen, passwd_modes mode)
{
char *hash = NULL;
/* first make sure we have a salt */
if (!passed_salt) {
# ifndef OPENSSL_NO_DES
- if (usecrypt) {
- if (*salt_malloc_p == NULL) {
+ if (mode == passwd_crypt) {
+ if (*salt_malloc_p == NULL)
*salt_p = *salt_malloc_p = app_malloc(3, "salt buffer");
- }
if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0)
goto end;
(*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
# endif /* !OPENSSL_NO_DES */
# ifndef NO_MD5CRYPT_1
- if (use1 || useapr1) {
+ if (mode == passwd_md5 || mode == passwd_apr1 || mode == passwd_aixmd5) {
int i;
- if (*salt_malloc_p == NULL) {
+ if (*salt_malloc_p == NULL)
*salt_p = *salt_malloc_p = app_malloc(9, "salt buffer");
- }
if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0)
goto end;
# endif /* !NO_MD5CRYPT_1 */
# ifndef NO_SHACRYPT
- if (use5 || use6) {
+ if (mode == passwd_sha256 || mode == passwd_sha512) {
int i;
- if (*salt_malloc_p == NULL) {
+ if (*salt_malloc_p == NULL)
*salt_p = *salt_malloc_p = app_malloc(17, "salt buffer");
- }
if (RAND_bytes((unsigned char *)*salt_p, 16) <= 0)
goto end;
/* now compute password hash */
# ifndef OPENSSL_NO_DES
- if (usecrypt)
+ if (mode == passwd_crypt)
hash = DES_crypt(passwd, *salt_p);
# endif
# ifndef NO_MD5CRYPT_1
- if (use1 || useapr1)
- hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
+ if (mode == passwd_md5 || mode == passwd_apr1)
+ hash = md5crypt(passwd, (mode == passwd_md5 ? "1" : "apr1"), *salt_p);
+ if (mode == passwd_aixmd5)
+ hash = md5crypt(passwd, "", *salt_p);
# endif
# ifndef NO_SHACRYPT
- if (use5 || use6)
- hash = shacrypt(passwd, (use5 ? "5" : "6"), *salt_p);
+ if (mode == passwd_sha256 || mode == passwd_sha512)
+ hash = shacrypt(passwd, (mode == passwd_sha256 ? "5" : "6"), *salt_p);
# endif
assert(hash != NULL);