Skip to content

Commit

Permalink
adds support for DKIM flags. fixes emersion#44
Browse files Browse the repository at this point in the history
  • Loading branch information
gowthamgts committed Jul 31, 2021
1 parent 5995b67 commit 5294351
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 1 deletion.
8 changes: 8 additions & 0 deletions dkim/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ const dnsPublicKey = "v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ" +
"/RtdC2UzJ1lWT947qR+Rcac2gbto/NMqJ0fzfVjH4OuKhi" +
"tdY9tf6mcwGjaNBcWToIMmPSPDdQPNUYckcQ2QIDAQAB"

const dnsPublicKeySFlag = "v=DKIM1; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ" +
"KBgQDwIRP/UC3SBsEmGqZ9ZJW3/DkMoGeLnQg1fWn7/zYt" +
"IxN2SnFCjxOCKG9v3b4jYfcTNh5ijSsq631uBItLa7od+v" +
"/RtdC2UzJ1lWT947qR+Rcac2gbto/NMqJ0fzfVjH4OuKhi" +
"tdY9tf6mcwGjaNBcWToIMmPSPDdQPNUYckcQ2QIDAQAB"

const dnsEd25519PublicKey = "v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo="

func init() {
Expand All @@ -31,6 +37,8 @@ func queryTest(domain, selector string, txtLookup txtLookupFunc) (*queryResult,
return parsePublicKey(dnsRawRSAPublicKey)
case "brisbane._domainkey.football.example.com":
return parsePublicKey(dnsEd25519PublicKey)
case "helsinki._domainkey.example.com":
return parsePublicKey(dnsPublicKeySFlag)
}
return nil, fmt.Errorf("unknown test DNS record %v", record)
}
2 changes: 1 addition & 1 deletion dkim/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ type SignOptions struct {
//
// The whole message header and body must be written to the Signer. Close should
// always be called (either after the whole message has been written, or after
// an error occured and the signer won't be used anymore). Close may return an
// an error occurred and the signer won't be used anymore). Close may return an
// error in case signing fails.
//
// After a successful Close, Signature can be called to retrieve the
Expand Down
14 changes: 14 additions & 0 deletions dkim/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,20 @@ func verify(h header, r io.Reader, sigField, sigValue string, options *VerifyOpt
return verif, permFailError("unsupported public key query method")
}

// Parse flags
for _, flag := range res.Flags {
switch flag {
case "y":
// domain is testing DKIM.
return verif, nil
case "s":
// i domain and d domain should be equal
if !strings.HasSuffix(verif.Identifier, "@"+verif.Domain) {
return verif, permFailError("identifier and domain mismatch")
}
}
}

// Parse algos
algos := strings.SplitN(stripWhitespace(params["a"]), "-", 2)
if len(algos) != 2 {
Expand Down
90 changes: 90 additions & 0 deletions dkim/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,3 +294,93 @@ func TestVerify_tooManySignatures(t *testing.T) {
t.Fatalf("Expected %v verifications, got %v", options.MaxVerifications, len(verifs))
}
}

const validSignatureWithSFlag = `DKIM-Signature: a=rsa-sha256; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
c=simple/simple; d=example.com;
h=Received:From:To:Subject:Date:Message-ID; s=helsinki; t=1627654546; v=1;
b=IKIukw2EoRWxb86Ke2ingZFWLoAeNnKYAwGghFe1y0bbn5QLSoyk78o36JXT8z1DzmPquMHt
C//jnBna6DtqBneiKAUo3OyYmv1+EbTWWEvHGGtUkrKge2VdIXM3ttaOpuTHJRG+6irPKq0Ul4T
Ofa99PVg4o6nfY6Ctakv3aYc=
Received: from helsinki.example.com [192.0.2.1]
by submitserver.example.com with SUBMISSION;
Fri, 11 Jul 2003 21:01:54 -0700 (PDT)
From: Joe Helsinki <[email protected]>
To: Suzie Q <[email protected]>
Subject: Is dinner ready?
Date: Fri, 11 Jul 2021 21:00:37 -0700 (PDT)
Message-ID: <[email protected]>
Hi.
We lost the game. Are you hungry yet?
Joe.`

var testSFlagVerification = &Verification{
Domain: "example.com",
Identifier: "@example.com",
HeaderKeys: []string{"Received", "From", "To", "Subject", "Date", "Message-ID"},
Time: time.Unix(1627654546, 0),
}

func TestVerify_SFlag(t *testing.T) {
r := newMailStringReader(validSignatureWithSFlag)

verifications, err := Verify(r)
if err != nil {
t.Fatalf("Expected no error while verifying signature with flags, got: %v", err)
} else if len(verifications) != 1 {
t.Fatalf("Expected exactly one verification with flags, got %v", len(verifications))
}

v := verifications[0]
if !reflect.DeepEqual(testSFlagVerification, v) {
t.Errorf("Expected verification with flags to be \n%+v\n but got \n%+v", testSFlagVerification, v)
}
}

const invalidSignatureWithSFlag = `DKIM-Signature: a=rsa-sha256; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
c=simple/simple; d=example.com;
h=Received:From:To:Subject:Date:Message-ID; [email protected];
s=helsinki; t=1627654996; v=1;
b=k07JuWvk3PZkanimQ0QtIXRwXC5W4EhG/0sPH+r7zWKQ731fNZE//9+ofz+vcA3K5YQ0cOR2
EXY9qjriMPHFlaYsKZ4gj5YebNhRHyjJ9xlsTPNtFLqs9wnnaKCZu3VxJpualfTaY+Vs3RMjYLq
7IvOY4tqxnifJg2uFC/5kRbY=
Received: from helsinki.example.com [192.0.2.1]
by submitserver.example.com with SUBMISSION;
Fri, 11 Jul 2003 21:01:54 -0700 (PDT)
From: Joe Helsinki <[email protected]>
To: Suzie Q <[email protected]>
Subject: Is dinner ready?
Date: Fri, 11 Jul 2021 21:00:37 -0700 (PDT)
Message-ID: <[email protected]>
Hi.
We lost the game. Are you hungry yet?
Joe.`

var testSFlagVerificationFail = &Verification{
Domain: "example.com",
Identifier: "[email protected]",
HeaderKeys: []string{"Received", "From", "To", "Subject", "Date", "Message-ID"},
Time: time.Unix(1627654996, 0),
Err: permFailError("identifier and domain mismatch"),
}

func TestVerify_InvalidSFlag(t *testing.T) {
r := newMailStringReader(invalidSignatureWithSFlag)

verifications, err := Verify(r)
if err != nil {
t.Fatalf("Expected no error while verifying signature with flags, got: %v", err)
} else if len(verifications) != 1 {
t.Fatalf("Expected exactly one verification with flags, got %v", len(verifications))
}

v := verifications[0]
if !reflect.DeepEqual(testSFlagVerificationFail, v) {
t.Errorf("Expected verification with flags to be \n%+v\n but got \n%+v", testSFlagVerificationFail, v)
}
}

0 comments on commit 5294351

Please sign in to comment.