> On 4 Jul 2026, at 08:25, Mauro De Gennaro <[email protected]> > wrote: > > Hi all, > > I wanted to share some news from implementing DKIM2, along with a few > findings that came out of interop testing. Incidentally, this message is > itself DKIM2 signed, so if your tooling supports it, feel free to use it as a > small real-world sample. > > I have added DKIM2 support (draft-ietf-dkim-dkim2-spec-03) to mail-auth, the > Rust library for email authentication, which lives at > https://github.com/stalwartlabs/mail-auth. One thing worth mentioning is that > mail-auth also compiles to WebAssembly, so it can be used from JavaScript > applications and other WASM environments. To make it easy to try, I put > together a playground at https://mail-auth.stalw.art/ that signs and > validates DKIM2, as well as DMARC, entirely from the browser, resolving the > records using DNS-over-HTTP. > > DKIM2 is now also supported in Stalwart mail server > (https://github.com/stalwartlabs/stalwart/), which uses mail-auth internally. > Beyond signing and verification, I have implemented inbound DSN validation > for DKIM2 as described in the draft, so that delivery status notifications > coming back along the chain can themselves be authenticated. > > On interoperability, I tested mail-auth against Bron's Python implementation > (https://github.com/dkim2wg/interop.git) and Steve's Go implementation > (https://forge.turscar.ie/turscar/dkim2.git). The integration tests are at > https://github.com/stalwartlabs/mail-auth/blob/main/src/dkim2/interop_test.rs > and they exercise signing, verification and recipe generation across all > three implementations, in both directions, including multi-hop chains. The > good news is that with header folding disabled, every combination passes: > signing, verifying and recipe based reconstruction all agree across the three > implementations.
Nice work! > > I did hit one issue, when mail-auth folds the DKIM2-Signature and > Message-Instance header fields, which is expected behaviour for long fields > such as the base64 signature, both the Python and the Go implementations fail > to parse them. The draft describes in section 2.12 that folding whitespace is > allowed inside base64 strings and must be ignored when the value is used, so > I believe mail-auth's output is conformant here, and it round-trips cleanly > through my own parser. In Steve's Go library the mf= and rt= values are > base64 decoded in strict mode without first removing the folding whitespace, > which trips on the embedded space or tab. In Bron's Python library the s= > value is split on the colon without unfolding first, so the algorithm token > ends up carrying the leading CRLF and tab, and the algorithm comparison then > fails. Neither looks hard to fix, and as noted, disabling folding on my side > makes all tests pass. We should add some test vectors to check folding and otehr FWS in all the places things can be folded, I guess. > Finally, a couple of small notes on the spec itself. Overall I found it > clear, but a few of the sections that describe algorithms in prose would > benefit from some accompanying pseudocode, in particular the parts covering > recipe application and the chain walk during verification. It would remove a > little ambiguity for implementers. The other point concerns header field > names in recipes. It is not entirely clear from the text whether the JSON > keys must be lowercased or may retain their original case. Steve's > implementation expects lowercase and rejects mixed case, whereas I initially > generated recipes preserving the original header case, which the current > wording about matching without regard to case seemed to permit. A sentence > stating the expected behaviour would avoid this divergence. The current spec says they’re case-sensitive. There was discussion about requiring lower case around the time I implemented that bit, and I apparently got ahead of the spec. Cheers, Steve _______________________________________________ Ietf-dkim mailing list -- [email protected] To unsubscribe send an email to [email protected]
