Skip to content

Commit 664c4d5

Browse files
committed
Remove support weak digest hash algos
Also refactor file digest options to use enum for hash algorithms and update related tests
1 parent cbf0c11 commit 664c4d5

6 files changed

Lines changed: 60 additions & 45 deletions

File tree

src/SignhostAPIClient.Tests/SignhostApiClientTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ await signhostApiClient.AddOrReplaceFileToTransactionAsync(
429429
new FileUploadOptions{
430430
DigestOptions = new FileDigestOptions
431431
{
432-
DigestHashAlgorithm = "SHA-512"
432+
DigestHashAlgorithm = DigestHashAlgorithm.SHA512,
433433
}
434434
});
435435
}
@@ -443,7 +443,7 @@ public async Task when_AddOrReplaceFileToTransaction_with_digest_value_is_used_a
443443
var mockHttp = new MockHttpMessageHandler();
444444
mockHttp
445445
.Expect(HttpMethod.Put, "http://localhost/api/transaction/transaction Id/file/file Id")
446-
.WithHeaders("Digest", "SHA-1=AAEC")
446+
.WithHeaders("Digest", "SHA-256=AAEC")
447447
.Respond(HttpStatusCode.OK);
448448

449449
using (var httpClient = mockHttp.ToHttpClient()) {
@@ -457,7 +457,7 @@ await signhostApiClient.AddOrReplaceFileToTransactionAsync(
457457
{
458458
DigestOptions = new FileDigestOptions
459459
{
460-
DigestHashAlgorithm = "SHA-1",
460+
DigestHashAlgorithm = DigestHashAlgorithm.SHA256,
461461
DigestHashValue = new byte[] { 0x00, 0x01, 0x02 }
462462
}
463463
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
namespace Signhost.APIClient.Rest;
2+
3+
/// <summary>
4+
/// Provides constants for hash algorithm names used in HTTP Digest headers,
5+
/// following the naming conventions specified in RFC 3230 (Instance Digests in HTTP)
6+
/// and RFC 5843 (Additional Hash Algorithms for HTTP Instance Digests).
7+
///
8+
/// These names are in accordance with the Digest header in HTTP requests,
9+
/// where the header specifies the algorithm used to create the digest of the resource.
10+
///
11+
/// For more information:
12+
/// https://evidos.github.io/endpoints/##/paths//api/transaction/%7BtransactionId%7D/file/%7BfileId%7D/put
13+
/// </summary>
14+
public enum DigestHashAlgorithm
15+
{
16+
/// <summary>
17+
/// Use no digest.
18+
/// </summary>
19+
None = 0,
20+
21+
/// <summary>
22+
/// SHA-256 hash algorithm, as specified in RFC 5843.
23+
/// </summary>
24+
SHA256,
25+
26+
/// <summary>
27+
/// SHA-512 hash algorithm, as specified in RFC 5843.
28+
/// </summary>
29+
SHA512,
30+
}

src/SignhostAPIClient/Rest/FileDigestOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class FileDigestOptions
2020
/// the hash value or the digest algorithm that is used
2121
/// to set the <see cref="DigestHashValue"/>.
2222
/// </summary>
23-
public string DigestHashAlgorithm { get; set; } = "SHA-256";
23+
public DigestHashAlgorithm DigestHashAlgorithm { get; set; } = DigestHashAlgorithm.SHA256;
2424

2525
/// <summary>
2626
/// Gets or sets the hash digest value, you can set this yourself

src/SignhostAPIClient/Rest/StreamContentDigestOptionsExtensions.cs

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,33 @@ public static StreamContent WithDigest(
2323
Stream fileStream,
2424
FileDigestOptions options)
2525
{
26-
if (!options.UseFileDigesting || options.DigestHashAlgorithm == null) {
26+
if (
27+
!options.UseFileDigesting ||
28+
options.DigestHashAlgorithm == DigestHashAlgorithm.None
29+
) {
2730
return content;
2831
}
2932

3033
SetHashValue(fileStream, options);
3134

3235
string base64Digest = Convert.ToBase64String(options.DigestHashValue);
3336

34-
content.Headers.Add("Digest", $"{options.DigestHashAlgorithm}={base64Digest}");
37+
content.Headers.Add("Digest", $"{GetDigestHashAlgorithmName(options)}={base64Digest}");
3538

3639
return content;
3740
}
3841

42+
private static string GetDigestHashAlgorithmName(FileDigestOptions options)
43+
{
44+
return options.DigestHashAlgorithm switch {
45+
DigestHashAlgorithm.SHA256 => "SHA-256",
46+
DigestHashAlgorithm.SHA512 => "SHA-512",
47+
48+
_ => throw new InvalidOperationException(
49+
$"No hash algorithm name for '{options.DigestHashAlgorithm}'"),
50+
};
51+
}
52+
3953
private static void SetHashValue(
4054
Stream fileStream,
4155
FileDigestOptions options)
@@ -60,48 +74,17 @@ private static void SetHashValue(
6074
private static HashAlgorithm HashAlgorithmCreate(
6175
FileDigestOptions options)
6276
{
63-
string algorithmName = options.DigestHashAlgorithm;
64-
HashAlgorithm algorithm = null;
65-
77+
return options.DigestHashAlgorithm switch {
6678
#if NETSTANDARD2_0 || NET8_0
67-
switch (algorithmName) {
68-
case "SHA1":
69-
case "SHA-1":
70-
algorithm = SHA1.Create();
71-
break;
72-
case "SHA256":
73-
case "SHA-256":
74-
algorithm = SHA256.Create();
75-
break;
76-
case "SHA384":
77-
case "SHA-384":
78-
algorithm = SHA384.Create();
79-
break;
80-
case "SHA512":
81-
case "SHA-512":
82-
algorithm = SHA512.Create();
83-
break;
84-
}
79+
DigestHashAlgorithm.SHA256 => SHA256.Create(),
80+
DigestHashAlgorithm.SHA512 => SHA512.Create(),
8581
#else
86-
algorithm = HashAlgorithm.Create(algorithmName);
82+
DigestHashAlgorithm.SHA256 => HashAlgorithm.Create("SHA256"),
83+
DigestHashAlgorithm.SHA512 => HashAlgorithm.Create("SHA512"),
8784
#endif
88-
if (algorithm == null && options.DigestHashValue == null) {
89-
algorithm = DefaultHashAlgorithm();
90-
options.DigestHashAlgorithm = algorithm.GetType().Name;
91-
}
92-
93-
if (algorithm == null) {
94-
throw new InvalidOperationException($"No hash algorithm for '{algorithmName}'");
95-
}
96-
97-
return algorithm;
85+
_ => throw new InvalidOperationException(
86+
$"No hash algorithm for '{options.DigestHashAlgorithm}'"),
87+
};
9888
}
99-
100-
private static HashAlgorithm DefaultHashAlgorithm() =>
101-
#if NETSTANDARD2_0 || NET8_0
102-
SHA256.Create();
103-
#else
104-
HashAlgorithm.Create();
105-
#endif
10689
}
10790
}

src/SignhostAPIClient/SignhostAPIClient.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup Label="Build">
33
<TargetFrameworks>netstandard2.0;net8.0;net462</TargetFrameworks>
4+
<LangVersion>10.0</LangVersion>
45
<CodeAnalysisRuleSet>../signhost.ruleset</CodeAnalysisRuleSet>
56
<DefineConstants Condition="'$(TargetFramework)' == 'net462'">SERIALIZABLE</DefineConstants>
67
<DefineConstants Condition="'$(TargetFramework)' == 'netstandard2.0'">TYPEINFO</DefineConstants>

src/signhost.ruleset

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<Rules AnalyzerId="RefactoringEssentials" RuleNamespace="RefactoringEssentials">
77
</Rules>
88
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
9+
<Rule Id="SA1009" Action="None" /><!-- Closing parenthesis must not be preceded by a space -->
910
<Rule Id="SA1027" Action="None" /><!-- Tabs must not be used -->
1011
<Rule Id="SA1633" Action="None" /><!-- FileMustHaveHeader -->
1112
<Rule Id="SA1652" Action="None" /><!-- Enable XML documentation output -->

0 commit comments

Comments
 (0)