Skip to content

Commit

Permalink
[py3] Fixed #17040 -- ported django.utils.crypto.constant_time_compare.
Browse files Browse the repository at this point in the history
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
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)):

This comment has been minimized.

Copy link
@georgemarshall

georgemarshall Aug 21, 2012

Contributor

Breaks CSRF middleware in python 2.7

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
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
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.