[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:
parent
54899d810d
commit
62954ba04c
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue