diff --git a/src/util/crypto/bcrypt.c b/src/util/crypto/bcrypt.c index bd8722beb..c8cc14e23 100644 --- a/src/util/crypto/bcrypt.c +++ b/src/util/crypto/bcrypt.c @@ -15,14 +15,21 @@ #include #include #include -#include #include +#ifdef WIN32 +#include +#include +#else +#include +#endif + #include "bcrypt.h" #include "crypt_blowfish/ow-crypt.h" #define RANDBYTES (16) +#ifndef WIN32 static int try_close(int fd) { int ret; @@ -60,7 +67,7 @@ static int try_read(int fd, char *out, size_t count) return 0; } - +#endif /* * This is a best effort implementation. Nothing prevents a compiler from * optimizing this function and making it vulnerable to timing attacks, but @@ -96,12 +103,15 @@ static int timing_safe_strcmp(const char *str1, const char *str2) int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE]) { - int fd; char input[RANDBYTES]; int workf; char *aux; - fd = open("/dev/urandom", O_RDONLY); +#ifdef WIN32 + BCryptGenRandom(NULL, input, RANDBYTES, BCRYPT_USE_SYSTEM_PREFERRED_RNG); +#else + int fd; + fd = open("/dev/urandom", O_RDONLY); if (fd == -1) return 1; @@ -113,7 +123,7 @@ int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE]) if (try_close(fd) != 0) return 3; - +#endif /* Generate salt. */ workf = (factor < 4 || factor > 31)?12:factor; aux = crypt_gensalt_rn("$2a$", workf, input, RANDBYTES, diff --git a/src/util/crypto/crypt_blowfish/crypt_blowfish.c b/src/util/crypto/crypt_blowfish/crypt_blowfish.c index 9d3f3be82..b0b11d3ad 100644 --- a/src/util/crypto/crypt_blowfish/crypt_blowfish.c +++ b/src/util/crypto/crypt_blowfish/crypt_blowfish.c @@ -896,7 +896,7 @@ char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count, output[1] = '2'; output[2] = prefix[2]; output[3] = '$'; - output[4] = '0' + count / 10; + output[4] = '0' + (char)count / 10; output[5] = '0' + count % 10; output[6] = '$'; diff --git a/src/util/password.test.c b/src/util/password.test.c index 8efe5b107..34a252531 100644 --- a/src/util/password.test.c +++ b/src/util/password.test.c @@ -4,17 +4,23 @@ #include static void test_passwords(CuTest *tc) { - const char *hash, *expect; + const char *hash; - expect = "password"; + if (password_is_implemented(PASSWORD_BCRYPT)) { + hash = password_encode("password", PASSWORD_BCRYPT); + CuAssertPtrNotNull(tc, hash); + CuAssertIntEquals(tc, '$', hash[0]); + CuAssertIntEquals(tc, '2', hash[1]); + CuAssertIntEquals(tc, '$', hash[3]); + CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password")); + CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(hash, "arseword")); + } if (password_is_implemented(PASSWORD_PLAINTEXT)) { hash = password_encode("password", PASSWORD_PLAINTEXT); CuAssertPtrNotNull(tc, hash); - CuAssertStrEquals(tc, hash, expect); - CuAssertIntEquals(tc, VERIFY_OK, password_verify(expect, "password")); - CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(expect, "arseword")); - } else { - CuAssertIntEquals(tc, VERIFY_UNKNOWN, password_verify(expect, "password")); + CuAssertStrEquals(tc, hash, "password"); + CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password")); + CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(hash, "arseword")); } }