def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') ident = cls.ident if not hash.startswith(ident): raise uh.exc.InvalidHashError(cls) parts = hash[3:].split(_UDOLLAR) if parts[0].startswith(_UROUNDS): rounds = parts.pop(0)[7:] if rounds.startswith(_UZERO) and rounds != _UZERO: raise uh.exc.ZeroPaddedRoundsError(cls) rounds = int(rounds) implicit_rounds = False else: rounds = 5000 implicit_rounds = True if len(parts) == 2: salt, chk = parts else: if len(parts) == 1: salt = parts[0] chk = None else: raise uh.exc.MalformedHashError(cls) return cls(rounds=rounds, salt=salt, checksum=chk or None, implicit_rounds=implicit_rounds)
def _parse_ident(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') for ident in cls.ident_values: if hash.startswith(ident): return (ident, hash[len(ident):]) raise exc.InvalidHashError(cls)
def parse_mc3(hash, prefix, sep=_UDOLLAR, rounds_base=10, default_rounds=None, handler=None): hash = to_unicode(hash, 'ascii', 'hash') if not hash.startswith(prefix): raise exc.InvalidHashError(handler) parts = hash[len(prefix):].split(sep) if len(parts) == 3: rounds, salt, chk = parts else: if len(parts) == 2: rounds, salt = parts chk = None else: raise exc.MalformedHashError(handler) if rounds.startswith(_UZERO) and rounds != _UZERO: raise exc.ZeroPaddedRoundsError(handler) else: if rounds: rounds = int(rounds, rounds_base) else: if default_rounds is None: raise exc.MalformedHashError(handler, 'empty rounds field') else: rounds = default_rounds return (rounds, salt, chk or None)
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') m = cls._hash_regex.match(hash) if not m: raise uh.exc.InvalidHashError(cls) salt, chk = m.group('salt', 'chk') return cls(salt=salt, checksum=chk)
def from_uri(cls, uri): uri = to_unicode(uri, param='uri').strip() result = urlparse(uri) if result.scheme != 'otpauth': raise cls._uri_parse_error('wrong uri scheme') cls._check_otp_type(result.netloc) return cls._from_parsed_uri(result)
def _calc_checksum(self, secret): if isinstance(secret, bytes): secret = secret.decode('utf-8') user = to_unicode(self.user, 'utf-8', param='user') input = (user + secret).upper().encode('utf-16-be') hash = des_cbc_encrypt(ORACLE10_MAGIC, input) hash = des_cbc_encrypt(hash, input) return hexlify(hash).decode('ascii').upper()
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') ident = cls.ident if not hash.startswith(ident): raise uh.exc.InvalidHashError(cls) data = b64decode(hash[len(ident):].encode('ascii')) salt, chk = data[:16], data[16:] return cls(salt=salt, checksum=chk)
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') if not hash.startswith(cls.django_prefix): raise uh.exc.InvalidHashError(cls) bhash = hash[len(cls.django_prefix):] if not bhash.startswith('$2'): raise uh.exc.MalformedHashError(cls) return super(django_bcrypt_sha256, cls).from_string(bhash)
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') m = cls._hash_regex.match(hash) if not m: raise uh.exc.InvalidHashError(cls) rounds, salt, chk = m.group('rounds', 'salt', 'chk') return cls(rounds=h64.decode_int24(rounds.encode('ascii')), salt=salt, checksum=chk)
def from_string(cls, hash, **context): hash = to_unicode(hash, 'ascii', 'hash') hash = cls._norm_hash(hash) prefix = cls._hash_prefix if prefix: if hash.startswith(prefix): hash = hash[len(prefix):] else: raise exc.InvalidHashError(cls) return cls(checksum=hash, **context)
def from_source(cls, source): if isinstance(source, TOTP): if cls.wallet == source.wallet: return source source = source.to_dict(encrypt=False) if isinstance(source, dict): return cls.from_dict(source) source = to_unicode(source, param='totp source') if source.startswith('otpauth://'): return cls.from_uri(source) return cls.from_json(source)
def test_90_decode(self): from otp.ai.passlib.utils import to_unicode, to_bytes handler = self.handler for secret, hash in self.known_correct_hashes: usecret = to_unicode(secret) bsecret = to_bytes(secret) self.assertEqual(handler.decode(hash), usecret) self.assertEqual(handler.decode(hash, None), bsecret) self.assertRaises(UnicodeDecodeError, handler.decode, '0958EDC8A9F495F6F8A5FD', 'ascii') return
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, ))
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') m = cls._hash_regex.match(hash) if not m: raise uh.exc.InvalidHashError(cls) try: data = b64decode(m.group('tmp').encode('ascii')) except TypeError: raise uh.exc.MalformedHashError(cls) cs = cls.checksum_size return cls(checksum=data[:cs], salt=data[cs:])
def parse_mc2(hash, prefix, sep=_UDOLLAR, handler=None): hash = to_unicode(hash, 'ascii', 'hash') if not hash.startswith(prefix): raise exc.InvalidHashError(handler) parts = hash[len(prefix):].split(sep) if len(parts) == 2: salt, chk = parts return (salt, chk or None) if len(parts) == 1: return (parts[0], None) raise exc.MalformedHashError(handler) return
def __init__(self, chars=None, charset=None, **kwds): if chars: if charset: raise TypeError('`chars` and `charset` are mutually exclusive') else: if not charset: charset = self.charset chars = default_charsets[charset] self.charset = charset chars = to_unicode(chars, param='chars') _ensure_unique(chars, param='chars') self.chars = chars super(WordGenerator, self).__init__(**kwds)
def normalize_token(self_or_cls, token): digits = self_or_cls.digits if isinstance(token, int_types): token = u('%0*d') % (digits, token) else: token = to_unicode(token, param='token') token = _clean_re.sub(u(''), token) if not token.isdigit(): raise MalformedTokenError( 'Token must contain only the digits 0-9') if len(token) != digits: raise MalformedTokenError('Token must have exactly %d digits' % digits) return token
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') if not hash.startswith(cls.prefix): raise uh.exc.InvalidHashError(cls) m = cls._hash_re.match(hash) if not m: raise uh.exc.MalformedHashError(cls) rounds = m.group('rounds') if rounds.startswith(uh._UZERO) and rounds != uh._UZERO: raise uh.exc.ZeroPaddedRoundsError(cls) return cls(ident=m.group('variant'), rounds=int(rounds), salt=m.group('salt'), checksum=m.group('digest'))
def test_02_from_string(self): policy = CryptPolicy.from_string(self.sample_config_1s) self.assertEqual(policy.to_dict(), self.sample_config_1pd) policy = CryptPolicy.from_string( self.sample_config_1s.replace('\n', '\r\n')) self.assertEqual(policy.to_dict(), self.sample_config_1pd) data = to_unicode(self.sample_config_1s) policy = CryptPolicy.from_string(data) self.assertEqual(policy.to_dict(), self.sample_config_1pd) uc2 = to_bytes(self.sample_config_1s, 'utf-16', source_encoding='utf-8') policy = CryptPolicy.from_string(uc2, encoding='utf-16') self.assertEqual(policy.to_dict(), self.sample_config_1pd) policy = CryptPolicy.from_string(self.sample_config_4s) self.assertEqual(policy.to_dict(), self.sample_config_4pd)
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') m = cls._hash_regex.match(hash) if not m: raise uh.exc.InvalidHashError(cls) variant, salt_size, rounds, data = m.group(1, 2, 3, 4) variant = int(variant) salt_size = int(salt_size) rounds = int(rounds) try: data = b64decode(data.encode('ascii')) except TypeError: raise uh.exc.MalformedHashError(cls) salt = data[:salt_size] chk = data[salt_size:] return cls(salt=salt, checksum=chk, rounds=rounds, variant=variant)
def test_to_unicode(self): from otp.ai.passlib.utils import to_unicode self.assertEqual(to_unicode(u('abc')), u('abc')) self.assertEqual(to_unicode(u('\x00\xff')), u('\x00\xff')) self.assertEqual(to_unicode(u('\x00\xff'), 'ascii'), u('\x00\xff')) self.assertEqual(to_unicode('abc'), u('abc')) self.assertEqual(to_unicode('\x00\xc3\xbf'), u('\x00\xff')) self.assertEqual(to_unicode('\x00\xff', 'latin-1'), u('\x00\xff')) self.assertRaises(ValueError, to_unicode, '\x00\xff') self.assertRaises(AssertionError, to_unicode, 'abc', None) self.assertRaises(TypeError, to_unicode, None) return
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') if hash.startswith(u('$md5$')): rounds = 0 salt_idx = 5 else: if hash.startswith(u('$md5,rounds=')): idx = hash.find(u('$'), 12) if idx == -1: raise uh.exc.MalformedHashError(cls, 'unexpected end of rounds') rstr = hash[12:idx] try: rounds = int(rstr) except ValueError: raise uh.exc.MalformedHashError(cls, 'bad rounds') if rstr != unicode(rounds): raise uh.exc.ZeroPaddedRoundsError(cls) if rounds == 0: raise uh.exc.MalformedHashError(cls, 'explicit zero rounds') salt_idx = idx + 1 else: raise uh.exc.InvalidHashError(cls) chk_idx = hash.rfind(u('$'), salt_idx) if chk_idx == -1: salt = hash[salt_idx:] chk = None bare_salt = True else: if chk_idx == len(hash) - 1: if chk_idx > salt_idx and hash[(-2)] == u('$'): raise uh.exc.MalformedHashError(cls, "too many '$' separators") salt = hash[salt_idx:-1] chk = None bare_salt = False else: if chk_idx > 0 and hash[(chk_idx - 1)] == u('$'): salt = hash[salt_idx:chk_idx - 1] chk = hash[chk_idx + 1:] bare_salt = False else: salt = hash[salt_idx:chk_idx] chk = hash[chk_idx + 1:] bare_salt = True return cls(rounds=rounds, salt=salt, checksum=chk, bare_salt=bare_salt)
def __init__(self, wordset=None, words=None, sep=None, **kwds): if words is not None: if wordset is not None: raise TypeError('`words` and `wordset` are mutually exclusive') else: if wordset is None: wordset = self.wordset words = default_wordsets[wordset] self.wordset = wordset if not isinstance(words, _sequence_types): words = tuple(words) _ensure_unique(words, param='words') self.words = words if sep is None: sep = self.sep sep = to_unicode(sep, param='sep') self.sep = sep super(PhraseGenerator, self).__init__(**kwds) return
def load(self, source, update=False, section='passlib', encoding='utf-8'): parse_keys = True if isinstance(source, unicode_or_bytes_types): if PY3: source = to_unicode(source, encoding, param='source') else: source = to_bytes(source, 'utf-8', source_encoding=encoding, param='source') source = self._parse_ini_stream( NativeStringIO(source), section, '<string passed to CryptContext.load()>') else: if isinstance(source, CryptContext): source = dict(source._config.iter_config(resolve=True)) parse_keys = False else: if not hasattr(source, 'items'): raise ExpectedTypeError(source, 'string or dict', 'source') if parse_keys: parse = self._parse_config_key source = dict( (parse(key), value) for key, value in iteritems(source)) if update and self._config is not None: if not source: return tmp = source source = dict(self._config.iter_config(resolve=True)) source.update(tmp) config = _CryptConfig(source) self._config = config self._reset_dummy_verify() self._get_record = config.get_record self._identify_record = config.identify_record if config.context_kwds: self.__dict__.pop('_strip_unused_context_kwds', None) else: self._strip_unused_context_kwds = None return
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') salt, chk = hash[:2], hash[2:] return cls(salt=salt, checksum=chk or None)
def from_string(cls, hash): hash = to_unicode(hash, 'ascii', 'hash') if len(hash) < 2: raise uh.exc.InvalidHashError(cls) salt = int(hash[:2]) return cls(salt=salt, checksum=hash[2:].upper())
def from_json(cls, source): source = to_unicode(source, param='json source') return cls.from_dict(json.loads(source))
def raw(cls, secret, user): from otp.ai.passlib.crypto.digest import pbkdf2_hmac secret = to_unicode(secret, 'utf-8', param='secret').encode('utf-16-le') user = to_unicode(user, 'utf-8', param='user').lower().encode('utf-16-le') tmp = md4(md4(secret).digest() + user).digest() return pbkdf2_hmac('sha1', tmp, user, 10240, 16)
def raw(cls, secret): secret = to_unicode(secret, 'utf-8', param='secret') return md4(secret.encode('utf-16-le')).digest()
def raw(cls, secret, user): secret = to_unicode(secret, 'utf-8', param='secret').encode('utf-16-le') user = to_unicode(user, 'utf-8', param='user').lower().encode('utf-16-le') return md4(md4(secret).digest() + user).digest()