Merge lp:~mbp/dkimpy/587783-relaxed into lp:dkimpy

Proposed by Martin Pool
Status: Merged
Approved by: Scott Kitterman
Approved revision: 10
Merged at revision: 10
Proposed branch: lp:~mbp/dkimpy/587783-relaxed
Merge into: lp:dkimpy
Diff against target: 56 lines (+16/-6)
2 files modified
ChangeLog (+5/-0)
dkim/__init__.py (+11/-6)
To merge this branch: bzr merge lp:~mbp/dkimpy/587783-relaxed
Reviewer Review Type Date Requested Status
Scott Kitterman Approve
Review via email: mp+53373@code.launchpad.net

Commit message

* when verifying Relaxed mode signatures, the partial DKIM-Signature
   header must be canonicalized before hashing (Martin Pool)
   <https://launchpad.net/bugs/587783>

Description of the change

This is a forward-port and update of the fix originally done in <https://bugs.launchpad.net/pydkim/+bug/587783>:

When generating a signature dkim specifies that a placeholder DKIM-Signature should be hashed. Without this patch, pydkim doesn't apply the right canonicalization rules and therefore can't it can't verify Relaxed-mode signatures it generates itself.

To post a comment you must log in.
Revision history for this message
Scott Kitterman (kitterman) wrote :

Ship it.

review: Approve
lp:~mbp/dkimpy/587783-relaxed updated
11. By Martin Pool

ChangeLog correction

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2011-03-08 04:25:49 +0000
+++ ChangeLog 2011-03-15 05:46:12 +0000
@@ -1,3 +1,8 @@
1Not yet released
2 - when producing Relaxed mode signatures, the partial DKIM-Signature
3 header must be canonicalized before hashing (Martin Pool)
4 <https://launchpad.net/bugs/587783>
5
12008-06-25 Version 0.362008-06-25 Version 0.3
27
3 - length parameter to sign() is now a boolean8 - length parameter to sign() is now a boolean
49
=== modified file 'dkim/__init__.py'
--- dkim/__init__.py 2011-03-15 04:10:03 +0000
+++ dkim/__init__.py 2011-03-15 05:46:12 +0000
@@ -313,18 +313,23 @@
313 ('bh', bodyhash),313 ('bh', bodyhash),
314 ('b', ""),314 ('b', ""),
315 ] if x]315 ] if x]
316 sig = "DKIM-Signature: " + "; ".join("%s=%s" % x for x in sigfields)
317316
318 sig = fold(sig)317 sig_value = fold("; ".join("%s=%s" % x for x in sigfields))
318 dkim_header = canonicalize[0].canonicalize_headers([
319 ['DKIM-Signature', ' ' + sig_value]])[0]
320 # the dkim sig is hashed with no trailing crlf, even if the
321 # canonicalization algorithm would add one.
322 if dkim_header[1][-2:] == '\r\n':
323 dkim_header = (dkim_header[0], dkim_header[1][:-2])
324 sign_headers.append(dkim_header)
319325
320 if debuglog is not None:326 if debuglog is not None:
321 print >>debuglog, "sign headers:", sign_headers + [("DKIM-Signature", " "+"; ".join("%s=%s" % x for x in sigfields))]327 print >>debuglog, "sign headers:", sign_headers
322 h = hashlib.sha256()328 h = hashlib.sha256()
323 for x in sign_headers:329 for x in sign_headers:
324 h.update(x[0])330 h.update(x[0])
325 h.update(":")331 h.update(":")
326 h.update(x[1])332 h.update(x[1])
327 h.update(sig)
328 d = h.digest()333 d = h.digest()
329 if debuglog is not None:334 if debuglog is not None:
330 print >>debuglog, "sign digest:", " ".join("%02x" % ord(x) for x in d)335 print >>debuglog, "sign digest:", " ".join("%02x" % ord(x) for x in d)
@@ -334,9 +339,9 @@
334 d, HASHID_SHA256, pk['privateExponent'], pk['modulus'])339 d, HASHID_SHA256, pk['privateExponent'], pk['modulus'])
335 except DigestTooLargeError:340 except DigestTooLargeError:
336 raise ParameterError("digest too large for modulus")341 raise ParameterError("digest too large for modulus")
337 sig += base64.b64encode(sig2)342 sig_value += base64.b64encode(sig2)
338343
339 return sig + "\r\n"344 return 'DKIM-Signature: ' + sig_value + "\r\n"
340345
341def verify(message, debuglog=None, dnsfunc=dnstxt):346def verify(message, debuglog=None, dnsfunc=dnstxt):
342 """Verify a DKIM signature on an RFC822 formatted message.347 """Verify a DKIM signature on an RFC822 formatted message.

Subscribers

People subscribed via source and target branches