]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #18775: Add name and block_size attribute to HMAC object. They now
authorChristian Heimes <christian@cheimes.de>
Wed, 20 Nov 2013 16:35:06 +0000 (17:35 +0100)
committerChristian Heimes <christian@cheimes.de>
Wed, 20 Nov 2013 16:35:06 +0000 (17:35 +0100)
provide the same API elements as non-keyed cryptographic hash functions.

Doc/library/hmac.rst
Lib/hmac.py
Lib/test/test_hmac.py
Misc/NEWS

index 8fa1435f881a043669e4ea633205a164fe03b6c4..2e9b0b26a57525ffbba742046600d31de673ec7f 100644 (file)
@@ -79,6 +79,25 @@ An HMAC object has the following methods:
    compute the digests of strings that share a common initial substring.
 
 
+A hash object has the following attributes:
+
+.. attribute:: HMAC.digest_size
+
+   The size of the resulting HMAC digest in bytes.
+
+.. attribute:: HMAC.block_size
+
+   The internal block size of the hash algorithm in bytes.
+
+   .. versionadded:: 3.4
+
+.. attribute:: HMAC.name
+
+   The canonical name of this HMAC, always lowercase, e.g. ``hmac-md5``.
+
+   .. versionadded:: 3.4
+
+
 This module also provides the following helper function:
 
 .. function:: compare_digest(a, b)
index 873327bf37c1d36cfb05023f276b9982cb85af69..77785a2d9b655912706c16d48d38159dbf4fb826 100644 (file)
@@ -70,6 +70,10 @@ class HMAC:
                            RuntimeWarning, 2)
             blocksize = self.blocksize
 
+        # self.blocksize is the default blocksize. self.block_size is
+        # effective block size as well as the public API attribute.
+        self.block_size = blocksize
+
         if len(key) > blocksize:
             key = self.digest_cons(key).digest()
 
@@ -79,6 +83,10 @@ class HMAC:
         if msg is not None:
             self.update(msg)
 
+    @property
+    def name(self):
+        return "hmac-" + self.inner.name
+
     def update(self, msg):
         """Update this hashing object with the string msg.
         """
index eb23b26578cb288d66152de0d055cb1d32678e5b..52665bd47cb19cdc8da6891e28f215abfea8e511 100644 (file)
@@ -12,8 +12,16 @@ class TestVectorsTestCase(unittest.TestCase):
         def md5test(key, data, digest):
             h = hmac.HMAC(key, data, digestmod=hashlib.md5)
             self.assertEqual(h.hexdigest().upper(), digest.upper())
+            self.assertEqual(h.name, "hmac-md5")
+            self.assertEqual(h.digest_size, 16)
+            self.assertEqual(h.block_size, 64)
+
             h = hmac.HMAC(key, data, digestmod='md5')
             self.assertEqual(h.hexdigest().upper(), digest.upper())
+            self.assertEqual(h.name, "hmac-md5")
+            self.assertEqual(h.digest_size, 16)
+            self.assertEqual(h.block_size, 64)
+
 
         md5test(b"\x0b" * 16,
                 b"Hi There",
@@ -48,8 +56,15 @@ class TestVectorsTestCase(unittest.TestCase):
         def shatest(key, data, digest):
             h = hmac.HMAC(key, data, digestmod=hashlib.sha1)
             self.assertEqual(h.hexdigest().upper(), digest.upper())
+            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.name, "hmac-sha1")
+            self.assertEqual(h.digest_size, 20)
+            self.assertEqual(h.block_size, 64)
 
 
         shatest(b"\x0b" * 20,
@@ -81,12 +96,20 @@ class TestVectorsTestCase(unittest.TestCase):
                  b"and Larger Than One Block-Size Data"),
                 "e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
 
-    def _rfc4231_test_cases(self, hashfunc, hashname):
+    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])
-            h = hmac.HMAC(key, data, digestmod=hashname)
+            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)
 
 
         # 4.2.  Test Case 1
@@ -197,16 +220,16 @@ class TestVectorsTestCase(unittest.TestCase):
                  })
 
     def test_sha224_rfc4231(self):
-        self._rfc4231_test_cases(hashlib.sha224, 'sha224')
+        self._rfc4231_test_cases(hashlib.sha224, 'sha224', 28, 64)
 
     def test_sha256_rfc4231(self):
-        self._rfc4231_test_cases(hashlib.sha256, 'sha256')
+        self._rfc4231_test_cases(hashlib.sha256, 'sha256', 32, 64)
 
     def test_sha384_rfc4231(self):
-        self._rfc4231_test_cases(hashlib.sha384, 'sha384')
+        self._rfc4231_test_cases(hashlib.sha384, 'sha384', 48, 128)
 
     def test_sha512_rfc4231(self):
-        self._rfc4231_test_cases(hashlib.sha512, 'sha512')
+        self._rfc4231_test_cases(hashlib.sha512, 'sha512', 64, 128)
 
     def test_legacy_block_size_warnings(self):
         class MockCrazyHash(object):
index 1aaf8c159bbef80d543a89acc7667a63c59e286f..be6a1197c5a2305003ce43533d95deaebc73d694 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -59,6 +59,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #18775: Add name and block_size attribute to HMAC object. They now
+  provide the same API elements as non-keyed cryptographic hash functions.
+
 - Issue #17276: MD5 as default digestmod for HMAC is deprecated. The HMAC
   module supports digestmod names, e.g. hmac.HMAC('sha1').