Incorrect signature in ARC-Seal on LF as linesep

Bug #2052720 reported by Nikolay
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
dkimpy
Fix Released
Medium
Scott Kitterman

Bug Description

With linesep=b'\n' the generated ARC-Seal header may include a broken b= signature. This happens when the generated ARC-Authentication-Results header value contains line continuations, in which case they would use '\n' (instead of '\r\n') and the header would not be properly canonicalized before including it into the signature for the respective ARC-Seal.

This can be checked by running dkim.arcverify over the ARC-signed mail. It fails for such mail with an error like:

  ...
  DEBUG:dkimpy:b'ARC-Seal' valid: False
  DEBUG:dkimpy:as valid: False
  arc verification: cv=b'fail' ARC-Seal[1] did not validate
  ...

The issue is also confirmed by failed validation at both Gmail and <email address hidden>.

Library version: dkimpy==1.1.5

The following patch can be used to address the issue. This change ensures that self.headers stays canonicalized (regardless of the line separator used) for any newly added headers. The patch also assumes other related bugs are fixed, specifically https://bugs.launchpad.net/dkimpy/+bug/2049018 .

--- dkim/canonicalization.py.orig 2024-02-08 17:48:49.913019640 +0200
+++ dkim/canonicalization.py 2024-02-08 17:59:14.433014990 +0200
@@ -58,7 +58,7 @@
     return content[:end]

 def unfold_header_value(content):
- return re.sub(b"\r\n", b"", content)
+ return re.sub(b"\r?\n", b"", content)

 def correct_empty_body(content):
--- dkim/__init__.py.orig 2024-02-08 18:00:51.593014267 +0200
+++ dkim/__init__.py 2024-02-08 18:01:02.383014187 +0200
@@ -1120,13 +1120,13 @@
     # Compute ARC-Authentication-Results
     aar_value = ("i=%d; " % instance).encode('utf-8') + auth_results.rstrip() + self.linesep

+ canon_policy = CanonicalizationPolicy.from_c_value(b'relaxed/relaxed')
+
     new_arc_set.append(b"ARC-Authentication-Results: " + aar_value)
- self.headers.insert(0, (b"arc-authentication-results", aar_value))
     arc_headers.insert(0, (b"ARC-Authentication-Results", aar_value))
+ self.headers = canon_policy.canonicalize_headers(arc_headers[:1]) + self.headers

     # Compute bh=
- canon_policy = CanonicalizationPolicy.from_c_value(b'relaxed/relaxed')
-
     self.hasher = HASH_ALGORITHMS[self.signature_algorithm]
     h = HashThrough(self.hasher(), self.debug_content)
     h.update(canon_policy.canonicalize_body(self.body))
@@ -1154,8 +1154,8 @@
                           b"ARC-Message-Signature", pk, standardize)

     new_arc_set.append(b"ARC-Message-Signature: " + res)
- self.headers.insert(0, (b"ARC-Message-Signature", res))
     arc_headers.insert(0, (b"ARC-Message-Signature", res))
+ self.headers = canon_policy.canonicalize_headers(arc_headers[:1]) + self.headers

     # Compute ARC-Seal
     as_fields = [x for x in [
@@ -1183,8 +1183,8 @@
                            b"ARC-Seal", pk, standardize)

     new_arc_set.append(b"ARC-Seal: " + res)
- self.headers.insert(0, (b"ARC-Seal", res))
     arc_headers.insert(0, (b"ARC-Seal", res))
+ self.headers = canon_policy.canonicalize_headers(arc_headers[:1]) + self.headers

     new_arc_set.reverse()

Changed in dkimpy:
status: New → Fix Committed
importance: Undecided → Medium
assignee: nobody → Scott Kitterman (kitterman)
milestone: none → 1.1.7
Changed in dkimpy:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.