tags 704030 patch thanks Hi,
I created a patch from the upstream, see attached. Cheers, Adrian -- .''`. John Paul Adrian Glaubitz : :' : Debian Developer - glaub...@debian.org `. `' Freie Universitaet Berlin - glaub...@physik.fu-berlin.de `- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
changeset: 12:3bc365ff4373 user: Damien Miller <d...@mindrot.org> date: Tue Mar 19 07:17:53 2013 +1100 summary: Fix concurrency bug reported by Alan Fairless of spideroak.com: diff -r 79e29a6fdcd5 -r 3bc365ff4373 bcrypt/bcrypt.c --- a/bcrypt/bcrypt.c Tue Mar 19 07:13:52 2013 +1100 +++ b/bcrypt/bcrypt.c Tue Mar 19 07:17:53 2013 +1100 @@ -66,15 +66,12 @@ #define BCRYPT_BLOCKS 6 /* Ciphertext blocks */ #define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */ -char *pybc_bcrypt(const char *, const char *); +int pybc_bcrypt(const char *, const char *, char *, size_t); void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t); static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t); static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *); -static char encrypted[128]; -static char error[] = ":"; - const static u_int8_t Base64Code[] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @@ -146,8 +143,8 @@ /* We handle $Vers$log2(NumRounds)$salt+passwd$ i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */ -char * -pybc_bcrypt(const char *key, const char *salt) +int +pybc_bcrypt(const char *key, const char *salt, char *result, size_t result_len) { pybc_blf_ctx state; u_int32_t rounds, i, k; @@ -157,14 +154,18 @@ u_int8_t csalt[BCRYPT_MAXSALT]; u_int32_t cdata[BCRYPT_BLOCKS]; int n; + char encrypted[128]; + size_t elen; + + /* Return the error marker unless otherwise specified */ + bzero(result, result_len); + *result = ':'; /* Discard "$" identifier */ salt++; - if (*salt > BCRYPT_VERSION) { - /* How do I handle errors ? Return ':' */ - return error; - } + if (*salt > BCRYPT_VERSION) + return -1; /* Check for minor versions */ if (salt[1] != '$') { @@ -175,7 +176,7 @@ salt++; break; default: - return error; + return -1; } } else minor = 0; @@ -185,21 +186,21 @@ if (salt[2] != '$') /* Out of sync with passwd entry */ - return error; + return -1; /* Computer power doesn't increase linear, 2^x should be fine */ n = atoi(salt); if (n > 31 || n < 0) - return error; + return -1; logr = (u_int8_t)n; if ((rounds = (u_int32_t) 1 << logr) < BCRYPT_MINROUNDS) - return error; + return -1; /* Discard num rounds + "$" identifier */ salt += 3; if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT) - return error; + return -1; /* We dont want the base64 salt but the raw data */ decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt); @@ -249,7 +250,14 @@ encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT); encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext, 4 * BCRYPT_BLOCKS - 1); - return encrypted; + elen = strlen(encrypted); + if (result_len <= elen) { + bzero(encrypted, sizeof(encrypted)); + return -1; + } + memcpy(result, encrypted, elen + 1); + bzero(encrypted, sizeof(encrypted)); + return 0; } static void diff -r 79e29a6fdcd5 -r 3bc365ff4373 bcrypt/bcrypt_python.c --- a/bcrypt/bcrypt_python.c Tue Mar 19 07:13:52 2013 +1100 +++ b/bcrypt/bcrypt_python.c Tue Mar 19 07:17:53 2013 +1100 @@ -25,7 +25,7 @@ /* $Id$ */ /* Import */ -char *pybc_bcrypt(const char *, const char *); +int pybc_bcrypt(const char *, const char *, char *, size_t); void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t); PyDoc_STRVAR(bcrypt_encode_salt_doc, @@ -67,7 +67,8 @@ { static char *keywords[] = { "password", "salt", NULL }; char *password = NULL, *salt = NULL; - char *ret; + char hashed[128]; + int ret; char *password_copy; char *salt_copy; @@ -79,21 +80,19 @@ salt_copy = strdup(salt); Py_BEGIN_ALLOW_THREADS; - ret = pybc_bcrypt(password_copy, salt_copy); + ret = pybc_bcrypt(password_copy, salt_copy, hashed, sizeof(hashed)); Py_END_ALLOW_THREADS; bzero(password_copy, strlen(password_copy)); free(password_copy); bzero(salt_copy, strlen(salt_copy)); free(salt_copy); - - if ((ret == NULL) || - strcmp(ret, ":") == 0) { + if (ret != 0 || strcmp(hashed, ":") == 0) { PyErr_SetString(PyExc_ValueError, "Invalid salt"); return NULL; } - return PyString_FromString(ret); + return PyString_FromString(hashed); } static PyMethodDef bcrypt_methods[] = {