[py3] Fixed #17040 -- ported django.utils.crypto.constant_time_compare.

This is a private API; adding a type check is acceptable.
This commit is contained in:
Aymeric Augustin 2012-08-20 22:45:13 +02:00
parent 54899d810d
commit 62954ba04c
3 changed files with 22 additions and 5 deletions

View File

@ -24,6 +24,7 @@ except NotImplementedError:
from django.conf import settings
from django.utils.encoding import smart_bytes
from django.utils import six
from django.utils.six.moves import xrange
@ -81,15 +82,21 @@ def get_random_string(length=12,
def constant_time_compare(val1, val2):
"""
Returns True if the two strings are equal, False otherwise.
Returns True if the two bytestrings are equal, False otherwise.
The time taken is independent of the number of characters that match.
"""
if not (isinstance(val1, bytes) and isinstance(val2, bytes)):
raise TypeError("constant_time_compare only supports bytes")
if len(val1) != len(val2):
return False
result = 0
for x, y in zip(val1, val2):
result |= ord(x) ^ ord(y)
if six.PY3:
for x, y in zip(val1, val2):
result |= x ^ y
else:
for x, y in zip(val1, val2):
result |= ord(x) ^ ord(y)
return result == 0

View File

@ -6,7 +6,17 @@ import timeit
import hashlib
from django.utils import unittest
from django.utils.crypto import pbkdf2
from django.utils.crypto import constant_time_compare, pbkdf2
class TestUtilsCryptoMisc(unittest.TestCase):
def test_constant_time_compare(self):
# It's hard to test for constant time, just test the result.
self.assertTrue(constant_time_compare(b'spam', b'spam'))
self.assertFalse(constant_time_compare(b'spam', b'eggs'))
with self.assertRaises(TypeError):
constant_time_compare('spam', 'spam')
class TestUtilsCryptoPBKDF2(unittest.TestCase):

View File

@ -6,7 +6,7 @@ from __future__ import absolute_import
from .archive import TestBzip2Tar, TestGzipTar, TestTar, TestZip
from .baseconv import TestBaseConv
from .checksums import TestUtilsChecksums
from .crypto import TestUtilsCryptoPBKDF2
from .crypto import TestUtilsCryptoMisc, TestUtilsCryptoPBKDF2
from .datastructures import (DictWrapperTests, ImmutableListTests,
MergeDictTests, MultiValueDictTests, SortedDictTests)
from .dateformat import DateFormatTests