Documentation
¶
Overview ¶
Package dkim implements DomainKeys Identified Mail (DKIM) signatures per RFC 6376.
DKIM allows a sender to associate a domain name with an email message, thus vouching for its authenticity. A message is signed by adding a DKIM-Signature header, which contains a cryptographic signature of the message headers and body.
This implementation supports:
- RSA-SHA256 (required by RFC 6376)
- RSA-SHA1 (deprecated, but supported for compatibility)
- Ed25519-SHA256 (RFC 8463)
Basic Usage ¶
Signing a message:
signer := dkim.Signer{
Domain: "example.com",
Selector: "selector1",
PrivateKey: privateKey,
}
signature, err := signer.Sign(message)
Verifying a message:
results, err := dkim.Verify(ctx, resolver, message)
for _, r := range results {
if r.Status == dkim.StatusPass {
// Signature verified
}
}
Index ¶
- Variables
- func IsTemporaryError(err error) bool
- func QuickSign(mail *ravenmail.Mail, domain, selector string, privateKey crypto.Signer) error
- func SignMail(mail *ravenmail.Mail, signer *Signer) error
- func SignMailMultiple(mail *ravenmail.Mail, signers []Signer) error
- func SignMultiple(message []byte, signers []Signer) (string, error)
- type Algorithm
- type Canonicalization
- type Record
- type Result
- func Verify(ctx context.Context, resolver ravendns.Resolver, message []byte) ([]Result, error)
- func VerifyMailContext(ctx context.Context, mail *ravenmail.Mail, resolver ravendns.Resolver) ([]Result, error)
- func VerifyReader(ctx context.Context, resolver ravendns.Resolver, message io.ReaderAt) ([]Result, error)
- type Signature
- type Signer
- type Status
- type Verifier
Constants ¶
This section is empty.
Variables ¶
var ( // DNS lookup errors. ErrNoRecord = errors.New("dkim: no DKIM DNS record found") ErrMultipleRecords = errors.New("dkim: multiple DKIM DNS records found") ErrDNS = errors.New("dkim: DNS lookup failed") ErrSyntax = errors.New("dkim: syntax error in DKIM record") // Signature verification errors. ErrSigAlgMismatch = errors.New("dkim: signature algorithm mismatch with DNS record") ErrHashAlgNotAllowed = errors.New("dkim: hash algorithm not allowed by DNS record") ErrKeyNotForEmail = errors.New("dkim: DNS record not allowed for email") ErrDomainIdentityMismatch = errors.New("dkim: domain and identity mismatch") ErrSigExpired = errors.New("dkim: signature has expired") ErrHashAlgorithmUnknown = errors.New("dkim: unknown hash algorithm") ErrBodyHashMismatch = errors.New("dkim: body hash does not match") ErrSigVerify = errors.New("dkim: signature verification failed") ErrSigAlgorithmUnknown = errors.New("dkim: unknown signature algorithm") ErrCanonicalizationUnknown = errors.New("dkim: unknown canonicalization") ErrHeaderMalformed = errors.New("dkim: mail header is malformed") ErrFromRequired = errors.New("dkim: From header is required") ErrQueryMethod = errors.New("dkim: no recognized query method") ErrKeyRevoked = errors.New("dkim: key has been revoked") ErrWeakKey = errors.New("dkim: key is too weak") ErrPolicy = errors.New("dkim: signature rejected by policy") ErrMissingTag = errors.New("dkim: missing required tag") ErrDuplicateTag = errors.New("dkim: duplicate tag") ErrInvalidVersion = errors.New("dkim: invalid version") ErrTLD = errors.New("dkim: signed domain is top-level domain") ErrBodyHashLength = errors.New("dkim: body hash length mismatch") )
Common errors.
var DefaultSignedHeaders = []string{
"From",
"To",
"Cc",
"Subject",
"Date",
"Message-ID",
"In-Reply-To",
"References",
"MIME-Version",
"Content-Type",
"Content-Transfer-Encoding",
"Content-Disposition",
"Reply-To",
}
DefaultSignedHeaders is the default list of headers to sign. These headers are commonly signed for message integrity.
var MinimumSignedHeaders = []string{
"From",
"To",
"Subject",
"Date",
}
MinimumSignedHeaders is the minimum set of headers that should be signed.
Functions ¶
func IsTemporaryError ¶
IsTemporaryError returns true if the error is temporary.
func SignMail ¶
SignMail signs a mail message and adds the DKIM-Signature header. This is a convenience function for signing mail objects.
func SignMailMultiple ¶
SignMailMultiple signs a mail message with multiple signers.
func SignMultiple ¶
SignMultiple signs the message with multiple selectors. Returns multiple DKIM-Signature headers concatenated. This function caches body hashes to avoid recomputation when multiple signers use the same canonicalization and hash algorithm.
Types ¶
type Algorithm ¶
type Algorithm string
Algorithm represents a DKIM signing algorithm.
const ( // AlgRSASHA256 is the RSA-SHA256 algorithm (required by RFC 6376). AlgRSASHA256 Algorithm = "rsa-sha256" // AlgRSASHA1 is the deprecated RSA-SHA1 algorithm. AlgRSASHA1 Algorithm = "rsa-sha1" // AlgEd25519SHA256 is the Ed25519-SHA256 algorithm (RFC 8463). AlgEd25519SHA256 Algorithm = "ed25519-sha256" )
type Canonicalization ¶
type Canonicalization string
Canonicalization represents header/body canonicalization algorithms.
const ( // CanonSimple uses the "simple" canonicalization algorithm. CanonSimple Canonicalization = "simple" // CanonRelaxed uses the "relaxed" canonicalization algorithm. CanonRelaxed Canonicalization = "relaxed" )
type Record ¶
type Record struct {
// Version is the record version, must be "DKIM1".
Version string
// Hashes is the list of acceptable hash algorithms (e.g., "sha256", "sha1").
// Empty means all algorithms are acceptable.
Hashes []string
// Key is the key type: "rsa" (default) or "ed25519".
Key string
// Notes contains optional human-readable notes.
Notes string
// Pubkey is the raw public key data (base64-decoded).
// Empty means the key has been revoked.
Pubkey []byte
// Services lists acceptable service types.
// Empty or containing "*" means all services.
Services []string
// Flags contains key flags:
// "y" - Domain is testing DKIM
// "s" - i= domain must exactly match d= domain
Flags []string
// PublicKey is the parsed public key.
// This is *rsa.PublicKey or ed25519.PublicKey.
PublicKey any
}
Record represents a DKIM DNS TXT record (RFC 6376 Section 3.6.1). The record is retrieved from <selector>._domainkey.<domain>.
func ParseRecord ¶
ParseRecord parses a DKIM DNS TXT record. Returns the parsed record and a boolean indicating if it's a DKIM record.
func (*Record) HashAllowed ¶
HashAllowed returns true if the given hash algorithm is allowed.
func (*Record) RequireStrictAlignment ¶
RequireStrictAlignment returns true if strict alignment is required (t=s).
func (*Record) ServiceAllowed ¶
ServiceAllowed returns true if the given service is allowed by this key.
type Result ¶
type Result struct {
// Status is the verification result.
Status Status
// Signature is the parsed DKIM-Signature header.
Signature *Signature
// Record is the parsed DKIM DNS record.
Record *Record
// RecordAuthentic indicates if a trusted validating recursive resolver
// authenticated the DNS record lookup.
RecordAuthentic bool
// Err contains any error that occurred during verification.
Err error
}
Result represents the result of verifying a single DKIM-Signature.
type Signature ¶
type Signature struct {
// Required fields
Version int // v= Version, must be 1
Algorithm string // a= Algorithm (e.g., "rsa-sha256")
Signature []byte // b= Signature data
BodyHash []byte // bh= Body hash
Domain string // d= Signing domain
SignedHeaders []string // h= Signed header fields
Selector string // s= Selector
// Optional fields
Canonicalization string // c= Canonicalization (e.g., "relaxed/simple")
Identity string // i= Agent or User Identifier (AUID)
Length int64 // l= Body length limit (-1 if not set)
QueryMethods []string // q= Query methods
SignTime int64 // t= Signature timestamp (-1 if not set)
ExpireTime int64 // x= Signature expiration (-1 if not set)
CopiedHeaders []string // z= Copied header fields
}
Signature represents a parsed DKIM-Signature header (RFC 6376 Section 3.5).
func NewSignature ¶
func NewSignature() *Signature
NewSignature creates a new Signature with default values.
func ParseSignature ¶
ParseSignature parses a DKIM-Signature header value. The input should include the header name (DKIM-Signature:). Returns the parsed signature and the original header with b= value removed (for signature verification).
func (*Signature) AlgorithmHash ¶
AlgorithmHash returns the hash algorithm part (e.g., "sha256" from "rsa-sha256").
func (*Signature) AlgorithmSign ¶
AlgorithmSign returns the signing algorithm part (e.g., "rsa" from "rsa-sha256").
func (*Signature) BodyCanon ¶
func (s *Signature) BodyCanon() Canonicalization
BodyCanon returns the body canonicalization algorithm.
func (*Signature) Header ¶
Header generates the DKIM-Signature header string. If includeSignature is false, the b= value is left empty for signing.
func (*Signature) HeaderCanon ¶
func (s *Signature) HeaderCanon() Canonicalization
HeaderCanon returns the header canonicalization algorithm.
type Signer ¶
type Signer struct {
// Domain is the signing domain (d= tag).
Domain string
// Selector is the selector for the signing key (s= tag).
Selector string
// PrivateKey is the signing key.
// Supported types: *rsa.PrivateKey, ed25519.PrivateKey
PrivateKey crypto.Signer
// Headers is the list of headers to sign.
// If empty, DefaultSignedHeaders is used.
Headers []string
// HeaderCanonicalization is the header canonicalization algorithm.
// Default is CanonRelaxed.
HeaderCanonicalization Canonicalization
// BodyCanonicalization is the body canonicalization algorithm.
// Default is CanonRelaxed.
BodyCanonicalization Canonicalization
// Hash is the hash algorithm name (e.g., "sha256").
// Default is "sha256".
Hash string
// Identity is the signing identity (i= tag).
// If empty, defaults to "@" + Domain.
Identity string
// Expiration is the signature validity period.
// If zero, no expiration is set.
Expiration time.Duration
// OversignHeaders causes header names to be repeated to prevent header addition.
// When enabled, each header in Headers is signed one more time than it appears
// in the message, which prevents additional headers with the same name from
// being added later.
OversignHeaders bool
}
Signer provides DKIM message signing.
type Status ¶
type Status string
Status represents the result of DKIM verification per RFC 8601.
const ( // StatusNone indicates the message was not signed. StatusNone Status = "none" // StatusPass indicates the signature was verified successfully. StatusPass Status = "pass" // StatusFail indicates the signature verification failed. StatusFail Status = "fail" // StatusPolicy indicates the signature is not accepted by policy. StatusPolicy Status = "policy" // StatusNeutral indicates the signature could not be processed. StatusNeutral Status = "neutral" // StatusTemperror indicates a temporary error (e.g., DNS timeout). StatusTemperror Status = "temperror" // StatusPermerror indicates a permanent error (e.g., invalid syntax). StatusPermerror Status = "permerror" )
type Verifier ¶
type Verifier struct {
// Resolver is the DNS resolver to use.
Resolver ravendns.Resolver
// IgnoreTestMode ignores the t=y flag in DKIM records.
// When false (default), signatures from domains in test mode
// that fail verification return StatusNone instead of StatusFail.
IgnoreTestMode bool
// Policy is a function that can reject signatures based on policy.
// Return an error to reject the signature with StatusPolicy.
// If nil, all signatures are accepted.
Policy func(*Signature) error
// MinRSAKeyBits is the minimum RSA key size to accept.
// Default is 1024 (per RFC 8301).
MinRSAKeyBits int
}
Verifier provides DKIM signature verification.