Skip to main content

Crate mailrs_dkim

Crate mailrs_dkim 

Source
Expand description

§mailrs-dkim

Crates.io docs.rs License

RFC 6376 DKIM signature verifier. Pairs with mailrs-spf and mailrs-rfc5322 to give mailrs full ownership of the inbound email-auth stack — together they replace the mail-auth umbrella crate with shape we control.

§Quickstart

use mailrs_dkim::{verify, HickoryDkimResolver};
use hickory_resolver::TokioResolver;

let inner = TokioResolver::builder_tokio()?.build();
let resolver = HickoryDkimResolver::new(inner);

let result = verify(&resolver, raw_message).await;
// Returns mailrs_dkim::DkimResult: Pass / Fail / Neutral / TempError /
// PermError / None / Policy.

§What this crate does (1.0)

  • Parse DKIM-Signature: headers (all tags: v, a, b, bh, c, d, h, l, q, s, t, x, i, z).
  • Canonicalization: simple/simple, simple/relaxed, relaxed/simple, relaxed/relaxed — all four combinations per RFC 6376 §3.4.
  • Body hash computation (SHA-256) with optional length limit (l=).
  • Header hash computation over the signed-header list in order, with the DKIM-Signature value itself appended with the b= tag cleared (RFC 6376 §3.7).
  • Public-key fetch: TXT at <selector>._domainkey.<domain>.
  • Signature verification: a=rsa-sha256 (covers ~99% of real-world DKIM in 2026).
  • Returns the seven RFC 8601 vocabulary values: none / pass / fail / neutral / temperror / permerror / policy.
  • Pluggable DkimResolver async trait — bring your own DNS or use the bundled hickory-backed adapter.

§What this crate does not (yet)

  • a=ed25519-sha256 (RFC 8463) — modern but rare. Deferred to 1.1. The header parser rejects with UnsupportedAlgorithm; treat this as PermError.
  • Multiple signatures: verify finds the first DKIM-Signature header. Most legitimate mail signs once; some ARC-bridged mail signs multiple times. The trait shape allows a future verify_all without breaking changes.
  • DSN bounce signature verification — same protocol shape, but the DKIM-Signature is on a different header anchor; future addition.
  • Author Domain Signing Practices — historical (RFC 5617), deprecated.

§Why a new crate?

mail-auth includes DKIM but bundles it with SPF + DMARC + ARC. By the project’s DEPS_AUDIT we want each in a focused stone so:

  • the perf of each step is measurable independently
  • the API shape is tunable per-RFC
  • the crate’s transitive deps stay tight per use case

mailrs-spf shipped first (DEPS_AUDIT #1). This is its sibling.

§Performance

Measured (criterion, M-series Mac, release):

OperationMedian
DkimHeader::parse (minimal header)147 ns
DkimHeader::parse (realistic 11-tag header)405 ns
canonicalize_body (simple)70 ns
canonicalize_body (relaxed)140 ns
canonicalize_header (relaxed, one header)85 ns

§Vs. mail-auth 0.9 (the de-facto Rust competitor)

Inputmailrs-dkim 1.1.3mail-auth 0.9Winner
minimal (7 tags)147 ns167 nsmailrs +12%
realistic (folded, 11 tags)405 ns423 nsmailrs +4%

We beat mail-auth on both inputs. The 4.6× / 3.5× cumulative speedup since 1.1.1 came from: (1) single-pass byte scanner replaces HashMap + unfold pre-pass; (2) byte-level tag dispatch via match name.as_bytes() (lowercase fast path + case-insensitive fallback); (3) h= signed- headers parsed via byte-iter with from_utf8_unchecked (safe because only ASCII-lowercased bytes are pushed). Reproduce via cargo bench -p mailrs-dkim --bench compare_mail_auth.

Production verify is dominated by:

  • DNS lookup for the selector key (5-50 ms)
  • RSA-SHA256 signature verification (~1-2 ms for 2048-bit keys)

The bench numbers above are the pure CPU pieces. Reproduce: cargo bench -p mailrs-dkim --bench dkim.

§License

Apache-2.0 OR MIT. Module layout:

  • header — DKIM-Signature header parser
  • canon — header + body canonicalization (simple / relaxed)
  • headers — low-level byte-region helpers (body offset, fold-aware find, b= clear)
  • crypto — standalone RSA-SHA256 / Ed25519-SHA256 signature verify + DNS pubkey parse
  • resolverDkimResolver trait + (optional) hickory impl
  • verifier — full verify() entry point
  • error — error / temp-fail / perm-fail types

Re-exports§

pub use error::DkimError;
pub use error::DkimResult;
pub use header::Algorithm;
pub use header::Canon;
pub use header::DkimHeader;
pub use resolver::DkimResolver;
pub use sign::DkimSigningKey;
pub use sign::SignOpts;
pub use sign::sign;
pub use verifier::SignatureOutput;
pub use verifier::verify;
pub use verifier::verify_all;
pub use resolver::hickory::HickoryDkimResolver;

Modules§

canon
Canonicalization (RFC 6376 §3.4).
crypto
Standalone signature verification primitives — extracted from crate::verifier so other crates in the email-auth family (notably mailrs-arc’s AMS / AS verify) can reuse the same RSA-SHA256 + Ed25519-SHA256 verifier without depending on the DKIM-Signature header layout.
error
Error + result types per RFC 6376 §3.9 / RFC 8601 §2.7.1.
header
DKIM-Signature header parsing (RFC 6376 §3.5).
headers
Low-level byte-region helpers for navigating an RFC 5322 message buffer without parsing it into owned structures.
resolver
DNS resolver trait for DKIM public-key TXT lookups.
sign
DKIM signer (RFC 6376 §3.7).
verifier
End-to-end DKIM verifier: parse DKIM-Signature → fetch public key → canonicalize → hash → verify signature.