1// Copyright (c) 2020 Shivaram Lingamneni
2// released under the MIT license
3
4package email
5
6import (
7	"errors"
8	dkim "github.com/toorop/go-dkim"
9	"os"
10)
11
12var (
13	ErrMissingFields = errors.New("DKIM config is missing fields")
14)
15
16type DKIMConfig struct {
17	Domain   string
18	Selector string
19	KeyFile  string `yaml:"key-file"`
20	keyBytes []byte
21}
22
23func (dkim *DKIMConfig) Postprocess() (err error) {
24	if dkim.Domain != "" {
25		if dkim.Selector == "" || dkim.KeyFile == "" {
26			return ErrMissingFields
27		}
28		dkim.keyBytes, err = os.ReadFile(dkim.KeyFile)
29		if err != nil {
30			return err
31		}
32	}
33	return nil
34}
35
36var defaultOptions = dkim.SigOptions{
37	Version:               1,
38	Canonicalization:      "relaxed/relaxed",
39	Algo:                  "rsa-sha256",
40	Headers:               []string{"from", "to", "subject", "message-id", "date"},
41	BodyLength:            0,
42	QueryMethods:          []string{"dns/txt"},
43	AddSignatureTimestamp: true,
44	SignatureExpireIn:     0,
45}
46
47func DKIMSign(message []byte, dkimConfig DKIMConfig) (result []byte, err error) {
48	options := defaultOptions
49	options.PrivateKey = dkimConfig.keyBytes
50	options.Domain = dkimConfig.Domain
51	options.Selector = dkimConfig.Selector
52	err = dkim.Sign(&message, options)
53	return message, err
54}
55