diff options
Diffstat (limited to 'Lib/test/test_hmac.py')
-rw-r--r-- | Lib/test/test_hmac.py | 197 |
1 files changed, 125 insertions, 72 deletions
diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py index 1f3ec4c..7a52e39 100644 --- a/Lib/test/test_hmac.py +++ b/Lib/test/test_hmac.py @@ -8,6 +8,13 @@ import warnings from test.support import hashlib_helper +try: + from _hashlib import HMAC as C_HMAC + from _hashlib import hmac_new as c_hmac_new +except ImportError: + C_HMAC = None + c_hmac_new = None + def ignore_warning(func): @functools.wraps(func) @@ -21,34 +28,91 @@ def ignore_warning(func): class TestVectorsTestCase(unittest.TestCase): - @hashlib_helper.requires_hashdigest('md5', openssl=True) - def test_md5_vectors(self): - # Test the HMAC module against test vectors from the RFC. + def asssert_hmac( + self, key, data, digest, hashfunc, hashname, digest_size, block_size + ): + h = hmac.HMAC(key, data, digestmod=hashfunc) + self.assertEqual(h.hexdigest().upper(), digest.upper()) + self.assertEqual(h.digest(), binascii.unhexlify(digest)) + self.assertEqual(h.name, f"hmac-{hashname}") + self.assertEqual(h.digest_size, digest_size) + self.assertEqual(h.block_size, block_size) + + h = hmac.HMAC(key, data, digestmod=hashname) + self.assertEqual(h.hexdigest().upper(), digest.upper()) + self.assertEqual(h.digest(), binascii.unhexlify(digest)) + self.assertEqual(h.name, f"hmac-{hashname}") + self.assertEqual(h.digest_size, digest_size) + self.assertEqual(h.block_size, block_size) + + h = hmac.HMAC(key, digestmod=hashname) + h2 = h.copy() + h2.update(b"test update") + h.update(data) + self.assertEqual(h.hexdigest().upper(), digest.upper()) + + h = hmac.new(key, data, digestmod=hashname) + self.assertEqual(h.hexdigest().upper(), digest.upper()) + self.assertEqual(h.digest(), binascii.unhexlify(digest)) + self.assertEqual(h.name, f"hmac-{hashname}") + self.assertEqual(h.digest_size, digest_size) + self.assertEqual(h.block_size, block_size) + + h = hmac.new(key, None, digestmod=hashname) + h.update(data) + self.assertEqual(h.hexdigest().upper(), digest.upper()) + + h = hmac.new(key, digestmod=hashname) + h.update(data) + self.assertEqual(h.hexdigest().upper(), digest.upper()) + + h = hmac.new(key, data, digestmod=hashfunc) + self.assertEqual(h.hexdigest().upper(), digest.upper()) + + self.assertEqual( + hmac.digest(key, data, digest=hashname), + binascii.unhexlify(digest) + ) + self.assertEqual( + hmac.digest(key, data, digest=hashfunc), + binascii.unhexlify(digest) + ) + with unittest.mock.patch('hmac._openssl_md_meths', {}): + self.assertEqual( + hmac.digest(key, data, digest=hashname), + binascii.unhexlify(digest) + ) + self.assertEqual( + hmac.digest(key, data, digest=hashfunc), + binascii.unhexlify(digest) + ) - def md5test(key, data, digest): - h = hmac.HMAC(key, data, digestmod=hashlib.md5) + if c_hmac_new is not None: + h = c_hmac_new(key, data, digestmod=hashname) self.assertEqual(h.hexdigest().upper(), digest.upper()) self.assertEqual(h.digest(), binascii.unhexlify(digest)) - self.assertEqual(h.name, "hmac-md5") - self.assertEqual(h.digest_size, 16) - self.assertEqual(h.block_size, 64) + self.assertEqual(h.name, f"hmac-{hashname}") + self.assertEqual(h.digest_size, digest_size) + self.assertEqual(h.block_size, block_size) - h = hmac.HMAC(key, data, digestmod='md5') + h = c_hmac_new(key, digestmod=hashname) + h2 = h.copy() + h2.update(b"test update") + h.update(data) self.assertEqual(h.hexdigest().upper(), digest.upper()) - self.assertEqual(h.digest(), binascii.unhexlify(digest)) - self.assertEqual(h.name, "hmac-md5") - self.assertEqual(h.digest_size, 16) - self.assertEqual(h.block_size, 64) - self.assertEqual( - hmac.digest(key, data, digest='md5'), - binascii.unhexlify(digest) + @hashlib_helper.requires_hashdigest('md5', openssl=True) + def test_md5_vectors(self): + # Test the HMAC module against test vectors from the RFC. + + def md5test(key, data, digest): + self.asssert_hmac( + key, data, digest, + hashfunc=hashlib.md5, + hashname="md5", + digest_size=16, + block_size=64 ) - with unittest.mock.patch('hmac._openssl_md_meths', {}): - self.assertEqual( - hmac.digest(key, data, digest='md5'), - binascii.unhexlify(digest) - ) md5test(b"\x0b" * 16, b"Hi There", @@ -82,26 +146,14 @@ class TestVectorsTestCase(unittest.TestCase): @hashlib_helper.requires_hashdigest('sha1', openssl=True) def test_sha_vectors(self): def shatest(key, data, digest): - h = hmac.HMAC(key, data, digestmod=hashlib.sha1) - self.assertEqual(h.hexdigest().upper(), digest.upper()) - self.assertEqual(h.digest(), binascii.unhexlify(digest)) - self.assertEqual(h.name, "hmac-sha1") - self.assertEqual(h.digest_size, 20) - self.assertEqual(h.block_size, 64) - - h = hmac.HMAC(key, data, digestmod='sha1') - self.assertEqual(h.hexdigest().upper(), digest.upper()) - self.assertEqual(h.digest(), binascii.unhexlify(digest)) - self.assertEqual(h.name, "hmac-sha1") - self.assertEqual(h.digest_size, 20) - self.assertEqual(h.block_size, 64) - - self.assertEqual( - hmac.digest(key, data, digest='sha1'), - binascii.unhexlify(digest) + self.asssert_hmac( + key, data, digest, + hashfunc=hashlib.sha1, + hashname="sha1", + digest_size=20, + block_size=64 ) - shatest(b"\x0b" * 20, b"Hi There", "b617318655057264e28bc0b6fb378c8ef146be00") @@ -133,37 +185,15 @@ class TestVectorsTestCase(unittest.TestCase): def _rfc4231_test_cases(self, hashfunc, hash_name, digest_size, block_size): def hmactest(key, data, hexdigests): - hmac_name = "hmac-" + hash_name - h = hmac.HMAC(key, data, digestmod=hashfunc) - self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc]) - self.assertEqual(h.name, hmac_name) - self.assertEqual(h.digest_size, digest_size) - self.assertEqual(h.block_size, block_size) - - h = hmac.HMAC(key, data, digestmod=hash_name) - self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc]) - self.assertEqual(h.name, hmac_name) - self.assertEqual(h.digest_size, digest_size) - self.assertEqual(h.block_size, block_size) - - self.assertEqual( - hmac.digest(key, data, digest=hashfunc), - binascii.unhexlify(hexdigests[hashfunc]) + digest = hexdigests[hashfunc] + + self.asssert_hmac( + key, data, digest, + hashfunc=hashfunc, + hashname=hash_name, + digest_size=digest_size, + block_size=block_size ) - self.assertEqual( - hmac.digest(key, data, digest=hash_name), - binascii.unhexlify(hexdigests[hashfunc]) - ) - - with unittest.mock.patch('hmac._openssl_md_meths', {}): - self.assertEqual( - hmac.digest(key, data, digest=hashfunc), - binascii.unhexlify(hexdigests[hashfunc]) - ) - self.assertEqual( - hmac.digest(key, data, digest=hash_name), - binascii.unhexlify(hexdigests[hashfunc]) - ) # 4.2. Test Case 1 hmactest(key = b'\x0b'*20, @@ -385,6 +415,14 @@ class ConstructorTestCase(unittest.TestCase): except Exception: self.fail("Constructor call with hashlib.sha256 raised exception.") + @unittest.skipUnless(C_HMAC is not None, 'need _hashlib') + def test_internal_types(self): + # internal types like _hashlib.C_HMAC are not constructable + with self.assertRaisesRegex( + TypeError, "cannot create 'HMAC' instance" + ): + C_HMAC() + class SanityTestCase(unittest.TestCase): @@ -395,9 +433,9 @@ class SanityTestCase(unittest.TestCase): try: h = hmac.HMAC(b"my secret key", digestmod="sha256") h.update(b"compute the hash of this text!") - dig = h.digest() - dig = h.hexdigest() - h2 = h.copy() + h.digest() + h.hexdigest() + h.copy() except Exception: self.fail("Exception raised during normal usage of HMAC class.") @@ -450,6 +488,21 @@ class CopyTestCase(unittest.TestCase): self.assertEqual(h1.hexdigest(), h2.hexdigest(), "Hexdigest of copy doesn't match original hexdigest.") + @hashlib_helper.requires_hashdigest('sha256') + def test_equality_new(self): + # Testing if the copy has the same digests with hmac.new(). + h1 = hmac.new(b"key", digestmod="sha256") + h1.update(b"some random text") + h2 = h1.copy() + self.assertTrue( + id(h1) != id(h2), "No real copy of the HMAC instance." + ) + self.assertEqual(h1.digest(), h2.digest(), + "Digest of copy doesn't match original digest.") + self.assertEqual(h1.hexdigest(), h2.hexdigest(), + "Hexdigest of copy doesn't match original hexdigest.") + + class CompareDigestTestCase(unittest.TestCase): def test_compare_digest(self): |