Skip to content

Commit b763069

Browse files
authored
Merge pull request #13 from charsyam/bugfix/hmac-compare-digest-for-under-python277
hmac.compare_digest is not in earlier version python2.7.7
2 parents a9b3f6e + 29759f7 commit b763069

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

linebot/utils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,25 @@ def to_camel_case(text):
4545
"""
4646
split = text.split('_')
4747
return split[0] + "".join(x.title() for x in split[1:])
48+
49+
50+
def safe_compare_digest(val1, val2):
51+
"""safe_compare_digest method.
52+
53+
:param val1: string or bytes for compare
54+
:type val1: str | bytes
55+
:param val2: string or bytes for compare
56+
:type val2: str | bytes
57+
"""
58+
if len(val1) != len(val2):
59+
return False
60+
61+
result = 0
62+
if PY3 and isinstance(val1, bytes) and isinstance(val2, bytes):
63+
for i, j in zip(val1, val2):
64+
result |= i ^ j
65+
else:
66+
for i, j in zip(val1, val2):
67+
result |= (ord(i) ^ ord(j))
68+
69+
return result == 0

linebot/webhook.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,33 @@
3232
PostbackEvent,
3333
BeaconEvent
3434
)
35-
from .utils import LOGGER, PY3
35+
from .utils import LOGGER, PY3, safe_compare_digest
36+
37+
38+
if hasattr(hmac, "compare_digest"):
39+
def compare_digest(val1, val2):
40+
"""compare_digest method.
41+
42+
:param val1: string or bytes for compare
43+
:type val1: str | bytes
44+
:param val2: string or bytes for compare
45+
:type val2: str | bytes
46+
:rtype: bool
47+
:return: result
48+
"""
49+
return hmac.compare_digest(val1, val2)
50+
else:
51+
def compare_digest(val1, val2):
52+
"""compare_digest method.
53+
54+
:param val1: string or bytes for compare
55+
:type val1: str | bytes
56+
:param val2: string or bytes for compare
57+
:type val2: str | bytes
58+
:rtype: bool
59+
:return: result
60+
"""
61+
return safe_compare_digest(val1, val2)
3662

3763

3864
class SignatureValidator(object):
@@ -64,8 +90,8 @@ def validate(self, body, signature):
6490
hashlib.sha256
6591
).digest()
6692

67-
return hmac.compare_digest(
68-
signature.encode('utf-8'), base64.b64encode(gen_signature)
93+
return compare_digest(
94+
signature.encode('utf-8'), base64.b64encode(gen_signature)
6995
)
7096

7197

tests/test_utils.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import unittest
1818

19-
from linebot.utils import to_camel_case, to_snake_case
19+
from linebot.utils import to_camel_case, to_snake_case, safe_compare_digest
2020

2121

2222
class TestUtils(unittest.TestCase):
@@ -26,6 +26,15 @@ def test_to_snake_case(self):
2626
def test_to_camel_case(self):
2727
self.assertEqual(to_camel_case('hoge_bar'), 'hogeBar')
2828

29+
def test_safe_compare_digest_true(self):
30+
self.assertTrue(safe_compare_digest('/gg9a+LvFevTH1sd7', '/gg9a+LvFevTH1sd7'))
31+
32+
def test_safe_compare_digest_false_same_size(self):
33+
self.assertFalse(safe_compare_digest('/gg9a+LvFevTH1sd7', '/gg9a+LvFevTH1sd8'))
34+
35+
def test_safe_compare_digest_false_different_size(self):
36+
self.assertFalse(safe_compare_digest('/gg9a+LvFevTH1sd7', '/gg9a+LvFevTH1sd78'))
37+
2938

3039
if __name__ == '__main__':
3140
unittest.main()

0 commit comments

Comments
 (0)