Skip to content

Commit

Permalink
Fix folding signature algorithm
Browse files Browse the repository at this point in the history
Closes: #18
Co-authored-by: Ludovico Russo <[email protected]>
  • Loading branch information
ludusrusso and Ludovico Russo authored May 28, 2020
1 parent e4c8736 commit fb07ec9
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 34 deletions.
55 changes: 34 additions & 21 deletions dkim/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,35 +92,48 @@ func parseHeaderParams(s string) (map[string]string, error) {
return params, nil
}

func formatHeaderParams(params map[string]string) string {
keys := make([]string, 0, len(params))
found := false
for k := range params {
if k == "b" {
found = true
} else {
keys = append(keys, k)
func formatHeaderParams(headerFieldName string, params map[string]string) string {
keys, bvalue, bfound := sortParams(params)

s := headerFieldName + ":"
var line string

for _, k := range keys {
v := params[k]
nextLength := 3 + len(line) + len(v) + len(k)
if nextLength > 75 {
s += line + crlf
line = ""
}
line = fmt.Sprintf("%v %v=%v;", line, k, v)
}
sort.Strings(keys)
if found {
keys = append(keys, "b")

if line != "" {
s += line
}

var s string
first := true
for _, k := range keys {
v := params[k]
if bfound {
bfiled := foldHeaderField(" b=" + bvalue)
s += crlf + bfiled
}

if first {
first = false
return s
}

func sortParams(params map[string]string) ([]string, string, bool) {
keys := make([]string, 0, len(params))
bfound := false
var bvalue string
for k := range params {
if k == "b" {
bvalue = params["b"]
bfound = true
} else {
s += " "
keys = append(keys, k)
}

s += k + "=" + v + ";"
}
return s
sort.Strings(keys)
return keys, bvalue, bfound
}

type headerPicker struct {
Expand Down
38 changes: 36 additions & 2 deletions dkim/header_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,48 @@ func TestFormatHeaderParams(t *testing.T) {
"d": "example.org",
}

expected := "a=rsa-sha256; d=example.org; v=1;"
expected := "DKIM-Signature: a=rsa-sha256; d=example.org; v=1;"

s := formatHeaderParams(params)
s := formatHeaderParams("DKIM-Signature", params)
if s != expected {
t.Errorf("Expected formatted params to be %q, but got %q", expected, s)
}
}

func TestLongHeaderFolding(t *testing.T) {
// see #29 and #27

params := map[string]string{
"v": "1",
"a": "rsa-sha256",
"d": "example.org",
"h": "From:To:Subject:Date:Message-ID:Long-Header-Name",
}

expected := "DKIM-Signature: a=rsa-sha256; d=example.org;\r\n h=From:To:Subject:Date:Message-ID:Long-Header-Name; v=1;"

s := formatHeaderParams("DKIM-Signature", params)
if s != expected {
t.Errorf("Expected formatted params to be\n\n %q\n\n, but got\n\n %q", expected, s)
}
}

func TestSignedHeaderFolding(t *testing.T) {
hValue := "From:To:Subject:Date:Message-ID:Long-Header-Name:Another-Long-Header-Name"

params := map[string]string{
"v": "1",
"a": "rsa-sha256",
"d": "example.org",
"h": hValue,
}

s := formatHeaderParams("DKIM-Signature", params)
if !strings.Contains(s, hValue) {
t.Errorf("Signed Headers names (%v) are not well folded in the signed header %q", hValue, s)
}
}

func TestParseHeaderParams_malformed(t *testing.T) {
_, err := parseHeaderParams("abc; def")
if err == nil {
Expand Down
4 changes: 2 additions & 2 deletions dkim/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ func Sign(w io.Writer, r io.Reader, options *SignOptions) error {
}

func formatSignature(params map[string]string) string {
sig := headerFieldName + ": " + formatHeaderParams(params)
return foldHeaderField(sig)
sig := formatHeaderParams(headerFieldName, params)
return sig
}

func formatTagList(l []string) string {
Expand Down
9 changes: 5 additions & 4 deletions dkim/sign_ed25519_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (
"testing"
)

const signedEd25519MailString = "DKIM-Signature: a=ed25519-sha256; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJ" + "\r\n" +
" " + "VOzv8=; c=simple/simple; d=football.example.com; h=From:To:Subject:Date:Mes" + "\r\n" +
" " + "sage-ID; s=brisbane; t=424242; v=1; b=ZduPZq83AOTqjhScIfHll6W90tMG1nf34a34Q" + "\r\n" +
" " + "XKat3iFtP7NQE/3AwnHOrcsR2r5nVNoW+LeZURpT2obCthPCw==;" + "\r\n" +
const signedEd25519MailString = "DKIM-Signature: a=ed25519-sha256; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;" + "\r\n" +
" " + "c=simple/simple; d=football.example.com;" + "\r\n" +
" " + "h=From:To:Subject:Date:Message-ID; s=brisbane; t=424242; v=1;" + "\r\n" +
" " + "b=k1LzRxs9/DfN/whlMICYKNIJhqUSmup0d5yw8tpi+Cfiqe6I3oSBmJ+HEp+moWy7/XvcUY/t" + "\r\n" +
" " + "ERHc3D2m7vw1AA==" + "\r\n" +
mailHeaderString +
"\r\n" +
mailBodyString
Expand Down
11 changes: 6 additions & 5 deletions dkim/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ const mailBodyString = "Hi.\r\n" +

const mailString = mailHeaderString + "\r\n" + mailBodyString

const signedMailString = "DKIM-Signature: a=rsa-sha256; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv" + "\r\n" +
" " + "8=; c=simple/simple; d=example.org; h=From:To:Subject:Date:Message-ID; s=br" + "\r\n" +
" " + "isbane; t=424242; v=1; b=bXtqB8uOEvtd1Xv/DHatdjb9onP0+vnzdYBbPMZm1qrRmhSuFH" + "\r\n" +
" " + "WsbkETafswNvJ4VqNX0gMoaYvzcmoMkUhW9m4pgZqR5y+62yA+B7WJCd6mz82UVkS1qEJeGjMxX" + "\r\n" +
" " + "mmPDkmLDA5HHL5LLTc3DLrxkwWMLzwrhQL48WhNFD1d6L4=;" + "\r\n" +
const signedMailString = "DKIM-Signature: a=rsa-sha256; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;" + "\r\n" +
" " + "c=simple/simple; d=example.org; h=From:To:Subject:Date:Message-ID;" + "\r\n" +
" " + "s=brisbane; t=424242; v=1;" + "\r\n" +
" " + "b=MobyyDTeHhMhNJCEI6ATNK63ZQ7deSXK9umyzAvYwFqE6oGGvlQBQwqr1aC11hWpktjMLP1/" + "\r\n" +
" " + "m0PBi9v7cRLKMXXBIv2O0B1mIWdZPqd9jveRJqKzCb7SpqH2u5kK6i2vZI639ENTQzRQdxSAGXc" + "\r\n" +
" " + "PcPYjrgkqj7xklnrNBs0aIUA=" + "\r\n" +
mailHeaderString +
"\r\n" +
mailBodyString
Expand Down

0 comments on commit fb07ec9

Please sign in to comment.