Merge "Fix exception with secretutils"
This commit is contained in:
commit
8b0a17ed6e
|
@ -20,28 +20,26 @@ Secret utilities.
|
||||||
|
|
||||||
import hmac
|
import hmac
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
|
def _constant_time_compare(first, second):
|
||||||
|
"""Return True if both string or binary inputs are equal, otherwise False.
|
||||||
|
|
||||||
|
This function should take a constant amount of time regardless of
|
||||||
|
how many characters in the strings match. This function uses an
|
||||||
|
approach designed to prevent timing analysis by avoiding
|
||||||
|
content-based short circuiting behaviour, making it appropriate
|
||||||
|
for cryptography.
|
||||||
|
"""
|
||||||
|
first = str(first)
|
||||||
|
second = str(second)
|
||||||
|
if len(first) != len(second):
|
||||||
|
return False
|
||||||
|
result = 0
|
||||||
|
for x, y in zip(first, second):
|
||||||
|
result |= ord(x) ^ ord(y)
|
||||||
|
return result == 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
constant_time_compare = hmac.compare_digest
|
constant_time_compare = hmac.compare_digest
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
def constant_time_compare(first, second):
|
constant_time_compare = _constant_time_compare
|
||||||
"""Returns 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. This function uses an
|
|
||||||
approach designed to prevent timing analysis by avoiding
|
|
||||||
content-based short circuiting behaviour, making it appropriate
|
|
||||||
for cryptography.
|
|
||||||
"""
|
|
||||||
if isinstance(first, six.string_types):
|
|
||||||
first = first.encode('utf-8')
|
|
||||||
if isinstance(second, six.string_types):
|
|
||||||
second = second.encode('utf-8')
|
|
||||||
if len(first) != len(second):
|
|
||||||
return False
|
|
||||||
result = 0
|
|
||||||
for x, y in zip(first, second):
|
|
||||||
result |= ord(x) ^ ord(y)
|
|
||||||
return result == 0
|
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import hmac
|
||||||
|
|
||||||
from oslotest import base as test_base
|
from oslotest import base as test_base
|
||||||
import testscenarios
|
import testscenarios
|
||||||
|
|
||||||
|
@ -21,15 +23,20 @@ from oslo_utils import secretutils
|
||||||
class SecretUtilsTest(testscenarios.TestWithScenarios,
|
class SecretUtilsTest(testscenarios.TestWithScenarios,
|
||||||
test_base.BaseTestCase):
|
test_base.BaseTestCase):
|
||||||
|
|
||||||
|
_gen_digest = lambda text: hmac.new(b'foo', text.encode('utf-8')).digest()
|
||||||
scenarios = [
|
scenarios = [
|
||||||
('binary', {'converter': lambda text: text.encode('utf-8')}),
|
('binary', {'converter': _gen_digest}),
|
||||||
('unicode', {'converter': lambda text: text}),
|
('unicode', {'converter': lambda text: text}),
|
||||||
]
|
]
|
||||||
|
|
||||||
def test_constant_time_compare(self):
|
def test_constant_time_compare(self):
|
||||||
# make sure it works as a compare, the "constant time" aspect
|
# make sure it works as a compare, the "constant time" aspect
|
||||||
# isn't appropriate to test in unittests
|
# isn't appropriate to test in unittests
|
||||||
ctc = secretutils.constant_time_compare
|
|
||||||
|
# Make sure the unittests are applied to our function instead of
|
||||||
|
# the built-in function, otherwise that is in vain.
|
||||||
|
ctc = secretutils._constant_time_compare
|
||||||
|
|
||||||
self.assertTrue(ctc(self.converter(u'abcd'),
|
self.assertTrue(ctc(self.converter(u'abcd'),
|
||||||
self.converter(u'abcd')))
|
self.converter(u'abcd')))
|
||||||
self.assertTrue(ctc(self.converter(u''),
|
self.assertTrue(ctc(self.converter(u''),
|
||||||
|
|
Loading…
Reference in New Issue