Merge "Use compare_digest or an equivalent when available"

This commit is contained in:
Jenkins 2014-07-25 00:05:43 +00:00 committed by Gerrit Code Review
commit d70a907f36

View File

@ -21,6 +21,30 @@ import os
import six
try:
# Only in python 2.7.7+ (and python 3.3+)
# https://docs.python.org/2/library/hmac.html#hmac.compare_digest
from hmac import compare_digest # noqa
except (AttributeError, ImportError):
# Taken/slightly modified from:
# https://mail.python.org/pipermail/python-checkins/2012-June/114532.html
def compare_digest(a, b):
"""Returns the equivalent of 'a == b', but avoids content based short
circuiting to reduce the vulnerability to timing attacks.
"""
# We assume the length of the expected digest is public knowledge,
# thus this early return isn't leaking anything an attacker wouldn't
# already know
if len(a) != len(b):
return False
# We assume that integers in the bytes range are all cached,
# thus timing shouldn't vary much due to integer object creation
result = 0
for x, y in zip(a, b):
result |= ord(x) ^ ord(y)
return result == 0
def binary_encode(text, encoding='utf-8'):
"""Converts a string of into a binary type using given encoding.
@ -84,10 +108,11 @@ def signed_unpack(data, hmac_data, hmac_key):
if not (hmac_key and hmac_data):
return None
hmac_data = hmac_data.strip()
try:
if generate_hmac(data, hmac_key) != hmac_data.strip():
user_hmac_data = generate_hmac(data, hmac_key)
if not compare_digest(hmac_data, user_hmac_data):
return None
return json.loads(binary_decode(base64.urlsafe_b64decode(data)))
except Exception:
return None