1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
"""tests for passlib.pwhash -- (c) Assurance Technologies 2003-2009"""
#=========================================================
#imports
#=========================================================
from __future__ import with_statement
#core
import re
import hashlib
from logging import getLogger
#site
#pkg
from passlib.handler import CryptHandler
from passlib.tests.handler_utils import _HandlerTestCase
from passlib.utils import generate_h64_salt
#module
log = getLogger(__name__)
#=========================================================
#sample algorithms - these serve as known quantities
# to test the unittests themselves, as well as other
# parts of passlib
#=========================================================
class UnsaltedHash(CryptHandler):
"example algorithm which lacks a salt [REALLY INSECURE - DO NOT USE]"
name = "unsalted-example"
#stats: 160 bit checksum, no salt
@classmethod
def identify(cls, hash):
return bool(hash and re.match("^[0-9a-f]{40}$", hash))
@classmethod
def genhash(cls, secret, config):
return hashlib.sha1("boblious" + secret).hexdigest()
class SaltedHash(CryptHandler):
"example algorithm with a salt [REALLY INSECURE - DO NOT USE]"
name = "salted-example"
#stats: 160 bit checksum, 12 bit salt
setting_kwds = ("salt",)
@classmethod
def identify(cls, hash):
return bool(hash and re.match("^@salt[0-9a-zA-Z./]{2}[0-9a-f]{40}$", hash))
@classmethod
def _parse(cls, hash):
if not cls.identify(hash):
raise ValueError, "not a salted-example hash"
return dict(
salt=hash[5:7],
checksum=hash[7:],
)
@classmethod
def _render(cls, salt, checksum):
assert len(salt) == 2
assert len(checksum) == 40
return "@salt%s%s" % (salt, checksum)
@classmethod
def genconfig(cls, salt=None):
if not salt:
salt = generate_h64_salt(2)
return cls._render(salt[:2], '0' * 40)
@classmethod
def genhash(cls, secret, config):
salt = cls._parse(config)['salt']
checksum = hashlib.sha1(salt+secret).hexdigest()
return cls._render(salt, checksum)
#=========================================================
#test sample algorithms
#=========================================================
#TODO: provide data samples for algorithms
# (positive knowns, negative knowns, invalid identify)
class UnsaltedHashTest(_HandlerTestCase):
handler = UnsaltedHash
class SaltedHashTest(_HandlerTestCase):
handler = SaltedHash
#=========================================================
#
#=========================================================
#TODO: test registry system
#=========================================================
#EOF
#=========================================================
|