NAME
Mail::DKIM2::Signer - Sign a message with a DKIM2-Signature header
SYNOPSIS
use Mail::DKIM2::Signer;
# A signature covers a Message-Instance, so a message that has none yet
# gets one first (an originating hop: m=1).
use Mail::DKIM2::MessageInstance;
use Mail::DKIM2::Common qw(fold_header);
unless ($message =~ /^Message-Instance:/mi) {
my $mi = Mail::DKIM2::MessageInstance->calculate($message);
$message = fold_header('Message-Instance: ' . $mi->as_string) . "\r\n" . $message;
}
my $signer = Mail::DKIM2::Signer->new(
Domain => 'example.com',
Selector => 'sel1',
KeyFile => '/etc/dkim2/sel1.pem',
MailFrom => '<sender@example.com>',
RcptTo => ['<recipient@example.net>'],
);
# One shot ...
$signer->load($message);
# ... or streaming, with CRLF line endings
$signer->PRINT($chunk) for @chunks;
$signer->CLOSE;
die $signer->result_detail unless $signer->result eq 'signed';
my $header = $signer->as_string; # "DKIM2-Signature: i=1; ..." (folded)
# The same message to several envelope recipients: one pass, one cheap
# signature per recipient.
for my $rcpt (@rcpts) {
my $header = $signer->sign_for_recipient($rcpt);
}
DESCRIPTION
Adds a DKIM2-Signature header for this hop. The message must already carry the Message-Instance header this hop wants to sign over (see Mail::DKIM2::MessageInstance; a message with none is a fail); the Signer reads the existing Message-Instance and DKIM2-Signature headers, chooses the next i=, builds the signing input of spec-06 section 8.5, and signs it. It does not alter the message: the caller prepends the header as_string returns.
Extends Mail::DKIM2::HeaderParser, which provides PRINT, CLOSE, load and the tie interface.
This module implements draft-ietf-dkim-dkim2-spec-06; see "STATUS" in Mail::DKIM2 for what that means for the wire format and the API, and "CONVENTIONS" in Mail::DKIM2 for the option, input and error conventions every module here follows.
CONSTRUCTOR
new(%options)
Required:
- Domain
-
The signing domain, the
d=tag. - Selector
-
The selector of the key, published at
<Selector>._domainkey.<Domain>. - Key or KeyFile
-
The private key as a Crypt::PK::RSA or Crypt::PK::Ed25519 object, or the path of a PEM file holding one (loaded with "load_private_key" in Mail::DKIM2::Common).
Optional:
- Algorithm
-
rsa-sha256(the default) ored25519-sha256. - MailFrom
-
The envelope sender of this hop, recorded in
mf=. Bare addresses are bracketed;'<>'or undef records the null sender. - RcptTo
-
An arrayref of this hop's envelope recipients, recorded in
rt=. - NextDomain
-
The
d=of the hop that will sign next, recorded innd=for an imaginary forwarding hop (spec-06 section 9.3). ExcludesMailFromandRcptTo. - Timestamp
-
The
t=value; defaults to now. Fix it for reproducible test output. - Nonce
-
The
n=value, at most 64 characters. - Flags
-
An arrayref of
f=flags, such asdonotmodify.
An option not listed here croaks.
METHODS
PRINT($bytes), CLOSE(), load($input)
Feed the message; see Mail::DKIM2::HeaderParser.
result()
Undef until CLOSE; then 'signed', or 'fail' when the message cannot be signed (no Message-Instance to sign over, a chain already at the length limit, or a repeated i= or m=). A failure is a result, not an exception: PRINT and CLOSE return normally.
details()
The reason for a 'fail' result, or undef.
result_detail()
result and details together, e.g. "fail (PERMERROR ...)".
as_string()
The complete DKIM2-Signature: ... header, folded for insertion, or the empty string if there is no signature. The folding is part of what was signed and must not be changed.
signature()
The Mail::DKIM2::Signature object, available after CLOSE.
sign_for_recipient($rcpt)
Re-signs for a different envelope recipient (one address or an arrayref of them) and returns the folded header. Spec-06 section 9.6 signs only the Message-Instance and DKIM2-Signature fields, so the body and header hashes in the Message-Instance are the same for every recipient and only rt= changes; an extra recipient costs one signature over a few hundred bytes, not another pass over the message. Feed the message once, then call this per recipient. Croaks on a signature carrying nd=, which excludes rt=.
AUTHOR
Bron Gondwana <brong@fastmailteam.com>
COPYRIGHT AND LICENSE
Copyright (c) 2025-2026 Fastmail Pty Ltd. This is free software; you can redistribute it and/or modify it under the same terms as Perl itself.