Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve folding signature algorithm #29

Merged
merged 5 commits into from
May 28, 2020

Conversation

ludusrusso
Copy link
Contributor

@ludusrusso ludusrusso commented May 22, 2020

Following #27, I've rewritten the folding algorithm in order to better fold headers and avoid introducing new lines inside headers.

However, it seems it breaks the skim sign.

In my understanding, this should have been call after the signature was generated, but it seems that the new algorithm changes the generates signature itself.

Any help?

@ludusrusso
Copy link
Contributor Author

Example output:

        DKIM-Signature: a=ed25519-sha256;
         bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; c=simple/simple;
         d=football.example.com; h=From:To:Subject:Date:Message-ID; s=brisbane;
         t=424242; v=1;
         b=CtvfpO96cCh7+PJLDna/bOJ1WdQ2qt7Nfrq6FzJqjYQv+TjOUc+rWk81TQJnmvdZsCDbmpr2
         hj7RDH4JDGa0CA==

@ludusrusso ludusrusso changed the title WIP: Improve format signature algorithm WIP: Improve folding signature algorithm May 22, 2020
@foxcpp
Copy link
Contributor

foxcpp commented May 24, 2020

In my understanding, this should have been call after the signature was generated, but it seems that the new algorithm changes the generates signature itself.

The likely issue is addition of non-empty b= that changes how folding behaves. I tried to integrate go-message/textproto algorithm into go-msgauth and hit the exactly same issue.
You can observe it by adding fmt.Println for sigField here:

hashed := hasher.Sum(nil)

and for formatSignature(s.sigParams) here:
s.sigParams = params

It is important to make sure both values are equal (with the exception of b= vs b=BASE64).

@foxcpp
Copy link
Contributor

foxcpp commented May 24, 2020

In your case, it shows:

DKIM-Signature: a=rsa-sha256;
 bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; c=simple/simple;
 d=example.org; h=From:To:Subject:Date:Message-ID; s=brisbane; t=424242;
 v=1;
DKIM-Signature: a=rsa-sha256;
 bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; c=simple/simple;
 d=example.org; h=From:To:Subject:Date:Message-ID; s=brisbane; t=424242;
 v=1;
 b=KXuOIdcHesiuc+CNVJC0ooTO9LvodnM01dstXNTA7elICw7r9LKD5zrPnGwtP5Ye+sOndhJO
 23pJIY3LP5oXzCnV3nkZiEwIb0rKIgYxgxx8JfCWbZgurhN35rQjnwCtmcGvN1aJ7ba1x1x63Vf
 xp0zwssLR2w8R+PkR4r1ROlM=

Uh, missing b=?

Copy link
Contributor

@foxcpp foxcpp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a problem with b= handling that causes generation of broken signatures. Additionally, I would appreciate if you add more test cases to ensure it generates valid signatures in edge cases related to folding.

dkim/header.go Outdated
}
}
sort.Strings(keys)
if found {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never set to anything other than false.

dkim/header.go Outdated
}

if bvalue != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty string is a valid value. The DKIM-Signature contents are signed with b=.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh thanks, I've got it now! It seems it works :D

@codecov-commenter
Copy link

codecov-commenter commented May 24, 2020

Codecov Report

Merging #29 into master will increase coverage by 0.31%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #29      +/-   ##
==========================================
+ Coverage   66.30%   66.62%   +0.31%     
==========================================
  Files           7        7              
  Lines         837      845       +8     
==========================================
+ Hits          555      563       +8     
  Misses        213      213              
  Partials       69       69              
Impacted Files Coverage Δ
dkim/header.go 93.68% <100.00%> (+0.58%) ⬆️
dkim/sign.go 68.58% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e4c8736...a231a2f. Read the comment docs.

@ludusrusso
Copy link
Contributor Author

Additionally, I would appreciate if you add more test cases to ensure it generates valid signatures in edge cases related to folding.

Yea! I'll add some additional test cases! To be honest, I did not added more test before because they are covered by TestSign

@ludusrusso
Copy link
Contributor Author

Now, if we have some part of the header longher than 75cahrs, the new algorithm will break the line length limit. This should not be an issues since this limit is only a recommendation! What do you think? #18 (comment)

Anyway this should fix #18

@foxcpp
Copy link
Contributor

foxcpp commented May 24, 2020

I agree that 75 chars limitation can be ignored. Following rationale in RFC, it is not really relevant today as a rare person looks at message header.

@ludusrusso
Copy link
Contributor Author

@foxcpp thanks! I've also added a more test that checks only if the headers names in the "h" values are properly folded in the generated signature!

@ludusrusso ludusrusso changed the title WIP: Improve folding signature algorithm Improve folding signature algorithm May 24, 2020
@foxcpp
Copy link
Contributor

foxcpp commented May 24, 2020

FWIW, That's the h= value my mail server used for a typical plaintext message:

Subject:Subject:Sender:To:To:Cc:From:From:Date:Date:MIME-Version:Content-Type:Content-Type:Content-Transfer-Encoding:Reply-To:In-Reply-To:Message-Id:Message-Id:References:Autocrypt:Openpgp

Interesting is that old folding algorithm broke it in the middle of a field name yet
OpenDKIM verified the signature successfully:
https://paste.dn42.us/paste/#/8T1GgumCllH0ZGDbwvOI8dvNYA8!TqXFCKZWbnYkBUP4_rBv1Fd3e-OVScQBZDav2mXSMw4

@foxcpp
Copy link
Contributor

foxcpp commented May 24, 2020

@emersion, what do you think about this PR?

@ludusrusso
Copy link
Contributor Author

FWIW, That's the h= value my mail server used for a typical plaintext message:

Subject:Subject:Sender:To:To:Cc:From:From:Date:Date:MIME-Version:Content-Type:Content-Type:Content-Transfer-Encoding:Reply-To:In-Reply-To:Message-Id:Message-Id:References:Autocrypt:Openpgp

Interesting is that old folding algorithm broke it in the middle of a field name yet
OpenDKIM verified the signature successfully:
https://paste.dn42.us/paste/#/8T1GgumCllH0ZGDbwvOI8dvNYA8!TqXFCKZWbnYkBUP4_rBv1Fd3e-OVScQBZDav2mXSMw4

I also notice this! I've tried with different mail provider receivers and in some case (like hotmail/outlook) the dkim fails while other (like gmail) it passes.

dkim/header.go Outdated Show resolved Hide resolved
dkim/header.go Outdated Show resolved Hide resolved
dkim/header.go Outdated Show resolved Hide resolved
Copy link
Owner

@emersion emersion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the meat of the patch looks good :)

@ludusrusso
Copy link
Contributor Author

Hi @emersion, thanks for the feedback! I was wondering: if we do not want to limit the line lenght to 75 chars, we could make the folding algorithm simpler by just putting the "b" value at the end of the header without folding it! What do you think about this?

@emersion
Copy link
Owner

Would the b= value ever be longer than 1000 chars? (I guess that's an issue with other header fields too, like h=)

@ludusrusso
Copy link
Contributor Author

Would the b= value ever be longer than 1000 chars? (I guess that's an issue with other header fields too, like h=)

Not super sure about b, but since it's an hash it should be fixed in length, I'm correct?

Regarding h, you're right, it could be more then 1000 chars if you include a lot of headers! I've to think about a way to fold it :D

@ludusrusso
Copy link
Contributor Author

@emersion what do you think about b folding?

@foxcpp
Copy link
Contributor

foxcpp commented May 27, 2020

b= is a signature value. I do not expect it to hit 998 characters limitation even with RSA-4096 (though one might consider it to be dangerously close, ~682 characters in base64)

Copy link
Owner

@emersion emersion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All right, let's merge this as-is since it already fixes a bug. I've opened #31 for future work.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants