Use constant time string comparisons for auth.

Fix bug 942644.

Use constant time string comparisons when doing authentication to help
guard against timing attacks.

Change-Id: Iaaefb13f7618b06834630d9ccb97aff056b4bf4c
This commit is contained in:
Russell Bryant
2012-02-28 10:55:38 -05:00
parent 58c22f4549
commit d165c73d99
2 changed files with 23 additions and 3 deletions

View File

@@ -328,7 +328,7 @@ class AuthManager(object):
LOG.debug(_('user.secret: %s'), user.secret)
LOG.debug(_('expected_signature: %s'), expected_signature)
LOG.debug(_('signature: %s'), signature)
if signature != expected_signature:
if not utils.strcmp_const_time(signature, expected_signature):
LOG.audit(_("Invalid signature for user %s"), user.name)
raise exception.InvalidSignature(signature=signature,
user=user)
@@ -340,7 +340,7 @@ class AuthManager(object):
LOG.debug(_('user.secret: %s'), user.secret)
LOG.debug(_('expected_signature: %s'), expected_signature)
LOG.debug(_('signature: %s'), signature)
if signature != expected_signature:
if not utils.strcmp_const_time(signature, expected_signature):
(addr_str, port_str) = utils.parse_server_string(server_string)
# If the given server_string contains port num, try without it.
if port_str != '':
@@ -349,7 +349,7 @@ class AuthManager(object):
addr_str, path)
LOG.debug(_('host_only_signature: %s'),
host_only_signature)
if signature == host_only_signature:
if utils.strcmp_const_time(signature, host_only_signature):
return (user, project)
LOG.audit(_("Invalid signature for user %s"), user.name)
raise exception.InvalidSignature(signature=signature,

View File

@@ -1560,3 +1560,23 @@ def tempdir(**kwargs):
shutil.rmtree(tmpdir)
except OSError, e:
LOG.debug(_('Could not remove tmpdir: %s'), str(e))
def strcmp_const_time(s1, s2):
"""Constant-time string comparison.
:params s1: the first string
:params s2: the second string
:return: True if the strings are equal.
This function takes two strings and compares them. It is intended to be
used when doing a comparison for authentication purposes to help guard
against timing attacks.
"""
if len(s1) != len(s2):
return False
result = 0
for (a, b) in zip(s1, s2):
result |= ord(a) ^ ord(b)
return result == 0