Commit 62954ba0 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

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

This is a private API; adding a type check is acceptable.
parent 54899d81
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -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,13 +82,19 @@ 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
    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
+11 −1
Original line number Diff line number Diff line
@@ -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):
+1 −1
Original line number Diff line number Diff line
@@ -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