Esempio n. 1
0
    def raw(cls, secret, user):
        """encode password using mscash v1 algorithm

        :arg secret: secret as unicode or utf-8 encoded bytes
        :arg user: username to use as salt

        :returns: returns string of raw bytes
        """
        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()
Esempio n. 2
0
    def __init__(self, wordset=None, words=None, sep=None, **kwds):

        # load wordset
        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
                assert wordset
            words = default_wordsets[wordset]
        self.wordset = wordset

        # init words
        if not isinstance(words, _sequence_types):
            words = tuple(words)
        _ensure_unique(words, param="words")
        self.words = words

        # init separator
        if sep is None:
            sep = self.sep
        sep = to_unicode(sep, param="sep")
        self.sep = sep

        # hand off to parent
        super(PhraseGenerator, self).__init__(**kwds)
Esempio n. 3
0
 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.upper())
    def test_02_from_string(self):
        """test CryptPolicy.from_string() constructor"""
        # test "\n" linesep
        policy = CryptPolicy.from_string(self.sample_config_1s)
        self.assertEqual(policy.to_dict(), self.sample_config_1pd)

        # test "\r\n" linesep
        policy = CryptPolicy.from_string(
            self.sample_config_1s.replace("\n", "\r\n"))
        self.assertEqual(policy.to_dict(), self.sample_config_1pd)

        # test with unicode
        data = to_unicode(self.sample_config_1s)
        policy = CryptPolicy.from_string(data)
        self.assertEqual(policy.to_dict(), self.sample_config_1pd)

        # test with non-ascii-compatible encoding
        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)

        # test category specific options
        policy = CryptPolicy.from_string(self.sample_config_4s)
        self.assertEqual(policy.to_dict(), self.sample_config_4pd)
Esempio n. 5
0
 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)
Esempio n. 6
0
    def raw(cls, secret, user):
        """encode password using msdcc v2 algorithm

        :type secret: unicode or utf-8 bytes
        :arg secret: secret

        :type user: str
        :arg user: username to use as salt

        :returns: returns string of raw bytes
        """
        from lib.passlib.utils.pbkdf2 import pbkdf2
        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(tmp, user, 10240, 16, 'hmac-sha1')
Esempio n. 7
0
 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)
Esempio n. 8
0
 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)
Esempio n. 9
0
 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)
Esempio n. 10
0
    def raw(cls, secret):
        """encode password using MD4-based NTHASH algorithm

        :arg secret: secret as unicode or utf-8 encoded bytes

        :returns: returns string of raw bytes
        """
        secret = to_unicode(secret, "utf-8", param="secret")
        # XXX: found refs that say only first 128 chars are used.
        return md4(secret.encode("utf-16-le")).digest()
Esempio n. 11
0
 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,
     )
Esempio n. 12
0
 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,
     )
Esempio n. 13
0
 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
     assert cs
     return cls(checksum=data[:cs], salt=data[cs:])
Esempio n. 14
0
 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"),
                )
Esempio n. 15
0
 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)
Esempio n. 16
0
    def from_string(cls, hash):
        # basic format this parses -
        # $5$[rounds=<rounds>$]<salt>[$<checksum>]

        # TODO: this *could* use uh.parse_mc3(), except that the rounds
        # portion has a slightly different grammar.

        # convert to unicode, check for ident prefix, split on dollar signs.
        hash = to_unicode(hash, "ascii", "hash")
        ident = cls.ident
        if not hash.startswith(ident):
            raise uh.exc.InvalidHashError(cls)
        assert len(ident) == 3
        parts = hash[3:].split(_UDOLLAR)

        # extract rounds value
        if parts[0].startswith(_UROUNDS):
            assert len(_UROUNDS) == 7
            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

        # rest should be salt and checksum
        if len(parts) == 2:
            salt, chk = parts
        elif len(parts) == 1:
            salt = parts[0]
            chk = None
        else:
            raise uh.exc.MalformedHashError(cls)

        # return new object
        return cls(
            rounds=rounds,
            salt=salt,
            checksum=chk or None,
            implicit_rounds=implicit_rounds,
            relaxed=not chk, # NOTE: relaxing parsing for config strings
                             # so that out-of-range rounds are clipped,
                             # since SHA2-Crypt spec treats them this way.
            )
Esempio n. 17
0
    def from_string(cls, hash):
        # basic format this parses -
        # $5$[rounds=<rounds>$]<salt>[$<checksum>]

        # TODO: this *could* use uh.parse_mc3(), except that the rounds
        # portion has a slightly different grammar.

        # convert to unicode, check for ident prefix, split on dollar signs.
        hash = to_unicode(hash, "ascii", "hash")
        ident = cls.ident
        if not hash.startswith(ident):
            raise uh.exc.InvalidHashError(cls)
        assert len(ident) == 3
        parts = hash[3:].split(_UDOLLAR)

        # extract rounds value
        if parts[0].startswith(_UROUNDS):
            assert len(_UROUNDS) == 7
            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

        # rest should be salt and checksum
        if len(parts) == 2:
            salt, chk = parts
        elif len(parts) == 1:
            salt = parts[0]
            chk = None
        else:
            raise uh.exc.MalformedHashError(cls)

        # return new object
        return cls(
            rounds=rounds,
            salt=salt,
            checksum=chk or None,
            implicit_rounds=implicit_rounds,
            relaxed=not chk,  # NOTE: relaxing parsing for config strings
            # so that out-of-range rounds are clipped,
            # since SHA2-Crypt spec treats them this way.
        )
Esempio n. 18
0
    def __init__(self, chars=None, charset=None, **kwds):

        # init chars and charset
        if chars:
            if charset:
                raise TypeError("`chars` and `charset` are mutually exclusive")
        else:
            if not charset:
                charset = self.charset
                assert charset
            chars = default_charsets[charset]
        self.charset = charset
        chars = to_unicode(chars, param="chars")
        _ensure_unique(chars, param="chars")
        self.chars = chars

        # hand off to parent
        super(WordGenerator, self).__init__(**kwds)
Esempio n. 19
0
 def _calc_checksum(self, secret):
     # FIXME: not sure how oracle handles unicode.
     #        online docs about 10g hash indicate it puts ascii chars
     #        in a 2-byte encoding w/ the high byte set to null.
     #        they don't say how it handles other chars, or what encoding.
     #
     #        so for now, encoding secret & user to utf-16-be,
     #        since that fits, and if secret/user is bytes,
     #        we assume utf-8, and decode first.
     #
     #        this whole mess really needs someone w/ an oracle system,
     #        and some answers :)
     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 test_02_from_string(self):
        """test CryptPolicy.from_string() constructor"""
        # test "\n" linesep
        policy = CryptPolicy.from_string(self.sample_config_1s)
        self.assertEqual(policy.to_dict(), self.sample_config_1pd)

        # test "\r\n" linesep
        policy = CryptPolicy.from_string(
            self.sample_config_1s.replace("\n","\r\n"))
        self.assertEqual(policy.to_dict(), self.sample_config_1pd)

        # test with unicode
        data = to_unicode(self.sample_config_1s)
        policy = CryptPolicy.from_string(data)
        self.assertEqual(policy.to_dict(), self.sample_config_1pd)

        # test with non-ascii-compatible encoding
        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)

        # test category specific options
        policy = CryptPolicy.from_string(self.sample_config_4s)
        self.assertEqual(policy.to_dict(), self.sample_config_4pd)
Esempio n. 21
0
    def test_to_unicode(self):
        """test to_unicode()"""
        from lib.passlib.utils import to_unicode

        # check unicode inputs
        self.assertEqual(to_unicode(u('abc')), u('abc'))
        self.assertEqual(to_unicode(u('\x00\xff')), u('\x00\xff'))

        # check unicode input ignores encoding
        self.assertEqual(to_unicode(u('\x00\xff'), "ascii"), u('\x00\xff'))

        # check bytes input
        self.assertEqual(to_unicode(b('abc')), u('abc'))
        self.assertEqual(to_unicode(b('\x00\xc3\xbf')), u('\x00\xff'))
        self.assertEqual(to_unicode(b('\x00\xff'), 'latin-1'), u('\x00\xff'))
        self.assertRaises(ValueError, to_unicode, b('\x00\xff'))

        # check other
        self.assertRaises(AssertionError, to_unicode, 'abc', None)
        self.assertRaises(TypeError, to_unicode, None)
Esempio n. 22
0
    def from_string(cls, hash):
        hash = to_unicode(hash, "ascii", "hash")

        #
        # detect if hash specifies rounds value.
        # if so, parse and validate it.
        # by end, set 'rounds' to int value, and 'tail' containing salt+chk
        #
        if hash.startswith(u("$md5$")):
            rounds = 0
            salt_idx = 5
        elif 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:
                # NOTE: not sure if this is forbidden by spec or not;
                #      but allowing it would complicate things,
                #      and it should never occur anyways.
                raise uh.exc.MalformedHashError(cls, "explicit zero rounds")
            salt_idx = idx+1
        else:
            raise uh.exc.InvalidHashError(cls)

        #
        # salt/checksum separation is kinda weird,
        # to deal cleanly with some backward-compatible workarounds
        # implemented by original implementation.
        #
        chk_idx = hash.rfind(u("$"), salt_idx)
        if chk_idx == -1:
            # ''-config for $-hash
            salt = hash[salt_idx:]
            chk = None
            bare_salt = True
        elif chk_idx == len(hash)-1:
            if chk_idx > salt_idx and hash[-2] == u("$"):
                raise uh.exc.MalformedHashError(cls, "too many '$' separators")
            # $-config for $$-hash
            salt = hash[salt_idx:-1]
            chk = None
            bare_salt = False
        elif chk_idx > 0 and hash[chk_idx-1] == u("$"):
            # $$-hash
            salt = hash[salt_idx:chk_idx-1]
            chk = hash[chk_idx+1:]
            bare_salt = False
        else:
            # $-hash
            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,
        )
Esempio n. 23
0
 def from_string(cls, hash):
     hash = to_unicode(hash, "ascii", "hash")
     if len(hash) < 2:
         raise uh.exc.InvalidHashError(cls)
     salt = int(hash[:2]) # may throw ValueError
     return cls(salt=salt, checksum=hash[2:].upper())
Esempio n. 24
0
 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)
Esempio n. 25
0
 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)
Esempio n. 26
0
    def from_string(cls, hash):
        hash = to_unicode(hash, "ascii", "hash")

        #
        # detect if hash specifies rounds value.
        # if so, parse and validate it.
        # by end, set 'rounds' to int value, and 'tail' containing salt+chk
        #
        if hash.startswith(u("$md5$")):
            rounds = 0
            salt_idx = 5
        elif 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:
                # NOTE: not sure if this is forbidden by spec or not;
                #      but allowing it would complicate things,
                #      and it should never occur anyways.
                raise uh.exc.MalformedHashError(cls, "explicit zero rounds")
            salt_idx = idx + 1
        else:
            raise uh.exc.InvalidHashError(cls)

        #
        # salt/checksum separation is kinda weird,
        # to deal cleanly with some backward-compatible workarounds
        # implemented by original implementation.
        #
        chk_idx = hash.rfind(u("$"), salt_idx)
        if chk_idx == -1:
            # ''-config for $-hash
            salt = hash[salt_idx:]
            chk = None
            bare_salt = True
        elif chk_idx == len(hash) - 1:
            if chk_idx > salt_idx and hash[-2] == u("$"):
                raise uh.exc.MalformedHashError(cls, "too many '$' separators")
            # $-config for $$-hash
            salt = hash[salt_idx:-1]
            chk = None
            bare_salt = False
        elif chk_idx > 0 and hash[chk_idx - 1] == u("$"):
            # $$-hash
            salt = hash[salt_idx:chk_idx - 1]
            chk = hash[chk_idx + 1:]
            bare_salt = False
        else:
            # $-hash
            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,
        )