Skip to content

Commit

Permalink
[py3] Fixed django#17040 -- ported django.utils.crypto.constant_time_…
Browse files Browse the repository at this point in the history
…compare.

This is a private API; adding a type check is acceptable.
  • Loading branch information
aaugustin committed Aug 20, 2012
1 parent 54899d8 commit 62954ba
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
13 changes: 10 additions & 3 deletions django/utils/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from django.conf import settings
from django.utils.encoding import smart_bytes
from django.utils import six
from django.utils.six.moves import xrange


Expand Down Expand Up @@ -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


Expand Down
12 changes: 11 additions & 1 deletion tests/regressiontests/utils/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@
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):
Expand Down
2 changes: 1 addition & 1 deletion tests/regressiontests/utils/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
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
Expand Down

0 comments on commit 62954ba

Please sign in to comment.