up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using StellaOps.Cryptography;
|
||||
|
||||
namespace StellaOps.EvidenceLocker.Core.Builders;
|
||||
|
||||
@@ -10,6 +10,35 @@ public interface IMerkleTreeCalculator
|
||||
|
||||
public sealed class MerkleTreeCalculator : IMerkleTreeCalculator
|
||||
{
|
||||
private readonly ICryptoHasher _hasher;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a MerkleTreeCalculator using the specified hasher.
|
||||
/// </summary>
|
||||
/// <param name="hasher">Crypto hasher resolved from the provider registry.</param>
|
||||
public MerkleTreeCalculator(ICryptoHasher hasher)
|
||||
{
|
||||
_hasher = hasher ?? throw new ArgumentNullException(nameof(hasher));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a MerkleTreeCalculator using the crypto registry to resolve the hasher.
|
||||
/// </summary>
|
||||
/// <param name="cryptoRegistry">Crypto provider registry.</param>
|
||||
/// <param name="algorithmId">Hash algorithm to use (defaults to SHA256).</param>
|
||||
/// <param name="preferredProvider">Optional preferred crypto provider.</param>
|
||||
public MerkleTreeCalculator(
|
||||
ICryptoProviderRegistry cryptoRegistry,
|
||||
string? algorithmId = null,
|
||||
string? preferredProvider = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(cryptoRegistry);
|
||||
|
||||
var algorithm = algorithmId ?? HashAlgorithms.Sha256;
|
||||
var resolution = cryptoRegistry.ResolveHasher(algorithm, preferredProvider);
|
||||
_hasher = resolution.Hasher;
|
||||
}
|
||||
|
||||
public string CalculateRootHash(IEnumerable<string> canonicalLeafValues)
|
||||
{
|
||||
var leaves = canonicalLeafValues
|
||||
@@ -24,7 +53,7 @@ public sealed class MerkleTreeCalculator : IMerkleTreeCalculator
|
||||
return BuildTree(leaves);
|
||||
}
|
||||
|
||||
private static string BuildTree(IReadOnlyList<string> currentLevel)
|
||||
private string BuildTree(IReadOnlyList<string> currentLevel)
|
||||
{
|
||||
if (currentLevel.Count == 1)
|
||||
{
|
||||
@@ -45,10 +74,9 @@ public sealed class MerkleTreeCalculator : IMerkleTreeCalculator
|
||||
return BuildTree(nextLevel);
|
||||
}
|
||||
|
||||
private static string HashString(string value)
|
||||
private string HashString(string value)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(value);
|
||||
var hash = SHA256.HashData(bytes);
|
||||
return Convert.ToHexString(hash).ToLowerInvariant();
|
||||
return _hasher.ComputeHashHex(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ public sealed class EvidenceLockerOptions
|
||||
public PortableOptions Portable { get; init; } = new();
|
||||
|
||||
public IncidentModeOptions Incident { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cryptographic options for hash algorithm selection and provider routing.
|
||||
/// </summary>
|
||||
public EvidenceCryptoOptions Crypto { get; init; } = new();
|
||||
}
|
||||
|
||||
public sealed class DatabaseOptions
|
||||
@@ -208,3 +213,20 @@ public sealed class PortableOptions
|
||||
[MinLength(1)]
|
||||
public string MetadataFileName { get; init; } = "bundle.json";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cryptographic options for evidence bundle hashing and provider routing.
|
||||
/// </summary>
|
||||
public sealed class EvidenceCryptoOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Hash algorithm used for Merkle tree computation. Defaults to SHA256.
|
||||
/// Supported: SHA256, SHA384, SHA512, GOST3411-2012-256, GOST3411-2012-512.
|
||||
/// </summary>
|
||||
public string HashAlgorithm { get; init; } = HashAlgorithms.Sha256;
|
||||
|
||||
/// <summary>
|
||||
/// Preferred crypto provider name. When null, the registry uses its default resolution order.
|
||||
/// </summary>
|
||||
public string? PreferredProvider { get; init; }
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Cryptography;
|
||||
using StellaOps.Cryptography.DependencyInjection;
|
||||
using StellaOps.Cryptography.Plugin.BouncyCastle;
|
||||
using StellaOps.EvidenceLocker.Core.Builders;
|
||||
@@ -61,7 +62,15 @@ public static class EvidenceLockerInfrastructureServiceCollectionExtensions
|
||||
services.AddSingleton<IEvidenceLockerMigrationRunner, EvidenceLockerMigrationRunner>();
|
||||
services.AddHostedService<EvidenceLockerMigrationHostedService>();
|
||||
|
||||
services.AddSingleton<IMerkleTreeCalculator, MerkleTreeCalculator>();
|
||||
services.AddSingleton<IMerkleTreeCalculator>(provider =>
|
||||
{
|
||||
var options = provider.GetRequiredService<IOptions<EvidenceLockerOptions>>().Value;
|
||||
var cryptoRegistry = provider.GetRequiredService<ICryptoProviderRegistry>();
|
||||
return new MerkleTreeCalculator(
|
||||
cryptoRegistry,
|
||||
options.Crypto.HashAlgorithm,
|
||||
options.Crypto.PreferredProvider);
|
||||
});
|
||||
services.AddScoped<IEvidenceBundleBuilder, EvidenceBundleBuilder>();
|
||||
services.AddScoped<IEvidenceBundleRepository, EvidenceBundleRepository>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user