Skip to content

Commit 97f6e58

Browse files
committed
Optimize SignatureAlgorithm parsing for DkimSignature
1 parent f3ef60f commit 97f6e58

File tree

5 files changed

+77
-6
lines changed

5 files changed

+77
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
namespace Nager.EmailAuthentication.UnitTest.DkimSignatureParserTests
2+
{
3+
[TestClass]
4+
public sealed class SignatureAlgorithmTest
5+
{
6+
[DataRow("rsa-sha256")]
7+
[DataRow("ed25519-sha256")]
8+
[DataTestMethod]
9+
public void TryParse_ValidSignatureAlgorithm_ReturnsTrueAndPopulatesDataFragment(string signatureAlgorithm)
10+
{
11+
var dkimSignature = $"v=1; a={signatureAlgorithm}; d=domain.com; s=test; h=message-id:from; bh=testbodyhash=; b=signaturedata";
12+
13+
var isSuccessful = DkimSignatureDataFragmentParser.TryParse(dkimSignature, out var dkimSignatureDataFragment, out var parsingResults);
14+
15+
Assert.IsTrue(isSuccessful);
16+
Assert.IsNotNull(dkimSignatureDataFragment);
17+
Assert.IsNull(parsingResults, "ParsingResults is null");
18+
}
19+
20+
[DataRow("rsa-sha1")]
21+
[DataTestMethod]
22+
public void TryParse_UnsecureSignatureAlgorithm_ReturnsTrueAndPopulatesDataFragment(string signatureAlgorithm)
23+
{
24+
var dkimSignature = $"v=1; a={signatureAlgorithm}; d=domain.com; s=test; h=message-id:from; bh=testbodyhash=; b=signaturedata";
25+
26+
var isSuccessful = DkimSignatureDataFragmentParser.TryParse(dkimSignature, out var dkimSignatureDataFragment, out var parsingResults);
27+
28+
Assert.IsTrue(isSuccessful);
29+
Assert.IsNotNull(dkimSignatureDataFragment);
30+
Assert.IsNotNull(parsingResults, "ParsingResults is null");
31+
}
32+
33+
[DataRow("rsa-sha512")]
34+
[DataTestMethod]
35+
public void TryParse_InvalidSignatureAlgorithm_ReturnsTrueAndPopulatesDataFragment(string signatureAlgorithm)
36+
{
37+
var dkimSignature = $"v=1; a={signatureAlgorithm}; d=domain.com; s=test; h=message-id:from; bh=testbodyhash=; b=signaturedata";
38+
39+
var isSuccessful = DkimSignatureDataFragmentParser.TryParse(dkimSignature, out var dkimSignatureDataFragment, out var parsingResults);
40+
41+
Assert.IsTrue(isSuccessful);
42+
Assert.IsNotNull(dkimSignatureDataFragment);
43+
Assert.IsNotNull(parsingResults, "ParsingResults is null");
44+
}
45+
}
46+
}

src/Nager.EmailAuthentication/DkimSignatureDataFragmentParser.cs

+19-4
Original file line numberDiff line numberDiff line change
@@ -189,19 +189,34 @@ private static ParsingResult[] ValidateSignatureAlgorithm(ValidateRequest valida
189189
return [.. errors];
190190
}
191191

192-
if (!validateRequest.Value.StartsWith("rsa-", StringComparison.OrdinalIgnoreCase))
192+
if (validateRequest.Value.Equals("rsa-sha256", StringComparison.OrdinalIgnoreCase))
193+
{
194+
return [];
195+
}
196+
else if (validateRequest.Value.Equals("ed25519-sha256", StringComparison.OrdinalIgnoreCase))
197+
{
198+
return [];
199+
}
200+
else if (validateRequest.Value.Equals("rsa-sha1", StringComparison.OrdinalIgnoreCase))
193201
{
194202
errors.Add(new ParsingResult
195203
{
196-
Status = ParsingStatus.Error,
204+
Status = ParsingStatus.Warning,
197205
Field = validateRequest.Field,
198-
Message = "Starts not with rsa-"
206+
Message = "RSA with SHA-1 as the hash algorithm. No longer secure and should not be used."
199207
});
200208

201209
return [.. errors];
202210
}
203211

204-
return [];
212+
errors.Add(new ParsingResult
213+
{
214+
Status = ParsingStatus.Error,
215+
Field = validateRequest.Field,
216+
Message = "Unknown hash algorithm used"
217+
});
218+
219+
return [.. errors];
205220
}
206221

207222
private static ParsingResult[] ValidateSelector(ValidateRequest validateRequest)

src/Nager.EmailAuthentication/DkimSignatureParser.cs

+5
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ private static bool TryGetSignatureAlgorithm(
200200
signatureAlgorithm = SignatureAlgorithm.RsaSha1;
201201
return true;
202202
}
203+
else if (signatureAlgorithmRaw.Equals("ed25519-sha256", StringComparison.OrdinalIgnoreCase))
204+
{
205+
signatureAlgorithm = SignatureAlgorithm.Ed25519Sha256;
206+
return true;
207+
}
203208

204209
return false;
205210
}

src/Nager.EmailAuthentication/Models/SignatureAlgorithm.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ public enum SignatureAlgorithm
1313
/// <summary>
1414
/// RSA SHA-256
1515
/// </summary>
16-
RsaSha256
16+
RsaSha256,
17+
18+
/// <summary>
19+
/// Ed25519 with SHA-256
20+
/// </summary>
21+
Ed25519Sha256
1722
}
1823
}

src/Nager.EmailAuthentication/Nager.EmailAuthentication.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
2222

23-
<Version>1.5.5</Version>
23+
<Version>1.5.6</Version>
2424
</PropertyGroup>
2525

2626
<ItemGroup>

0 commit comments

Comments
 (0)