1{-# LANGUAGE OverloadedStrings #-} 2 3module BCrypt 4 ( tests 5 ) 6where 7 8import Crypto.KDF.BCrypt 9import qualified Data.ByteString as B 10import Imports 11 12-- Openwall bcrypt tests, with 2x versions and 0xFF special cases removed. 13expected :: [(ByteString, ByteString)] 14expected = 15 [ ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW", "U*U") 16 , ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK", "U*U*") 17 , ("$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a", "U*U*U") 18 , ("$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui", 19 "0123456789abcdefghijklmnopqrstuvwxyz\ 20 \ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\ 21 \chars after 72 are ignored") 22 , ("$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", "\xff\xff\xa3") 23 , ("$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", "\xff\xff\xa3") 24 , ("$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") 25 , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") 26 , ("$2b$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") 27 , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6", 28 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ 29 \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ 30 \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ 31 \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ 32 \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ 33 \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ 34 \chars after 72 are ignored as usual") 35 , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy", 36 "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ 37 \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ 38 \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ 39 \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ 40 \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ 41 \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55") 42 , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe", 43 "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ 44 \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ 45 \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ 46 \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ 47 \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ 48 \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff") 49 , ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy", "") 50 , ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.", "") 51 , ("$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye", "") 52 , ("$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW", "") 53 , ("$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO", "") 54 , ("$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe", "a") 55 , ("$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.", "a") 56 , ("$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS", "a") 57 , ("$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i", "abc") 58 , ("$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm", "abc") 59 , ("$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi", "abc") 60 , ("$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC", "abcdefghijklmnopqrstuvwxyz") 61 ] 62 63makeKATs = concatMap maketest (zip3 is passwords hashes) 64 where 65 is :: [Int] 66 is = [1..] 67 68 passwords = map snd expected 69 hashes = map fst expected 70 71 maketest (i, password, hash) = 72 [ testCase (show i) (assertBool "" (validatePassword password hash)) 73 ] 74 75tests = testGroup "bcrypt" 76 [ testGroup "KATs" makeKATs 77 , testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash format") (validatePasswordEither B.empty ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: B.ByteString))) 78 , testCase "Hash and validate" (assertBool "Hashed password should validate" (validatePassword somePassword (bcrypt 5 aSalt somePassword :: B.ByteString))) 79 ] 80 where 81 somePassword = "some password" :: B.ByteString 82 aSalt = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" :: B.ByteString 83