summaryrefslogtreecommitdiff
path: root/contrib/pgcrypto/crypt-blowfish.c
diff options
context:
space:
mode:
authorNoah Misch2015-10-05 14:06:29 +0000
committerNoah Misch2015-10-05 14:06:29 +0000
commit1d812c8b059d0b9b1fba4a459c9876de0f6259b6 (patch)
tree567ebc7798e9792adb395a26f48c8a57dd1b4001 /contrib/pgcrypto/crypt-blowfish.c
parent2ca9d5445c35db8956e4abbf1e653373820e8c0a (diff)
pgcrypto: Detect and report too-short crypt() salts.
Certain short salts crashed the backend or disclosed a few bytes of backend memory. For existing salt-induced error conditions, emit a message saying as much. Back-patch to 9.0 (all supported versions). Josh Kupershmidt Security: CVE-2015-5288
Diffstat (limited to 'contrib/pgcrypto/crypt-blowfish.c')
-rw-r--r--contrib/pgcrypto/crypt-blowfish.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/contrib/pgcrypto/crypt-blowfish.c b/contrib/pgcrypto/crypt-blowfish.c
index fbaa3d776a0..4054e6a06fc 100644
--- a/contrib/pgcrypto/crypt-blowfish.c
+++ b/contrib/pgcrypto/crypt-blowfish.c
@@ -602,6 +602,17 @@ _crypt_blowfish_rn(const char *key, const char *setting,
if (size < 7 + 22 + 31 + 1)
return NULL;
+ /*
+ * Blowfish salt value must be formatted as follows: "$2a$" or "$2x$", a
+ * two digit cost parameter, "$", and 22 digits from the alphabet
+ * "./0-9A-Za-z". -- from the PHP crypt docs. Apparently we enforce a few
+ * more restrictions on the count in the salt as well.
+ */
+ if (strlen(setting) < 29)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid salt")));
+
if (setting[0] != '$' ||
setting[1] != '2' ||
(setting[2] != 'a' && setting[2] != 'x') ||
@@ -611,14 +622,18 @@ _crypt_blowfish_rn(const char *key, const char *setting,
(setting[4] == '3' && setting[5] > '1') ||
setting[6] != '$')
{
- return NULL;
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid salt")));
}
count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16))
{
px_memset(data.binary.salt, 0, sizeof(data.binary.salt));
- return NULL;
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid salt")));
}
BF_swap(data.binary.salt, 4);