Fix bug#644046
This commit is contained in:
+17
-21
@@ -93,9 +93,13 @@ def _remove(s, t):
|
|||||||
def select_headers(headers, include_headers):
|
def select_headers(headers, include_headers):
|
||||||
"""Select message header fields to be signed/verified.
|
"""Select message header fields to be signed/verified.
|
||||||
>>> h = [('from','biz'),('foo','bar'),('from','baz'),('subject','boring')]
|
>>> h = [('from','biz'),('foo','bar'),('from','baz'),('subject','boring')]
|
||||||
>>> i = ['from','subject','from']
|
>>> i = ['from','subject','to','from']
|
||||||
>>> select_headers(h,i)
|
>>> select_headers(h,i)
|
||||||
[('from', 'baz'), ('subject', 'boring'), ('from', 'biz')]
|
[('from', 'baz'), ('subject', 'boring'), ('from', 'biz')]
|
||||||
|
>>> h = [('from','biz'),('foo','bar'),('subject','boring')]
|
||||||
|
>>> i = ['from','subject','to','from']
|
||||||
|
>>> select_headers(h,i)
|
||||||
|
[('from', 'biz'), ('subject', 'boring')]
|
||||||
"""
|
"""
|
||||||
sign_headers = []
|
sign_headers = []
|
||||||
lastindex = {}
|
lastindex = {}
|
||||||
@@ -118,11 +122,14 @@ def hash_headers(hasher, canonicalize_headers, headers, include_headers,
|
|||||||
# once in the signature header
|
# once in the signature header
|
||||||
cheaders = canonicalize_headers.canonicalize_headers(
|
cheaders = canonicalize_headers.canonicalize_headers(
|
||||||
[(sigheaders[0][0], _remove(sigheaders[0][1], sig[b'b']))])
|
[(sigheaders[0][0], _remove(sigheaders[0][1], sig[b'b']))])
|
||||||
|
# the dkim sig is hashed with no trailing crlf, even if the
|
||||||
|
# canonicalization algorithm would add one.
|
||||||
sign_headers += [(x, y.rstrip()) for x,y in cheaders]
|
sign_headers += [(x, y.rstrip()) for x,y in cheaders]
|
||||||
for x,y in sign_headers:
|
for x,y in sign_headers:
|
||||||
hasher.update(x)
|
hasher.update(x)
|
||||||
hasher.update(b":")
|
hasher.update(b":")
|
||||||
hasher.update(y)
|
hasher.update(y)
|
||||||
|
return sign_headers
|
||||||
|
|
||||||
def validate_signature_fields(sig):
|
def validate_signature_fields(sig):
|
||||||
"""Validate DKIM-Signature fields.
|
"""Validate DKIM-Signature fields.
|
||||||
@@ -259,10 +266,7 @@ class DKIM(object):
|
|||||||
headers = canon_policy.canonicalize_headers(self.headers)
|
headers = canon_policy.canonicalize_headers(self.headers)
|
||||||
|
|
||||||
if include_headers is None:
|
if include_headers is None:
|
||||||
include_headers = [x.lower() for x,y in headers]
|
include_headers = [x for x,y in headers]
|
||||||
else:
|
|
||||||
include_headers = [x.lower() for x in include_headers]
|
|
||||||
sign_headers = [(x,y) for x,y in headers if x.lower() in include_headers]
|
|
||||||
|
|
||||||
body = canon_policy.canonicalize_body(self.body)
|
body = canon_policy.canonicalize_body(self.body)
|
||||||
|
|
||||||
@@ -281,28 +285,21 @@ class DKIM(object):
|
|||||||
(b'q', b"dns/txt"),
|
(b'q', b"dns/txt"),
|
||||||
(b's', selector),
|
(b's', selector),
|
||||||
(b't', str(int(time.time())).encode('ascii')),
|
(b't', str(int(time.time())).encode('ascii')),
|
||||||
(b'h', b" : ".join(x for x,y in sign_headers)),
|
(b'h', b" : ".join(include_headers)),
|
||||||
(b'bh', bodyhash),
|
(b'bh', bodyhash),
|
||||||
(b'b', b""),
|
(b'b', b""),
|
||||||
] if x]
|
] if x]
|
||||||
|
include_headers = [x.lower() for x in include_headers]
|
||||||
# record what verify should extract
|
# record what verify should extract
|
||||||
self.include_headers = tuple([x.lower() for x,y in sign_headers])
|
self.include_headers = tuple(include_headers)
|
||||||
|
|
||||||
sig_value = fold(b"; ".join(b"=".join(x) for x in sigfields))
|
sig_value = fold(b"; ".join(b"=".join(x) for x in sigfields))
|
||||||
dkim_header = canon_policy.canonicalize_headers([
|
dkim_header = (b'DKIM-Signature', b' ' + sig_value)
|
||||||
[b'DKIM-Signature', b' ' + sig_value]])[0]
|
|
||||||
# the dkim sig is hashed with no trailing crlf, even if the
|
|
||||||
# canonicalization algorithm would add one.
|
|
||||||
if dkim_header[1][-2:] == b'\r\n':
|
|
||||||
dkim_header = (dkim_header[0], dkim_header[1][:-2])
|
|
||||||
sign_headers.append(dkim_header)
|
|
||||||
|
|
||||||
self.logger.debug("sign headers: %r" % sign_headers)
|
|
||||||
h = hashlib.sha256()
|
h = hashlib.sha256()
|
||||||
for x in sign_headers:
|
sig = dict(sigfields)
|
||||||
h.update(x[0])
|
signed_headers = hash_headers(
|
||||||
h.update(b":")
|
h, canon_policy, headers, include_headers, [dkim_header],sig)
|
||||||
h.update(x[1])
|
self.logger.debug("sign headers: %r" % signed_headers)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sig2 = RSASSA_PKCS1_v1_5_sign(
|
sig2 = RSASSA_PKCS1_v1_5_sign(
|
||||||
@@ -376,7 +373,6 @@ class DKIM(object):
|
|||||||
pk = parse_public_key(base64.b64decode(pub[b'p']))
|
pk = parse_public_key(base64.b64decode(pub[b'p']))
|
||||||
except (TypeError,UnparsableKeyError) as e:
|
except (TypeError,UnparsableKeyError) as e:
|
||||||
raise KeyFormatError("could not parse public key (%s): %s" % (pub[b'p'],e))
|
raise KeyFormatError("could not parse public key (%s): %s" % (pub[b'p'],e))
|
||||||
|
|
||||||
include_headers = [x.lower() for x in re.split(br"\s*:\s*", sig[b'h'])]
|
include_headers = [x.lower() for x in re.split(br"\s*:\s*", sig[b'h'])]
|
||||||
self.include_headers = tuple(include_headers)
|
self.include_headers = tuple(include_headers)
|
||||||
# address bug#644046 by including any additional From header
|
# address bug#644046 by including any additional From header
|
||||||
|
|||||||
Reference in New Issue
Block a user