dkim

package
v0.53.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 2, 2024 License: BSD-3-Clause Imports: 19 Imported by: 0

Documentation

Overview

Package dkim provide a library to parse and create DKIM-Signature header field value, as defined in RFC 6376, DomainKeys Identified Mail (DKIM) Signatures.

The process to signing and verying a message is handled by parent package "lib/email", not by this package.

Index

Constants

This section is empty.

Variables

View Source
var (
	DefaultKeyPool = &KeyPool{
		pool: make(map[string]*Key),
	}
)

DefaultKeyPool contains cached DKIM key.

Implementor of this library can use the KeyPool.Get method to retrieve key instead of LookupKey to minimize network traffic and process to decode and parse public key.

View Source
var DefaultNameServers []string

DefaultNameServers contains list of nameserver's IP addresses.

If its not empty, the public key lookup using DNS/TXT will use this values; otherwise it will try to use the system name servers.

Functions

func Canonicalize

func Canonicalize(raw []byte) (out []byte)

Canonicalize a simple or relaxed input of DKIM-Signature value by removing the value of tag "b=" and CRLF at the end.

For example, "v=1; b=base64; bh=base64\r\n" would become "v=1; b=; bh=base64".

func DecodeQP

func DecodeQP(raw []byte) (out []byte)

DecodeQP decode DKIM quoted printable text.

Types

type Canon

type Canon byte

Canon define type of canonicalization algorithm.

const (
	CanonSimple Canon = iota // "simple" (default)
	CanonRelaxed
)

List of valid and known canonicalization algorithms.

type HashAlg

type HashAlg byte

HashAlg define the type for hash algorithm.

const (
	HashAlgALL    HashAlg = iota // (default to allow all)
	HashAlgSHA256                // sha256
	HashAlgSHA1                  // sha1
)

List of valid and known hash algorithms.

type Key

type Key struct {
	// Type of key.
	// ("k=", plain-text, OPTIONAL, default is "rsa").
	Type *KeyType

	// RSA contains parsed Public key.
	RSA *rsa.PublicKey

	// Public contains public key data.
	// ("p=", base64, REQUIRED)
	Public []byte

	// Version of DKIM key record.
	// ("v=", plain-text, RECOMMENDED, default is "DKIM1")
	Version []byte

	// HashAlgs contains list of hash algorithm that might be used.
	// ("h=", plain-text colon-separated,  OPTIONAL, defaults to allowing
	// all algorithms)
	HashAlgs []HashAlg

	// Notes that might be interest to human.
	// ("n=", qp-section, OPTIONAL, default is empty)
	Notes []byte

	// Services contains list of service types to which this record
	// applies.
	// ("s=", plain-text colon-separated, OPTIONAL, default is "*").
	Services [][]byte

	// Flags contains list of flags.
	// ("t=", plain-text colon-separated, OPTIONAL, default is no flags set)
	Flags []KeyFlag

	// ExpiredAt define time when the key will be expired.
	// This is a local value derived from lookup time + RR TTL.
	ExpiredAt int64
}

Key represent a DKIM key record.

func LookupKey

func LookupKey(qmethod QueryMethod, dname string) (key *Key, err error)

LookupKey DKIM (public) key using specific query method and DKIM domain name (selector plus SDID).

func ParseTXT

func ParseTXT(txt []byte, ttl uint32) (key *Key, err error)

ParseTXT parse DNS TXT resource record into Key.

func (*Key) IsExpired

func (key *Key) IsExpired() bool

IsExpired will return true if key ExpiredAt time is less than current time; otherwise it will return false.

func (*Key) Pack

func (key *Key) Pack() string

Pack the key to be used in DNS TXT record.

type KeyFlag

type KeyFlag byte

KeyFlag define a type of key flag in DKIM key record.

const (
	// KeyFlagTesting or "y" in text, indicate that domain is for testing
	// DKIM.
	KeyFlagTesting KeyFlag = iota

	// KeyFlagStrict or "s" in text, means that the domain in AUID ("i=")
	// tag value MUST equal or subdomain of SDID "d=" tag value.
	KeyFlagStrict
)

List of valid key flags.

type KeyPool

type KeyPool struct {
	sync.Mutex
	// contains filtered or unexported fields
}

KeyPool maintain cached DKIM public keys.

func (*KeyPool) Clear

func (kp *KeyPool) Clear()

Clear the contents of key pool.

func (*KeyPool) Get

func (kp *KeyPool) Get(dname string) (key *Key, err error)

Get cached DKIM key from pool or lookup using DNS/TXT method if not exist.

func (*KeyPool) Put

func (kp *KeyPool) Put(dname string, key *Key)

Put key to pool based on DKIM domain name ("d=" value plus "s=" value).

func (*KeyPool) String

func (kp *KeyPool) String() string

String return text representation of DKIM key inside pool sorted by domain name. Each key is printed with the following format: "{DomainName:ExpiredAt}"

type KeyType

type KeyType byte

KeyType define a type of algorithm that sign the key.

const (
	KeyTypeRSA KeyType = iota // "rsa" (default)
)

List of valid key types.

type QueryMethod

type QueryMethod struct {
	Type   QueryType
	Option QueryOption
}

QueryMethod define a type and option to retrieve public key. An empty QueryMethod will use default type and option, which is "dns/txt".

type QueryOption

type QueryOption byte

QueryOption define an option for query.

const (
	QueryOptionTXT QueryOption = iota // "txt" (default)
)

List of valid and known query option.

type QueryType

type QueryType byte

QueryType define type for query.

const (
	QueryTypeDNS QueryType = iota // "dns" (default)
)

List of valid and known query type.

type SignAlg

type SignAlg byte

SignAlg define the type of signing and verification algorithm.

const (
	SignAlgRS256 SignAlg = iota // rsa-sha256 (default)
	SignAlgRS1                  // rsa-sha1
)

List of valid and known signing/verifying algorithms.

type Signature

type Signature struct {
	// Algorithm used to generate the signature.
	// Valid values is "rsa-sha1" or "rsa-sha256".
	// ("a=", text, REQUIRED).
	Alg *SignAlg

	// Type of canonicalization for header.  Default is "simple".
	// ("c=header/body", text, OPTIONAL).
	CanonHeader *Canon

	// Type of canonicalization for body.  Default is "simple".
	// ("c=header/body", text, OPTIONAL).
	CanonBody *Canon

	// The number of octets in body, after canonicalization, included when
	// computing hash.
	// If nil, its means entire body is signed.
	// If 0, its means the body is not signed.
	// ("l=", text, OPTIONAL).
	BodyLength *uint64

	// QMethod define a type and option used to retrieve the public keys.
	// ("q=type/option", text, OPTIONAL).  Default is "dns/txt".
	QMethod *QueryMethod

	// Version of specification.
	// It MUST have the value "1" for compliant with RFC 6376.
	// ("v=", text, REQUIRED).
	Version []byte

	// Signer domain
	// ("d=", text, REQUIRED).
	SDID []byte

	// The selector subdividing the namespace for the "d=" tag.
	// ("s=", text, REQUIRED).
	Selector []byte

	// List of header field names included in signing or verifying.
	// ("h=", text, REQUIRED).
	Headers [][]byte

	// The hash of canonicalized body data.
	// ("bh=", base64, REQUIRED).
	BodyHash []byte

	// The signature data.
	// ("b=", base64, REQUIRED)
	Value []byte

	// List of header field name and value that present when the message
	// is signed.
	// ("z=", dkim-quoted-printable, OPTIONAL).  Default is null.
	PresentHeaders [][]byte

	// The agent or user identifier.
	// Default is "@" + "d=" value)
	// ("i=", dkim-quoted-printable, OPTIONAL).
	AUID []byte

	// Time when signature created, in UNIX timestamp.
	// ("t=", text, RECOMMENDED).
	CreatedAt uint64

	// Expiration time, in UNIX timestamp.
	// ("x=", text, RECOMMENDED).
	ExpiredAt uint64
	// contains filtered or unexported fields
}

Signature represents the value of DKIM-Signature header field tag.

func NewSignature

func NewSignature(sdid, selector []byte) (sig *Signature)

NewSignature create and initialize new signature using SDID ("d=") and selector ("s=") and default value for the rest of field.

func Parse

func Parse(value []byte) (sig *Signature, err error)

Parse DKIM-Signature field value. The signature value MUST be end with CRLF.

func (*Signature) Hash

func (sig *Signature) Hash(in []byte) (h, h64 []byte)

Hash compute the hash of input using the defined signature algorithm and return their binary and base64 representation.

func (*Signature) Pack

func (sig *Signature) Pack(simple bool) []byte

Pack the Signature into stream. Each non empty tag field is printed, ordered by tag priority: required, recommended, and optional. Recommended and optional field values will be printed only if its not empty.

func (*Signature) Relaxed

func (sig *Signature) Relaxed() []byte

Relaxed return the "relaxed" canonicalization of Signature.

func (*Signature) SetDefault

func (sig *Signature) SetDefault()

SetDefault signature field's values.

The default values are "sha-rsa256" for signing algorithm, and "relaxed/relaxed" for canonicalization in header and body.

func (*Signature) Sign

func (sig *Signature) Sign(pk *rsa.PrivateKey, hashHeader []byte) (err error)

Sign compute the signature of message hash header using specific private key and store the base64 result in Signature.Value ("b=").

func (*Signature) Simple

func (sig *Signature) Simple() []byte

Simple return the "simple" canonicalization of Signature.

func (*Signature) Validate

func (sig *Signature) Validate() (err error)

Validate the signature's tag values.

Rules of tags,

* Tags MUST NOT duplicate. This was already handled by parser.

* All the required fields MUST NOT be empty or nil.

* The "h=" tag MUST include the "From" header field

* The value of the "x=" tag MUST be greater than the value of the "t=" tag if both are present.

* The "d=" value MUST be the same or parent domain of "i="

func (*Signature) Verify

func (sig *Signature) Verify(key *Key, headerHash []byte) (err error)

Verify the signature value ("b=") using DKIM public key record and computed hash of message header.

type Status

type Status struct {
	Error error      // Error contains the cause of failed verification.
	SDID  []byte     // SDID in signature ("d=" tag).
	Type  StatusType // Type of status.
}

Status represent the result of DKIM verification.

type StatusType

type StatusType byte

StatusType define type of status.

const (
	// StatusUnverify means that the signature has not been verified.
	StatusUnverify StatusType = iota

	// StatusNoSignature no dkim signature in message.
	StatusNoSignature

	// StatusOK the signature is valid.
	StatusOK

	// StatusTempFail the signature could not be verified at this time but
	// may be tried again later.
	StatusTempFail

	// StatusPermFail the signature failed and should not be reconsidered.
	StatusPermFail
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL