def test_lookup_hash_metadata(self): from otp.ai.passlib.crypto.digest import lookup_hash info = lookup_hash('sha256') self.assertEqual(info.name, 'sha256') self.assertEqual(info.iana_name, 'sha-256') self.assertEqual(info.block_size, 64) self.assertEqual(info.digest_size, 32) self.assertIs(lookup_hash('SHA2-256'), info) info = lookup_hash('md5') self.assertEqual(info.name, 'md5') self.assertEqual(info.iana_name, 'md5') self.assertEqual(info.block_size, 64) self.assertEqual(info.digest_size, 16)
def create_hex_hash(digest, module=__name__): info = lookup_hash(digest) name = 'hex_' + info.name return type( name, (HexDigestHash, ), dict( name=name, __module__=module, _hash_func=staticmethod(info.const), checksum_size=info.digest_size * 2, __doc__= 'This class implements a plain hexadecimal %s hash, and follows the :ref:`password-hash-api`.\n\nIt supports no optional or contextual keywords.\n' % (info.name, )))
def test_lookup_hash_ctor(self): from otp.ai.passlib.crypto.digest import lookup_hash self.assertRaises(ValueError, lookup_hash, 'new') self.assertRaises(ValueError, lookup_hash, '__name__') self.assertRaises(ValueError, lookup_hash, 'sha4') self.assertEqual(lookup_hash('md5'), (hashlib.md5, 16, 64)) try: hashlib.new('sha') has_sha = True except ValueError: has_sha = False else: if has_sha: record = lookup_hash('sha') const = record[0] self.assertEqual(record, (const, 20, 64)) self.assertEqual(hexlify(const('abc').digest()), '0164b8a914cd2a5e74c4f7ff082c4d97f1edf880') else: self.assertRaises(ValueError, lookup_hash, 'sha') try: hashlib.new('md4') has_md4 = True except ValueError: has_md4 = False record = lookup_hash('md4') const = record[0] if not has_md4: from otp.ai.passlib.crypto._md4 import md4 self.assertIs(const, md4) self.assertEqual(record, (const, 16, 64)) self.assertEqual(hexlify(const('abc').digest()), 'a448017aaf21d8525fc10ae87aa6729d') self.assertRaises(ValueError, lookup_hash, 'xxx256') self.assertIs(lookup_hash('md5'), lookup_hash('md5'))
def get_prf(name): global _prf_cache if name in _prf_cache: return _prf_cache[name] if isinstance(name, native_string_types): if not name.startswith(_HMAC_PREFIXES): raise ValueError('unknown prf algorithm: %r' % (name, )) digest = lookup_hash(name[5:]).name def hmac(key, msg): return compile_hmac(digest, key)(msg) record = (hmac, hmac.digest_info.digest_size) else: if callable(name): digest_size = len(name('x', 'y')) record = (name, digest_size) else: raise ExpectedTypeError(name, 'str or callable', 'prf name') _prf_cache[name] = record return record
def __init__(self, key=None, format='base32', new=False, digits=None, alg=None, size=None, period=None, label=None, issuer=None, changed=False, **kwds): super(TOTP, self).__init__(**kwds) if changed: self.changed = changed info = lookup_hash(alg or self.alg) self.alg = info.name digest_size = info.digest_size if digest_size < 4: raise RuntimeError('%r hash digest too small' % alg) if new: if key: raise TypeError("'key' and 'new=True' are mutually exclusive") if size is None: size = digest_size else: if size > digest_size: raise ValueError( "'size' should be less than digest size (%d)" % digest_size) self.key = getrandbytes(rng, size) else: if not key: raise TypeError( "must specify either an existing 'key', or 'new=True'") else: if format == 'encrypted': self.encrypted_key = key else: if key: self.key = _decode_bytes(key, format) if len(self.key) < self._min_key_size: msg = 'for security purposes, secret key must be >= %d bytes' % self._min_key_size if new: raise ValueError(msg) else: warn(msg, exc.PasslibSecurityWarning, stacklevel=1) if digits is None: digits = self.digits if not isinstance(digits, int_types): raise TypeError('digits must be an integer, not a %r' % type(digits)) if digits < 6 or digits > 10: raise ValueError('digits must in range(6,11)') self.digits = digits if label: self._check_label(label) self.label = label if issuer: self._check_issuer(issuer) self.issuer = issuer if period is not None: self._check_serial(period, 'period', minval=1) self.period = period return
from binascii import hexlify import logging log = logging.getLogger(__name__) from warnings import warn from otp.ai.passlib.utils import to_unicode, right_pad_string from otp.ai.passlib.utils.compat import unicode from otp.ai.passlib.crypto.digest import lookup_hash md4 = lookup_hash('md4').const import otp.ai.passlib.utils.handlers as uh __all__ = [ 'lmhash', 'nthash', 'bsd_nthash', 'msdcc', 'msdcc2'] class lmhash(uh.TruncateMixin, uh.HasEncodingContext, uh.StaticHandler): name = 'lmhash' setting_kwds = ('truncate_error', ) checksum_chars = uh.HEX_CHARS checksum_size = 32 truncate_size = 14 default_encoding = 'cp437' @classmethod def _norm_hash(cls, hash): return hash.lower() def _calc_checksum(self, secret): if self.use_defaults: self._check_truncate_policy(secret)
def test_lookup_hash_alt_types(self): from otp.ai.passlib.crypto.digest import lookup_hash info = lookup_hash('sha256') self.assertIs(lookup_hash(info), info) self.assertIs(lookup_hash(info.const), info) self.assertRaises(TypeError, lookup_hash, 123)
def get_md4_const(self): return lookup_hash('md4').const