Merge "Avoid possible timing attack in metadata api" into stable/icehouse
This commit is contained in:
commit
8bc955375c
@ -30,6 +30,7 @@ from nova import exception
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import memorycache
|
||||
from nova import utils
|
||||
from nova import wsgi
|
||||
|
||||
CACHE_EXPIRATION = 15 # in seconds
|
||||
@ -169,7 +170,7 @@ class MetadataRequestHandler(wsgi.Application):
|
||||
instance_id,
|
||||
hashlib.sha256).hexdigest()
|
||||
|
||||
if expected_signature != signature:
|
||||
if not utils.constant_time_compare(expected_signature, signature):
|
||||
if instance_id:
|
||||
LOG.warn(_('X-Instance-ID-Signature: %(signature)s does not '
|
||||
'match the expected value: %(expected_signature)s '
|
||||
|
@ -979,3 +979,10 @@ class VersionTestCase(test.NoDBTestCase):
|
||||
|
||||
def test_convert_version_to_tuple(self):
|
||||
self.assertEqual(utils.convert_version_to_tuple('6.7.0'), (6, 7, 0))
|
||||
|
||||
|
||||
class ConstantTimeCompareTestCase(test.NoDBTestCase):
|
||||
def test_constant_time_compare(self):
|
||||
self.assertTrue(utils.constant_time_compare("abcd1234", "abcd1234"))
|
||||
self.assertFalse(utils.constant_time_compare("abcd1234", "a"))
|
||||
self.assertFalse(utils.constant_time_compare("abcd1234", "ABCD234"))
|
||||
|
@ -21,6 +21,7 @@ import contextlib
|
||||
import datetime
|
||||
import functools
|
||||
import hashlib
|
||||
import hmac
|
||||
import inspect
|
||||
import multiprocessing
|
||||
import os
|
||||
@ -1170,3 +1171,20 @@ def cpu_count():
|
||||
return multiprocessing.cpu_count()
|
||||
except NotImplementedError:
|
||||
return 1
|
||||
|
||||
if hasattr(hmac, 'compare_digest'):
|
||||
constant_time_compare = hmac.compare_digest
|
||||
else:
|
||||
def constant_time_compare(first, second):
|
||||
"""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.
|
||||
|
||||
"""
|
||||
if len(first) != len(second):
|
||||
return False
|
||||
result = 0
|
||||
for x, y in zip(first, second):
|
||||
result |= ord(x) ^ ord(y)
|
||||
return result == 0
|
||||
|
Loading…
Reference in New Issue
Block a user