diff options
| author | Eli Collins <elic@assurancetechnologies.com> | 2011-03-18 17:21:26 -0400 |
|---|---|---|
| committer | Eli Collins <elic@assurancetechnologies.com> | 2011-03-18 17:21:26 -0400 |
| commit | a8bd4647cabe847ee728944428962e947c6df7bd (patch) | |
| tree | 325722c5d0303dab48c029f6308d3def242a7c6d /passlib/utils | |
| parent | 56accc0d41a711066dfb5c13c703e029673c0519 (diff) | |
| download | passlib-a8bd4647cabe847ee728944428962e947c6df7bd.tar.gz | |
bugfixes, tweaks, test cases
============================
* now at 99% coverage
* changed some error types
* bugfix to min_verify_time code
* tests for registry, some cryptcontext border cases
* ldap hash tests
* tests for rest of utils
* tests for skeleton hash classes in passlib.utils.drivers
* moved validate_class code from skeleton hash classes to HandlerCase
main things still needing testing:
* category support for CryptContext/Policy
* some bits of registry
Diffstat (limited to 'passlib/utils')
| -rw-r--r-- | passlib/utils/__init__.py | 8 | ||||
| -rw-r--r-- | passlib/utils/_slow_bcrypt.py | 1 | ||||
| -rw-r--r-- | passlib/utils/drivers.py | 60 | ||||
| -rw-r--r-- | passlib/utils/h64.py | 6 | ||||
| -rw-r--r-- | passlib/utils/pbkdf2.py | 2 |
5 files changed, 16 insertions, 61 deletions
diff --git a/passlib/utils/__init__.py b/passlib/utils/__init__.py index f99b4f1..619d492 100644 --- a/passlib/utils/__init__.py +++ b/passlib/utils/__init__.py @@ -46,7 +46,7 @@ __all__ = [ try: #NOTE: just doing this import once, for all the various hashes that need it. from crypt import crypt as os_crypt -except ImportError: +except ImportError: #pragma: no cover os_crypt = None #================================================================================= @@ -118,7 +118,7 @@ def is_crypt_handler(obj): def is_crypt_context(obj): "check if object follows :class:`CryptContext` interface" return all(hasattr(obj, name) for name in ( - "lookup", + "hash_needs_update", "genconfig", "genhash", "verify", "encrypt", "identify", )) @@ -305,7 +305,7 @@ def xor_bytes(left, right): try: os.urandom(1) has_urandom = True -except NotImplementedError: +except NotImplementedError: #pragma: no cover has_urandom = False def genseed(value=None): @@ -335,7 +335,7 @@ def genseed(value=None): if has_urandom: rng = random.SystemRandom() -else: +else: #pragma: no cover #NOTE: to reseed - rng.seed(genseed(rng)) rng = random.Random(genseed()) diff --git a/passlib/utils/_slow_bcrypt.py b/passlib/utils/_slow_bcrypt.py index 5f68add..7b469aa 100644 --- a/passlib/utils/_slow_bcrypt.py +++ b/passlib/utils/_slow_bcrypt.py @@ -1,3 +1,4 @@ +#pragma: no cover - this module currently isn't used. """passlib._slow_bcrypt - fallback pure-python bcrypt implementation History diff --git a/passlib/utils/drivers.py b/passlib/utils/drivers.py index 7f1cb32..b3a97cd 100644 --- a/passlib/utils/drivers.py +++ b/passlib/utils/drivers.py @@ -58,18 +58,6 @@ class BaseHash(object): context_kwds = () #===================================================== - #init - #===================================================== - @classmethod - def validate_class(cls): - "helper to ensure class is configured property" - if not cls.name: - raise AssertionError, "class must have .name attribute set" - - if cls.setting_kwds is None: - raise AssertionError, "class must have .setting_kwds attribute set" - - #===================================================== #init helpers #===================================================== @classproperty @@ -241,44 +229,6 @@ class ExtHash(BaseHash): setattr(self, key, value) super(ExtHash, self).__init__(**kwds) - @classmethod - def validate_class(cls): - "helper to ensure class is configured property" - super(ExtHash, cls).validate_class() - - if any(k not in cls.setting_kwds for k in cls._extra_init_settings): - raise AssertionError, "_extra_init_settings must be subset of setting_kwds" - - if 'salt' in cls.setting_kwds: - - if cls.min_salt_chars > cls.max_salt_chars: - raise AssertionError, "min salt chars too large" - - if cls.default_salt_chars < cls.min_salt_chars: - raise AssertionError, "default salt chars too small" - if cls.default_salt_chars > cls.max_salt_chars: - raise AssertionError, "default salt chars too large" - - if any(c not in cls.salt_charset for c in cls.default_salt_charset): - raise AssertionError, "default salt charset not subset of salt charset" - - if 'rounds' in cls.setting_kwds: - - if cls.max_rounds is None: - raise AssertionError, "max rounds not specified" - - if cls.min_rounds > cls.max_rounds: - raise AssertionError, "min rounds too large" - - if cls.default_rounds is not None: - if cls.default_rounds < cls.min_rounds: - raise AssertionError, "default rounds too small" - if cls.default_rounds > cls.max_rounds: - raise AssertionError, "default rounds too large" - - if cls.rounds_cost not in ("linear", "log2"): - raise AssertionError, "unknown rounds cost function" - #========================================================= #init helpers #========================================================= @@ -343,7 +293,7 @@ class ExtHash(BaseHash): if not cls._has_salt: #NOTE: special casing schemes which have no salt... if salt is not None: - raise ValueError, "%s does not support ``salt`` parameter" % (cls.name,) + raise TypeError, "%s does not support ``salt`` parameter" % (cls.name,) return None if salt is None: @@ -397,7 +347,7 @@ class ExtHash(BaseHash): if not cls._has_rounds: #NOTE: special casing schemes which don't have rounds if rounds is not None: - raise ValueError, "%s does not support ``rounds``" % (cls.name,) + raise TypeError, "%s does not support ``rounds``" % (cls.name,) return None if rounds is None: @@ -443,11 +393,11 @@ class ExtHash(BaseHash): return False @classmethod - def from_string(cls, hash): + def from_string(cls, hash): #pragma: no cover "return parsed instance from hash/configuration string; raising ValueError on invalid inputs" raise NotImplementedError, "%s must implement from_string()" % (cls,) - def to_string(self): + def to_string(self): #pragma: no cover "render instance to hash or configuration string (depending on if checksum attr is set)" raise NotImplementedError, "%s must implement from_string()" % (type(self),) @@ -484,7 +434,7 @@ class ExtHash(BaseHash): self.checksum = self.calc_checksum(secret) return self.to_string() - def calc_checksum(self, secret): + def calc_checksum(self, secret): #pragma: no cover "given secret; calcuate and return encoded checksum portion of hash string, taking config from object state" raise NotImplementedError, "%s must implement calc_checksum()" % (cls,) diff --git a/passlib/utils/h64.py b/passlib/utils/h64.py index d9c46a7..27c376c 100644 --- a/passlib/utils/h64.py +++ b/passlib/utils/h64.py @@ -128,6 +128,8 @@ def decode_int6(value): def encode_int6(value): "encodes 6-bit integer -> single hash64 character" + if value < 0 or value > 63: + raise ValueError, "value out of range" return encode_6bit(value) #--------------------------------------------------------------------- @@ -201,7 +203,7 @@ def decode_dc_int64(value): this format is used primarily by des-crypt & variants to encode the DES output value used as a checksum. """ - return decode_int(value, 11, True)>>2 + return decode_int(value, True)>>2 def encode_dc_int64(value): """encode 64-bit integer -> 11 char hash64 string (big-endian order; 2 lsb added as padding) @@ -247,6 +249,8 @@ def encode_int(value, count, big=False): :returns: a hash64 string of length ``count``. """ + if value < 0: + raise ValueError, "value cannot be negative" if big: itr = xrange(6*count-6, -6, -6) else: diff --git a/passlib/utils/pbkdf2.py b/passlib/utils/pbkdf2.py index e4fa337..ad6f087 100644 --- a/passlib/utils/pbkdf2.py +++ b/passlib/utils/pbkdf2.py @@ -31,7 +31,7 @@ __all__ = [ #================================================================================= def hmac_sha1(key, msg): "perform raw hmac-sha1 of a message" - return hmac(key, msg, sha1).digest() + return hmac.new(key, msg, hashlib.sha1).digest() if _EVP: #default *should* be sha1, which saves us a wrapper function, but might as well check. |
