1import sys 2from test import support 3import unittest 4 5crypt = support.import_module('crypt') 6 7class CryptTestCase(unittest.TestCase): 8 9 def test_crypt(self): 10 cr = crypt.crypt('mypassword') 11 cr2 = crypt.crypt('mypassword', cr) 12 self.assertEqual(cr2, cr) 13 cr = crypt.crypt('mypassword', 'ab') 14 if cr is not None: 15 cr2 = crypt.crypt('mypassword', cr) 16 self.assertEqual(cr2, cr) 17 18 def test_salt(self): 19 self.assertEqual(len(crypt._saltchars), 64) 20 for method in crypt.methods: 21 salt = crypt.mksalt(method) 22 self.assertIn(len(salt) - method.salt_chars, {0, 1, 3, 4, 6, 7}) 23 if method.ident: 24 self.assertIn(method.ident, salt[:len(salt)-method.salt_chars]) 25 26 def test_saltedcrypt(self): 27 for method in crypt.methods: 28 cr = crypt.crypt('assword', method) 29 self.assertEqual(len(cr), method.total_size) 30 cr2 = crypt.crypt('assword', cr) 31 self.assertEqual(cr2, cr) 32 cr = crypt.crypt('assword', crypt.mksalt(method)) 33 self.assertEqual(len(cr), method.total_size) 34 35 def test_methods(self): 36 self.assertTrue(len(crypt.methods) >= 1) 37 if sys.platform.startswith('openbsd'): 38 self.assertEqual(crypt.methods, [crypt.METHOD_BLOWFISH]) 39 else: 40 self.assertEqual(crypt.methods[-1], crypt.METHOD_CRYPT) 41 42 @unittest.skipUnless(crypt.METHOD_SHA256 in crypt.methods or 43 crypt.METHOD_SHA512 in crypt.methods, 44 'requires support of SHA-2') 45 def test_sha2_rounds(self): 46 for method in (crypt.METHOD_SHA256, crypt.METHOD_SHA512): 47 for rounds in 1000, 10_000, 100_000: 48 salt = crypt.mksalt(method, rounds=rounds) 49 self.assertIn('$rounds=%d$' % rounds, salt) 50 self.assertEqual(len(salt) - method.salt_chars, 51 11 + len(str(rounds))) 52 cr = crypt.crypt('mypassword', salt) 53 self.assertTrue(cr) 54 cr2 = crypt.crypt('mypassword', cr) 55 self.assertEqual(cr2, cr) 56 57 @unittest.skipUnless(crypt.METHOD_BLOWFISH in crypt.methods, 58 'requires support of Blowfish') 59 def test_blowfish_rounds(self): 60 for log_rounds in range(4, 11): 61 salt = crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=1 << log_rounds) 62 self.assertIn('$%02d$' % log_rounds, salt) 63 self.assertIn(len(salt) - crypt.METHOD_BLOWFISH.salt_chars, {6, 7}) 64 cr = crypt.crypt('mypassword', salt) 65 self.assertTrue(cr) 66 cr2 = crypt.crypt('mypassword', cr) 67 self.assertEqual(cr2, cr) 68 69 def test_invalid_rounds(self): 70 for method in (crypt.METHOD_SHA256, crypt.METHOD_SHA512, 71 crypt.METHOD_BLOWFISH): 72 with self.assertRaises(TypeError): 73 crypt.mksalt(method, rounds='4096') 74 with self.assertRaises(TypeError): 75 crypt.mksalt(method, rounds=4096.0) 76 for rounds in (0, 1, -1, 1<<999): 77 with self.assertRaises(ValueError): 78 crypt.mksalt(method, rounds=rounds) 79 with self.assertRaises(ValueError): 80 crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=1000) 81 for method in (crypt.METHOD_CRYPT, crypt.METHOD_MD5): 82 with self.assertRaisesRegex(ValueError, 'support'): 83 crypt.mksalt(method, rounds=4096) 84 85 86if __name__ == "__main__": 87 unittest.main() 88