summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2014-05-11 23:11:44 (GMT)
committerBenjamin Peterson <benjamin@python.org>2014-05-11 23:11:44 (GMT)
commit629026aecc6bbb7cf8df25f7699eaf97d8e45701 (patch)
tree9e3f3097933a1d4ab83265f34271ad8cbacc29ad /Lib
parente9314e4a3c7bf9bc297922bbc130ec3dc004654c (diff)
downloadcpython-629026aecc6bbb7cf8df25f7699eaf97d8e45701.zip
cpython-629026aecc6bbb7cf8df25f7699eaf97d8e45701.tar.gz
cpython-629026aecc6bbb7cf8df25f7699eaf97d8e45701.tar.bz2
backport hmac.compare_digest to partially implement PEP 466 (closes #21306)
Backport from Alex Gaynor.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/hmac.py3
-rw-r--r--Lib/test/test_hmac.py112
2 files changed, 114 insertions, 1 deletions
diff --git a/Lib/hmac.py b/Lib/hmac.py
index 5388106..9cd1a9f 100644
--- a/Lib/hmac.py
+++ b/Lib/hmac.py
@@ -5,6 +5,9 @@ Implements the HMAC algorithm as described by RFC 2104.
import warnings as _warnings
+from operator import _compare_digest as compare_digest
+
+
trans_5C = "".join ([chr (x ^ 0x5C) for x in xrange(256)])
trans_36 = "".join ([chr (x ^ 0x36) for x in xrange(256)])
diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py
index cd148e9..3f6f756 100644
--- a/Lib/test/test_hmac.py
+++ b/Lib/test/test_hmac.py
@@ -302,12 +302,122 @@ class CopyTestCase(unittest.TestCase):
self.assertTrue(h1.hexdigest() == h2.hexdigest(),
"Hexdigest of copy doesn't match original hexdigest.")
+
+class CompareDigestTestCase(unittest.TestCase):
+
+ def test_compare_digest(self):
+ # Testing input type exception handling
+ a, b = 100, 200
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+ a, b = 100, b"foobar"
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+ a, b = b"foobar", 200
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+ a, b = u"foobar", b"foobar"
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+ a, b = b"foobar", u"foobar"
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+
+ # Testing bytes of different lengths
+ a, b = b"foobar", b"foo"
+ self.assertFalse(hmac.compare_digest(a, b))
+ a, b = b"\xde\xad\xbe\xef", b"\xde\xad"
+ self.assertFalse(hmac.compare_digest(a, b))
+
+ # Testing bytes of same lengths, different values
+ a, b = b"foobar", b"foobaz"
+ self.assertFalse(hmac.compare_digest(a, b))
+ a, b = b"\xde\xad\xbe\xef", b"\xab\xad\x1d\xea"
+ self.assertFalse(hmac.compare_digest(a, b))
+
+ # Testing bytes of same lengths, same values
+ a, b = b"foobar", b"foobar"
+ self.assertTrue(hmac.compare_digest(a, b))
+ a, b = b"\xde\xad\xbe\xef", b"\xde\xad\xbe\xef"
+ self.assertTrue(hmac.compare_digest(a, b))
+
+ # Testing bytearrays of same lengths, same values
+ a, b = bytearray(b"foobar"), bytearray(b"foobar")
+ self.assertTrue(hmac.compare_digest(a, b))
+
+ # Testing bytearrays of diffeent lengths
+ a, b = bytearray(b"foobar"), bytearray(b"foo")
+ self.assertFalse(hmac.compare_digest(a, b))
+
+ # Testing bytearrays of same lengths, different values
+ a, b = bytearray(b"foobar"), bytearray(b"foobaz")
+ self.assertFalse(hmac.compare_digest(a, b))
+
+ # Testing byte and bytearray of same lengths, same values
+ a, b = bytearray(b"foobar"), b"foobar"
+ self.assertTrue(hmac.compare_digest(a, b))
+ self.assertTrue(hmac.compare_digest(b, a))
+
+ # Testing byte bytearray of diffeent lengths
+ a, b = bytearray(b"foobar"), b"foo"
+ self.assertFalse(hmac.compare_digest(a, b))
+ self.assertFalse(hmac.compare_digest(b, a))
+
+ # Testing byte and bytearray of same lengths, different values
+ a, b = bytearray(b"foobar"), b"foobaz"
+ self.assertFalse(hmac.compare_digest(a, b))
+ self.assertFalse(hmac.compare_digest(b, a))
+
+ # Testing str of same lengths
+ a, b = "foobar", "foobar"
+ self.assertTrue(hmac.compare_digest(a, b))
+
+ # Testing str of diffeent lengths
+ a, b = "foo", "foobar"
+ self.assertFalse(hmac.compare_digest(a, b))
+
+ # Testing bytes of same lengths, different values
+ a, b = "foobar", "foobaz"
+ self.assertFalse(hmac.compare_digest(a, b))
+
+ # Testing error cases
+ a, b = u"foobar", b"foobar"
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+ a, b = b"foobar", u"foobar"
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+ a, b = b"foobar", 1
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+ a, b = 100, 200
+ self.assertRaises(TypeError, hmac.compare_digest, a, b)
+ a, b = "fooä", "fooä"
+ self.assertTrue(hmac.compare_digest(a, b))
+
+ # subclasses are supported by ignore __eq__
+ class mystr(str):
+ def __eq__(self, other):
+ return False
+
+ a, b = mystr("foobar"), mystr("foobar")
+ self.assertTrue(hmac.compare_digest(a, b))
+ a, b = mystr("foobar"), "foobar"
+ self.assertTrue(hmac.compare_digest(a, b))
+ a, b = mystr("foobar"), mystr("foobaz")
+ self.assertFalse(hmac.compare_digest(a, b))
+
+ class mybytes(bytes):
+ def __eq__(self, other):
+ return False
+
+ a, b = mybytes(b"foobar"), mybytes(b"foobar")
+ self.assertTrue(hmac.compare_digest(a, b))
+ a, b = mybytes(b"foobar"), b"foobar"
+ self.assertTrue(hmac.compare_digest(a, b))
+ a, b = mybytes(b"foobar"), mybytes(b"foobaz")
+ self.assertFalse(hmac.compare_digest(a, b))
+
+
def test_main():
test_support.run_unittest(
TestVectorsTestCase,
ConstructorTestCase,
SanityTestCase,
- CopyTestCase
+ CopyTestCase,
+ CompareDigestTestCase,
)
if __name__ == "__main__":