Exemplo n.º 1
0
def pbkdf2_hmac(digest, secret, salt, rounds, keylen=None):
    secret = to_bytes(secret, param='secret')
    salt = to_bytes(salt, param='salt')
    digest_info = lookup_hash(digest)
    digest_size = digest_info.digest_size
    if not isinstance(rounds, int_types):
        raise exc.ExpectedTypeError(rounds, 'int', 'rounds')
    if rounds < 1:
        raise ValueError('rounds must be at least 1')
    if keylen is None:
        keylen = digest_size
    else:
        if not isinstance(keylen, int_types):
            raise exc.ExpectedTypeError(keylen, 'int or None', 'keylen')
        else:
            if keylen < 1:
                raise ValueError('keylen must be at least 1')
            block_count = (keylen + digest_size - 1) // digest_size
            if block_count > MAX_UINT32:
                raise OverflowError('keylen too long for digest')
            if digest_info.supported_by_fastpbkdf2:
                return _fast_pbkdf2_hmac(digest_info.name, secret, salt,
                                         rounds, keylen)
        if digest_info.supported_by_hashlib_pbkdf2:
            return _stdlib_pbkdf2_hmac(digest_info.name, secret, salt, rounds,
                                       keylen)
    keyed_hmac = compile_hmac(digest, secret)
    calc_block = _get_pbkdf2_looper(digest_size)
    return join_bytes(
        calc_block(keyed_hmac, keyed_hmac(salt + _pack_uint32(i)), rounds)
        for i in irange(1, block_count + 1))[:keylen]
Exemplo n.º 2
0
 def _norm_salt(cls, salt, relaxed=False):
     if cls._salt_is_bytes:
         if not isinstance(salt, bytes):
             raise exc.ExpectedTypeError(salt, 'bytes', 'salt')
     else:
         if not isinstance(salt, unicode):
             if isinstance(salt, bytes) and (PY2 or relaxed):
                 salt = salt.decode('ascii')
             else:
                 raise exc.ExpectedTypeError(salt, 'unicode', 'salt')
         sc = cls.salt_chars
         if sc is not None and any(c not in sc for c in salt):
             raise ValueError('invalid characters in %s salt' % cls.name)
     mn = cls.min_salt_size
     if mn and len(salt) < mn:
         msg = 'salt too small (%s requires %s %d %s)' % (
             cls.name, 'exactly' if mn == cls.max_salt_size else '>=', mn,
             cls._salt_unit)
         raise ValueError(msg)
     mx = cls.max_salt_size
     if mx and len(salt) > mx:
         msg = 'salt too large (%s requires %s %d %s)' % (
             cls.name, 'exactly' if mx == mn else '<=', mx, cls._salt_unit)
         if relaxed:
             warn(msg, PasslibHashWarning)
             salt = cls._truncate_salt(salt, mx)
         else:
             raise ValueError(msg)
     return salt
Exemplo n.º 3
0
def pbkdf1(digest, secret, salt, rounds, keylen=None):
    const, digest_size, block_size = lookup_hash(digest)
    secret = to_bytes(secret, param='secret')
    salt = to_bytes(salt, param='salt')
    if not isinstance(rounds, int_types):
        raise exc.ExpectedTypeError(rounds, 'int', 'rounds')
    if rounds < 1:
        raise ValueError('rounds must be at least 1')
    if keylen is None:
        keylen = digest_size
    else:
        if not isinstance(keylen, int_types):
            raise exc.ExpectedTypeError(keylen, 'int or None', 'keylen')
        else:
            if keylen < 0:
                raise ValueError('keylen must be at least 0')
            else:
                if keylen > digest_size:
                    raise ValueError(
                        'keylength too large for digest: %r > %r' %
                        (keylen, digest_size))
    block = secret + salt
    for _ in irange(rounds):
        block = const(block).digest()

    return block[:keylen]
Exemplo n.º 4
0
 def _load_settings(self):
     from django.conf import settings
     _UNSET = object()
     config = getattr(settings, 'PASSLIB_CONFIG', _UNSET)
     if config is _UNSET:
         config = getattr(settings, 'PASSLIB_CONTEXT', _UNSET)
     if config is _UNSET:
         config = 'passlib-default'
     if config is None:
         warn(
             "setting PASSLIB_CONFIG=None is deprecated, and support will be removed in Passlib 1.8, use PASSLIB_CONFIG='disabled' instead.",
             DeprecationWarning)
         config = 'disabled'
     else:
         if not isinstance(config, (unicode, bytes, dict)):
             raise exc.ExpectedTypeError(config, 'str or dict',
                                         'PASSLIB_CONFIG')
         get_category = getattr(settings, 'PASSLIB_GET_CATEGORY', None)
         if get_category and not callable(get_category):
             raise exc.ExpectedTypeError(get_category, 'callable',
                                         'PASSLIB_GET_CATEGORY')
         if config == 'disabled':
             self.enabled = False
             return
     self.__dict__.pop('enabled', None)
     if isinstance(config, str) and '\n' not in config:
         config = get_preset_config(config)
     if get_category:
         self.get_user_category = get_category
     else:
         self.__dict__.pop('get_category', None)
     self.context.load(config)
     self.reset_hashers()
     return
Exemplo n.º 5
0
def des_encrypt_int_block(key, input, salt=0, rounds=1):
    if rounds < 1:
        raise ValueError('rounds must be positive integer')
    if salt < 0 or salt > INT_24_MASK:
        raise ValueError('salt must be 24-bit non-negative integer')
    if not isinstance(key, int_types):
        raise exc.ExpectedTypeError(key, 'int', 'key')
    else:
        if key < 0 or key > INT_64_MASK:
            raise ValueError('key must be 64-bit non-negative integer')
    if not isinstance(input, int_types):
        raise exc.ExpectedTypeError(input, 'int', 'input')
    else:
        if input < 0 or input > INT_64_MASK:
            raise ValueError('input must be 64-bit non-negative integer')
        if PCXROT is None:
            _load_tables()
        SPE0, SPE1, SPE2, SPE3, SPE4, SPE5, SPE6, SPE7 = SPE

        def _iter_key_schedule(ks_odd):
            for p_even, p_odd in PCXROT:
                ks_even = _permute(ks_odd, p_even)
                ks_odd = _permute(ks_even, p_odd)
                yield (ks_even & _KS_MASK, ks_odd & _KS_MASK)

        ks_list = list(_iter_key_schedule(key))
        salt = (salt & 63) << 26 | (salt & 4032) << 12 | (
            salt & 258048) >> 2 | (salt & 16515072) >> 16
        if input == 0:
            L = R = 0
        else:
            L = input >> 31 & 2863311530L | input & 1431655765
            L = _permute(L, IE3264)
            R = input >> 32 & 2863311530L | input >> 1 & 1431655765
            R = _permute(R, IE3264)
        while rounds:
            rounds -= 1
            for ks_even, ks_odd in ks_list:
                k = (R >> 32 ^ R) & salt
                B = k << 32 ^ k ^ R ^ ks_even
                L ^= SPE0[(B >> 58 & 63)] ^ SPE1[(B >> 50 & 63)] ^ SPE2[(
                    B >> 42 & 63)] ^ SPE3[(B >> 34 & 63)] ^ SPE4[(
                        B >> 26 & 63)] ^ SPE5[(B >> 18 & 63)] ^ SPE6[(
                            B >> 10 & 63)] ^ SPE7[(B >> 2 & 63)]
                k = (L >> 32 ^ L) & salt
                B = k << 32 ^ k ^ L ^ ks_odd
                R ^= SPE0[(B >> 58 & 63)] ^ SPE1[(B >> 50 & 63)] ^ SPE2[(
                    B >> 42 & 63)] ^ SPE3[(B >> 34 & 63)] ^ SPE4[(
                        B >> 26 & 63)] ^ SPE5[(B >> 18 & 63)] ^ SPE6[(
                            B >> 10 & 63)] ^ SPE7[(B >> 2 & 63)]

            L, R = R, L

    C = L >> 3 & 1085102592318504960L | L << 33 & 17361641477096079360L | R >> 35 & 252645135 | R << 1 & 4042322160L
    return _permute(C, CF6464)
Exemplo n.º 6
0
def norm_integer(handler,
                 value,
                 min=1,
                 max=None,
                 param='value',
                 relaxed=False):
    if not isinstance(value, int_types):
        raise exc.ExpectedTypeError(value, 'integer', param)
    if value < min:
        msg = '%s: %s (%d) is too low, must be at least %d' % (
            handler.name, param, value, min)
        if relaxed:
            warn(msg, exc.PasslibHashWarning)
            value = min
        else:
            raise ValueError(msg)
    if max and value > max:
        msg = '%s: %s (%d) is too large, cannot be more than %d' % (
            handler.name, param, value, max)
        if relaxed:
            warn(msg, exc.PasslibHashWarning)
            value = max
        else:
            raise ValueError(msg)
    return value
Exemplo n.º 7
0
 def __call__(self, returns=None):
     if returns is None:
         return next(self)
     if isinstance(returns, int_types):
         return [ next(self) for _ in irange(returns) ]
     if returns is iter:
         return self
     raise exc.ExpectedTypeError(returns, '<None>, int, or <iter>', 'returns')
     return
Exemplo n.º 8
0
def des_encrypt_block(key, input, salt=0, rounds=1):
    if isinstance(key, bytes):
        if len(key) == 7:
            key = expand_des_key(key)
        else:
            if len(key) != 8:
                raise ValueError('key must be 7 or 8 bytes')
        key = _unpack64(key)
    else:
        raise exc.ExpectedTypeError(key, 'bytes', 'key')
    if isinstance(input, bytes):
        if len(input) != 8:
            raise ValueError('input block must be 8 bytes')
        input = _unpack64(input)
    else:
        raise exc.ExpectedTypeError(input, 'bytes', 'input')
    result = des_encrypt_int_block(key, input, salt, rounds)
    return _pack64(result)
Exemplo n.º 9
0
 def normalize_time(cls, time):
     if isinstance(time, int_types):
         return time
     if isinstance(time, float):
         return int(time)
     if time is None:
         return int(cls.now())
     if hasattr(time, 'utctimetuple'):
         return calendar.timegm(time.utctimetuple())
     raise exc.ExpectedTypeError(time, 'int, float, or datetime', 'time')
     return
Exemplo n.º 10
0
def _decode_bytes(key, format):
    if format == 'raw':
        if not isinstance(key, bytes):
            raise exc.ExpectedTypeError(key, 'bytes', 'key')
        return key
    key = to_unicode(key, param='key')
    key = _clean_re.sub('', key).encode('utf-8')
    if format == 'hex' or format == 'base16':
        return base64.b16decode(key.upper())
    if format == 'base32':
        return b32decode(key)
    raise ValueError('unknown byte-encoding format: %r' % (format, ))
Exemplo n.º 11
0
def expand_des_key(key):
    if isinstance(key, bytes):
        if len(key) != 7:
            raise ValueError('key must be 7 bytes in size')
    else:
        if isinstance(key, int_types):
            if key < 0 or key > INT_56_MASK:
                raise ValueError('key must be 56-bit non-negative integer')
            return _unpack64(expand_des_key(_pack56(key)))
        raise exc.ExpectedTypeError(key, 'bytes or int', 'key')
    key = _unpack56(key)
    return join_byte_values(
        (key >> shift & 127) << 1 for shift in _EXPAND_ITER)
Exemplo n.º 12
0
 def _norm_checksum(self, checksum, relaxed=False):
     raw = self._checksum_is_bytes
     if raw:
         if not isinstance(checksum, bytes):
             raise exc.ExpectedTypeError(checksum, 'bytes', 'checksum')
     else:
         if not isinstance(checksum, unicode):
             if isinstance(checksum, bytes) and relaxed:
                 warn('checksum should be unicode, not bytes',
                      PasslibHashWarning)
                 checksum = checksum.decode('ascii')
             else:
                 raise exc.ExpectedTypeError(checksum, 'unicode',
                                             'checksum')
     cc = self.checksum_size
     if cc and len(checksum) != cc:
         raise exc.ChecksumSizeError(self, raw=raw)
     if not raw:
         cs = self.checksum_chars
         if cs and any(c not in cs for c in checksum):
             raise ValueError('invalid characters in %s checksum' %
                              (self.name, ))
     return checksum
Exemplo n.º 13
0
def lookup_hash(digest, return_unknown=False):
    cache = _hash_info_cache
    try:
        return cache[digest]
    except (KeyError, TypeError):
        pass
    else:
        cache_by_name = True
        if isinstance(digest, unicode_or_bytes_types):
            name_list = _get_hash_aliases(digest)
            name = name_list[0]
            if name != digest:
                info = lookup_hash(name, return_unknown=return_unknown)
                if info.const is None:
                    return info
                cache[digest] = info
                return info
            const = _get_hash_const(name)
            if const is None:
                if return_unknown:
                    return HashInfo(None, name_list)
                raise exc.UnknownHashError(name)
        else:
            if isinstance(digest, HashInfo):
                return digest
        if callable(digest):
            const = digest
            name_list = _get_hash_aliases(const().name)
            name = name_list[0]
            other_const = _get_hash_const(name)
            if other_const is None:
                pass
            elif other_const is const:
                pass
            else:
                cache_by_name = False
        else:
            raise exc.ExpectedTypeError(digest, 'digest name or constructor',
                                        'digest')

    info = HashInfo(const, name_list)
    cache[const] = info
    if cache_by_name:
        for name in name_list:
            if name:
                cache[name] = info

    return info
Exemplo n.º 14
0
def shrink_des_key(key):
    if isinstance(key, bytes):
        if len(key) != 8:
            raise ValueError('key must be 8 bytes in size')
        return _pack56(shrink_des_key(_unpack64(key)))
    if isinstance(key, int_types):
        if key < 0 or key > INT_64_MASK:
            raise ValueError('key must be 64-bit non-negative integer')
    else:
        raise exc.ExpectedTypeError(key, 'bytes or int', 'key')
    key >>= 1
    result = 0
    offset = 0
    while offset < 56:
        result |= (key & 127) << offset
        key >>= 8
        offset += 7

    return result
Exemplo n.º 15
0
    def using(cls,
              digits=None,
              alg=None,
              period=None,
              issuer=None,
              wallet=None,
              now=None,
              **kwds):
        subcls = type('TOTP', (cls, ), {})

        def norm_param(attr, value):
            kwds = dict(key=_DUMMY_KEY, format='raw')
            kwds[attr] = value
            obj = subcls(**kwds)
            return getattr(obj, attr)

        if digits is not None:
            subcls.digits = norm_param('digits', digits)
        if alg is not None:
            subcls.alg = norm_param('alg', alg)
        if period is not None:
            subcls.period = norm_param('period', period)
        if issuer is not None:
            subcls.issuer = norm_param('issuer', issuer)
        if kwds:
            subcls.wallet = AppWallet(**kwds)
            if wallet:
                raise TypeError(
                    "'wallet' and 'secrets' keywords are mutually exclusive")
        else:
            if wallet is not None:
                if not isinstance(wallet, AppWallet):
                    raise exc.ExpectedTypeError(wallet, AppWallet, 'wallet')
                subcls.wallet = wallet
        if now is not None:
            subcls.now = staticmethod(now)
        return subcls
Exemplo n.º 16
0
 def key(self, value):
     if not isinstance(value, bytes):
         raise exc.ExpectedTypeError(value, bytes, 'key')
     self._key = value
     self._encrypted_key = self._keyed_hmac = None
     return
Exemplo n.º 17
0
 def _check_serial(value, param, minval=0):
     if not isinstance(value, int_types):
         raise exc.ExpectedTypeError(value, 'int', param)
     if value < minval:
         raise ValueError('%s must be >= %d' % (param, minval))
Exemplo n.º 18
0
def _resolve(hasher, param='value'):
    if is_crypt_handler(hasher):
        return hasher
    if isinstance(hasher, unicode_or_str):
        return get_crypt_handler(hasher)
    raise exc.ExpectedTypeError(hasher, unicode_or_str, param)