Beispiel #1
0
def b64s_decode(data):
    """
    decode from shortened base64 format which omits padding & whitespace.
    uses default ``+/`` altchars.
    """
    if isinstance(data, unicode):
        # needs bytes for replace() call, but want to accept ascii-unicode ala a2b_base64()
        try:
            data = data.encode("ascii")
        except UnicodeEncodeError:
            raise suppress_cause(
                ValueError(
                    "string argument should contain only ASCII characters"))
    off = len(data) & 3
    if off == 0:
        pass
    elif off == 2:
        data += _BASE64_PAD2
    elif off == 3:
        data += _BASE64_PAD1
    else:  # off == 1
        raise ValueError("invalid base64 input")
    try:
        return a2b_base64(data)
    except _BinAsciiError as err:
        raise suppress_cause(TypeError(err))
Beispiel #2
0
    def _calc_checksum(self, secret):
        if isinstance(secret, unicode):
            secret = secret.encode("utf-8")

        # check for truncation (during .hash() calls only)
        if self.use_defaults:
            self._check_truncate_policy(secret)

        # parse salt value
        try:
            salt_value = h64.decode_int12(self.salt.encode("ascii"))
        except ValueError:  # pragma: no cover - caught by class
            raise suppress_cause(ValueError("invalid chars in salt"))

        # convert first 8 byts of secret string into an integer,
        key1 = _crypt_secret_to_key(secret)

        # run data through des using input of 0
        result1 = des_encrypt_int_block(key1, 0, salt_value, 20)

        # convert next 8 bytes of secret string into integer (key=0 if secret < 8 chars)
        key2 = _crypt_secret_to_key(secret[8:16])

        # run data through des using input of 0
        result2 = des_encrypt_int_block(key2, 0, salt_value, 5)

        # done
        chk = h64big.encode_int64(result1) + h64big.encode_int64(result2)
        return chk.decode("ascii")
Beispiel #3
0
    def _calc_checksum(self, secret):
        if isinstance(secret, unicode):
            secret = secret.encode("utf-8")

        # check for truncation (during .hash() calls only)
        if self.use_defaults:
            self._check_truncate_policy(secret)

        # parse salt value
        try:
            salt_value = h64.decode_int12(self.salt.encode("ascii"))
        except ValueError: # pragma: no cover - caught by class
            raise suppress_cause(ValueError("invalid chars in salt"))

        # convert first 8 byts of secret string into an integer,
        key1 = _crypt_secret_to_key(secret)

        # run data through des using input of 0
        result1 = des_encrypt_int_block(key1, 0, salt_value, 20)

        # convert next 8 bytes of secret string into integer (key=0 if secret < 8 chars)
        key2 = _crypt_secret_to_key(secret[8:16])

        # run data through des using input of 0
        result2 = des_encrypt_int_block(key2, 0, salt_value, 5)

        # done
        chk = h64big.encode_int64(result1) + h64big.encode_int64(result2)
        return chk.decode("ascii")
Beispiel #4
0
 def to_string(self):
     ident = self.ident
     if ident == IDENT_SCRYPT:
         return "$scrypt$ln=%d,r=%d,p=%d$%s$%s" % (
             self.rounds,
             self.block_size,
             self.parallelism,
             bascii_to_str(b64s_encode(self.salt)),
             bascii_to_str(b64s_encode(self.checksum)),
         )
     else:
         assert ident == IDENT_7
         salt = self.salt
         try:
             salt.decode("ascii")
         except UnicodeDecodeError:
             raise suppress_cause(
                 NotImplementedError(
                     "scrypt $7$ hashes dont support non-ascii salts"))
         return bascii_to_str(b"".join([
             b"$7$",
             h64.encode_int6(self.rounds),
             h64.encode_int30(self.block_size),
             h64.encode_int30(self.parallelism), self.salt, b"$",
             h64.encode_bytes(self.checksum)
         ]))
Beispiel #5
0
def ab64_decode(data):
    """
    decode from shortened base64 format which omits padding & whitespace.
    uses custom ``./`` altchars, but supports decoding normal ``+/`` altchars as well.

    it is primarily used by Passlib's custom pbkdf2 hashes.
    """
    if isinstance(data, unicode):
        # needs bytes for replace() call, but want to accept ascii-unicode ala a2b_base64()
        try:
            data = data.encode("ascii")
        except UnicodeEncodeError:
            raise suppress_cause(ValueError("string argument should contain only ASCII characters"))
    return b64s_decode(data.replace(b".", b"+"))
Beispiel #6
0
    def using(cls, block_size=None, **kwds):
        subcls = super(scrypt, cls).using(**kwds)
        if block_size is not None:
            if isinstance(block_size, uh.native_string_types):
                block_size = int(block_size)
            subcls.block_size = subcls._norm_block_size(block_size, relaxed=kwds.get("relaxed"))

        # make sure param combination is valid for scrypt()
        try:
            _scrypt.validate(1 << cls.default_rounds, cls.block_size, cls.parallelism)
        except ValueError as err:
            raise suppress_cause(ValueError("scrypt: invalid settings combination: " + str(err)))

        return subcls
Beispiel #7
0
def ab64_decode(data):
    """
    decode from shortened base64 format which omits padding & whitespace.
    uses custom ``./`` altchars, but supports decoding normal ``+/`` altchars as well.

    it is primarily used by Passlib's custom pbkdf2 hashes.
    """
    if isinstance(data, unicode):
        # needs bytes for replace() call, but want to accept ascii-unicode ala a2b_base64()
        try:
            data = data.encode("ascii")
        except UnicodeEncodeError:
            raise suppress_cause(ValueError("string argument should contain only ASCII characters"))
    return b64s_decode(data.replace(b".", b"+"))
Beispiel #8
0
def b64s_decode(data):
    """
    decode from shortened base64 format which omits padding & whitespace.
    uses default ``+/`` altchars.
    """
    if isinstance(data, unicode):
        # needs bytes for replace() call, but want to accept ascii-unicode ala a2b_base64()
        try:
            data = data.encode("ascii")
        except UnicodeEncodeError:
            raise suppress_cause(ValueError("string argument should contain only ASCII characters"))
    off = len(data) & 3
    if off == 0:
        pass
    elif off == 2:
        data += _BASE64_PAD2
    elif off == 3:
        data += _BASE64_PAD1
    else:  # off == 1
        raise ValueError("invalid base64 input")
    try:
        return a2b_base64(data)
    except _BinAsciiError as err:
        raise suppress_cause(TypeError(err))
        if not os.path.exists(source_path):
            raise EnvironmentError("django source path not found: %r" %
                                   source_path)
        if not all(
                os.path.exists(os.path.join(source_path, name))
                for name in ["django", "tests"]):
            raise EnvironmentError("invalid django source path: %r" %
                                   source_path)
        log.info("using django tests from source path: %r", source_path)
        tests_path = os.path.join(source_path, "tests")
        sys.path.insert(0, tests_path)
        try:
            from auth_tests import test_hashers as test_hashers_mod
        except ImportError as err:
            raise suppress_cause(
                EnvironmentError("error trying to import django tests "
                                 "from source path (%r): %r" %
                                 (source_path, err)))
        finally:
            sys.path.remove(tests_path)

    else:
        hashers_skip_msg = "requires PASSLIB_TESTS_DJANGO_SOURCE_PATH to be set"

        if TEST_MODE("full"):
            # print warning so user knows what's happening
            sys.stderr.write(
                "\nWARNING: $PASSLIB_TESTS_DJANGO_SOURCE_PATH is not set; "
                "can't run Django's own unittests against passlib.ext.django\n"
            )

elif DJANGO_VERSION:
    source_path = os.environ.get("PASSLIB_TESTS_DJANGO_SOURCE_PATH")

    if source_path:
        if not os.path.exists(source_path):
            raise EnvironmentError("django source path not found: %r" % source_path)
        if not all(os.path.exists(os.path.join(source_path, name))
                   for name in ["django", "tests"]):
            raise EnvironmentError("invalid django source path: %r" % source_path)
        log.info("using django tests from source path: %r", source_path)
        tests_path = os.path.join(source_path, "tests")
        sys.path.insert(0, tests_path)
        try:
            from auth_tests import test_hashers as test_hashers_mod
        except ImportError as err:
            raise suppress_cause(
                EnvironmentError("error trying to import django tests "
                                 "from source path (%r): %r" %
                                 (source_path, err)))
        finally:
            sys.path.remove(tests_path)

    else:
        hashers_skip_msg = "requires PASSLIB_TESTS_DJANGO_SOURCE_PATH to be set"

        if TEST_MODE("full"):
            # print warning so user knows what's happening
            sys.stderr.write("\nWARNING: $PASSLIB_TESTS_DJANGO_SOURCE_PATH is not set; "
                             "can't run Django's own unittests against passlib.ext.django\n")

elif DJANGO_VERSION:
    hashers_skip_msg = "django version too old"