synergy moats product advisory implementations

This commit is contained in:
master
2026-01-17 01:30:03 +02:00
parent 77ff029205
commit 702a27ac83
112 changed files with 21356 additions and 127 deletions

View File

@@ -7,7 +7,9 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Cronos" />
<PackageReference Include="JsonSchema.Net" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Options" />

View File

@@ -114,7 +114,7 @@ public sealed class RekorVerificationService : IRekorVerificationService
// Get proof from Rekor
var backend = new RekorBackend
{
Url = entry.RekorUrl ?? opts.RekorUrl,
Url = new Uri(entry.RekorUrl ?? opts.RekorUrl),
Name = "verification"
};
@@ -134,22 +134,11 @@ public sealed class RekorVerificationService : IRekorVerificationService
duration: stopwatch.Elapsed);
}
// Verify log index matches
if (proof.LogIndex != entry.LogIndex)
// Verify body hash if available (leaf hash provides best-effort match)
var proofLeafHash = proof.Inclusion?.LeafHash;
if (!string.IsNullOrEmpty(entry.EntryBodyHash) && !string.IsNullOrEmpty(proofLeafHash))
{
stopwatch.Stop();
return RekorVerificationResult.Failure(
entry.Uuid,
$"Log index mismatch: expected {entry.LogIndex}, got {proof.LogIndex}",
RekorVerificationFailureCode.LogIndexMismatch,
startTime,
duration: stopwatch.Elapsed);
}
// Verify body hash if available
if (!string.IsNullOrEmpty(entry.EntryBodyHash) && !string.IsNullOrEmpty(proof.EntryBodyHash))
{
if (!string.Equals(entry.EntryBodyHash, proof.EntryBodyHash, StringComparison.OrdinalIgnoreCase))
if (!string.Equals(entry.EntryBodyHash, proofLeafHash, StringComparison.OrdinalIgnoreCase))
{
stopwatch.Stop();
_metrics.RecordSignatureFailure();
@@ -171,7 +160,7 @@ public sealed class RekorVerificationService : IRekorVerificationService
backend,
cts.Token);
if (!inclusionResult.IsValid)
if (!inclusionResult.Verified)
{
stopwatch.Stop();
_metrics.RecordInclusionProofFailure();
@@ -185,6 +174,17 @@ public sealed class RekorVerificationService : IRekorVerificationService
duration: stopwatch.Elapsed);
}
if (inclusionResult.LogIndex.HasValue && inclusionResult.LogIndex.Value != entry.LogIndex)
{
stopwatch.Stop();
return RekorVerificationResult.Failure(
entry.Uuid,
$"Log index mismatch: expected {entry.LogIndex}, got {inclusionResult.LogIndex.Value}",
RekorVerificationFailureCode.LogIndexMismatch,
startTime,
duration: stopwatch.Elapsed);
}
// Check time skew
var timeSkewResult = CheckTimeSkew(entry, opts.MaxTimeSkewSeconds);
if (!timeSkewResult.IsValid)
@@ -356,7 +356,7 @@ public sealed class RekorVerificationService : IRekorVerificationService
{
var backend = new RekorBackend
{
Url = opts.RekorUrl,
Url = new Uri(opts.RekorUrl),
Name = "verification"
};
@@ -376,24 +376,26 @@ public sealed class RekorVerificationService : IRekorVerificationService
}
// Verify consistency: tree size should only increase
if (currentCheckpoint.TreeSize < expectedTreeSize)
var checkpoint = currentCheckpoint.Value;
if (checkpoint.TreeSize < expectedTreeSize)
{
return RootConsistencyResult.Inconsistent(
currentCheckpoint.TreeRoot,
currentCheckpoint.TreeSize,
checkpoint.TreeRoot,
checkpoint.TreeSize,
expectedTreeRoot,
expectedTreeSize,
$"Tree size decreased from {expectedTreeSize} to {currentCheckpoint.TreeSize} (possible log truncation)",
$"Tree size decreased from {expectedTreeSize} to {checkpoint.TreeSize} (possible log truncation)",
now);
}
// If sizes match, roots should match
if (currentCheckpoint.TreeSize == expectedTreeSize &&
!string.Equals(currentCheckpoint.TreeRoot, expectedTreeRoot, StringComparison.OrdinalIgnoreCase))
if (checkpoint.TreeSize == expectedTreeSize &&
!string.Equals(checkpoint.TreeRoot, expectedTreeRoot, StringComparison.OrdinalIgnoreCase))
{
return RootConsistencyResult.Inconsistent(
currentCheckpoint.TreeRoot,
currentCheckpoint.TreeSize,
checkpoint.TreeRoot,
checkpoint.TreeSize,
expectedTreeRoot,
expectedTreeSize,
"Tree root changed without size change (possible log tampering)",
@@ -401,8 +403,8 @@ public sealed class RekorVerificationService : IRekorVerificationService
}
return RootConsistencyResult.Consistent(
currentCheckpoint.TreeRoot,
currentCheckpoint.TreeSize,
checkpoint.TreeRoot,
checkpoint.TreeSize,
now);
}
catch (Exception ex)