summaryrefslogtreecommitdiff
path: root/passlib/utils
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2011-03-18 17:21:26 -0400
committerEli Collins <elic@assurancetechnologies.com>2011-03-18 17:21:26 -0400
commita8bd4647cabe847ee728944428962e947c6df7bd (patch)
tree325722c5d0303dab48c029f6308d3def242a7c6d /passlib/utils
parent56accc0d41a711066dfb5c13c703e029673c0519 (diff)
downloadpasslib-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__.py8
-rw-r--r--passlib/utils/_slow_bcrypt.py1
-rw-r--r--passlib/utils/drivers.py60
-rw-r--r--passlib/utils/h64.py6
-rw-r--r--passlib/utils/pbkdf2.py2
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.