X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=apps%2Fpasswd.c;h=e2c90960e5409d0e6280fa0b6a2bf06afce7eaf6;hp=7ae9e8888012f8a92b9b2e976dfb737530c6c382;hb=63db6b772fa264a62927f6a3584733192dc5a352;hpb=4de9913b8c2a11f17258a2ad5e357046fd221360 diff --git a/apps/passwd.c b/apps/passwd.c index 7ae9e88880..e2c90960e5 100644 --- a/apps/passwd.c +++ b/apps/passwd.c @@ -1,50 +1,10 @@ -/* ==================================================================== - * Copyright (c) 2000-2015 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" +/* + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC @@ -118,7 +78,10 @@ int passwd_main(int argc, char **argv) char *infile = NULL, *salt = NULL, *passwd = NULL, **passwds = NULL; char *salt_malloc = NULL, *passwd_malloc = NULL, *prog; OPTION_CHOICE o; - int in_stdin = 0, in_noverify = 0, pw_source_defined = 0; + int in_stdin = 0, pw_source_defined = 0; +#ifndef OPENSSL_NO_UI + int in_noverify = 0; +#endif int passed_salt = 0, quiet = 0, table = 0, reverse = 0; int ret = 1, usecrypt = 0, use1 = 0, useapr1 = 0; size_t passwd_malloc_size = 0, pw_maxlen = 256; @@ -142,7 +105,9 @@ int passwd_main(int argc, char **argv) pw_source_defined = 1; break; case OPT_NOVERIFY: +#ifndef OPENSSL_NO_UI in_noverify = 1; +#endif break; case OPT_QUIET: quiet = 1; @@ -170,6 +135,7 @@ int passwd_main(int argc, char **argv) if (pw_source_defined) goto opthelp; in_stdin = 1; + pw_source_defined = 1; break; } } @@ -232,18 +198,26 @@ int passwd_main(int argc, char **argv) } if ((in == NULL) && (passwds == NULL)) { - /* build a null-terminated list */ - static char *passwds_static[2] = { NULL, NULL }; - - passwds = passwds_static; - 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; + if (1) { +#ifndef OPENSSL_NO_UI + /* build a null-terminated list */ + static char *passwds_static[2] = { NULL, NULL }; + + passwds = passwds_static; + 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 + BIO_printf(bio_err, "password required\n"); + goto end; + } } + if (in == NULL) { assert(passwds != NULL); assert(*passwds != NULL); @@ -313,69 +287,93 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt) char *salt_out; int n; unsigned int i; - EVP_MD_CTX *md, *md2; - size_t passwd_len, salt_len; + EVP_MD_CTX *md = NULL, *md2 = NULL; + size_t passwd_len, salt_len, magic_len; passwd_len = strlen(passwd); out_buf[0] = '$'; out_buf[1] = 0; - assert(strlen(magic) <= 4); /* "1" or "apr1" */ + magic_len = strlen(magic); + + 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, salt, sizeof out_buf); - assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */ - salt_out = out_buf + 2 + strlen(magic); - salt_len = strlen(salt_out); - assert(salt_len <= 8); - md = EVP_MD_CTX_new(); - if (md == NULL) + if (strlen(out_buf) > 6 + 8) /* assert "$apr1$..salt.." */ return NULL; - EVP_DigestInit_ex(md, EVP_md5(), NULL); - EVP_DigestUpdate(md, passwd, passwd_len); - EVP_DigestUpdate(md, "$", 1); - EVP_DigestUpdate(md, magic, strlen(magic)); - EVP_DigestUpdate(md, "$", 1); - EVP_DigestUpdate(md, salt_out, salt_len); - md2 = EVP_MD_CTX_new(); - if (md2 == NULL) + salt_out = out_buf + 2 + magic_len; + salt_len = strlen(salt_out); + + if (salt_len > 8) return NULL; - EVP_DigestInit_ex(md2, EVP_md5(), NULL); - EVP_DigestUpdate(md2, passwd, passwd_len); - EVP_DigestUpdate(md2, salt_out, salt_len); - EVP_DigestUpdate(md2, passwd, passwd_len); - EVP_DigestFinal_ex(md2, buf, NULL); - for (i = passwd_len; i > sizeof buf; i -= sizeof buf) - EVP_DigestUpdate(md, buf, sizeof buf); - EVP_DigestUpdate(md, buf, i); + 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)) + + md2 = EVP_MD_CTX_new(); + if (md2 == NULL + || !EVP_DigestInit_ex(md2, EVP_md5(), NULL) + || !EVP_DigestUpdate(md2, passwd, passwd_len) + || !EVP_DigestUpdate(md2, salt_out, salt_len) + || !EVP_DigestUpdate(md2, passwd, passwd_len) + || !EVP_DigestFinal_ex(md2, buf, NULL)) + goto err; + + for (i = passwd_len; i > sizeof buf; i -= sizeof buf) { + if (!EVP_DigestUpdate(md, buf, sizeof buf)) + goto err; + } + if (!EVP_DigestUpdate(md, buf, i)) + goto err; n = passwd_len; while (n) { - EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1); + if (!EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1)) + goto err; n >>= 1; } - EVP_DigestFinal_ex(md, buf, NULL); + if (!EVP_DigestFinal_ex(md, buf, NULL)) + return NULL; for (i = 0; i < 1000; i++) { - EVP_DigestInit_ex(md2, EVP_md5(), NULL); - EVP_DigestUpdate(md2, (i & 1) ? (unsigned const char *)passwd : buf, - (i & 1) ? passwd_len : sizeof buf); - if (i % 3) - EVP_DigestUpdate(md2, salt_out, salt_len); - if (i % 7) - EVP_DigestUpdate(md2, passwd, passwd_len); - EVP_DigestUpdate(md2, (i & 1) ? buf : (unsigned const char *)passwd, - (i & 1) ? sizeof buf : passwd_len); - EVP_DigestFinal_ex(md2, buf, NULL); + if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL)) + goto err; + if (!EVP_DigestUpdate(md2, + (i & 1) ? (unsigned const char *)passwd : buf, + (i & 1) ? passwd_len : sizeof buf)) + goto err; + if (i % 3) { + if (!EVP_DigestUpdate(md2, salt_out, salt_len)) + goto err; + } + if (i % 7) { + if (!EVP_DigestUpdate(md2, passwd, passwd_len)) + goto err; + } + if (!EVP_DigestUpdate(md2, + (i & 1) ? buf : (unsigned const char *)passwd, + (i & 1) ? sizeof buf : passwd_len)) + goto err; + if (!EVP_DigestFinal_ex(md2, buf, NULL)) + goto err; } EVP_MD_CTX_free(md2); EVP_MD_CTX_free(md); + md2 = NULL; + md = NULL; { /* transform buf into output string */ - unsigned char buf_perm[sizeof buf]; int dest, source; char *output; @@ -412,6 +410,11 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt) } return out_buf; + + err: + EVP_MD_CTX_free(md2); + EVP_MD_CTX_free(md); + return NULL; } # endif @@ -493,10 +496,10 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, BIO_printf(out, "%s\t%s\n", hash, passwd); else BIO_printf(out, "%s\n", hash); - return 0; + return 1; end: - return 1; + return 0; } #else