From 6ced68d629f62eb7ed67bd1f0e99dfa2ac613a57 Mon Sep 17 00:00:00 2001 From: "ChangBo Guo(gcb)" Date: Mon, 26 Sep 2016 15:10:42 +0800 Subject: [PATCH] Use method constant_time_compare from oslo.utils Oslo.utils provides same function constant_time_compare, so just use it. Change-Id: Ie9a9f1912b22b5bda55497542ef348b82e7b8939 --- .../auth_token/_memcache_crypt.py | 27 +++---------------- .../unit/auth_token/test_memcache_crypt.py | 21 --------------- 2 files changed, 3 insertions(+), 45 deletions(-) diff --git a/keystonemiddleware/auth_token/_memcache_crypt.py b/keystonemiddleware/auth_token/_memcache_crypt.py index c88418dd..35067de6 100644 --- a/keystonemiddleware/auth_token/_memcache_crypt.py +++ b/keystonemiddleware/auth_token/_memcache_crypt.py @@ -34,7 +34,8 @@ import hmac import math import os import six -import sys + +from oslo_utils import secretutils from keystonemiddleware.i18n import _ @@ -82,28 +83,6 @@ def assert_crypto_availability(f): return wrapper -if sys.version_info >= (3, 3): - constant_time_compare = hmac.compare_digest -else: - def constant_time_compare(first, second): - """Return True if both string inputs are equal, otherwise False. - - This function should take a constant amount of time regardless of - how many characters in the strings match. - - """ - if len(first) != len(second): - return False - result = 0 - if six.PY3 and isinstance(first, bytes) and isinstance(second, bytes): - for x, y in zip(first, second): - result |= x ^ y - else: - for x, y in zip(first, second): - result |= ord(x) ^ ord(y) - return result == 0 - - def derive_keys(token, secret, strategy): """Derive keys for MAC and ENCRYPTION from the user-provided secret. @@ -192,7 +171,7 @@ def unprotect_data(keys, signed_data): signed_data[DIGEST_LENGTH_B64:]) # Then verify that it matches the provided value - if not constant_time_compare(provided_mac, calculated_mac): + if not secretutils.constant_time_compare(provided_mac, calculated_mac): raise InvalidMacError(_('Invalid MAC; data appears to be corrupted.')) data = base64.b64decode(signed_data[DIGEST_LENGTH_B64:]) diff --git a/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py b/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py index e9189831..48a7fb32 100644 --- a/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py +++ b/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py @@ -20,27 +20,6 @@ class MemcacheCryptPositiveTests(utils.BaseTestCase): def _setup_keys(self, strategy): return memcache_crypt.derive_keys(b'token', b'secret', strategy) - def test_constant_time_compare(self): - # make sure it works as a compare, the "constant time" aspect - # isn't appropriate to test in unittests - ctc = memcache_crypt.constant_time_compare - self.assertTrue(ctc('abcd', 'abcd')) - self.assertTrue(ctc('', '')) - self.assertFalse(ctc('abcd', 'efgh')) - self.assertFalse(ctc('abc', 'abcd')) - self.assertFalse(ctc('abc', 'abc\x00')) - self.assertFalse(ctc('', 'abc')) - - # For Python 3, we want to test these functions with both str and bytes - # as input. - if six.PY3: - self.assertTrue(ctc(b'abcd', b'abcd')) - self.assertTrue(ctc(b'', b'')) - self.assertFalse(ctc(b'abcd', b'efgh')) - self.assertFalse(ctc(b'abc', b'abcd')) - self.assertFalse(ctc(b'abc', b'abc\x00')) - self.assertFalse(ctc(b'', b'abc')) - def test_derive_keys(self): keys = self._setup_keys(b'strategy') self.assertEqual(len(keys['ENCRYPTION']),