Skip to content
This repository was archived by the owner on Apr 13, 2024. It is now read-only.

Commit c340c80

Browse files
committed
Use constant-time compare for HMAC verification.
1 parent 2b7714a commit c340c80

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

CHANGELOG.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
httpsig Changes
22
---------------
33

4+
1.1.2 (2015-Feb-11)
5+
-------------------
6+
7+
* HMAC verification is now constant-time.
8+
9+
1.1.1 (2015-Feb-11)
10+
-------------------
11+
12+
* (pulled)
13+
414
1.1.0 (2014-Jul-24)
515
-------------------
616

httpsig/utils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,28 @@
2323
class HttpSigException(Exception):
2424
pass
2525

26+
"""
27+
Constant-time string compare.
28+
http://codahale.com/a-lesson-in-timing-attacks/
29+
"""
30+
def ct_bytes_compare(a, b):
31+
if not isinstance(a, six.binary_type):
32+
a = a.decode('utf8')
33+
if not isinstance(b, six.binary_type):
34+
b = b.decode('utf8')
35+
36+
if len(a) != len(b):
37+
return False
38+
39+
result = 0
40+
for x, y in zip(a, b):
41+
if six.PY2:
42+
result |= ord(x) ^ ord(y)
43+
else:
44+
result |= x ^ y
45+
46+
return (result == 0)
47+
2648
def generate_message(required_headers, headers, host=None, method=None, path=None):
2749
headers = CaseInsensitiveDict(headers)
2850

httpsig/verify.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def _verify(self, data, signature):
3636
elif self.sign_algorithm == 'hmac':
3737
h = self._sign_hmac(data)
3838
s = b64decode(signature)
39-
return (h == s)
39+
return ct_bytes_compare(h, s)
4040

4141
else:
4242
raise HttpSigException("Unsupported algorithm.")

0 commit comments

Comments
 (0)