예제 #1
0
 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)
예제 #2
0
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, )))
예제 #3
0
    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'))
예제 #4
0
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
예제 #5
0
 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
예제 #6
0
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)
예제 #7
0
 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)
예제 #8
0
 def get_md4_const(self):
     return lookup_hash('md4').const