feat: Implement DefaultCryptoHmac for compliance-aware HMAC operations
- Added DefaultCryptoHmac class implementing ICryptoHmac interface. - Introduced purpose-based HMAC computation methods. - Implemented verification methods for HMACs with constant-time comparison. - Created HmacAlgorithms and HmacPurpose classes for well-known identifiers. - Added compliance profile support for HMAC algorithms. - Included asynchronous methods for HMAC computation from streams.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using StellaOps.Cryptography;
|
||||
|
||||
namespace StellaOps.ExportCenter.RiskBundles;
|
||||
|
||||
@@ -28,11 +28,13 @@ public sealed record RiskBundleManifestDsseSignature(
|
||||
public sealed class HmacRiskBundleManifestSigner : IRiskBundleManifestSigner, IRiskBundleArchiveSigner
|
||||
{
|
||||
private const string DefaultPayloadType = "application/stellaops.risk-bundle.provider-manifest+json";
|
||||
private readonly ICryptoHmac _cryptoHmac;
|
||||
private readonly byte[] _key;
|
||||
private readonly string _keyId;
|
||||
|
||||
public HmacRiskBundleManifestSigner(string key, string keyId)
|
||||
public HmacRiskBundleManifestSigner(ICryptoHmac cryptoHmac, string key, string keyId)
|
||||
{
|
||||
_cryptoHmac = cryptoHmac ?? throw new ArgumentNullException(nameof(cryptoHmac));
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
throw new ArgumentException("Signing key cannot be empty.", nameof(key));
|
||||
@@ -48,7 +50,7 @@ public sealed class HmacRiskBundleManifestSigner : IRiskBundleManifestSigner, IR
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var pae = CreatePreAuthenticationEncoding(DefaultPayloadType, manifestJson);
|
||||
var signature = ComputeHmac(pae, _key);
|
||||
var signature = _cryptoHmac.ComputeHmacBase64ForPurpose(_key, pae, HmacPurpose.Signing);
|
||||
|
||||
var document = new RiskBundleManifestSignatureDocument(
|
||||
DefaultPayloadType,
|
||||
@@ -58,7 +60,7 @@ public sealed class HmacRiskBundleManifestSigner : IRiskBundleManifestSigner, IR
|
||||
return Task.FromResult(document);
|
||||
}
|
||||
|
||||
public Task<string> SignArchiveAsync(Stream archiveStream, CancellationToken cancellationToken = default)
|
||||
public async Task<string> SignArchiveAsync(Stream archiveStream, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(archiveStream);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -69,16 +71,8 @@ public sealed class HmacRiskBundleManifestSigner : IRiskBundleManifestSigner, IR
|
||||
}
|
||||
|
||||
archiveStream.Position = 0;
|
||||
using var hmac = new HMACSHA256(_key);
|
||||
var signature = hmac.ComputeHash(archiveStream);
|
||||
var signature = await _cryptoHmac.ComputeHmacForPurposeAsync(_key, archiveStream, HmacPurpose.Signing, cancellationToken);
|
||||
archiveStream.Position = 0;
|
||||
return Task.FromResult(Convert.ToBase64String(signature));
|
||||
}
|
||||
|
||||
private static string ComputeHmac(byte[] pae, byte[] key)
|
||||
{
|
||||
using var hmac = new HMACSHA256(key);
|
||||
var signature = hmac.ComputeHash(pae);
|
||||
return Convert.ToBase64String(signature);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../StellaOps.ExportCenter/StellaOps.ExportCenter.Infrastructure/StellaOps.ExportCenter.Infrastructure.csproj" />
|
||||
<ProjectReference Include="../StellaOps.ExportCenter/StellaOps.ExportCenter.Core/StellaOps.ExportCenter.Core.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user