test_handlers.py 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819
  1. """passlib.tests.test_handlers - tests for passlib hash algorithms"""
  2. #=============================================================================
  3. # imports
  4. #=============================================================================
  5. from __future__ import with_statement
  6. # core
  7. import logging; log = logging.getLogger(__name__)
  8. import os
  9. import sys
  10. import warnings
  11. # site
  12. # pkg
  13. from passlib import exc, hash
  14. from passlib.utils import repeat_string
  15. from passlib.utils.compat import irange, PY3, u, get_method_function
  16. from passlib.tests.utils import TestCase, HandlerCase, skipUnless, \
  17. TEST_MODE, UserHandlerMixin, EncodingHandlerMixin
  18. # module
  19. #=============================================================================
  20. # constants & support
  21. #=============================================================================
  22. # some common unicode passwords which used as test cases
  23. UPASS_WAV = u('\u0399\u03c9\u03b1\u03bd\u03bd\u03b7\u03c2')
  24. UPASS_USD = u("\u20AC\u00A5$")
  25. UPASS_TABLE = u("t\u00e1\u0411\u2113\u0259")
  26. PASS_TABLE_UTF8 = b't\xc3\xa1\xd0\x91\xe2\x84\x93\xc9\x99' # utf-8
  27. # handlers which support multiple backends, but don't have multi-backend tests.
  28. _omitted_backend_tests = ["django_bcrypt", "django_bcrypt_sha256", "django_argon2"]
  29. #: modules where get_handler_case() should search for test cases.
  30. _handler_test_modules = [
  31. "test_handlers",
  32. "test_handlers_argon2",
  33. "test_handlers_bcrypt",
  34. "test_handlers_cisco",
  35. "test_handlers_django",
  36. "test_handlers_pbkdf2",
  37. "test_handlers_scrypt",
  38. ]
  39. def get_handler_case(scheme):
  40. """
  41. return HandlerCase instance for scheme, used by other tests.
  42. :param scheme: name of hasher to locate test for (e.g. "bcrypt")
  43. :raises KeyError:
  44. if scheme isn't known hasher.
  45. :raises MissingBackendError:
  46. if hasher doesn't have any available backends.
  47. :returns:
  48. HandlerCase subclass (which derives from TestCase)
  49. """
  50. from passlib.registry import get_crypt_handler
  51. handler = get_crypt_handler(scheme)
  52. if hasattr(handler, "backends") and scheme not in _omitted_backend_tests:
  53. # XXX: if no backends available, could proceed to pick first backend for test lookup;
  54. # should investigate if that would be useful to callers.
  55. try:
  56. backend = handler.get_backend()
  57. except exc.MissingBackendError:
  58. assert scheme in conditionally_available_hashes
  59. raise
  60. name = "%s_%s_test" % (scheme, backend)
  61. else:
  62. name = "%s_test" % scheme
  63. for module in _handler_test_modules:
  64. modname = "passlib.tests." + module
  65. __import__(modname)
  66. mod = sys.modules[modname]
  67. try:
  68. return getattr(mod, name)
  69. except AttributeError:
  70. pass
  71. # every hasher should have test suite, so if we get here, means test is either missing,
  72. # misnamed, or _handler_test_modules list is out of date.
  73. raise RuntimeError("can't find test case named %r for %r" % (name, scheme))
  74. #: hashes which there may not be a backend available for,
  75. #: and get_handler_case() may (correctly) throw a MissingBackendError
  76. conditionally_available_hashes = ["argon2", "bcrypt", "bcrypt_sha256"]
  77. #=============================================================================
  78. # apr md5 crypt
  79. #=============================================================================
  80. class apr_md5_crypt_test(HandlerCase):
  81. handler = hash.apr_md5_crypt
  82. known_correct_hashes = [
  83. #
  84. # http://httpd.apache.org/docs/2.2/misc/password_encryptions.html
  85. #
  86. ('myPassword', '$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/'),
  87. #
  88. # custom
  89. #
  90. # ensures utf-8 used for unicode
  91. (UPASS_TABLE, '$apr1$bzYrOHUx$a1FcpXuQDJV3vPY20CS6N1'),
  92. ]
  93. known_malformed_hashes = [
  94. # bad char in otherwise correct hash ----\/
  95. '$apr1$r31.....$HqJZimcKQFAMYayBlzkrA!'
  96. ]
  97. #=============================================================================
  98. # bigcrypt
  99. #=============================================================================
  100. class bigcrypt_test(HandlerCase):
  101. handler = hash.bigcrypt
  102. # TODO: find an authoritative source of test vectors
  103. known_correct_hashes = [
  104. #
  105. # various docs & messages on the web.
  106. #
  107. ("passphrase", "qiyh4XPJGsOZ2MEAyLkfWqeQ"),
  108. ("This is very long passwd", "f8.SVpL2fvwjkAnxn8/rgTkwvrif6bjYB5c"),
  109. #
  110. # custom
  111. #
  112. # ensures utf-8 used for unicode
  113. (UPASS_TABLE, 'SEChBAyMbMNhgGLyP7kD1HZU'),
  114. ]
  115. known_unidentified_hashes = [
  116. # one char short (10 % 11)
  117. "qiyh4XPJGsOZ2MEAyLkfWqe"
  118. # one char too many (1 % 11)
  119. "f8.SVpL2fvwjkAnxn8/rgTkwvrif6bjYB5cd"
  120. ]
  121. # omit des_crypt from known_other since it's a valid bigcrypt hash too.
  122. known_other_hashes = [row for row in HandlerCase.known_other_hashes
  123. if row[0] != "des_crypt"]
  124. def test_90_internal(self):
  125. # check that _norm_checksum() also validates checksum size.
  126. # (current code uses regex in parser)
  127. self.assertRaises(ValueError, hash.bigcrypt, use_defaults=True,
  128. checksum=u('yh4XPJGsOZ'))
  129. #=============================================================================
  130. # bsdi crypt
  131. #=============================================================================
  132. class _bsdi_crypt_test(HandlerCase):
  133. """test BSDiCrypt algorithm"""
  134. handler = hash.bsdi_crypt
  135. known_correct_hashes = [
  136. #
  137. # from JTR 1.7.9
  138. #
  139. ('U*U*U*U*', '_J9..CCCCXBrJUJV154M'),
  140. ('U*U***U', '_J9..CCCCXUhOBTXzaiE'),
  141. ('U*U***U*', '_J9..CCCC4gQ.mB/PffM'),
  142. ('*U*U*U*U', '_J9..XXXXvlzQGqpPPdk'),
  143. ('*U*U*U*U*', '_J9..XXXXsqM/YSSP..Y'),
  144. ('*U*U*U*U*U*U*U*U', '_J9..XXXXVL7qJCnku0I'),
  145. ('*U*U*U*U*U*U*U*U*', '_J9..XXXXAj8cFbP5scI'),
  146. ('ab1234567', '_J9..SDizh.vll5VED9g'),
  147. ('cr1234567', '_J9..SDizRjWQ/zePPHc'),
  148. ('zxyDPWgydbQjgq', '_J9..SDizxmRI1GjnQuE'),
  149. ('726 even', '_K9..SaltNrQgIYUAeoY'),
  150. ('', '_J9..SDSD5YGyRCr4W4c'),
  151. #
  152. # custom
  153. #
  154. (" ", "_K1..crsmZxOLzfJH8iw"),
  155. ("my", '_KR/.crsmykRplHbAvwA'), # <-- to detect old 12-bit rounds bug
  156. ("my socra", "_K1..crsmf/9NzZr1fLM"),
  157. ("my socrates", '_K1..crsmOv1rbde9A9o'),
  158. ("my socrates note", "_K1..crsm/2qeAhdISMA"),
  159. # ensures utf-8 used for unicode
  160. (UPASS_TABLE, '_7C/.ABw0WIKy0ILVqo2'),
  161. ]
  162. known_unidentified_hashes = [
  163. # bad char in otherwise correctly formatted hash
  164. # \/
  165. "_K1.!crsmZxOLzfJH8iw"
  166. ]
  167. platform_crypt_support = [
  168. # openbsd 5.8 dropped everything except bcrypt
  169. ("openbsd[6789]", False),
  170. ("openbsd5", None),
  171. ("openbsd", True),
  172. ("freebsd|netbsd|darwin", True),
  173. ("solaris", False),
  174. ("linux", None), # may be present if libxcrypt is in use
  175. ]
  176. def test_77_fuzz_input(self, **kwds):
  177. # we want to generate even rounds to verify it's correct, but want to ignore warnings
  178. warnings.filterwarnings("ignore", "bsdi_crypt rounds should be odd.*")
  179. super(_bsdi_crypt_test, self).test_77_fuzz_input(**kwds)
  180. def test_needs_update_w_even_rounds(self):
  181. """needs_update() should flag even rounds"""
  182. handler = self.handler
  183. even_hash = '_Y/../cG0zkJa6LY6k4c'
  184. odd_hash = '_Z/..TgFg0/ptQtpAgws'
  185. secret = 'test'
  186. # don't issue warning
  187. self.assertTrue(handler.verify(secret, even_hash))
  188. self.assertTrue(handler.verify(secret, odd_hash))
  189. # *do* signal as needing updates
  190. self.assertTrue(handler.needs_update(even_hash))
  191. self.assertFalse(handler.needs_update(odd_hash))
  192. # new hashes shouldn't have even rounds
  193. new_hash = handler.hash("stub")
  194. self.assertFalse(handler.needs_update(new_hash))
  195. # create test cases for specific backends
  196. bsdi_crypt_os_crypt_test = _bsdi_crypt_test.create_backend_case("os_crypt")
  197. bsdi_crypt_builtin_test = _bsdi_crypt_test.create_backend_case("builtin")
  198. #=============================================================================
  199. # crypt16
  200. #=============================================================================
  201. class crypt16_test(HandlerCase):
  202. handler = hash.crypt16
  203. # TODO: find an authortative source of test vectors
  204. known_correct_hashes = [
  205. #
  206. # from messages around the web, including
  207. # http://seclists.org/bugtraq/1999/Mar/76
  208. #
  209. ("passphrase", "qi8H8R7OM4xMUNMPuRAZxlY."),
  210. ("printf", "aaCjFz4Sh8Eg2QSqAReePlq6"),
  211. ("printf", "AA/xje2RyeiSU0iBY3PDwjYo"),
  212. ("LOLOAQICI82QB4IP", "/.FcK3mad6JwYt8LVmDqz9Lc"),
  213. ("LOLOAQICI", "/.FcK3mad6JwYSaRHJoTPzY2"),
  214. ("LOLOAQIC", "/.FcK3mad6JwYelhbtlysKy6"),
  215. ("L", "/.CIu/PzYCkl6elhbtlysKy6"),
  216. #
  217. # custom
  218. #
  219. # ensures utf-8 used for unicode
  220. (UPASS_TABLE, 'YeDc9tKkkmDvwP7buzpwhoqQ'),
  221. ]
  222. #=============================================================================
  223. # des crypt
  224. #=============================================================================
  225. class _des_crypt_test(HandlerCase):
  226. """test des-crypt algorithm"""
  227. handler = hash.des_crypt
  228. known_correct_hashes = [
  229. #
  230. # from JTR 1.7.9
  231. #
  232. ('U*U*U*U*', 'CCNf8Sbh3HDfQ'),
  233. ('U*U***U', 'CCX.K.MFy4Ois'),
  234. ('U*U***U*', 'CC4rMpbg9AMZ.'),
  235. ('*U*U*U*U', 'XXxzOu6maQKqQ'),
  236. ('', 'SDbsugeBiC58A'),
  237. #
  238. # custom
  239. #
  240. ('', 'OgAwTx2l6NADI'),
  241. (' ', '/Hk.VPuwQTXbc'),
  242. ('test', 'N1tQbOFcM5fpg'),
  243. ('Compl3X AlphaNu3meric', 'um.Wguz3eVCx2'),
  244. ('4lpHa N|_|M3r1K W/ Cur5Es: #$%(*)(*%#', 'sNYqfOyauIyic'),
  245. ('AlOtBsOl', 'cEpWz5IUCShqM'),
  246. # ensures utf-8 used for unicode
  247. (u('hell\u00D6'), 'saykDgk3BPZ9E'),
  248. ]
  249. known_unidentified_hashes = [
  250. # bad char in otherwise correctly formatted hash
  251. #\/
  252. '!gAwTx2l6NADI',
  253. # wrong size
  254. 'OgAwTx2l6NAD',
  255. 'OgAwTx2l6NADIj',
  256. ]
  257. platform_crypt_support = [
  258. # openbsd 5.8 dropped everything except bcrypt
  259. ("openbsd[6789]", False),
  260. ("openbsd5", None),
  261. ("openbsd", True),
  262. ("freebsd|netbsd|linux|solaris|darwin", True),
  263. ]
  264. # create test cases for specific backends
  265. des_crypt_os_crypt_test = _des_crypt_test.create_backend_case("os_crypt")
  266. des_crypt_builtin_test = _des_crypt_test.create_backend_case("builtin")
  267. #=============================================================================
  268. # fshp
  269. #=============================================================================
  270. class fshp_test(HandlerCase):
  271. """test fshp algorithm"""
  272. handler = hash.fshp
  273. known_correct_hashes = [
  274. #
  275. # test vectors from FSHP reference implementation
  276. # https://github.com/bdd/fshp-is-not-secure-anymore/blob/master/python/test.py
  277. #
  278. ('test', '{FSHP0|0|1}qUqP5cyxm6YcTAhz05Hph5gvu9M='),
  279. ('test',
  280. '{FSHP1|8|4096}MTIzNDU2NzjTdHcmoXwNc0f'
  281. 'f9+ArUHoN0CvlbPZpxFi1C6RDM/MHSA=='
  282. ),
  283. ('OrpheanBeholderScryDoubt',
  284. '{FSHP1|8|4096}GVSUFDAjdh0vBosn1GUhz'
  285. 'GLHP7BmkbCZVH/3TQqGIjADXpc+6NCg3g=='
  286. ),
  287. ('ExecuteOrder66',
  288. '{FSHP3|16|8192}0aY7rZQ+/PR+Rd5/I9ss'
  289. 'RM7cjguyT8ibypNaSp/U1uziNO3BVlg5qPU'
  290. 'ng+zHUDQC3ao/JbzOnIBUtAeWHEy7a2vZeZ'
  291. '7jAwyJJa2EqOsq4Io='
  292. ),
  293. #
  294. # custom
  295. #
  296. # ensures utf-8 used for unicode
  297. (UPASS_TABLE, '{FSHP1|16|16384}9v6/l3Lu/d9by5nznpOS'
  298. 'cqQo8eKu/b/CKli3RCkgYg4nRTgZu5y659YV8cCZ68UL'),
  299. ]
  300. known_unidentified_hashes = [
  301. # incorrect header
  302. '{FSHX0|0|1}qUqP5cyxm6YcTAhz05Hph5gvu9M=',
  303. 'FSHP0|0|1}qUqP5cyxm6YcTAhz05Hph5gvu9M=',
  304. ]
  305. known_malformed_hashes = [
  306. # bad base64 padding
  307. '{FSHP0|0|1}qUqP5cyxm6YcTAhz05Hph5gvu9M',
  308. # wrong salt size
  309. '{FSHP0|1|1}qUqP5cyxm6YcTAhz05Hph5gvu9M=',
  310. # bad rounds
  311. '{FSHP0|0|A}qUqP5cyxm6YcTAhz05Hph5gvu9M=',
  312. ]
  313. def test_90_variant(self):
  314. """test variant keyword"""
  315. handler = self.handler
  316. kwds = dict(salt=b'a', rounds=1)
  317. # accepts ints
  318. handler(variant=1, **kwds)
  319. # accepts bytes or unicode
  320. handler(variant=u('1'), **kwds)
  321. handler(variant=b'1', **kwds)
  322. # aliases
  323. handler(variant=u('sha256'), **kwds)
  324. handler(variant=b'sha256', **kwds)
  325. # rejects None
  326. self.assertRaises(TypeError, handler, variant=None, **kwds)
  327. # rejects other types
  328. self.assertRaises(TypeError, handler, variant=complex(1,1), **kwds)
  329. # invalid variant
  330. self.assertRaises(ValueError, handler, variant='9', **kwds)
  331. self.assertRaises(ValueError, handler, variant=9, **kwds)
  332. #=============================================================================
  333. # hex digests
  334. #=============================================================================
  335. class hex_md4_test(HandlerCase):
  336. handler = hash.hex_md4
  337. known_correct_hashes = [
  338. ("password", '8a9d093f14f8701df17732b2bb182c74'),
  339. (UPASS_TABLE, '876078368c47817ce5f9115f3a42cf74'),
  340. ]
  341. class hex_md5_test(HandlerCase):
  342. handler = hash.hex_md5
  343. known_correct_hashes = [
  344. ("password", '5f4dcc3b5aa765d61d8327deb882cf99'),
  345. (UPASS_TABLE, '05473f8a19f66815e737b33264a0d0b0'),
  346. ]
  347. # XXX: should test this for ALL the create_hex_md5() hashers.
  348. def test_mock_fips_mode(self):
  349. """
  350. if md5 isn't available, a dummy instance should be created.
  351. (helps on FIPS systems).
  352. """
  353. from passlib.exc import UnknownHashError
  354. from passlib.crypto.digest import lookup_hash, _set_mock_fips_mode
  355. # check if md5 is available so we can test mock helper
  356. supported = lookup_hash("md5", required=False).supported
  357. self.assertEqual(self.handler.supported, supported)
  358. if supported:
  359. _set_mock_fips_mode()
  360. self.addCleanup(_set_mock_fips_mode, False)
  361. # HACK: have to recreate hasher, since underlying HashInfo has changed.
  362. # could reload module and re-import, but this should be good enough.
  363. from passlib.handlers.digests import create_hex_hash
  364. hasher = create_hex_hash("md5", required=False)
  365. self.assertFalse(hasher.supported)
  366. # can identify hashes even if disabled
  367. ref1 = '5f4dcc3b5aa765d61d8327deb882cf99'
  368. ref2 = 'xxx'
  369. self.assertTrue(hasher.identify(ref1))
  370. self.assertFalse(hasher.identify(ref2))
  371. # throw error if try to use it
  372. pat = "'md5' hash disabled for fips"
  373. self.assertRaisesRegex(UnknownHashError, pat, hasher.hash, "password")
  374. self.assertRaisesRegex(UnknownHashError, pat, hasher.verify, "password", ref1)
  375. class hex_sha1_test(HandlerCase):
  376. handler = hash.hex_sha1
  377. known_correct_hashes = [
  378. ("password", '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8'),
  379. (UPASS_TABLE, 'e059b2628e3a3e2de095679de9822c1d1466e0f0'),
  380. ]
  381. class hex_sha256_test(HandlerCase):
  382. handler = hash.hex_sha256
  383. known_correct_hashes = [
  384. ("password", '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8'),
  385. (UPASS_TABLE, '6ed729e19bf24d3d20f564375820819932029df05547116cfc2cc868a27b4493'),
  386. ]
  387. class hex_sha512_test(HandlerCase):
  388. handler = hash.hex_sha512
  389. known_correct_hashes = [
  390. ("password", 'b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c'
  391. '706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cac'
  392. 'bc86'),
  393. (UPASS_TABLE, 'd91bb0a23d66dca07a1781fd63ae6a05f6919ee5fc368049f350c9f'
  394. '293b078a18165d66097cf0d89fdfbeed1ad6e7dba2344e57348cd6d51308c843a06f'
  395. '29caf'),
  396. ]
  397. #=============================================================================
  398. # htdigest hash
  399. #=============================================================================
  400. class htdigest_test(UserHandlerMixin, HandlerCase):
  401. handler = hash.htdigest
  402. known_correct_hashes = [
  403. # secret, user, realm
  404. # from RFC 2617
  405. (("Circle Of Life", "Mufasa", "testrealm@host.com"),
  406. '939e7578ed9e3c518a452acee763bce9'),
  407. # custom
  408. ((UPASS_TABLE, UPASS_USD, UPASS_WAV),
  409. '4dabed2727d583178777fab468dd1f17'),
  410. ]
  411. known_unidentified_hashes = [
  412. # bad char \/ - currently rejecting upper hex chars, may change
  413. '939e7578edAe3c518a452acee763bce9',
  414. # bad char \/
  415. '939e7578edxe3c518a452acee763bce9',
  416. ]
  417. def test_80_user(self):
  418. raise self.skipTest("test case doesn't support 'realm' keyword")
  419. def populate_context(self, secret, kwds):
  420. """insert username into kwds"""
  421. if isinstance(secret, tuple):
  422. secret, user, realm = secret
  423. else:
  424. user, realm = "user", "realm"
  425. kwds.setdefault("user", user)
  426. kwds.setdefault("realm", realm)
  427. return secret
  428. #=============================================================================
  429. # ldap hashes
  430. #=============================================================================
  431. class ldap_md5_test(HandlerCase):
  432. handler = hash.ldap_md5
  433. known_correct_hashes = [
  434. ("helloworld", '{MD5}/F4DjTilcDIIVEHn/nAQsA=='),
  435. (UPASS_TABLE, '{MD5}BUc/ihn2aBXnN7MyZKDQsA=='),
  436. ]
  437. class ldap_sha1_test(HandlerCase):
  438. handler = hash.ldap_sha1
  439. known_correct_hashes = [
  440. ("helloworld", '{SHA}at+xg6SiyUovktq1redipHiJpaE='),
  441. (UPASS_TABLE, '{SHA}4FmyYo46Pi3glWed6YIsHRRm4PA='),
  442. ]
  443. class ldap_salted_md5_test(HandlerCase):
  444. handler = hash.ldap_salted_md5
  445. known_correct_hashes = [
  446. ("testing1234", '{SMD5}UjFY34os/pnZQ3oQOzjqGu4yeXE='),
  447. (UPASS_TABLE, '{SMD5}Z0ioJ58LlzUeRxm3K6JPGAvBGIM='),
  448. # alternate salt sizes (8, 15, 16)
  449. ('test', '{SMD5}LnuZPJhiaY95/4lmVFpg548xBsD4P4cw'),
  450. ('test', '{SMD5}XRlncfRzvGi0FDzgR98tUgBg7B3jXOs9p9S615qTkg=='),
  451. ('test', '{SMD5}FbAkzOMOxRbMp6Nn4hnZuel9j9Gas7a2lvI+x5hT6j0='),
  452. ]
  453. known_malformed_hashes = [
  454. # salt too small (3)
  455. '{SMD5}IGVhwK+anvspmfDt2t0vgGjt/Q==',
  456. # incorrect base64 encoding
  457. '{SMD5}LnuZPJhiaY95/4lmVFpg548xBsD4P4c',
  458. '{SMD5}LnuZPJhiaY95/4lmVFpg548xBsD4P4cw'
  459. '{SMD5}LnuZPJhiaY95/4lmVFpg548xBsD4P4cw=',
  460. '{SMD5}LnuZPJhiaY95/4lmV=pg548xBsD4P4cw',
  461. '{SMD5}LnuZPJhiaY95/4lmVFpg548xBsD4P===',
  462. ]
  463. class ldap_salted_sha1_test(HandlerCase):
  464. handler = hash.ldap_salted_sha1
  465. known_correct_hashes = [
  466. ("testing123", '{SSHA}0c0blFTXXNuAMHECS4uxrj3ZieMoWImr'),
  467. ("secret", "{SSHA}0H+zTv8o4MR4H43n03eCsvw1luG8LdB7"),
  468. (UPASS_TABLE, '{SSHA}3yCSD1nLZXznra4N8XzZgAL+s1sQYsx5'),
  469. # alternate salt sizes (8, 15, 16)
  470. ('test', '{SSHA}P90+qijSp8MJ1tN25j5o1PflUvlqjXHOGeOckw=='),
  471. ('test', '{SSHA}/ZMF5KymNM+uEOjW+9STKlfCFj51bg3BmBNCiPHeW2ttbU0='),
  472. ('test', '{SSHA}Pfx6Vf48AT9x3FVv8znbo8WQkEVSipHSWovxXmvNWUvp/d/7'),
  473. ]
  474. known_malformed_hashes = [
  475. # salt too small (3)
  476. '{SSHA}ZQK3Yvtvl6wtIRoISgMGPkcWU7Nfq5U=',
  477. # incorrect base64 encoding
  478. '{SSHA}P90+qijSp8MJ1tN25j5o1PflUvlqjXHOGeOck',
  479. '{SSHA}P90+qijSp8MJ1tN25j5o1PflUvlqjXHOGeOckw=',
  480. '{SSHA}P90+qijSp8MJ1tN25j5o1Pf=UvlqjXHOGeOckw==',
  481. '{SSHA}P90+qijSp8MJ1tN25j5o1PflUvlqjXHOGeOck===',
  482. ]
  483. class ldap_salted_sha256_test(HandlerCase):
  484. handler = hash.ldap_salted_sha256
  485. known_correct_hashes = [
  486. # generated locally
  487. # salt size = 8
  488. ("password", '{SSHA256}x1tymSTVjozxQ2PtT46ysrzhZxbcskK0o2f8hEFx7fAQQmhtDSEkJA=='),
  489. ("test", '{SSHA256}xfqc9aOR6z15YaEk3/Ufd7UL9+JozB/1EPmCDTizL0GkdA7BuNda6w=='),
  490. ("toomanysecrets", '{SSHA256}RrTKrg6HFXcjJ+eDAq4UtbODxOr9RLeG+I69FoJvutcbY0zpfU+p1Q=='),
  491. (u('letm\xe8\xefn'), '{SSHA256}km7UjUTBZN8a+gf1ND2/qn15N7LsO/jmGYJXvyTfJKAbI0RoLWWslQ=='),
  492. # alternate salt sizes (4, 15, 16)
  493. # generated locally
  494. ('test', '{SSHA256}TFv2RpwyO0U9mA0Hk8FsXRa1I+4dNUtv27Qa8dzGVLinlDIm'),
  495. ('test', '{SSHA256}J6MFQdkfjdmXz9UyUPb773kekJdm4dgSL4y8WQEQW11VipHSundOKaV0LsV4L6U='),
  496. ('test', '{SSHA256}uBLazLaiBaPb6Cpnvq2XTYDkvXbYIuqRW1anMKk85d1/j1GqFQIgpHSOMUYIIcS4'),
  497. ]
  498. known_malformed_hashes = [
  499. # salt too small (3)
  500. '{SSHA256}Lpdyr1+lR+rtxgp3SpQnUuNw33ENivTl28nzF2ZI4Gm41/o=',
  501. # incorrect base64 encoding
  502. '{SSHA256}TFv2RpwyO0U9mA0Hk8FsXRa1I+4dNUtv27Qa8dzGVLinlDI@',
  503. '{SSHA256}TFv2RpwyO0U9mA0Hk8FsXRa1I+4dNUtv27Qa8dzGVLinlDI',
  504. '{SSHA256}TFv2RpwyO0U9mA0Hk8FsXRa1I+4dNUtv27Qa8dzGVLinlDIm===',
  505. ]
  506. class ldap_salted_sha512_test(HandlerCase):
  507. handler = hash.ldap_salted_sha512
  508. known_correct_hashes = [
  509. # generated by testing ldap server web interface (see issue 124 comments)
  510. # salt size = 8
  511. ("toomanysecrets", '{SSHA512}wExp4xjiCHS0zidJDC4UJq9EEeIebAQPJ1PWSwfhxWjfutI9XiiKuHm2AE41cEFfK+8HyI8bh+ztbczUGsvVFIgICWWPt7qu'),
  512. (u('letm\xe8\xefn'), '{SSHA512}mpNUSmZc3TNx+RnPwkIAVMf7ocEKLPrIoQNsg4Eu8dHvyCeb2xzHp5A6n4tF7ntknSvfvRZaJII4ImvNJlYsgiwAm0FMqR+3'),
  513. # generated locally
  514. # salt size = 8
  515. ("password", '{SSHA512}f/lFQskkl7PdMsTGJxHZq8LDt/l+UqRMm6/pj4pV7/xZkcOaKCgvQqp+KCeXc/Vd4RY6vEHWn4y0DnFcQ6wgyv9fyxk='),
  516. ("test", '{SSHA512}Tgx/uhHnlM9/GgQvI31dN7cheDXg7WypZwaaIkyRsgV/BKIzBG3G/wUd9o1dpi06p3SYzMedg0lvTc3b6CtdO0Xo/f9/L+Uc'),
  517. # alternate salt sizes (4, 15, 16)
  518. # generated locally
  519. ('test', '{SSHA512}Yg9DQ2wURCFGwobu7R2O6cq7nVbnGMPrFCX0aPQ9kj/y1hd6k9PEzkgWCB5aXdPwPzNrVb0PkiHiBnG1CxFiT+B8L8U='),
  520. ('test', '{SSHA512}5ecDGWs5RY4xLszUO6hAcl90W3wAozGQoI4Gqj8xSZdcfU1lVEM4aY8s+4xVeLitcn7BO8i7xkzMFWLoxas7SeHc23sP4dx77937PyeE0A=='),
  521. ('test', '{SSHA512}6FQv5W47HGg2MFBFZofoiIbO8KRW75Pm51NKoInpthYQQ5ujazHGhVGzrj3JXgA7j0k+UNmkHdbJjdY5xcUHPzynFEII4fwfIySEcG5NKSU='),
  522. ]
  523. known_malformed_hashes = [
  524. # salt too small (3)
  525. '{SSHA512}zFnn4/8x8GveUaMqgrYWyIWqFQ0Irt6gADPtRk4Uv3nUC6uR5cD8+YdQni/0ZNij9etm6p17kSFuww3M6l+d6AbAeA==',
  526. # incorrect base64 encoding
  527. '{SSHA512}Tgx/uhHnlM9/GgQvI31dN7cheDXg7WypZwaaIkyRsgV/BKIzBG3G/wUd9o1dpi06p3SYzMedg0lvTc3b6CtdO0Xo/f9/L+U',
  528. '{SSHA512}Tgx/uhHnlM9/GgQvI31dN7cheDXg7WypZwaaIkyRsgV/BKIzBG3G/wUd9o1dpi06p3SYzMedg0lvTc3b6CtdO0Xo/f9/L+U@',
  529. '{SSHA512}Tgx/uhHnlM9/GgQvI31dN7cheDXg7WypZwaaIkyRsgV/BKIzBG3G/wUd9o1dpi06p3SYzMedg0lvTc3b6CtdO0Xo/f9/L+U===',
  530. ]
  531. class ldap_plaintext_test(HandlerCase):
  532. # TODO: integrate EncodingHandlerMixin
  533. handler = hash.ldap_plaintext
  534. known_correct_hashes = [
  535. ("password", 'password'),
  536. (UPASS_TABLE, UPASS_TABLE if PY3 else PASS_TABLE_UTF8),
  537. (PASS_TABLE_UTF8, UPASS_TABLE if PY3 else PASS_TABLE_UTF8),
  538. ]
  539. known_unidentified_hashes = [
  540. "{FOO}bar",
  541. # NOTE: this hash currently rejects the empty string.
  542. "",
  543. ]
  544. known_other_hashes = [
  545. ("ldap_md5", "{MD5}/F4DjTilcDIIVEHn/nAQsA==")
  546. ]
  547. class FuzzHashGenerator(HandlerCase.FuzzHashGenerator):
  548. def random_password(self):
  549. # NOTE: this hash currently rejects the empty string.
  550. while True:
  551. pwd = super(ldap_plaintext_test.FuzzHashGenerator, self).random_password()
  552. if pwd:
  553. return pwd
  554. class _ldap_md5_crypt_test(HandlerCase):
  555. # NOTE: since the ldap_{crypt} handlers are all wrappers, don't need
  556. # separate test; this is just to test the codebase end-to-end
  557. handler = hash.ldap_md5_crypt
  558. known_correct_hashes = [
  559. #
  560. # custom
  561. #
  562. ('', '{CRYPT}$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o.'),
  563. (' ', '{CRYPT}$1$m/5ee7ol$bZn0kIBFipq39e.KDXX8I0'),
  564. ('test', '{CRYPT}$1$ec6XvcoW$ghEtNK2U1MC5l.Dwgi3020'),
  565. ('Compl3X AlphaNu3meric', '{CRYPT}$1$nX1e7EeI$ljQn72ZUgt6Wxd9hfvHdV0'),
  566. ('4lpHa N|_|M3r1K W/ Cur5Es: #$%(*)(*%#', '{CRYPT}$1$jQS7o98J$V6iTcr71CGgwW2laf17pi1'),
  567. ('test', '{CRYPT}$1$SuMrG47N$ymvzYjr7QcEQjaK5m1PGx1'),
  568. # ensures utf-8 used for unicode
  569. (UPASS_TABLE, '{CRYPT}$1$d6/Ky1lU$/xpf8m7ftmWLF.TjHCqel0'),
  570. ]
  571. known_malformed_hashes = [
  572. # bad char in otherwise correct hash
  573. '{CRYPT}$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o!',
  574. ]
  575. # create test cases for specific backends
  576. ldap_md5_crypt_os_crypt_test =_ldap_md5_crypt_test.create_backend_case("os_crypt")
  577. ldap_md5_crypt_builtin_test =_ldap_md5_crypt_test.create_backend_case("builtin")
  578. class _ldap_sha1_crypt_test(HandlerCase):
  579. # NOTE: this isn't for testing the hash (see ldap_md5_crypt note)
  580. # but as a self-test of the os_crypt patching code in HandlerCase.
  581. handler = hash.ldap_sha1_crypt
  582. known_correct_hashes = [
  583. ('password', '{CRYPT}$sha1$10$c.mcTzCw$gF8UeYst9yXX7WNZKc5Fjkq0.au7'),
  584. (UPASS_TABLE, '{CRYPT}$sha1$10$rnqXlOsF$aGJf.cdRPewJAXo1Rn1BkbaYh0fP'),
  585. ]
  586. def populate_settings(self, kwds):
  587. kwds.setdefault("rounds", 10)
  588. super(_ldap_sha1_crypt_test, self).populate_settings(kwds)
  589. def test_77_fuzz_input(self, **ignored):
  590. raise self.skipTest("unneeded")
  591. # create test cases for specific backends
  592. ldap_sha1_crypt_os_crypt_test = _ldap_sha1_crypt_test.create_backend_case("os_crypt")
  593. #=============================================================================
  594. # lanman
  595. #=============================================================================
  596. class lmhash_test(EncodingHandlerMixin, HandlerCase):
  597. handler = hash.lmhash
  598. secret_case_insensitive = True
  599. known_correct_hashes = [
  600. #
  601. # http://msdn.microsoft.com/en-us/library/cc245828(v=prot.10).aspx
  602. #
  603. ("OLDPASSWORD", "c9b81d939d6fd80cd408e6b105741864"),
  604. ("NEWPASSWORD", '09eeab5aa415d6e4d408e6b105741864'),
  605. ("welcome", "c23413a8a1e7665faad3b435b51404ee"),
  606. #
  607. # custom
  608. #
  609. ('', 'aad3b435b51404eeaad3b435b51404ee'),
  610. ('zzZZZzz', 'a5e6066de61c3e35aad3b435b51404ee'),
  611. ('passphrase', '855c3697d9979e78ac404c4ba2c66533'),
  612. ('Yokohama', '5ecd9236d21095ce7584248b8d2c9f9e'),
  613. # ensures cp437 used for unicode
  614. (u('ENCYCLOP\xC6DIA'), 'fed6416bffc9750d48462b9d7aaac065'),
  615. (u('encyclop\xE6dia'), 'fed6416bffc9750d48462b9d7aaac065'),
  616. # test various encoding values
  617. ((u("\xC6"), None), '25d8ab4a0659c97aaad3b435b51404ee'),
  618. ((u("\xC6"), "cp437"), '25d8ab4a0659c97aaad3b435b51404ee'),
  619. ((u("\xC6"), "latin-1"), '184eecbbe9991b44aad3b435b51404ee'),
  620. ((u("\xC6"), "utf-8"), '00dd240fcfab20b8aad3b435b51404ee'),
  621. ]
  622. known_unidentified_hashes = [
  623. # bad char in otherwise correct hash
  624. '855c3697d9979e78ac404c4ba2c6653X',
  625. ]
  626. def test_90_raw(self):
  627. """test lmhash.raw() method"""
  628. from binascii import unhexlify
  629. from passlib.utils.compat import str_to_bascii
  630. lmhash = self.handler
  631. for secret, hash in self.known_correct_hashes:
  632. kwds = {}
  633. secret = self.populate_context(secret, kwds)
  634. data = unhexlify(str_to_bascii(hash))
  635. self.assertEqual(lmhash.raw(secret, **kwds), data)
  636. self.assertRaises(TypeError, lmhash.raw, 1)
  637. #=============================================================================
  638. # md5 crypt
  639. #=============================================================================
  640. class _md5_crypt_test(HandlerCase):
  641. handler = hash.md5_crypt
  642. known_correct_hashes = [
  643. #
  644. # from JTR 1.7.9
  645. #
  646. ('U*U*U*U*', '$1$dXc3I7Rw$ctlgjDdWJLMT.qwHsWhXR1'),
  647. ('U*U***U', '$1$dXc3I7Rw$94JPyQc/eAgQ3MFMCoMF.0'),
  648. ('U*U***U*', '$1$dXc3I7Rw$is1mVIAEtAhIzSdfn5JOO0'),
  649. ('*U*U*U*U', '$1$eQT9Hwbt$XtuElNJD.eW5MN5UCWyTQ0'),
  650. ('', '$1$Eu.GHtia$CFkL/nE1BYTlEPiVx1VWX0'),
  651. #
  652. # custom
  653. #
  654. # NOTE: would need to patch HandlerCase to coerce hashes
  655. # to native str for this first one to work under py3.
  656. ## ('', b('$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o.')),
  657. ('', '$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o.'),
  658. (' ', '$1$m/5ee7ol$bZn0kIBFipq39e.KDXX8I0'),
  659. ('test', '$1$ec6XvcoW$ghEtNK2U1MC5l.Dwgi3020'),
  660. ('Compl3X AlphaNu3meric', '$1$nX1e7EeI$ljQn72ZUgt6Wxd9hfvHdV0'),
  661. ('4lpHa N|_|M3r1K W/ Cur5Es: #$%(*)(*%#', '$1$jQS7o98J$V6iTcr71CGgwW2laf17pi1'),
  662. ('test', '$1$SuMrG47N$ymvzYjr7QcEQjaK5m1PGx1'),
  663. (b'test', '$1$SuMrG47N$ymvzYjr7QcEQjaK5m1PGx1'),
  664. (u('s'), '$1$ssssssss$YgmLTApYTv12qgTwBoj8i/'),
  665. # ensures utf-8 used for unicode
  666. (UPASS_TABLE, '$1$d6/Ky1lU$/xpf8m7ftmWLF.TjHCqel0'),
  667. ]
  668. known_malformed_hashes = [
  669. # bad char in otherwise correct hash \/
  670. '$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o!',
  671. # too many fields
  672. '$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o.$',
  673. ]
  674. platform_crypt_support = [
  675. # openbsd 5.8 dropped everything except bcrypt
  676. ("openbsd[6789]", False),
  677. ("openbsd5", None),
  678. ("openbsd", True),
  679. ("freebsd|netbsd|linux|solaris", True),
  680. ("darwin", False),
  681. ]
  682. # create test cases for specific backends
  683. md5_crypt_os_crypt_test = _md5_crypt_test.create_backend_case("os_crypt")
  684. md5_crypt_builtin_test = _md5_crypt_test.create_backend_case("builtin")
  685. #=============================================================================
  686. # msdcc 1 & 2
  687. #=============================================================================
  688. class msdcc_test(UserHandlerMixin, HandlerCase):
  689. handler = hash.msdcc
  690. user_case_insensitive = True
  691. known_correct_hashes = [
  692. #
  693. # http://www.jedge.com/wordpress/windows-password-cache/
  694. #
  695. (("Asdf999", "sevans"), "b1176c2587478785ec1037e5abc916d0"),
  696. #
  697. # http://infosecisland.com/blogview/12156-Cachedump-for-Meterpreter-in-Action.html
  698. #
  699. (("ASDqwe123", "jdoe"), "592cdfbc3f1ef77ae95c75f851e37166"),
  700. #
  701. # http://comments.gmane.org/gmane.comp.security.openwall.john.user/1917
  702. #
  703. (("test1", "test1"), "64cd29e36a8431a2b111378564a10631"),
  704. (("test2", "test2"), "ab60bdb4493822b175486810ac2abe63"),
  705. (("test3", "test3"), "14dd041848e12fc48c0aa7a416a4a00c"),
  706. (("test4", "test4"), "b945d24866af4b01a6d89b9d932a153c"),
  707. #
  708. # http://ciscoit.wordpress.com/2011/04/13/metasploit-hashdump-vs-cachedump/
  709. #
  710. (("1234qwer!@#$", "Administrator"), "7b69d06ef494621e3f47b9802fe7776d"),
  711. #
  712. # http://www.securiteam.com/tools/5JP0I2KFPA.html
  713. #
  714. (("password", "user"), "2d9f0b052932ad18b87f315641921cda"),
  715. #
  716. # from JTR 1.7.9
  717. #
  718. (("", "root"), "176a4c2bd45ac73687676c2f09045353"),
  719. (("test1", "TEST1"), "64cd29e36a8431a2b111378564a10631"),
  720. (("okolada", "nineteen_characters"), "290efa10307e36a79b3eebf2a6b29455"),
  721. ((u("\u00FC"), u("\u00FC")), "48f84e6f73d6d5305f6558a33fa2c9bb"),
  722. ((u("\u00FC\u00FC"), u("\u00FC\u00FC")), "593246a8335cf0261799bda2a2a9c623"),
  723. ((u("\u20AC\u20AC"), "user"), "9121790702dda0fa5d353014c334c2ce"),
  724. #
  725. # custom
  726. #
  727. # ensures utf-8 used for unicode
  728. ((UPASS_TABLE, 'bob'), 'fcb82eb4212865c7ac3503156ca3f349'),
  729. ]
  730. known_alternate_hashes = [
  731. # check uppercase accepted.
  732. ("B1176C2587478785EC1037E5ABC916D0", ("Asdf999", "sevans"),
  733. "b1176c2587478785ec1037e5abc916d0"),
  734. ]
  735. class msdcc2_test(UserHandlerMixin, HandlerCase):
  736. handler = hash.msdcc2
  737. user_case_insensitive = True
  738. known_correct_hashes = [
  739. #
  740. # from JTR 1.7.9
  741. #
  742. (("test1", "test1"), "607bbe89611e37446e736f7856515bf8"),
  743. (("qerwt", "Joe"), "e09b38f84ab0be586b730baf61781e30"),
  744. (("12345", "Joe"), "6432f517a900b3fc34ffe57f0f346e16"),
  745. (("", "bin"), "c0cbe0313a861062e29f92ede58f9b36"),
  746. (("w00t", "nineteen_characters"), "87136ae0a18b2dafe4a41d555425b2ed"),
  747. (("w00t", "eighteencharacters"), "fc5df74eca97afd7cd5abb0032496223"),
  748. (("longpassword", "twentyXXX_characters"), "cfc6a1e33eb36c3d4f84e4c2606623d2"),
  749. (("longpassword", "twentyoneX_characters"), "99ff74cea552799da8769d30b2684bee"),
  750. (("longpassword", "twentytwoXX_characters"), "0a721bdc92f27d7fb23b87a445ec562f"),
  751. (("test2", "TEST2"), "c6758e5be7fc943d00b97972a8a97620"),
  752. (("test3", "test3"), "360e51304a2d383ea33467ab0b639cc4"),
  753. (("test4", "test4"), "6f79ee93518306f071c47185998566ae"),
  754. ((u("\u00FC"), "joe"), "bdb80f2c4656a8b8591bd27d39064a54"),
  755. ((u("\u20AC\u20AC"), "joe"), "1e1e20f482ff748038e47d801d0d1bda"),
  756. ((u("\u00FC\u00FC"), "admin"), "0839e4a07c00f18a8c65cf5b985b9e73"),
  757. #
  758. # custom
  759. #
  760. # custom unicode test
  761. ((UPASS_TABLE, 'bob'), 'cad511dc9edefcf69201da72efb6bb55'),
  762. ]
  763. #=============================================================================
  764. # mssql 2000 & 2005
  765. #=============================================================================
  766. class mssql2000_test(HandlerCase):
  767. handler = hash.mssql2000
  768. secret_case_insensitive = "verify-only"
  769. # FIXME: fix UT framework - this hash is sensitive to password case, but verify() is not
  770. known_correct_hashes = [
  771. #
  772. # http://hkashfi.blogspot.com/2007/08/breaking-sql-server-2005-hashes.html
  773. #
  774. ('Test', '0x010034767D5C0CFA5FDCA28C4A56085E65E882E71CB0ED2503412FD54D6119FFF04129A1D72E7C3194F7284A7F3A'),
  775. ('TEST', '0x010034767D5C2FD54D6119FFF04129A1D72E7C3194F7284A7F3A2FD54D6119FFF04129A1D72E7C3194F7284A7F3A'),
  776. #
  777. # http://www.sqlmag.com/forums/aft/68438
  778. #
  779. ('x', '0x010086489146C46DD7318D2514D1AC706457CBF6CD3DF8407F071DB4BBC213939D484BF7A766E974F03C96524794'),
  780. #
  781. # http://stackoverflow.com/questions/173329/how-to-decrypt-a-password-from-sql-server
  782. #
  783. ('AAAA', '0x0100CF465B7B12625EF019E157120D58DD46569AC7BF4118455D12625EF019E157120D58DD46569AC7BF4118455D'),
  784. #
  785. # http://msmvps.com/blogs/gladchenko/archive/2005/04/06/41083.aspx
  786. #
  787. ('123', '0x01002D60BA07FE612C8DE537DF3BFCFA49CD9968324481C1A8A8FE612C8DE537DF3BFCFA49CD9968324481C1A8A8'),
  788. #
  789. # http://www.simple-talk.com/sql/t-sql-programming/temporarily-changing-an-unknown-password-of-the-sa-account-/
  790. #
  791. ('12345', '0x01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3'),
  792. #
  793. # XXX: sample is incomplete, password unknown
  794. # https://anthonystechblog.wordpress.com/2011/04/20/password-encryption-in-sql-server-how-to-tell-if-a-user-is-using-a-weak-password/
  795. # (????, '0x0100813F782D66EF15E40B1A3FDF7AB88B322F51401A87D8D3E3A8483C4351A3D96FC38499E6CDD2B6F?????????'),
  796. #
  797. #
  798. # from JTR 1.7.9
  799. #
  800. ('foo', '0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254'),
  801. ('bar', '0x01000508513EADDF6DB7DDD270CCA288BF097F2FF69CC2DB74FBB9644D6901764F999BAB9ECB80DE578D92E3F80D'),
  802. ('canard', '0x01008408C523CF06DCB237835D701C165E68F9460580132E28ED8BC558D22CEDF8801F4503468A80F9C52A12C0A3'),
  803. ('lapin', '0x0100BF088517935FC9183FE39FDEC77539FD5CB52BA5F5761881E5B9638641A79DBF0F1501647EC941F3355440A2'),
  804. #
  805. # custom
  806. #
  807. # ensures utf-8 used for unicode
  808. (UPASS_USD, '0x0100624C0961B28E39FEE13FD0C35F57B4523F0DA1861C11D5A5B28E39FEE13FD0C35F57B4523F0DA1861C11D5A5'),
  809. (UPASS_TABLE, '0x010083104228FAD559BE52477F2131E538BE9734E5C4B0ADEFD7F6D784B03C98585DC634FE2B8CA3A6DFFEC729B4'),
  810. ]
  811. known_alternate_hashes = [
  812. # lower case hex
  813. ('0x01005b20054332752e1bc2e7c5df0f9ebfe486e9bee063e8d3b332752e1bc2e7c5df0f9ebfe486e9bee063e8d3b3',
  814. '12345', '0x01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3'),
  815. ]
  816. known_unidentified_hashes = [
  817. # malformed start
  818. '0X01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3',
  819. # wrong magic value
  820. '0x02005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3',
  821. # wrong size
  822. '0x01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3',
  823. '0x01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3AF',
  824. # mssql2005
  825. '0x01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3',
  826. ]
  827. known_malformed_hashes = [
  828. # non-hex char -----\/
  829. b'0x01005B200543327G2E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3',
  830. u('0x01005B200543327G2E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3'),
  831. ]
  832. class mssql2005_test(HandlerCase):
  833. handler = hash.mssql2005
  834. known_correct_hashes = [
  835. #
  836. # http://hkashfi.blogspot.com/2007/08/breaking-sql-server-2005-hashes.html
  837. #
  838. ('TEST', '0x010034767D5C2FD54D6119FFF04129A1D72E7C3194F7284A7F3A'),
  839. #
  840. # http://www.openwall.com/lists/john-users/2009/07/14/2
  841. #
  842. ('toto', '0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908'),
  843. #
  844. # http://msmvps.com/blogs/gladchenko/archive/2005/04/06/41083.aspx
  845. #
  846. ('123', '0x01004A335DCEDB366D99F564D460B1965B146D6184E4E1025195'),
  847. ('123', '0x0100E11D573F359629B344990DCD3D53DE82CF8AD6BBA7B638B6'),
  848. #
  849. # XXX: password unknown
  850. # http://www.simple-talk.com/sql/t-sql-programming/temporarily-changing-an-unknown-password-of-the-sa-account-/
  851. # (???, '0x01004086CEB6301EEC0A994E49E30DA235880057410264030797'),
  852. #
  853. #
  854. # http://therelentlessfrontend.com/2010/03/26/encrypting-and-decrypting-passwords-in-sql-server/
  855. #
  856. ('AAAA', '0x010036D726AE86834E97F20B198ACD219D60B446AC5E48C54F30'),
  857. #
  858. # from JTR 1.7.9
  859. #
  860. ("toto", "0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908"),
  861. ("titi", "0x01004086CEB60ED526885801C23B366965586A43D3DEAC6DD3FD"),
  862. ("foo", "0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8"),
  863. ("bar", "0x01000508513EADDF6DB7DDD270CCA288BF097F2FF69CC2DB74FB"),
  864. ("canard", "0x01008408C523CF06DCB237835D701C165E68F9460580132E28ED"),
  865. ("lapin", "0x0100BF088517935FC9183FE39FDEC77539FD5CB52BA5F5761881"),
  866. #
  867. # adapted from mssql2000.known_correct_hashes (above)
  868. #
  869. ('Test', '0x010034767D5C0CFA5FDCA28C4A56085E65E882E71CB0ED250341'),
  870. ('Test', '0x0100993BF2315F36CC441485B35C4D84687DC02C78B0E680411F'),
  871. ('x', '0x010086489146C46DD7318D2514D1AC706457CBF6CD3DF8407F07'),
  872. ('AAAA', '0x0100CF465B7B12625EF019E157120D58DD46569AC7BF4118455D'),
  873. ('123', '0x01002D60BA07FE612C8DE537DF3BFCFA49CD9968324481C1A8A8'),
  874. ('12345', '0x01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3'),
  875. #
  876. # custom
  877. #
  878. # ensures utf-8 used for unicode
  879. (UPASS_USD, '0x0100624C0961B28E39FEE13FD0C35F57B4523F0DA1861C11D5A5'),
  880. (UPASS_TABLE, '0x010083104228FAD559BE52477F2131E538BE9734E5C4B0ADEFD7'),
  881. ]
  882. known_alternate_hashes = [
  883. # lower case hex
  884. ('0x01005b20054332752e1bc2e7c5df0f9ebfe486e9bee063e8d3b3',
  885. '12345', '0x01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3'),
  886. ]
  887. known_unidentified_hashes = [
  888. # malformed start
  889. '0X010036D726AE86834E97F20B198ACD219D60B446AC5E48C54F30',
  890. # wrong magic value
  891. '0x020036D726AE86834E97F20B198ACD219D60B446AC5E48C54F30',
  892. # wrong size
  893. '0x010036D726AE86834E97F20B198ACD219D60B446AC5E48C54F',
  894. '0x010036D726AE86834E97F20B198ACD219D60B446AC5E48C54F3012',
  895. # mssql2000
  896. '0x01005B20054332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B332752E1BC2E7C5DF0F9EBFE486E9BEE063E8D3B3',
  897. ]
  898. known_malformed_hashes = [
  899. # non-hex char --\/
  900. '0x010036D726AE86G34E97F20B198ACD219D60B446AC5E48C54F30',
  901. ]
  902. #=============================================================================
  903. # mysql 323 & 41
  904. #=============================================================================
  905. class mysql323_test(HandlerCase):
  906. handler = hash.mysql323
  907. known_correct_hashes = [
  908. #
  909. # from JTR 1.7.9
  910. #
  911. ('drew', '697a7de87c5390b2'),
  912. ('password', "5d2e19393cc5ef67"),
  913. #
  914. # custom
  915. #
  916. ('mypass', '6f8c114b58f2ce9e'),
  917. # ensures utf-8 used for unicode
  918. (UPASS_TABLE, '4ef327ca5491c8d7'),
  919. ]
  920. known_unidentified_hashes = [
  921. # bad char in otherwise correct hash
  922. '6z8c114b58f2ce9e',
  923. ]
  924. def test_90_whitespace(self):
  925. """check whitespace is ignored per spec"""
  926. h = self.do_encrypt("mypass")
  927. h2 = self.do_encrypt("my pass")
  928. self.assertEqual(h, h2)
  929. class FuzzHashGenerator(HandlerCase.FuzzHashGenerator):
  930. def accept_password_pair(self, secret, other):
  931. # override to handle whitespace
  932. return secret.replace(" ","") != other.replace(" ","")
  933. class mysql41_test(HandlerCase):
  934. handler = hash.mysql41
  935. known_correct_hashes = [
  936. #
  937. # from JTR 1.7.9
  938. #
  939. ('verysecretpassword', '*2C905879F74F28F8570989947D06A8429FB943E6'),
  940. ('12345678123456781234567812345678', '*F9F1470004E888963FB466A5452C9CBD9DF6239C'),
  941. ("' OR 1 /*'", '*97CF7A3ACBE0CA58D5391AC8377B5D9AC11D46D9'),
  942. #
  943. # custom
  944. #
  945. ('mypass', '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4'),
  946. # ensures utf-8 used for unicode
  947. (UPASS_TABLE, '*E7AFE21A9CFA2FC9D15D942AE8FB5C240FE5837B'),
  948. ]
  949. known_unidentified_hashes = [
  950. # bad char in otherwise correct hash
  951. '*6Z8989366EAF75BB670AD8EA7A7FC1176A95CEF4',
  952. ]
  953. #=============================================================================
  954. # NTHASH
  955. #=============================================================================
  956. class nthash_test(HandlerCase):
  957. handler = hash.nthash
  958. known_correct_hashes = [
  959. #
  960. # http://msdn.microsoft.com/en-us/library/cc245828(v=prot.10).aspx
  961. #
  962. ("OLDPASSWORD", u("6677b2c394311355b54f25eec5bfacf5")),
  963. ("NEWPASSWORD", u("256781a62031289d3c2c98c14f1efc8c")),
  964. #
  965. # from JTR 1.7.9
  966. #
  967. # ascii
  968. ('', '31d6cfe0d16ae931b73c59d7e0c089c0'),
  969. ('tigger', 'b7e0ea9fbffcf6dd83086e905089effd'),
  970. # utf-8
  971. (b'\xC3\xBC', '8bd6e4fb88e01009818749c5443ea712'),
  972. (b'\xC3\xBC\xC3\xBC', 'cc1260adb6985ca749f150c7e0b22063'),
  973. (b'\xE2\x82\xAC', '030926b781938db4365d46adc7cfbcb8'),
  974. (b'\xE2\x82\xAC\xE2\x82\xAC','682467b963bb4e61943e170a04f7db46'),
  975. #
  976. # custom
  977. #
  978. ('passphrase', '7f8fe03093cc84b267b109625f6bbf4b'),
  979. ]
  980. known_unidentified_hashes = [
  981. # bad char in otherwise correct hash
  982. '7f8fe03093cc84b267b109625f6bbfxb',
  983. ]
  984. class bsd_nthash_test(HandlerCase):
  985. handler = hash.bsd_nthash
  986. known_correct_hashes = [
  987. ('passphrase', '$3$$7f8fe03093cc84b267b109625f6bbf4b'),
  988. (b'\xC3\xBC', '$3$$8bd6e4fb88e01009818749c5443ea712'),
  989. ]
  990. known_unidentified_hashes = [
  991. # bad char in otherwise correct hash --\/
  992. '$3$$7f8fe03093cc84b267b109625f6bbfxb',
  993. ]
  994. #=============================================================================
  995. # oracle 10 & 11
  996. #=============================================================================
  997. class oracle10_test(UserHandlerMixin, HandlerCase):
  998. handler = hash.oracle10
  999. secret_case_insensitive = True
  1000. user_case_insensitive = True
  1001. # TODO: get more test vectors (especially ones which properly test unicode)
  1002. known_correct_hashes = [
  1003. # ((secret,user),hash)
  1004. #
  1005. # http://www.petefinnigan.com/default/default_password_list.htm
  1006. #
  1007. (('tiger', 'scott'), 'F894844C34402B67'),
  1008. ((u('ttTiGGeR'), u('ScO')), '7AA1A84E31ED7771'),
  1009. (("d_syspw", "SYSTEM"), '1B9F1F9A5CB9EB31'),
  1010. (("strat_passwd", "strat_user"), 'AEBEDBB4EFB5225B'),
  1011. #
  1012. # http://openwall.info/wiki/john/sample-hashes
  1013. #
  1014. (('#95LWEIGHTS', 'USER'), '000EA4D72A142E29'),
  1015. (('CIAO2010', 'ALFREDO'), 'EB026A76F0650F7B'),
  1016. #
  1017. # from JTR 1.7.9
  1018. #
  1019. (('GLOUGlou', 'Bob'), 'CDC6B483874B875B'),
  1020. (('GLOUGLOUTER', 'bOB'), 'EF1F9139DB2D5279'),
  1021. (('LONG_MOT_DE_PASSE_OUI', 'BOB'), 'EC8147ABB3373D53'),
  1022. #
  1023. # custom
  1024. #
  1025. ((UPASS_TABLE, 'System'), 'B915A853F297B281'),
  1026. ]
  1027. known_unidentified_hashes = [
  1028. # bad char in hash --\
  1029. 'F894844C34402B6Z',
  1030. ]
  1031. class oracle11_test(HandlerCase):
  1032. handler = hash.oracle11
  1033. # TODO: find more test vectors (especially ones which properly test unicode)
  1034. known_correct_hashes = [
  1035. #
  1036. # from JTR 1.7.9
  1037. #
  1038. ("abc123", "S:5FDAB69F543563582BA57894FE1C1361FB8ED57B903603F2C52ED1B4D642"),
  1039. ("SyStEm123!@#", "S:450F957ECBE075D2FA009BA822A9E28709FBC3DA82B44D284DDABEC14C42"),
  1040. ("oracle", "S:3437FF72BD69E3FB4D10C750B92B8FB90B155E26227B9AB62D94F54E5951"),
  1041. ("11g", "S:61CE616647A4F7980AFD7C7245261AF25E0AFE9C9763FCF0D54DA667D4E6"),
  1042. ("11g", "S:B9E7556F53500C8C78A58F50F24439D79962DE68117654B6700CE7CC71CF"),
  1043. #
  1044. # source?
  1045. #
  1046. ("SHAlala", "S:2BFCFDF5895014EE9BB2B9BA067B01E0389BB5711B7B5F82B7235E9E182C"),
  1047. #
  1048. # custom
  1049. #
  1050. (UPASS_TABLE, 'S:51586343E429A6DF024B8F242F2E9F8507B1096FACD422E29142AA4974B0'),
  1051. ]
  1052. #=============================================================================
  1053. # PHPass Portable Crypt
  1054. #=============================================================================
  1055. class phpass_test(HandlerCase):
  1056. handler = hash.phpass
  1057. known_correct_hashes = [
  1058. #
  1059. # from official 0.3 implementation
  1060. # http://www.openwall.com/phpass/
  1061. #
  1062. ('test12345', '$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'), # from the source
  1063. #
  1064. # from JTR 1.7.9
  1065. #
  1066. ('test1', '$H$9aaaaaSXBjgypwqm.JsMssPLiS8YQ00'),
  1067. ('123456', '$H$9PE8jEklgZhgLmZl5.HYJAzfGCQtzi1'),
  1068. ('123456', '$H$9pdx7dbOW3Nnt32sikrjAxYFjX8XoK1'),
  1069. ('thisisalongertestPW', '$P$912345678LIjjb6PhecupozNBmDndU0'),
  1070. ('JohnRipper', '$P$612345678si5M0DDyPpmRCmcltU/YW/'),
  1071. ('JohnRipper', '$H$712345678WhEyvy1YWzT4647jzeOmo0'),
  1072. ('JohnRipper', '$P$B12345678L6Lpt4BxNotVIMILOa9u81'),
  1073. #
  1074. # custom
  1075. #
  1076. ('', '$P$7JaFQsPzJSuenezefD/3jHgt5hVfNH0'),
  1077. ('compL3X!', '$P$FiS0N5L672xzQx1rt1vgdJQRYKnQM9/'),
  1078. # ensures utf-8 used for unicode
  1079. (UPASS_TABLE, '$P$7SMy8VxnfsIy2Sxm7fJxDSdil.h7TW.'),
  1080. ]
  1081. known_malformed_hashes = [
  1082. # bad char in otherwise correct hash
  1083. # ---\/
  1084. '$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r!L0',
  1085. ]
  1086. #=============================================================================
  1087. # plaintext
  1088. #=============================================================================
  1089. class plaintext_test(HandlerCase):
  1090. # TODO: integrate EncodingHandlerMixin
  1091. handler = hash.plaintext
  1092. accepts_all_hashes = True
  1093. known_correct_hashes = [
  1094. ('',''),
  1095. ('password', 'password'),
  1096. # ensure unicode uses utf-8
  1097. (UPASS_TABLE, UPASS_TABLE if PY3 else PASS_TABLE_UTF8),
  1098. (PASS_TABLE_UTF8, UPASS_TABLE if PY3 else PASS_TABLE_UTF8),
  1099. ]
  1100. #=============================================================================
  1101. # postgres_md5
  1102. #=============================================================================
  1103. class postgres_md5_test(UserHandlerMixin, HandlerCase):
  1104. handler = hash.postgres_md5
  1105. known_correct_hashes = [
  1106. # ((secret,user),hash)
  1107. #
  1108. # generated using postgres 8.1
  1109. #
  1110. (('mypass', 'postgres'), 'md55fba2ea04fd36069d2574ea71c8efe9d'),
  1111. (('mypass', 'root'), 'md540c31989b20437833f697e485811254b'),
  1112. (("testpassword",'testuser'), 'md5d4fc5129cc2c25465a5370113ae9835f'),
  1113. #
  1114. # custom
  1115. #
  1116. # verify unicode->utf8
  1117. ((UPASS_TABLE, 'postgres'), 'md5cb9f11283265811ce076db86d18a22d2'),
  1118. ]
  1119. known_unidentified_hashes = [
  1120. # bad 'z' char in otherwise correct hash
  1121. 'md54zc31989b20437833f697e485811254b',
  1122. ]
  1123. #=============================================================================
  1124. # (netbsd's) sha1 crypt
  1125. #=============================================================================
  1126. class _sha1_crypt_test(HandlerCase):
  1127. handler = hash.sha1_crypt
  1128. known_correct_hashes = [
  1129. #
  1130. # custom
  1131. #
  1132. ("password", "$sha1$19703$iVdJqfSE$v4qYKl1zqYThwpjJAoKX6UvlHq/a"),
  1133. ("password", "$sha1$21773$uV7PTeux$I9oHnvwPZHMO0Nq6/WgyGV/tDJIH"),
  1134. (UPASS_TABLE, '$sha1$40000$uJ3Sp7LE$.VEmLO5xntyRFYihC7ggd3297T/D'),
  1135. ]
  1136. known_malformed_hashes = [
  1137. # bad char in otherwise correct hash
  1138. '$sha1$21773$u!7PTeux$I9oHnvwPZHMO0Nq6/WgyGV/tDJIH',
  1139. # zero padded rounds
  1140. '$sha1$01773$uV7PTeux$I9oHnvwPZHMO0Nq6/WgyGV/tDJIH',
  1141. # too many fields
  1142. '$sha1$21773$uV7PTeux$I9oHnvwPZHMO0Nq6/WgyGV/tDJIH$',
  1143. # empty rounds field
  1144. '$sha1$$uV7PTeux$I9oHnvwPZHMO0Nq6/WgyGV/tDJIH$',
  1145. ]
  1146. platform_crypt_support = [
  1147. ("netbsd", True),
  1148. ("freebsd|openbsd|solaris|darwin", False),
  1149. ("linux", None), # may be present if libxcrypt is in use
  1150. ]
  1151. # create test cases for specific backends
  1152. sha1_crypt_os_crypt_test = _sha1_crypt_test.create_backend_case("os_crypt")
  1153. sha1_crypt_builtin_test = _sha1_crypt_test.create_backend_case("builtin")
  1154. #=============================================================================
  1155. # roundup
  1156. #=============================================================================
  1157. # NOTE: all roundup hashes use PrefixWrapper,
  1158. # so there's nothing natively to test.
  1159. # so we just have a few quick cases...
  1160. class RoundupTest(TestCase):
  1161. def _test_pair(self, h, secret, hash):
  1162. self.assertTrue(h.verify(secret, hash))
  1163. self.assertFalse(h.verify('x'+secret, hash))
  1164. def test_pairs(self):
  1165. self._test_pair(
  1166. hash.ldap_hex_sha1,
  1167. "sekrit",
  1168. '{SHA}8d42e738c7adee551324955458b5e2c0b49ee655')
  1169. self._test_pair(
  1170. hash.ldap_hex_md5,
  1171. "sekrit",
  1172. '{MD5}ccbc53f4464604e714f69dd11138d8b5')
  1173. self._test_pair(
  1174. hash.ldap_des_crypt,
  1175. "sekrit",
  1176. '{CRYPT}nFia0rj2TT59A')
  1177. self._test_pair(
  1178. hash.roundup_plaintext,
  1179. "sekrit",
  1180. '{plaintext}sekrit')
  1181. self._test_pair(
  1182. hash.ldap_pbkdf2_sha1,
  1183. "sekrit",
  1184. '{PBKDF2}5000$7BvbBq.EZzz/O0HuwX3iP.nAG3s$g3oPnFFaga2BJaX5PoPRljl4XIE')
  1185. #=============================================================================
  1186. # sha256-crypt
  1187. #=============================================================================
  1188. class _sha256_crypt_test(HandlerCase):
  1189. handler = hash.sha256_crypt
  1190. known_correct_hashes = [
  1191. #
  1192. # from JTR 1.7.9
  1193. #
  1194. ('U*U*U*U*', '$5$LKO/Ute40T3FNF95$U0prpBQd4PloSGU0pnpM4z9wKn4vZ1.jsrzQfPqxph9'),
  1195. ('U*U***U', '$5$LKO/Ute40T3FNF95$fdgfoJEBoMajNxCv3Ru9LyQ0xZgv0OBMQoq80LQ/Qd.'),
  1196. ('U*U***U*', '$5$LKO/Ute40T3FNF95$8Ry82xGnnPI/6HtFYnvPBTYgOL23sdMXn8C29aO.x/A'),
  1197. ('*U*U*U*U', '$5$9mx1HkCz7G1xho50$O7V7YgleJKLUhcfk9pgzdh3RapEaWqMtEp9UUBAKIPA'),
  1198. ('', '$5$kc7lRD1fpYg0g.IP$d7CMTcEqJyTXyeq8hTdu/jB/I6DGkoo62NXbHIR7S43'),
  1199. #
  1200. # custom tests
  1201. #
  1202. ('', '$5$rounds=10428$uy/jIAhCetNCTtb0$YWvUOXbkqlqhyoPMpN8BMe.ZGsGx2aBvxTvDFI613c3'),
  1203. (' ', '$5$rounds=10376$I5lNtXtRmf.OoMd8$Ko3AI1VvTANdyKhBPavaRjJzNpSatKU6QVN9uwS9MH.'),
  1204. ('test', '$5$rounds=11858$WH1ABM5sKhxbkgCK$aTQsjPkz0rBsH3lQlJxw9HDTDXPKBxC0LlVeV69P.t1'),
  1205. ('Compl3X AlphaNu3meric', '$5$rounds=10350$o.pwkySLCzwTdmQX$nCMVsnF3TXWcBPOympBUUSQi6LGGloZoOsVJMGJ09UB'),
  1206. ('4lpHa N|_|M3r1K W/ Cur5Es: #$%(*)(*%#', '$5$rounds=11944$9dhlu07dQMRWvTId$LyUI5VWkGFwASlzntk1RLurxX54LUhgAcJZIt0pYGT7'),
  1207. (u('with unic\u00D6de'), '$5$rounds=1000$IbG0EuGQXw5EkMdP$LQ5AfPf13KufFsKtmazqnzSGZ4pxtUNw3woQ.ELRDF4'),
  1208. ]
  1209. if TEST_MODE("full"):
  1210. # builtin alg was changed in 1.6, and had possibility of fencepost
  1211. # errors near rounds that are multiples of 42. these hashes test rounds
  1212. # 1004..1012 (42*24=1008 +/- 4) to ensure no mistakes were made.
  1213. # (also relying on fuzz testing against os_crypt backend).
  1214. known_correct_hashes.extend([
  1215. ("secret", '$5$rounds=1004$nacl$oiWPbm.kQ7.jTCZoOtdv7/tO5mWv/vxw5yTqlBagVR7'),
  1216. ("secret", '$5$rounds=1005$nacl$6Mo/TmGDrXxg.bMK9isRzyWH3a..6HnSVVsJMEX7ud/'),
  1217. ("secret", '$5$rounds=1006$nacl$I46VwuAiUBwmVkfPFakCtjVxYYaOJscsuIeuZLbfKID'),
  1218. ("secret", '$5$rounds=1007$nacl$9fY4j1AV3N/dV/YMUn1enRHKH.7nEL4xf1wWB6wfDD4'),
  1219. ("secret", '$5$rounds=1008$nacl$CiFWCfn8ODmWs0I1xAdXFo09tM8jr075CyP64bu3by9'),
  1220. ("secret", '$5$rounds=1009$nacl$QtpFX.CJHgVQ9oAjVYStxAeiU38OmFILWm684c6FyED'),
  1221. ("secret", '$5$rounds=1010$nacl$ktAwXuT5WbjBW/0ZU1eNMpqIWY1Sm4twfRE1zbZyo.B'),
  1222. ("secret", '$5$rounds=1011$nacl$QJWLBEhO9qQHyMx4IJojSN9sS41P1Yuz9REddxdO721'),
  1223. ("secret", '$5$rounds=1012$nacl$mmf/k2PkbBF4VCtERgky3bEVavmLZKFwAcvxD1p3kV2'),
  1224. ])
  1225. known_malformed_hashes = [
  1226. # bad char in otherwise correct hash
  1227. '$5$rounds=10428$uy/:jIAhCetNCTtb0$YWvUOXbkqlqhyoPMpN8BMeZGsGx2aBvxTvDFI613c3',
  1228. # zero-padded rounds
  1229. '$5$rounds=010428$uy/jIAhCetNCTtb0$YWvUOXbkqlqhyoPMpN8BMe.ZGsGx2aBvxTvDFI613c3',
  1230. # extra "$"
  1231. '$5$rounds=10428$uy/jIAhCetNCTtb0$YWvUOXbkqlqhyoPMpN8BMe.ZGsGx2aBvxTvDFI613c3$',
  1232. ]
  1233. known_correct_configs = [
  1234. # config, secret, result
  1235. #
  1236. # taken from official specification at http://www.akkadia.org/drepper/SHA-crypt.txt
  1237. #
  1238. ( "$5$saltstring", "Hello world!",
  1239. "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5" ),
  1240. ( "$5$rounds=10000$saltstringsaltstring", "Hello world!",
  1241. "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2."
  1242. "opqey6IcA" ),
  1243. ( "$5$rounds=5000$toolongsaltstring", "This is just a test",
  1244. "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8"
  1245. "mGRcvxa5" ),
  1246. ( "$5$rounds=1400$anotherlongsaltstring",
  1247. "a very much longer text to encrypt. This one even stretches over more"
  1248. "than one line.",
  1249. "$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12"
  1250. "oP84Bnq1" ),
  1251. ( "$5$rounds=77777$short",
  1252. "we have a short salt string but not a short password",
  1253. "$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/" ),
  1254. ( "$5$rounds=123456$asaltof16chars..", "a short string",
  1255. "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/"
  1256. "cZKmF/wJvD" ),
  1257. ( "$5$rounds=10$roundstoolow", "the minimum number is still observed",
  1258. "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97"
  1259. "2bIC" ),
  1260. ]
  1261. filter_config_warnings = True # rounds too low, salt too small
  1262. platform_crypt_support = [
  1263. ("freebsd(9|1\d)|linux", True),
  1264. ("freebsd8", None), # added in freebsd 8.3
  1265. ("freebsd|openbsd|netbsd|darwin", False),
  1266. ("solaris", None), # depends on policy
  1267. ]
  1268. # create test cases for specific backends
  1269. sha256_crypt_os_crypt_test = _sha256_crypt_test.create_backend_case("os_crypt")
  1270. sha256_crypt_builtin_test = _sha256_crypt_test.create_backend_case("builtin")
  1271. #=============================================================================
  1272. # test sha512-crypt
  1273. #=============================================================================
  1274. class _sha512_crypt_test(HandlerCase):
  1275. handler = hash.sha512_crypt
  1276. known_correct_hashes = [
  1277. #
  1278. # from JTR 1.7.9
  1279. #
  1280. ('U*U*U*U*', "$6$LKO/Ute40T3FNF95$6S/6T2YuOIHY0N3XpLKABJ3soYcXD9mB7uVbtEZDj/LNscVhZoZ9DEH.sBciDrMsHOWOoASbNLTypH/5X26gN0"),
  1281. ('U*U***U', "$6$LKO/Ute40T3FNF95$wK80cNqkiAUzFuVGxW6eFe8J.fSVI65MD5yEm8EjYMaJuDrhwe5XXpHDJpwF/kY.afsUs1LlgQAaOapVNbggZ1"),
  1282. ('U*U***U*', "$6$LKO/Ute40T3FNF95$YS81pp1uhOHTgKLhSMtQCr2cDiUiN03Ud3gyD4ameviK1Zqz.w3oXsMgO6LrqmIEcG3hiqaUqHi/WEE2zrZqa/"),
  1283. ('*U*U*U*U', "$6$OmBOuxFYBZCYAadG$WCckkSZok9xhp4U1shIZEV7CCVwQUwMVea7L3A77th6SaE9jOPupEMJB.z0vIWCDiN9WLh2m9Oszrj5G.gt330"),
  1284. ('', "$6$ojWH1AiTee9x1peC$QVEnTvRVlPRhcLQCk/HnHaZmlGAAjCfrAN0FtOsOnUk5K5Bn/9eLHHiRzrTzaIKjW9NTLNIBUCtNVOowWS2mN."),
  1285. #
  1286. # custom tests
  1287. #
  1288. ('', '$6$rounds=11021$KsvQipYPWpr93wWP$v7xjI4X6vyVptJjB1Y02vZC5SaSijBkGmq1uJhPr3cvqvvkd42Xvo48yLVPFt8dvhCsnlUgpX.//Cxn91H4qy1'),
  1289. (' ', '$6$rounds=11104$ED9SA4qGmd57Fq2m$q/.PqACDM/JpAHKmr86nkPzzuR5.YpYa8ZJJvI8Zd89ZPUYTJExsFEIuTYbM7gAGcQtTkCEhBKmp1S1QZwaXx0'),
  1290. ('test', '$6$rounds=11531$G/gkPn17kHYo0gTF$Kq.uZBHlSBXyzsOJXtxJruOOH4yc0Is13uY7yK0PvAvXxbvc1w8DO1RzREMhKsc82K/Jh8OquV8FZUlreYPJk1'),
  1291. ('Compl3X AlphaNu3meric', '$6$rounds=10787$wakX8nGKEzgJ4Scy$X78uqaX1wYXcSCtS4BVYw2trWkvpa8p7lkAtS9O/6045fK4UB2/Jia0Uy/KzCpODlfVxVNZzCCoV9s2hoLfDs/'),
  1292. ('4lpHa N|_|M3r1K W/ Cur5Es: #$%(*)(*%#', '$6$rounds=11065$5KXQoE1bztkY5IZr$Jf6krQSUKKOlKca4hSW07MSerFFzVIZt/N3rOTsUgKqp7cUdHrwV8MoIVNCk9q9WL3ZRMsdbwNXpVk0gVxKtz1'),
  1293. # ensures utf-8 used for unicode
  1294. (UPASS_TABLE, '$6$rounds=40000$PEZTJDiyzV28M3.m$GTlnzfzGB44DGd1XqlmC4erAJKCP.rhvLvrYxiT38htrNzVGBnplFOHjejUGVrCfusGWxLQCc3pFO0A/1jYYr0'),
  1295. ]
  1296. known_malformed_hashes = [
  1297. # zero-padded rounds
  1298. '$6$rounds=011021$KsvQipYPWpr93wWP$v7xjI4X6vyVptJjB1Y02vZC5SaSijBkGmq1uJhPr3cvqvvkd42Xvo48yLVPFt8dvhCsnlUgpX.//Cxn91H4qy1',
  1299. # bad char in otherwise correct hash
  1300. '$6$rounds=11021$KsvQipYPWpr9:wWP$v7xjI4X6vyVptJjB1Y02vZC5SaSijBkGmq1uJhPr3cvqvvkd42Xvo48yLVPFt8dvhCsnlUgpX.//Cxn91H4qy1',
  1301. ]
  1302. known_correct_configs = [
  1303. # config, secret, result
  1304. #
  1305. # taken from official specification at http://www.akkadia.org/drepper/SHA-crypt.txt
  1306. #
  1307. ("$6$saltstring", "Hello world!",
  1308. "$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu"
  1309. "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1" ),
  1310. ( "$6$rounds=10000$saltstringsaltstring", "Hello world!",
  1311. "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb"
  1312. "HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v." ),
  1313. ( "$6$rounds=5000$toolongsaltstring", "This is just a test",
  1314. "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ"
  1315. "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" ),
  1316. ( "$6$rounds=1400$anotherlongsaltstring",
  1317. "a very much longer text to encrypt. This one even stretches over more"
  1318. "than one line.",
  1319. "$6$rounds=1400$anotherlongsalts$POfYwTEok97VWcjxIiSOjiykti.o/pQs.wP"
  1320. "vMxQ6Fm7I6IoYN3CmLs66x9t0oSwbtEW7o7UmJEiDwGqd8p4ur1" ),
  1321. ( "$6$rounds=77777$short",
  1322. "we have a short salt string but not a short password",
  1323. "$6$rounds=77777$short$WuQyW2YR.hBNpjjRhpYD/ifIw05xdfeEyQoMxIXbkvr0g"
  1324. "ge1a1x3yRULJ5CCaUeOxFmtlcGZelFl5CxtgfiAc0" ),
  1325. ( "$6$rounds=123456$asaltof16chars..", "a short string",
  1326. "$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc"
  1327. "elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1" ),
  1328. ( "$6$rounds=10$roundstoolow", "the minimum number is still observed",
  1329. "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x"
  1330. "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX." ),
  1331. ]
  1332. filter_config_warnings = True # rounds too low, salt too small
  1333. platform_crypt_support = _sha256_crypt_test.platform_crypt_support
  1334. # create test cases for specific backends
  1335. sha512_crypt_os_crypt_test = _sha512_crypt_test.create_backend_case("os_crypt")
  1336. sha512_crypt_builtin_test = _sha512_crypt_test.create_backend_case("builtin")
  1337. #=============================================================================
  1338. # sun md5 crypt
  1339. #=============================================================================
  1340. class sun_md5_crypt_test(HandlerCase):
  1341. handler = hash.sun_md5_crypt
  1342. # TODO: this scheme needs some real test vectors, especially due to
  1343. # the "bare salt" issue which plagued the official parser.
  1344. known_correct_hashes = [
  1345. #
  1346. # http://forums.halcyoninc.com/showthread.php?t=258
  1347. #
  1348. ("Gpcs3_adm", "$md5$zrdhpMlZ$$wBvMOEqbSjU.hu5T2VEP01"),
  1349. #
  1350. # http://www.c0t0d0s0.org/archives/4453-Less-known-Solaris-features-On-passwords-Part-2-Using-stronger-password-hashing.html
  1351. #
  1352. ("aa12345678", "$md5$vyy8.OVF$$FY4TWzuauRl4.VQNobqMY."),
  1353. #
  1354. # http://www.cuddletech.com/blog/pivot/entry.php?id=778
  1355. #
  1356. ("this", "$md5$3UqYqndY$$6P.aaWOoucxxq.l00SS9k0"),
  1357. #
  1358. # http://compgroups.net/comp.unix.solaris/password-file-in-linux-and-solaris-8-9
  1359. #
  1360. ("passwd", "$md5$RPgLF6IJ$WTvAlUJ7MqH5xak2FMEwS/"),
  1361. #
  1362. # source: http://solaris-training.com/301_HTML/docs/deepdiv.pdf page 27
  1363. # FIXME: password unknown
  1364. # "$md5,rounds=8000$kS9FT1JC$$mnUrRO618lLah5iazwJ9m1"
  1365. #
  1366. # source: http://www.visualexams.com/310-303.htm
  1367. # XXX: this has 9 salt chars unlike all other hashes. is that valid?
  1368. # FIXME: password unknown
  1369. # "$md5,rounds=2006$2amXesSj5$$kCF48vfPsHDjlKNXeEw7V."
  1370. #
  1371. #
  1372. # custom
  1373. #
  1374. # ensures utf-8 used for unicode
  1375. (UPASS_TABLE, '$md5,rounds=5000$10VYDzAA$$1arAVtMA3trgE1qJ2V0Ez1'),
  1376. ]
  1377. known_correct_configs = [
  1378. # (config, secret, hash)
  1379. #---------------------------
  1380. # test salt string handling
  1381. #
  1382. # these tests attempt to verify that passlib is handling
  1383. # the "bare salt" issue (see sun md5 crypt docs)
  1384. # in a sane manner
  1385. #---------------------------
  1386. # config with "$" suffix, hash strings with "$$" suffix,
  1387. # should all be treated the same, with one "$" added to salt digest.
  1388. ("$md5$3UqYqndY$",
  1389. "this", "$md5$3UqYqndY$$6P.aaWOoucxxq.l00SS9k0"),
  1390. ("$md5$3UqYqndY$$.................DUMMY",
  1391. "this", "$md5$3UqYqndY$$6P.aaWOoucxxq.l00SS9k0"),
  1392. # config with no suffix, hash strings with "$" suffix,
  1393. # should all be treated the same, and no suffix added to salt digest.
  1394. # NOTE: this is just a guess re: config w/ no suffix,
  1395. # but otherwise there's no sane way to encode bare_salt=False
  1396. # within config string.
  1397. ("$md5$3UqYqndY",
  1398. "this", "$md5$3UqYqndY$HIZVnfJNGCPbDZ9nIRSgP1"),
  1399. ("$md5$3UqYqndY$.................DUMMY",
  1400. "this", "$md5$3UqYqndY$HIZVnfJNGCPbDZ9nIRSgP1"),
  1401. ]
  1402. known_malformed_hashes = [
  1403. # unexpected end of hash
  1404. "$md5,rounds=5000",
  1405. # bad rounds
  1406. "$md5,rounds=500A$xxxx",
  1407. "$md5,rounds=0500$xxxx",
  1408. "$md5,rounds=0$xxxx",
  1409. # bad char in otherwise correct hash
  1410. "$md5$RPgL!6IJ$WTvAlUJ7MqH5xak2FMEwS/",
  1411. # digest too short
  1412. "$md5$RPgLa6IJ$WTvAlUJ7MqH5xak2FMEwS",
  1413. # digest too long
  1414. "$md5$RPgLa6IJ$WTvAlUJ7MqH5xak2FMEwS/.",
  1415. # 2+ "$" at end of salt in config
  1416. # NOTE: not sure what correct behavior is, so forbidding format for now.
  1417. "$md5$3UqYqndY$$",
  1418. # 3+ "$" at end of salt in hash
  1419. # NOTE: not sure what correct behavior is, so forbidding format for now.
  1420. "$md5$RPgLa6IJ$$$WTvAlUJ7MqH5xak2FMEwS/",
  1421. ]
  1422. platform_crypt_support = [
  1423. ("solaris", True),
  1424. ("freebsd|openbsd|netbsd|linux|darwin", False),
  1425. ]
  1426. def do_verify(self, secret, hash):
  1427. # Override to fake error for "$..." hash string listed in known_correct_configs (above)
  1428. # These have to be hash strings, in order to test bare salt issue.
  1429. if isinstance(hash, str) and hash.endswith("$.................DUMMY"):
  1430. raise ValueError("pretending '$...' stub hash is config string")
  1431. return self.handler.verify(secret, hash)
  1432. #=============================================================================
  1433. # unix disabled / fallback
  1434. #=============================================================================
  1435. class unix_disabled_test(HandlerCase):
  1436. handler = hash.unix_disabled
  1437. # accepts_all_hashes = True # TODO: turn this off.
  1438. known_correct_hashes = [
  1439. # everything should hash to "!" (or "*" on BSD),
  1440. # and nothing should verify against either string
  1441. ("password", "!"),
  1442. (UPASS_TABLE, "*"),
  1443. ]
  1444. known_unidentified_hashes = [
  1445. # should never identify anything crypt() could return...
  1446. "$1$xxx",
  1447. "abc",
  1448. "./az",
  1449. "{SHA}xxx",
  1450. ]
  1451. def test_76_hash_border(self):
  1452. # so empty strings pass
  1453. self.accepts_all_hashes = True
  1454. super(unix_disabled_test, self).test_76_hash_border()
  1455. def test_90_special(self):
  1456. """test marker option & special behavior"""
  1457. warnings.filterwarnings("ignore", "passing settings to .*.hash\(\) is deprecated")
  1458. handler = self.handler
  1459. # preserve hash if provided
  1460. self.assertEqual(handler.genhash("stub", "!asd"), "!asd")
  1461. # use marker if no hash
  1462. self.assertEqual(handler.genhash("stub", ""), handler.default_marker)
  1463. self.assertEqual(handler.hash("stub"), handler.default_marker)
  1464. self.assertEqual(handler.using().default_marker, handler.default_marker)
  1465. # custom marker
  1466. self.assertEqual(handler.genhash("stub", "", marker="*xxx"), "*xxx")
  1467. self.assertEqual(handler.hash("stub", marker="*xxx"), "*xxx")
  1468. self.assertEqual(handler.using(marker="*xxx").hash("stub"), "*xxx")
  1469. # reject invalid marker
  1470. self.assertRaises(ValueError, handler.genhash, 'stub', "", marker='abc')
  1471. self.assertRaises(ValueError, handler.hash, 'stub', marker='abc')
  1472. self.assertRaises(ValueError, handler.using, marker='abc')
  1473. class unix_fallback_test(HandlerCase):
  1474. handler = hash.unix_fallback
  1475. accepts_all_hashes = True
  1476. known_correct_hashes = [
  1477. # *everything* should hash to "!", and nothing should verify
  1478. ("password", "!"),
  1479. (UPASS_TABLE, "!"),
  1480. ]
  1481. # silence annoying deprecation warning
  1482. def setUp(self):
  1483. super(unix_fallback_test, self).setUp()
  1484. warnings.filterwarnings("ignore", "'unix_fallback' is deprecated")
  1485. def test_90_wildcard(self):
  1486. """test enable_wildcard flag"""
  1487. h = self.handler
  1488. self.assertTrue(h.verify('password','', enable_wildcard=True))
  1489. self.assertFalse(h.verify('password',''))
  1490. for c in "!*x":
  1491. self.assertFalse(h.verify('password',c, enable_wildcard=True))
  1492. self.assertFalse(h.verify('password',c))
  1493. def test_91_preserves_existing(self):
  1494. """test preserves existing disabled hash"""
  1495. handler = self.handler
  1496. # use marker if no hash
  1497. self.assertEqual(handler.genhash("stub", ""), "!")
  1498. self.assertEqual(handler.hash("stub"), "!")
  1499. # use hash if provided and valid
  1500. self.assertEqual(handler.genhash("stub", "!asd"), "!asd")
  1501. #=============================================================================
  1502. # eof
  1503. #=============================================================================