Fix cost parsing for bcrypt

The tens value was wrong for values of 20+, as reported in #230.
It should be 10*costTens not 10^costTens. This wasn't detected because
the values are the same when costTens is 1, and using high cost values
is rare with bcrypt because of the performance hit.

Also added a simple hash and validate test since the KAT tests only do
validation. This doesn't cover this bug since the cost value is too
high to include in the test. It allows similar issues to be tested
locally though.
This commit is contained in:
Luke Taylor 2018-04-17 13:46:51 +01:00
parent d2da00445d
commit d27d464627
2 changed files with 5 additions and 1 deletions

View File

@ -159,7 +159,7 @@ parseBCryptHash bc = do
costTens = fromIntegral (B.index bc 4) - zero
costUnits = fromIntegral (B.index bc 5) - zero
version = chr (fromIntegral (B.index bc 2))
cost = costUnits + (if costTens == 0 then 0 else 10^costTens) :: Int
cost = costUnits + 10*costTens :: Int
decodeSaltHash saltHash = do
let (s, h) = B.splitAt 22 saltHash

View File

@ -75,4 +75,8 @@ makeKATs = concatMap maketest (zip3 is passwords hashes)
tests = testGroup "bcrypt"
[ testGroup "KATs" makeKATs
, testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash format") (validatePasswordEither B.empty ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: B.ByteString)))
, testCase "Hash and validate" (assertBool "Hashed password should validate" (validatePassword somePassword (bcrypt 5 aSalt somePassword :: B.ByteString)))
]
where
somePassword = "some password" :: B.ByteString
aSalt = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" :: B.ByteString