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 costTens = fromIntegral (B.index bc 4) - zero
costUnits = fromIntegral (B.index bc 5) - zero costUnits = fromIntegral (B.index bc 5) - zero
version = chr (fromIntegral (B.index bc 2)) 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 decodeSaltHash saltHash = do
let (s, h) = B.splitAt 22 saltHash let (s, h) = B.splitAt 22 saltHash

View File

@ -75,4 +75,8 @@ makeKATs = concatMap maketest (zip3 is passwords hashes)
tests = testGroup "bcrypt" tests = testGroup "bcrypt"
[ testGroup "KATs" makeKATs [ testGroup "KATs" makeKATs
, testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash format") (validatePasswordEither B.empty ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: B.ByteString))) , 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