def _calc_checksum(self, secret): if isinstance(secret, unicode): secret = secret.encode("utf-8") # parse salt value try: salt_value = h64.decode_int12(self.salt.encode("ascii")) except ValueError: # pragma: no cover - caught by class raise 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")
def _raw_bsdi_crypt(secret, rounds, salt): """pure-python backend for bsdi_crypt""" # decode salt try: salt_value = h64.decode_int24(salt) except ValueError: # pragma: no cover - always caught by class raise ValueError("invalid salt") # gotta do something - no official policy since this predates unicode if isinstance(secret, unicode): secret = secret.encode("utf-8") assert isinstance(secret, bytes) # forbidding NULL char because underlying crypt() rejects them too. if _BNULL in secret: raise uh.exc.NullPasswordError(bsdi_crypt) # convert secret string into an integer key_value = _bsdi_secret_to_key(secret) # run data through des using input of 0 result = des_encrypt_int_block(key_value, 0, salt_value, rounds) # run h64 encode on result return h64big.encode_int64(result)
def _raw_des_crypt(secret, salt): """pure-python backed for des_crypt""" assert len(salt) == 2 # NOTE: some OSes will accept non-HASH64 characters in the salt, # but what value they assign these characters varies wildy, # so just rejecting them outright. # NOTE: the same goes for single-character salts... # some OSes duplicate the char, some insert a '.' char, # and openbsd does something which creates an invalid hash. try: salt_value = h64.decode_int12(salt) except ValueError: # pragma: no cover - always caught by class raise ValueError("invalid chars in salt") # gotta do something - no official policy since this predates unicode if isinstance(secret, unicode): secret = secret.encode("utf-8") assert isinstance(secret, bytes) # forbidding NULL char because underlying crypt() rejects them too. if _BNULL in secret: raise uh.exc.NullPasswordError(des_crypt) # convert first 8 bytes of secret string into an integer key_value = _crypt_secret_to_key(secret) # run data through des using input of 0 result = des_encrypt_int_block(key_value, 0, salt_value, 25) # run h64 encode on result return h64big.encode_int64(result)
def _bsdi_secret_to_key(secret): """covert secret to DES key used by bsdi_crypt""" key_value = _crypt_secret_to_key(secret) idx = 8 end = len(secret) while idx < end: next = idx+8 tmp_value = _crypt_secret_to_key(secret[idx:next]) key_value = des_encrypt_int_block(key_value, key_value) ^ tmp_value idx = next return key_value
def test_04_encrypt_ints(self): """test des_encrypt_int_block()""" from lib.passlib.utils.des import des_encrypt_int_block # run through test vectors for key, plaintext, correct in self.des_test_vectors: # test 64-bit key result = des_encrypt_int_block(key, plaintext) self.assertEqual(result, correct, "key=%r plaintext=%r:" % (key, plaintext)) # test with random parity bits for _ in range(20): key3 = self._random_parity(key) result = des_encrypt_int_block(key3, plaintext) self.assertEqual( result, correct, "key=%r rndparity(key)=%r plaintext=%r:" % (key, key3, plaintext)) # check invalid keys self.assertRaises(TypeError, des_encrypt_int_block, b('\x00'), 0) self.assertRaises(ValueError, des_encrypt_int_block, -1, 0) # check invalid input self.assertRaises(TypeError, des_encrypt_int_block, 0, b('\x00')) self.assertRaises(ValueError, des_encrypt_int_block, 0, -1) # check invalid salts self.assertRaises(ValueError, des_encrypt_int_block, 0, 0, salt=-1) self.assertRaises(ValueError, des_encrypt_int_block, 0, 0, salt=1 << 24) # check invalid rounds self.assertRaises(ValueError, des_encrypt_int_block, 0, 0, 0, rounds=0)