diff options
author | Benjamin Peterson <benjamin@python.org> | 2014-05-11 23:11:44 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2014-05-11 23:11:44 (GMT) |
commit | 629026aecc6bbb7cf8df25f7699eaf97d8e45701 (patch) | |
tree | 9e3f3097933a1d4ab83265f34271ad8cbacc29ad /Lib | |
parent | e9314e4a3c7bf9bc297922bbc130ec3dc004654c (diff) | |
download | cpython-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.py | 3 | ||||
-rw-r--r-- | Lib/test/test_hmac.py | 112 |
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__": |