Mail::D...erifier(3)
okay bestie, you're on the Mail::DKIM::Verifier(3) page from User Contributed Perl Documentation, and this is the DKIM verifier manual. Yes, the whole thing is about checking DKIM-signed mail. Let's go, because this is lowkey iconic. π
πΈ NAME πΈ
Mail::DKIM::Verifier β verifies a DKIM-signed message. That's the whole assignment, and it ate. β¨
π VERSION π
version 1.20240923 π«Ά
β¨ SYNOPSIS β¨
Here's the vibe in code, exactly as the page says:
use Mail::DKIM::Verifier;
# create a verifier object
my $dkim = Mail::DKIM::Verifier->new();
# read an email from a file handle
$dkim->load(*STDIN);
# or read an email and pass it into the verifier, incrementally
while (<STDIN>)
{
# remove local line terminators
chomp;
s/\015$//;
# use SMTP line terminators
$dkim->PRINT("$_\015\012");
}
$dkim->CLOSE;
# what is the result of the verify?
my $result = $dkim->result;
# there might be multiple signatures, what is the result per signature?
foreach my $signature ($dkim->signatures)
{
print 'signature identity: ' . $signature->identity . "\n";
print 'verify result: ' . $signature->result_detail . "\n";
}
# the alleged author of the email may specify how to handle email
foreach my $policy ($dkim->policies)
{
die 'fraudulent message' if ($policy->apply($dkim) eq 'reject');
}
π DESCRIPTION π
So the verifier object lets you scan an email message for DKIM and DomainKeys signatures, and then it verifies those signatures. The verifier is literally tracking the state of the message as it gets read into memory. When the message has been completely read, the signatures get verified, and then you can access the results of that verification. Obsessed. π
To use the verifier, first create the verifier object. Then start feeding it the email message you want verified. When all the headers have been read, the verifier:
- checks whether any DomainKeys/DKIM signatures were found
- queries for the public keys needed to verify the signatures
- sets up the appropriate algorithms and canonicalization objects
- canonicalizes the headers and computes the header hash
Then, when the body of the message has been completely fed into the verifier, the body hash is computed and the signatures are verified.
You can check the results of the verification with result() or signatures(). π¦
If a message doesn't verify, you can check it against the alleged sender's published signing policy with policies() and apply() in Mail::DKIM::Policy.
π¦ CONSTRUCTOR π¦
π§ new() π§
This is how you construct an object-oriented verifier, bestie:
my $dkim = Mail::DKIM::Verifier->new();
my $dkim = Mail::DKIM::Verifier->new(%options);
The only options supported at this time are:
Debug_Canonicalizationβ if specified, the canonicalized message for the first signature is written to the referenced string or file handle. Peek-behind-the-curtain moment, honestly. πStrictβ if true, it rejectssha1hashes and signing keys shorter than1024bits. Like, stricter vibe check. π
π METHODS π
okay bestie, this is the part where we actually do stuff with the verifier. stay with me, it's giving very much βgroup project but everyone actually pulled their weightβ energy π β¨
π PRINT()
Feeds part of the message to the verifier.
$dkim->PRINT("a line of the message\015\012");
$dkim->PRINT('more of');
$dkim->PRINT(" the message\015\012bye\015\012");
This feeds the content of the message being verified into the verifier. The API is designed this way so that the entire message does NOT need to be read into memory at once β literally so efficient of it πΈ
Please note that although the PRINT() method expects you to use SMTP-style line termination characters, you should NOT use the SMTP-style dot-stuffing technique described in RFC 2821 section 4.5.2. Nor should you use a <CR><LF>.<CR><LF> sequence to terminate the message. no cap, don't do it π«Ά
π CLOSE()
Call this when finished feeding in the message.
$dkim->CLOSE;
This method finishes the canonicalization process, computes a hash, and verifies the signature. it's the βokay we're done, do the thingβ button β¨
π¦ fetch_author_domain_policies()
Retrieves ADSP records from DNS.
my @policies = $dkim->fetch_author_domain_policies;
foreach my $policy (@policies)
{
my $policy_result = $policy->apply($dkim);
}
This method will retrieve all applicable "author-domain-signing-practices" published in DNS for this message. Author policies are keyed to the email address(es) in the From: header, i.e. the claimed author of the message.
This method returns a list of policy records, since there is allowed to be zero or multiple email addresses in the From: header. yes bestie, a list β plural rights π
The result of the apply() method is one of: "accept", "reject", "neutral".
See also: "policies()".
π§ fetch_author_policy()
Retrieves a signing policy from DNS.
my $policy = $dkim->fetch_author_policy;
my $policy_result = $policy->apply($dkim);
This method retrieves the DKIM Sender Signing Practices record as described in Internet Draft draft-ietf-dkim-ssp-00-01dc. This Internet Draft is now obsolete; this method is only kept for backward-compatibility purposes. it's giving legacy code that refuses to leave the group chat π
Please use the "policies()" method instead. seriously, use the newer one π«Ά
π fetch_sender_policy()
Retrieves a signing policy from DNS.
my $policy = $dkim->fetch_sender_policy;
my $policy_result = $policy->apply($dkim);
The "sender" policy is the sender signing policy as described by the DomainKeys specification, now available in RFC4870(historical). I call it the "sender" policy because it is keyed to the email address in the Sender: header, or the From: header if there is no Sender header. This is the person whom the message claims as the "transmitter" of the message (not necessarily the author). okay so sender β author and that distinction is lowkey important π
If the email being verified has no From or Sender header from which to get an email address (which violates email standards), then this method will "die". dramatic? yes. valid? also yes π
The result of the apply() method is one of: "accept", "reject", "neutral".
See also: "policies()".
π load()
Load the entire message from a file handle.
$dkim->load($file_handle);
Reads a complete message from the designated file handle, feeding it into the verifier. The message must use <CRLF> line terminators (same as the SMTP protocol). keep those line endings cute and correct β¨
π message_originator()
Access the "From" header.
my $address = $dkim->message_originator;
Returns the "originator address" found in the message, as a Mail::Address object. This is typically the (first) name and email address found in the From: header. If there is no From: header, then an empty Mail::Address object is returned.
To get just the email address part, do:
my $email = $dkim->message_originator->address;
See also "message_sender()".
π message_sender()
Access the "From" or "Sender" header.
my $address = $dkim->message_sender;
Returns the "sender" found in the message, as a Mail::Address object. This is typically the (first) name and email address found in the Sender: header. If there is no Sender: header, it is the first name and email address in the From: header. If neither header is present, then an empty Mail::Address object is returned.
To get just the email address part, do:
my $email = $dkim->message_sender->address;
The "sender" is the mailbox of the agent responsible for the actual transmission of the message. For example, if a secretary were to send a message for another person, the "sender" would be the secretary and the "originator" would be the actual author. it's giving βwho actually hit sendβ vs βwho wrote the thingβ π
πΈ policies()
Retrieves applicable signing policies from DNS.
my @policies = $dkim->policies;
foreach my $policy (@policies)
{
$policy_result = $policy->apply($dkim);
# $policy_result is one of "accept", "reject", "neutral"
}
This method searches for and returns any signing policies that would apply to this message. Signing policies are selected based on the domain that the message claims to be from. So, for example, if a message claims to be from security@bank, and forwarded by trusted@listserv, when in reality the message came from foe@evilcorp, this method would check for signing policies for security@bank and trusted@listserv. The signing policies might tell whether foe@evilcorp (the real sender) is allowed to send mail claiming to be from your bank or your listserv. the audacity of foe@evilcorp honestly π
I say "might tell", because in reality this is still really hard to specify with any accuracy. In addition, most senders do not publish useful policies. shrug emoji, but make it cybersecurity π«
π₯ result()
Access the result of the verification.
my $result = $dkim->result;
Gives the result of the verification. The following values are possible:
passβ Returned if a valid DKIM-Signature header was found, and the signature contains a correct value for the message. slay β¨failβ Returned if a valid DKIM-Signature header was found, but the signature does not contain a correct value for the message.invalidβ Returned if a DKIM-Signature could not be checked because of a problem in the signature itself or the public key record. I.e. the signature could not be processed.temperrorβ Returned if a DKIM-Signature could not be checked due to some error which is likely transient in nature, such as a temporary inability to retrieve a public key. A later attempt may produce a better result.noneβ Returned if no DKIM-Signature headers (valid or invalid) were found.
In case of multiple signatures, the "best" result will be returned. Best is defined as "pass", followed by "fail", "invalid", and "none". To examine the results of individual signatures, use the "signatures()" method to retrieve the signature objects. See "result()" in Mail::DKIM::Signature.
π result_detail()
Access the result, plus details if available.
my $detail = $dkim->result_detail;
The detail is constructed by taking the result (e.g. "pass", "fail", "invalid" or "none") and appending any details provided by the verification process in parenthesis.
The following are possible results from the result_detail() method:
pass
fail (bad RSA signature)
fail (OpenSSL error: ...)
fail (message has been altered)
fail (body has been altered)
invalid (bad identity)
invalid (invalid domain in d tag)
invalid (missing q tag)
invalid (missing d tag)
invalid (missing s tag)
invalid (unsupported version 0.1)
invalid (unsupported algorithm ...)
invalid (unsupported canonicalization ...)
invalid (unsupported query protocol ...)
invalid (signature is expired)
invalid (public key: not available)
invalid (public key: unknown query type ...)
invalid (public key: syntax error)
invalid (public key: unsupported version)
invalid (public key: unsupported key type)
invalid (public key: missing p= tag)
invalid (public key: invalid data)
invalid (public key: does not support email)
invalid (public key: does not support hash algorithm 'sha1')
invalid (public key: does not support signing subdomains)
invalid (public key: revoked)
invalid (public key: granularity mismatch)
invalid (public key: granularity is empty)
invalid (public key: OpenSSL error: ...)
none
π signature()
Access the message's DKIM signature.
my $sig = $dkim->signature;
Accesses the signature found and verified in this message. The returned object is of type Mail::DKIM::Signature.
In case of multiple signatures, the signature with the "best" result will be returned. Best is defined as "pass", followed by "fail", "invalid", and "none".
π¦ signatures()
Access all of this message's signatures.
my @all_signatures = $dkim->signatures;
Use $signature->result or $signature->result_detail to access the verification results of each signature.
π AUTHORS
- Jason Long
<jason@long.name> - Marc Bradshaw
<marc@marcbradshaw.net> - Bron Gondwana
<brong@fastmailteam.com>(ARC)
π«Ά THANKS
Work on ensuring that this module passes the ARC test suite was generously sponsored by Valimail (https://www.valimail.com/). sponsorship that ate, honestly πβ¨
π COPYRIGHT AND LICENSE
- Copyright (C) 2013 by Messiah College
- Copyright (C) 2010 by Jason Long
- Copyright (C) 2017 by Standcore LLC
- Copyright (C) 2020 by FastMail Pty Ltd
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.6 or, at your option, any later version of Perl 5 you may have available.
okay that's the whole page bestie! this little icon was served up by perl v5.42.0, dated 2024-09-23, and it lives under Mail::D...erifier(3) β mwah πβ¨
π¦ where this page comes from
- alpine 3.23: perl-mail-dkim-doc 1.20240923-r0 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- opensuse-leap 16.0: perl-Mail-DKIM 1.20240923-bp160.1.2 Β· Artistic-1.0 OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms