blob: d29e005fdad50670f4a27d78b201d2b832257489 [file] [log] [blame]
Serhiy Storchakaeab3ff72017-10-24 19:36:17 +03001import sys
Christian Heimesdd15f6c2008-03-16 00:07:10 +00002import unittest
R. David Murraya21e4ca2009-03-31 23:16:50 +00003
Roger E. Massefab8ab81996-12-20 22:36:52 +00004
Miss Islington (bot)e7ec9e02019-08-13 14:52:20 -07005try:
6 import crypt
7 IMPORT_ERROR = None
8except ImportError as ex:
9 crypt = None
10 IMPORT_ERROR = str(ex)
11
12
13@unittest.skipIf(crypt, 'This should only run on windows')
14class TestWhyCryptDidNotImport(unittest.TestCase):
15 def test_failure_only_for_windows(self):
16 self.assertEqual(sys.platform, 'win32')
17
18 def test_import_failure_message(self):
19 self.assertIn('not supported', IMPORT_ERROR)
20
21
22@unittest.skipUnless(crypt, 'Not supported on Windows')
Christian Heimesdd15f6c2008-03-16 00:07:10 +000023class CryptTestCase(unittest.TestCase):
24
25 def test_crypt(self):
Serhiy Storchakaeab3ff72017-10-24 19:36:17 +030026 cr = crypt.crypt('mypassword')
27 cr2 = crypt.crypt('mypassword', cr)
28 self.assertEqual(cr2, cr)
29 cr = crypt.crypt('mypassword', 'ab')
30 if cr is not None:
31 cr2 = crypt.crypt('mypassword', cr)
32 self.assertEqual(cr2, cr)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000033
Sean Reifscheidere2dfefb2011-02-22 10:55:44 +000034 def test_salt(self):
Brett Cannondaa57992011-02-22 21:48:06 +000035 self.assertEqual(len(crypt._saltchars), 64)
36 for method in crypt.methods:
Sean Reifscheidere2dfefb2011-02-22 10:55:44 +000037 salt = crypt.mksalt(method)
Serhiy Storchakaeab3ff72017-10-24 19:36:17 +030038 self.assertIn(len(salt) - method.salt_chars, {0, 1, 3, 4, 6, 7})
39 if method.ident:
40 self.assertIn(method.ident, salt[:len(salt)-method.salt_chars])
Sean Reifscheidere2dfefb2011-02-22 10:55:44 +000041
42 def test_saltedcrypt(self):
Brett Cannondaa57992011-02-22 21:48:06 +000043 for method in crypt.methods:
Serhiy Storchakaeab3ff72017-10-24 19:36:17 +030044 cr = crypt.crypt('assword', method)
45 self.assertEqual(len(cr), method.total_size)
46 cr2 = crypt.crypt('assword', cr)
47 self.assertEqual(cr2, cr)
48 cr = crypt.crypt('assword', crypt.mksalt(method))
49 self.assertEqual(len(cr), method.total_size)
Sean Reifscheidere2dfefb2011-02-22 10:55:44 +000050
51 def test_methods(self):
Brett Cannondaa57992011-02-22 21:48:06 +000052 self.assertTrue(len(crypt.methods) >= 1)
Serhiy Storchakaeab3ff72017-10-24 19:36:17 +030053 if sys.platform.startswith('openbsd'):
54 self.assertEqual(crypt.methods, [crypt.METHOD_BLOWFISH])
55 else:
56 self.assertEqual(crypt.methods[-1], crypt.METHOD_CRYPT)
57
Miss Islington (bot)e7ec9e02019-08-13 14:52:20 -070058 @unittest.skipUnless(
59 crypt
60 and (
61 crypt.METHOD_SHA256 in crypt.methods or crypt.METHOD_SHA512 in crypt.methods
62 ),
63 'requires support of SHA-2',
64 )
Serhiy Storchakacede8c92017-11-16 13:22:51 +020065 def test_sha2_rounds(self):
66 for method in (crypt.METHOD_SHA256, crypt.METHOD_SHA512):
67 for rounds in 1000, 10_000, 100_000:
68 salt = crypt.mksalt(method, rounds=rounds)
69 self.assertIn('$rounds=%d$' % rounds, salt)
70 self.assertEqual(len(salt) - method.salt_chars,
71 11 + len(str(rounds)))
72 cr = crypt.crypt('mypassword', salt)
73 self.assertTrue(cr)
74 cr2 = crypt.crypt('mypassword', cr)
75 self.assertEqual(cr2, cr)
76
Miss Islington (bot)e7ec9e02019-08-13 14:52:20 -070077 @unittest.skipUnless(
78 crypt and crypt.METHOD_BLOWFISH in crypt.methods, 'requires support of Blowfish'
79 )
Serhiy Storchakacede8c92017-11-16 13:22:51 +020080 def test_blowfish_rounds(self):
Serhiy Storchakaeab3ff72017-10-24 19:36:17 +030081 for log_rounds in range(4, 11):
Serhiy Storchakacede8c92017-11-16 13:22:51 +020082 salt = crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=1 << log_rounds)
Serhiy Storchakaeab3ff72017-10-24 19:36:17 +030083 self.assertIn('$%02d$' % log_rounds, salt)
84 self.assertIn(len(salt) - crypt.METHOD_BLOWFISH.salt_chars, {6, 7})
85 cr = crypt.crypt('mypassword', salt)
86 self.assertTrue(cr)
87 cr2 = crypt.crypt('mypassword', cr)
88 self.assertEqual(cr2, cr)
89
Serhiy Storchakacede8c92017-11-16 13:22:51 +020090 def test_invalid_rounds(self):
91 for method in (crypt.METHOD_SHA256, crypt.METHOD_SHA512,
92 crypt.METHOD_BLOWFISH):
93 with self.assertRaises(TypeError):
94 crypt.mksalt(method, rounds='4096')
95 with self.assertRaises(TypeError):
96 crypt.mksalt(method, rounds=4096.0)
97 for rounds in (0, 1, -1, 1<<999):
98 with self.assertRaises(ValueError):
99 crypt.mksalt(method, rounds=rounds)
100 with self.assertRaises(ValueError):
101 crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=1000)
102 for method in (crypt.METHOD_CRYPT, crypt.METHOD_MD5):
103 with self.assertRaisesRegex(ValueError, 'support'):
104 crypt.mksalt(method, rounds=4096)
Serhiy Storchakaeab3ff72017-10-24 19:36:17 +0300105
Sean Reifscheidere2dfefb2011-02-22 10:55:44 +0000106
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000107if __name__ == "__main__":
Ezio Melotti90bbbd12013-01-11 05:18:45 +0200108 unittest.main()