Skip to content

Commit 2febc32

Browse files
committed
Add Email Header Unfolding logic
1 parent f55fdbb commit 2febc32

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

src/Nager.EmailAuthentication.UnitTest/DkimSignatureTests/FragmentParser/BasicTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public void TryParse_ValidDkimSignature1_ReturnsTrueAndPopulatesDataFragment()
2020
[TestMethod]
2121
public void TryParse_ValidDkimSignatureWithTabs_ReturnsTrueAndPopulatesDataFragment()
2222
{
23-
var dkimSignature = "v=1; a=rsa-sha256; c=relaxed/relaxed; d=domain.com;\r\n s=testselector;\r\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\r\n bh=qxq6it6URJf9QDr82aTOS1esfmgKTsALYByECu5Ypjo=;\r\n b=Ps4k/pVqXOLkxP1x8YJL+ofgVAfNYNPGT0ln4pSQ5M7T+KTND8ijzYrPIocjiE40qLmQAnccrxMRS56weM2Jgb4F0cXkWJop1wJnUmKsFpMOYzaIXKUy4XnTaakR592E5t9ejoAgZIfE/jl3fcjKUIhNZuDGCSUYDAd64a1UndacEG+efXBG57bclUNmzuwx2tHXTBdKLecm0fZ0ST2OfAosrE8lwFyprzxSEoOFb8/PiA20MI1b2tMg7tH0pOcbLkdTHiSvkGuQFTvX87zCJk6WxW92bEP35kekPlqiFDKjpC5cVoIuC5UN9cHTsWvJLanaJJI+Ol9GB18dmqmCKw==";
23+
var dkimSignature = "v=1; a=rsa-sha256; c=relaxed/relaxed; d=domain.com;\r\n s=testselector;\r\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version\r\n :X-MS-Exchange-SenderADCheck;\r\n bh=qxq6it6URJf9QDr82aTOS1esfmgKTsALYByECu5Ypjo=;\r\n b=Ps4k/pVqXOLkxP1x8YJL+ofgVAfNYNPGT0ln4pSQ5M7T+KTND8ijzYrPIocjiE40qLmQAnccrxMRS56weM2Jgb4F0cXkWJop1wJnUmKsFpMOYzaIXKUy4XnTaakR592E5t9ejoAgZIfE/jl3fcjKUIhNZuDGCSUYDAd64a1UndacEG+efXBG57bclUNmzuwx2tHXTBdKLecm0fZ0ST2OfAosrE8lwFyprzxSEoOFb8/PiA20MI1b2tMg7tH0pOcbLkdTHiSvkGuQFTvX87zCJk6WxW92bEP35kekPlqiFDKjpC5cVoIuC5UN9cHTsWvJLanaJJI+Ol9GB18dmqmCKw==";
2424
//TODO: Add logic for removing tabs and line breaks
2525

2626
var isSuccessful = DkimSignatureDataFragmentParserV1.TryParse(dkimSignature, out var dkimSignatureDataFragment, out var parsingResults);

src/Nager.EmailAuthentication/FragmentParsers/DkimSignatureDataFragmentParserV1.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Nager.EmailAuthentication.Handlers;
2+
using Nager.EmailAuthentication.Helpers;
23
using Nager.EmailAuthentication.Models;
34
using Nager.EmailAuthentication.Models.Dkim;
45
using Nager.EmailAuthentication.RegexProviders;
@@ -136,8 +137,10 @@ public static bool TryParse(
136137
}
137138
};
138139

140+
var unfoldDkimSignatureHeader = MailHeaderHelper.UnfoldingHeader(dkimSignature);
141+
139142
var parserBase = new KeyValueParserBase<DkimSignatureDataFragmentV1>(handlers);
140-
return parserBase.TryParse(dkimSignature, out dkimSignatureDataFragment, out parsingResults);
143+
return parserBase.TryParse(unfoldDkimSignatureHeader, out dkimSignatureDataFragment, out parsingResults);
141144
}
142145

143146
private static ParsingResult[] ValidatePositiveNumber(
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
namespace Nager.EmailAuthentication.Helpers
2+
{
3+
/// <summary>
4+
/// Mail Header Helper
5+
/// </summary>
6+
public static class MailHeaderHelper
7+
{
8+
/// <summary>
9+
/// Unfolding Mail Header
10+
/// </summary>
11+
/// <param name="header"></param>
12+
/// <returns></returns>
13+
public static string UnfoldingHeader(string header)
14+
{
15+
Span<char> buffer = stackalloc char[header.Length];
16+
int bufferIndex = 0;
17+
bool newLine = false;
18+
19+
for (var i = 0; i < header.Length;)
20+
{
21+
if (i < header.Length)
22+
{
23+
if (header[i] == '\r' && header[i + 1] == '\n')
24+
{
25+
i += 2;
26+
newLine = true;
27+
continue;
28+
}
29+
}
30+
31+
if (newLine)
32+
{
33+
newLine = false;
34+
35+
if (header[i] == '\t')
36+
{
37+
i++;
38+
continue;
39+
}
40+
41+
if (header[i] == ' ')
42+
{
43+
i++;
44+
continue;
45+
}
46+
}
47+
48+
buffer[bufferIndex++] = header[i];
49+
i++;
50+
}
51+
52+
return new string(buffer[..bufferIndex]);
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)