emersion / go-msgauth Goto Github PK
View Code? Open in Web Editor NEW๐ A Go library and tools for DKIM, DMARC and Authentication-Results
License: MIT License
๐ A Go library and tools for DKIM, DMARC and Authentication-Results
License: MIT License
I did a profiling of my application, and noticed that msgauth/dkim
is comparing strings with ToLower
.
Lines 152 to 158 in e98a2ee
Line 244 in e98a2ee
EqualFold
.
WDYT ?
I can submit a benchmark if needed.
Hi, I'm playing with this library and I'm incurring in a strange issue.
In some case, when I try to generate a DKIM signature, the generated header get an extra "\r\n" that makes the mail invalid.
For istance, if I try to sign this email:
From: [email protected]
To: [email protected]
Subject: Send Test
Message-ID: <xxxxx@xxxxx>
Return-Path: <test@test>
Date: Mon, 09 Mar 2020 17:04:25 +0100
Message Body
I got this signed message
DKIM-Signature: a=rsa-sha256; bh=opmXtA9gMR670DN8CmqNEL8Q4RBdtB/ULgaN/SkjFn
0=; c=simple/simple; d=mail.ludusrusso.space; h=From:To:Subject:Message-ID:
Return-Path:Date; s=brisbane; t=1583769865; v=1; b=JHLkTc5vtTRA4udN9sAMcPWx
TLLfqQ6ry++3GLbcWjhR769N4hK7kaL2P1iseXaoVbQpxVGzZYz9x5P8q9brfYZEuuQciWPvk1n
k99E685amWpMsSqUnsHWifpeFtZpNHwPSVWJp03Kmeq2wE85+Fauq/P+7bVfRa/N1hUIFUpk=;
From: [email protected]
To: [email protected]
Subject: Send Test
Message-ID: <xxxxx@xxxxx>
Return-Path: <test@test>
Date: Mon, 09 Mar 2020 17:04:25 +0100
Message Body
notice that the extra black line added before From header makes the message to be worngly interpreded by a receiving SMTP.
The issues seems related to the length of the header, in fact if I try to add (or remove) headers from the message it works properly:
DKIM-Signature: a=rsa-sha256; bh=bvW0aiEWdP0ie2rawBb+IiTxlHI9KgEIYjEYTGzMRa
0=; c=simple/simple; d=mail.ludusrusso.space; h=X-Extra-Header:From:To:Subj
ect:Message-ID:Return-Path:Date; s=brisbane; t=1583770035; v=1; b=Rer+wvDGH
tVS7SwYC5kdouGz6Su0B0iEvegWcwQe4GcMERi5QfJWV8hDnjappa8KX1fst2YmhFjUST+Ai3zM
dyH1iKJiIm78Yt0n3c1f/95bP9Ey6xc1t1zYcJm3t/zQ8Sho/XjPRqdilOJYXPZB18y5JILnV67
69eKFcsnzmic=;
X-Extra-Header: extra header
From: [email protected]
To: [email protected]
Subject: Send Test
Message-ID: <xxxxx@xxxxx>
Return-Path: <test@test>
Date: Mon, 09 Mar 2020 17:07:15 +0100
Longer message body
Note the extra header here.
If you give me some tips, I could try to solve the issue and submit a PR!
It seems to me that the issue is due to the 76 char limitation of the message line.
Hi, this is not exactly an issue but an improvement.
There should be a flag where if someone only needs the DKIM signature instead of complete data (header + body).
r := strings.NewReader(mailString)
options := &dkim.SignOptions{
Domain: "example.org",
Selector: "brisbane",
Signer: privateKey,
}
var b bytes.Buffer
if err := dkim.Sign(&b, r, options); err != nil {
log.Fatal(err)
}
This provides complete data.
options := &dkim.SignOptions{
Domain: domain,
Selector: defaultKeySelector,
Signer: privateKey,
}
Here we can add another field like dkimSign : true
which only return the signature.
I have a verify issue with mails coming from gmail with attachments, i have cheked the mail with opendkim and other dkim libararys they Passed, but with go-msgauth i get body hash missmatch.
I have debugged it. Sometimes it happens that in the relaxedBodyCanonicalizer
produces a \r\r\n
which is written to the writer:
00000000: 6b48 4f53 636b 6748 3037 5662 4b4d 6557 kHOSckgH07VbKMeW
00000010: 424a 4841 2b59 6a41 4234 7750 3839 616e BJHA+YjAB4wP89an
00000020: 4344 4751 7135 4743 5431 344a 347a 3655 CDGQq5GCT14J4z6U
00000030: 7853 356c 6370 7648 7642 3373 6f5a 6944 xS5lcpvHvB3soZiD
00000040: 792f 4848 6334 2b76 5370 5869 0d0d 0a y/HHc4+vSpXi...
^--- \r\r \n
When i do a hotfix at the end of the Write() function:
func (c *relaxedBodyCanonicalizer) Write(b []byte) (int, error) {
...
if bytes.ContainsAny(canonical, "\r\r\n") {
canonical = bytes.ReplaceAll(canonical, []byte("\r\r\n"), []byte("\r\n"))
}
_, err := c.w.Write(canonical)
return written, err
}
the checksum is Valid! i think the fixCRLF() should be different in relaxed Mode I have attached a PR to fix this issue
Might as well remove it completely. It's too dangerous.
I use go-msgauth/dkim to verify signatures in my internal MDA.
In my development environment, I had an issue where mail was backed up for a few days. Once I fixed the issue and resumed queue processing at the upstream MTA, I began receiving a number of DKIM signature expiration failures.
It appears that the timestamp for verification is always the time at which the message was presented to the library.
https://github.com/emersion/go-msgauth/blob/master/dkim/verify.go#L268
I think it would be beneficial for both testing and delayed delivery if the caller could optionally present a timestamp to perform verification against rather than the current time.
I'm thinking of ways to make maddys DKIM support work well and it needs quite a lot of control over verification process for that. Here is my experience report so far:
Non-cancelable network I/O done by dkim.Verify makes latter less useful. Also, it is done not using
custom DNS resolver implementation provided by maddy.
Currently I have to serialize header to bytes.Buffer and then pass it to dkim.Verify.
Allowing to pass already parsed header would be nice.
It is not that important, as I can keep non-parsed header blob around and pass it to dkim.Verify, thus eliminating one part of the problem and hoping other is not that significant.
With that I would simply pass DKIM-Signature fields to dkim.ParseField, then fetch keys using replaceable DNS resolver with context.Context support, let dkim.ParseKey parse them and then finally pass everything to the dkim.VerifySig to do the actual verification.
Even more: I can take the subset of fields required for signature and pass it to dkim.VerifySig instead of resorting to serialize-then-parse hack. That could be complicated though, so I guess being able to simply pass go-message/textproto.Header is better..
This way I even will be able to distinguish different failure types and act accordingly (e.g. increase the "quarantine score" for messages with broken signatures, immediately quarantine messages with a signature without a corresponding key in DNS, but only if this is not caused by a temporary resolution error).
... or ...
Tell me what you think. I am willing to help with the implementation of whatever solution you think is better.
When the goroutine used in dkim.NewSigner
returns early due to some error, the done
channel never gets closed and thus the defer s.Close()
in dkim.Sign
blocks undefinitely.
This is a failing test:
package dkim_test
import (
"bytes"
"crypto/x509"
"encoding/pem"
"testing"
"github.com/emersion/go-msgauth/dkim"
)
func TestSignInvalidMessage(t *testing.T) {
rawMessage := bytes.NewBuffer([]byte("this is an invalid message"))
key := []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA2lasFKCWoAn6nBZ1J4WZP/5T2dfqHPW2iye5vzXyAFLTNr7v
nFYYj8XcUldneSXWzbvh47oZlyA3MEFn0ICrtg2nRXSeh6yjvuicoslNOtB1Z2lp
sjBJODIrhxRs/qSgv3h0AtlBXw8nFBUglaJrdxRo3AeWNIoSo0Ai9V2lTdi6Um4H
FL0eI2E5jg1G8ALt+g8JSp+hZh7y8z4xrW/8pikK71BTVhfoVqTwItS65uNRtzmw
27ymGNTJ62wfXEYilezDsOXamgvAMbGkPCAYMXvO0ChmKQtUdx+IAxba7pfFIobE
Gvt0eABOhlCIuplQwBbEhK1D30goV4KcNy6q3QIDAQABAoIBAQCRezbl96rlsECA
SKZ/UxGuBjSw7qFb8o1TY4Ds23EIrid2TvsxXFy5T8liREL6AjCCnTICnzn17M1Z
JfuafmHryGUwbmhDVtE0n6HfBeqjycqwwRhgVrQy8Zr3QrDta5yAeC40x7Y7NMmB
JCK2EacxjTPhiFyZXXbVuCKTA3blystm76JkXSov6i5wIpF6o5cvDvAkVRZSz0zY
XvkdGgGTjQlDLfiq7EGNipd8V7ikjS+o4egugc8LQuJ3cC/gEuMibU+ULuvkIhTy
6+Ylo122NmQnKau5WVNecXyMj3ltQqNNj2WPYFuiWtNW/reB5jX1exVZ/RzDwYiy
rj3W1kyBAoGBAP2BEBIg6CfJgQjw4ymMTqAhmG89RexKZS/9nipLDjL+MjGx2mJs
msfxboY9aXvGs6nS0f//dd1B83iMWrQNhrFbGdje8dvQsSIW+geFWyNHsKC95pOV
417TrtTEgPSwaljbpyeE5+Zd9L2XQAbAy6ZUTHUEfWx2azWY0kNQuRH1AoGBANx8
+jG152b5NsyWZ7UmDILThsNl76EJNt4XuNRzgWHV1wXLDeVSm7O+FgAM9bAIxc2E
TJOpxxeNurWm5vqzZqqgeb/4BUz5KAHCcp3yoKMQjixrtPeJiRt2z31YW0l6QU4S
kJ1qBtPlPt00dqPJXqfj6rON3fZnrVe9x9E80txJAoGAV9VG7zENnvN3TNTBsFyX
xW2+dhRhzLv+EUGrcnXs5ogidgtsYhvFCS/CnqpaiPNQvq936V3mxZGbPRJMPwRM
vdiVvQmJ/SJyrSAO41o2OKQXM6p4YHxXejyX38px79XMExuP7+ZhvvSg3quwGGbm
aKvejdDPcCwbe0eG2qH2bZ0CgYBstVHF4KHOq2DRTfaj4baZaiEvhbq38wsSRS/j
z28jBYOWX57iSfBqlnXSYJFh0XF0+p2m0DZQ7pf3p+qKAJnF1okwlOBIKzAGbhCE
v3Nj8m2miRQYV785w0JZ0o5vk89O5uhWNEhZgNWVyqAT8NyyejTlgjTFoChe8jrq
dsqfwQKBgQCVptrO3fMd+SaY3KBhw0ebEfJT7Q1mTv0LufIYpKxJ7Hb3+hRwJNoO
UdVdRNFimFJDULU76KuurvPEopZfI94uQB8zgzn/ENYWgWiIo4f1H/BqVzO4vEdN
01OSrsZ2QwyaBffRNc2QxX7ZGALmoaW7sJ+yXTf73+yS0tGQvyjfgQ==
-----END RSA PRIVATE KEY-----
`)
block, _ := pem.Decode([]byte(key))
if block == nil {
panic("no key")
}
dkimKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
panic("parse err")
}
opts := &dkim.SignOptions{
Domain: "example.com",
Selector: "selector",
Signer: dkimKey,
HeaderCanonicalization: dkim.CanonicalizationRelaxed,
BodyCanonicalization: dkim.CanonicalizationSimple,
HeaderKeys: []string{"From", "To"},
}
signedMessage := &bytes.Buffer{}
if err := dkim.Sign(signedMessage, rawMessage, opts); err != nil {
panic(err)
}
}
It should return an error.
It blocks indefinitely.
I would propose moving the close(done)
to the beginning of the goroutine as defer close(done)
in https://github.com/emersion/go-msgauth/blob/master/dkim/sign.go#L270
When s
is in a key's flags list, then:
Any DKIM-Signature header fields using the "i=" tag MUST have the same domain value on the right-hand side of the "@" in the "i=" tag and the value of the "d=" tag. That is, the "i=" domain MUST NOT be a subdomain of "d=". Use of this flag is RECOMMENDED unless subdomaining is required.
Currently, go-msgauth's DKIM verifier unconditionally allows the i=
domain to be a subdomain of d=
.
First off, thanks for the great work on this library!
Second, this issue is not directly related to go-msgauth
, but I was wondering if you could suggest a workaround. Also, I'm using this library through foxcpp/maddy
, and not directly.
So here goes:
I use namecheap for my DNS needs, but their emails fail to be delivered with the following line in my logs: dkim: key unavailable: lookup s1._domainkey.namecheap.com
. Upon closer examination, it looks like s1._domainkey.namecheap.com
is not a TXT record, but a CNAME that resolves to s1.domainkey.u1828068.wl069.sendgrid.net
.
What's more is that while nslookup
(provided by dnsutils
) on my (debian bookworm) server does not resolve CNAME records when looking up TXT records, the nslookup
(provided by bind
) on my (arch) desktop does so without any complaints.
Here's the output of both:
โฏ nslookup -type=txt s1._domainkey.namecheap.com
;; Truncated, retrying in TCP mode.
Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
s1._domainkey.namecheap.com canonical name = s1.domainkey.u1828068.wl069.sendgrid.net.
s1.domainkey.u1828068.wl069.sendgrid.net text = "k=rsa; t=s; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4EJ2WbK3G12fhP8hlHBTABlvdbKePJXwux+sjGXRnnoVdGAaw9q9D96qeW3uWqAbBSyPB06w4zTeK1qi7Ar+rBC91zKEiuoi6Rbd8xkDBG1Emo8RMhZjOHer5xl0TobynvYy6J4F/ge4OgA17nNDfc7n2Xg+OOKHVY4dVZfdgNR29eGraxD8X0E2pMBdNgtqKvt6S" "4irlnEuhvko+Ls3XqBicTnM30QO4ffyIJWlUqHEwVjBUHKXV+/sTif8UecWw2m9uLYlPbeNBAjMcRtmKYC+tKT39laA2mtPuQub9LHtgzkmAXqE9D7uvgc8gEoUgdvQyefKClRR/rKomB9CeQIDAQAB"
vs.
maddy@frodo:~$ nslookup -type=txt s1._domainkey.namecheap.com
;; Truncated, retrying in TCP mode.
;; Connection to xxx#53(xxx) for s1._domainkey.namecheap.com failed: timed out.
;; Connection to xxx#53(xxx) for s1._domainkey.namecheap.com failed: timed out.
;; Connection to xxx#53(xxx) for s1._domainkey.namecheap.com failed: timed out.
;; Connection to xxx#53(xxx) for s1._domainkey.namecheap.com failed: timed out.
;; Connection to xxx#53(xxx) for s1._domainkey.namecheap.com failed: timed out.
It also looks like the SendGrid key doesn't begin with v=DKIM1
, which the code explicitly ignores, but that's an issue for another day. I'll try reaching out to them to see if they will update their keys to conform to the RFC, but I don't have high hopes for that.
We already have a DKIM milter, we probbaly want a DMARC milter too.
ed25519: cannot sign hashed message
Setting hash to 0 for ed25519 and adding corresponding tests seems to reveal other problems (such as being unable to verify generated signatures). Need to look into it.
As discussed in https://tools.ietf.org/html/rfc6376#section-8.2, this should be used with care.
Maybe we should just choose not to support this, given the security issues it implies.
Error :
module github.com/emersion/go-msgauth@latest found (v0.4.0), but does not contain package github.com/emersion/go-msgauth
As the code in master is not tagged
Arcoding to https://tools.ietf.org/html/rfc8601:
reasonspec = "reason" [CFWS] "=" [CFWS] value
; a free-form comment on the reason the given result
; was returned
The "value" is as defined in Section 5.1 of [MIME], with
"quoted-string" updated as specified in [RFC6532].
For example:
var parseTests = []msgauthTest{
...
{
value: "example.com;" +
"dkim=pass reason=\"good signature\" [email protected];",
identifier: "example.com",
results: []Result{
&DKIMResult{Value: ResultPass, Reason: "good signature", Identifier: "@mail-router.example.net"},
},
},
}
Instead of good signature
, value of Reason is "good
.
I am reading the code and found that queryDNSTXT
may produce the wrong txt record using the default resolver net.LookupTXT
dkim/query.go
line 88 wrote that
// Long keys are split in multiple parts
txt := strings.Join(txts, "")
but the default resolve has already joined the txt record with multiple line.
// Multiple strings in one TXT record need to be
// concatenated without separator to be consistent
// with previous Go resolver.
n := 0
for _, s := range txt.TXT {
n += len(s)
}
txtJoin := make([]byte, 0, n)
for _, s := range txt.TXT {
txtJoin = append(txtJoin, s...)
}
if len(txts) == 0 {
txts = make([]string, 0, 1)
}
txts = append(txts, string(txtJoin))
So, if there are multiple records along with DKIM record. It will produce a wrong DKIM record, and the following parsePublicKey
will fail
According to rfc6376:
5.4. Determine the Header Fields to Sign
The From header field MUST be signed (that is, included in the "h="
tag of the resulting DKIM-Signature header field). Signers SHOULD
NOT sign an existing header field likely to be legitimately modified
or removed in transit. In particular, [RFC5321] explicitly permits
modification or removal of the Return-Path header field in transit.
This makes the dkim invalid
Please provide an externally usable API to run queries for DKIM records and see the parsed results.
Hi, I started playing with this lib today, so far so good...
But in some cases I got DKIM-Result: fail (bad signature)
when signing. I think it is because of the word wrapping on the headers.
I'm still researching how this should work, but so far it seems like a bug.
For example: this header is ok...
"DKIM-Signature: a=rsa-sha256; bh=1IgjdN5a9wQkm07TioMOwKf0/FIi4DDu2oUc6NEp6E\r\n
c=; c=relaxed/relaxed; d=XXXXXXXXXX.com.br; h=From:To:Subject:Message-ID; s\r\n
=2019; t=1573137354; v=1; b=z0oq308f6gtrdpGQp8RnYlvuIhCP/MTAP6x7jZd11hyBDrI\r\n
zXrFKBeg4Mg4/2KhxM7/yJ5frJ6qmApdDRTiRFRyOwj/QRvS6lZT1bLyblQLnZJEmJjCO4KK1L4\r\n
A4QZZorA2IuEA9h6k7XfA5FGydKEUwzXZOQCojCI950HSIaQM=;\r\n
..."
If I add another header on the mail message just to change the signature a little bit.
"DKIM-Signature: a=rsa-sha256; bh=1IgjdN5a9wQkm07TioMOwKf0/FIi4DDu2oUc6NEp6E\r\n
c=; c=relaxed/relaxed; d=XXXXXXXXXX.com.br; h=From:To:Subject:Message-ID:AB\r\n
CDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQ; s=2019;\r\n
t=1573138398; v=1; b=Ccb4SQE56OROMpx8Q8bFgsSz3lTypUcP/p/vSBPL2CXQJhT9evQsF\r\n
ROgsvTld1gXNbhFWp9wyjDXIsUBQS1L3LiWMeZpXfTcJx6MkpLG2h0IzjPBQ/jKnPT56CtKOdj2\r\n
SUQZ/GITsvQhurPgWfTq6G5jrMeMu6ZdXH3Vw/1GkmU=;\r\n
...
The DKIM starts to failing, probably because of that '\r\n' that was inserted on the middle of the header text.
Also, if the header had the right size the '\r\n' will be on the selector.
Like this: s=2\r\n 019
and will result in a DNS failure.
"DKIM-Signature: a=rsa-sha256; bh=1IgjdN5a9wQkm07TioMOwKf0/FIi4DDu2oUc6NEp6E\r\n
c=; c=relaxed/relaxed; d=XXXXXXXXXX.com.br; h=From:To:Subject:Message-ID:AB\r\n
CDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQABC; s=20\r\n
19; t=1573138139; v=1; b=QyQd6bbOy8OI1+r6t7g16CWU2kjS6tCK2ZOBsxXhEMnACZKVY3\r\n
ffO/5+RRgTOG748DO0zjQnuqOKPLF8O+DYQs/1fnkKbt04knC+1wNT5wK2ILgPERDlr3PG7rsNp\r\n
juE0VCkkVMgbVmamhb02qdevU/IX2qRpVOws0vr1MnqiG8=;\r\n
...
I'm not sure how others handle this... I'll keep looking.
Let me know if you have any clue.
AFAIK we can't have FWS (folded white spaces on that header value).
https://tools.ietf.org/html/rfc6376
This is the result from the same header being handled by nodemailer:
"DKIM-Signature: a=rsa-sha256;\r\n
bh=1IgjdN5a9wQkm07TioMOwKf0/FIi4DDu2oUc6NEp6Ec=; c=relaxed/relaxed;\r\n
d=XXXXXXXXXX.com.br;\r\n
h=From:To:Subject:Message-ID:ABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQ;\r\n
s=2019; t=1573138398; v=1;\r\n
b=Ccb4SQE56OROMpx8Q8bFgsSz3lTypUcP/p/vSBPL2CXQJhT9evQsFROgsvTld1gXNbhFWp9wyjDXIsUBQS1L3LiWMeZpXfTcJx6MkpLG2h0IzjPBQ/jKnPT56CtKOdj2SUQZ/GITsvQhurPgWfTq6G5jrMeMu6ZdXH3Vw/1GkmU=;\r\n
The RFC doesn't say to replace lone LF with CRLF.
https://github.com/emersion/go-dkim/blob/master/canonical.go#L19
We'll probably want to expose a DefaultVerifyOptions
variable to allow users to easily customize the defaults (e.g. keeping the default MaxVerifications
but change the default LookupTXT
).
In my application, nearly 50% of my memory allocations (in count) are caused by relaxedBodyCanonicalizer
.
Lines 130 to 158 in 6dd5b6c
I think this code could be optimized.
Currently each call to append
causes a new memory allocation and requires to copy the memory.
Because the slices are reset to nil.
It doesn't reuse the memory previously allocated.
The solution: do c.wspBuf = c.wspBuf[:0]
instead of c.wspBuf = nil
.
Same for crlfBuf
.
WDYT ?
Hi,
It would be nice to have the private function dkim.isFail() public available. In case of a "bad signature (body hash mismatched; bh=)" dkim.IsPermfail() and dkim.IsTempfail() returns false.
Thanks
Matthias
net.LookupTXT() returns a slice of strings, with one string for each TXT resource record returned. If there are multiple strings inside a TXT record it concatenates those before returning it.
dmarc.LookupWithOptions then concatenates all of those TXT resource records into a single string before parsing it.
If there are multiple TXT records for _dmarc.example.com it'll likely give the wrong response. That's not going to happen in
a healthy DNS zone, but it happens occasionally.
I think that correct behaviour would be for dmarc.LookupWithOptions to remove any TXT records that don't start with "v=", then return an error if there are more than one, then parse just the first remaining TXT RR, if any.
With #29 we no longer generate broken signatures with FWS where they shouldn't be. However we could still improve our folding algorithm. Given these constraints:
We may want to fix these:
h=
params if they are very longb=
params at 75 chars, but we don't need toThis would probably require to add a dkim.Verifier
type to allow library users to specify more options.
Hi, How to use your library? Can you give us a concrete example with the domain gmail.com?
NB: It is not issue
Hello,
I would like dkim-milter
to read config from a file. If you accept this feature, I could contribute it.
RFC 6376 Section 3.6.1 states that RSA public keys are encoded in the TXT record as "an ASN.1 DER-encoded [ITU-X660-1997] RSAPublicKey". This is the encoding produced by the dkim-keygen command.
Unfortunately, RFC 6376 contradicts itself in Appendix C, where it shows a public key in SubjectPublicKeyInfo format instead. Although Appendix C is only informative, it seems that other implementations have adopted it. opendkim's key generation tool uses SubjectPublicKeyInfo, as do the DKIM records for Gmail and Fastmail. Erratum 3017 has been filed against RFC 6376 proposing that both RSAPublicKey and SubjectPublicKeyInfo be allowed in the TXT record.
Currently, go-msgauth's DKIM verifier expects RSA public keys to use SubjectPublicKeyInfo format. If you try to verify a signature from a domain which uses RSAPublicKey format instead, you get this error:
dkim: key syntax error: x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)
I propose the following fix:
x509.ParsePKIXPublicKey
and x509.ParsePKCS1PublicKey
) in accordance with Erratum 3017.I'm happy to submit a PR for this.
This one for instance: https://lists.sr.ht/~sirodoht/mataroa-community/%3Co7uwxdbkfoyrelu5qgudcaetsg54kjeiywdecsqnwk5e6zkqjf%402kw32aoe7zt4%3E/raw
Invalid signature for startmail.com: dkim: signature did not verify: crypto/rsa: verification error
Hi,
Some of the providers doesn't include v tag on DKIM record as it wasn't specified as required in older versions of DKIM standard. It would be great if it was optional or fallback to DKIM1
if no v
tag was specified on TXT record.
Here are some of the examples of DKIM records without v tag:
Sendgrid:
dig s1._domainkey.sendgrid.com TXT
;; ANSWER SECTION:
s1._domainkey.sendgrid.com. 1800 IN CNAME s1.domainkey.u298828.wl079.sendgrid.net.
s1.domainkey.u298828.wl079.sendgrid.net. 1800 IN TXT "k=rsa; t=s; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2LaY8C3pdtdkSF6C+TTYw0bIKAHt70oFeM5IAHb0aLVY7mSWmjWmPHtV6MGbr4n35ABRKpobn40DJGLU7NmjaT54TDTLLsU2DjEFi+p6VQtHdqprrbFNXt5YmQmnYdsHQ0gSe/nyb6PwoX5q92HexVxfT4/etJ+WKnOf4rk2vZplVoeiaxT5Cxench8SzFLa9u1Ur" "JTdFHkWuVl3aR64Up2bOfR3u9uXjkvMXwX0NdjsZeF0GXi1fqUQXg8s7VriECC2TiioWcB0AWPJoGeNfgGO7O6Oj1mdLPQQJrxqzManJrKp43yS9cO+GVXCf92hPTb93nrAWQjehoRbS/rCrQIDAQAB"
GitLab:
dig mailo._domainkey.mg.gitlab.com TXT
;; ANSWER SECTION:
mailo._domainkey.mg.gitlab.com. 300 IN TXT "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqxee1GPSB+mZgCWVbzP8T+YbV+rxnw+3vPIkylf/mvD3jHBH4Ac66B2wSFAz/mFv+ormOZUKzoHaFZdjIcXhpT91h+Lpl21TJKbKTZ/oiX4y5YXOatENLuZM/W+HEyqi9fbV51IOUG9er4kKw29tEQG+DEBtr882ygr7T2WcAFwIDAQAB"
Note:
Line 91 in 6610fd7
RFC 6376 6.1.1
not in RFC 7489 6.6.3
as this RFC is about DMARC records not DKIM.Hi, I am using go-msgauth for DKIM signing, great work congratulations !!!
I have problems with DKIM Signature in Gmail for a few email contents, for these content DKIM signature keep getting failed.
for an example :
ARC-Authentication-Results: i=1; mx.google.com;
dkim=neutral (body hash did not verify) [email protected] header.s=mail header.b=T6i602+P;
spf=softfail (google.com: domain of transitioning [email protected] does not designate 35.205.54.170 as permitted sender) smtp.mailfrom="[email protected]";
dmarc=fail (p=QUARANTINE sp=REJECT dis=QUARANTINE) header.from=sendinblue.com
Return-Path: <[email protected]>
Received: from af.d.mailin.fr (170.54.205.35.bc.googleusercontent.com. [35.205.54.170])
by mx.google.com with ESMTPS id s9si2177413wrw.217.2020.11.04.06.51.40
for <[email protected]>
(version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);
Wed, 04 Nov 2020 06:51:40 -0800 (PST)
Received-SPF: softfail (google.com: domain of transitioning [email protected] does not designate 35.205.54.170 as permitted sender) client-ip=35.205.54.170;
Authentication-Results: mx.google.com;
dkim=neutral (body hash did not verify) [email protected] header.s=mail header.b=T6i602+P;
spf=softfail (google.com: domain of transitioning [email protected] does not designate 35.205.54.170 as permitted sender) smtp.mailfrom="[email protected]";
dmarc=fail (p=QUARANTINE sp=REJECT dis=QUARANTINE) header.from=sendinblue.com
DKIM-Signature: a=rsa-sha256; bh=tsJuZ3BBjTNiYd1Pko8h9O45UrrLuZSBfAKIytHhm2o=; c=relaxed/relaxed; d=sendinblue.com; h=to:cc:from:reply-to:subject:date:mime-version:content-type:list-id:list-unsubscribe:x-csa-complaints:list-unsubscribe-post:message-id:sender:x-sib-id:x-mailin-client:x-mailin-campaign:feedback-id; q=dns/txt; s=mail; t=1604501499; v=1; b=T6i602+P7mdrFC4aPd9dKM/58FXn60O9mj6x+7LdlvBQrUQIrPUOL4yjhtkn7fUAqxvs30Vt DihM3qpitLU+zh8aMOQQT/WNoThsxwJC/QRzWxdilJxVKj6Sni6ekbrbWhzsPTD02sSZgaLq9Cg xydC4YDTgmYjGTxh43Qu1Na8=
complete headers are:
DKIM-Signature: a=rsa-sha256; bh=tsJuZ3BBjTNiYd1Pko8h9O45UrrLuZSBfAKIytHhm2o=; c=relaxed/relaxed; d=sendinblue.com; h=to:cc:from:reply-to:subject:date:mime-version:content-type:list-id:list-unsubscribe:x-csa-complaints:list-unsubscribe-post:message-id:sender:x-sib-id:x-mailin-client:x-mailin-campaign:feedback-id; q=dns/txt; s=mail; t=1604501499; v=1; b=T6i602+P7mdrFC4aPd9dKM/58FXn60O9mj6x+7LdlvBQrUQIrPUOL4yjhtkn7fUAqxvs30Vt DihM3qpitLU+zh8aMOQQT/WNoThsxwJC/QRzWxdilJxVKj6Sni6ekbrbWhzsPTD02sSZgaLq9Cg xydC4YDTgmYjGTxh43Qu1Na8=
To: <[email protected]>
Subject: TEST - TOKEN
Content-Type: multipart/related; boundary="-------?=_15190-7781879174214"
Date: Wed, 04 Nov 2020 14:51:39 +0000
Feedback-ID: 185.41.28.6:2039507_20:2039507:Sendinblue
From: SendInBlue <[email protected]>
List-Id: MjAzOTUwNy05LTA= <MjAzOTUwNy05LTA=.list-id.mailin.fr>
List-Unsubscribe: <mailto:[email protected]?subject=unsub-q8f58wqygj&body=q8f58wqygj>,<https://r-auto-staging.51b.tech:4443/mk/un/li/OzndvdDOLEokf1e4v6_EcvlIfdLOPM7UEIkT8y2Qz1Is0lAlpXwDqIP4tUB8nJm_TLLR2QXxcNP05U-aEMZIHTue_kleNlwVhy9c8oKzw4WJUqThT71cCUtifsq_iXF-fnktEkUy1Jnj4si5kohK6zOUzxyJTTgZ>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
MIME-Version: 1.0
Message-Id: <[email protected]>
Precedence: bulk
Reply-To: [email protected]
X-Mailer: Sendinblue
X-Mailin-Campaign: 20
X-Mailin-Client: 2039507
X-sib-id: _YOHDLQjhQ2BrGXt57vL3A4UFIAMU8R9CSPxtOoJn865p0B2RADz3R3oIYC5c-YWGG_JPVf9N917KoSGd0PbI1Ol45-lALTkOTh5YmjUucT_Gtn8cUX4s4agq_KPIXaJ4EJFvkFYcGSeVYfdVuoxxrtVwP6VotoAoN0XhflPUB2FDQ
PS: DKIM is not failing for every email and for every domain. for few contents it keeps failing
Any Idea? Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.