finish off sprint advisories and sprints
This commit is contained in:
@@ -69,4 +69,11 @@ public sealed class RekorBackend
|
||||
/// Known log ID for the public Sigstore Rekor production instance.
|
||||
/// </summary>
|
||||
public const string SigstoreProductionLogId = "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d";
|
||||
|
||||
/// <summary>
|
||||
/// Rekor log public key (PEM or raw SPKI) for checkpoint signature verification.
|
||||
/// If not specified, checkpoint signatures will not be verified.
|
||||
/// For production Sigstore Rekor, this is the public key matching the LogId.
|
||||
/// </summary>
|
||||
public byte[]? PublicKey { get; init; }
|
||||
}
|
||||
|
||||
@@ -25,6 +25,13 @@ public sealed class RekorProofResponse
|
||||
|
||||
[JsonPropertyName("timestamp")]
|
||||
public DateTimeOffset? Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Signed checkpoint note for signature verification.
|
||||
/// Contains the checkpoint body followed by signature lines.
|
||||
/// </summary>
|
||||
[JsonPropertyName("signedNote")]
|
||||
public string? SignedNote { get; set; }
|
||||
}
|
||||
|
||||
public sealed class RekorInclusionProof
|
||||
|
||||
@@ -140,6 +140,9 @@ internal sealed class HttpRekorClient : IRekorClient
|
||||
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal,
|
||||
out var dto)
|
||||
? dto
|
||||
: null,
|
||||
SignedNote = checkpointElement.TryGetProperty("signedNote", out var signedNote) ? signedNote.GetString()
|
||||
: checkpointElement.TryGetProperty("note", out var note) ? note.GetString()
|
||||
: null
|
||||
}
|
||||
: null,
|
||||
@@ -278,15 +281,58 @@ internal sealed class HttpRekorClient : IRekorClient
|
||||
"Successfully verified Rekor inclusion for UUID {Uuid} at index {Index}",
|
||||
rekorUuid, logIndex);
|
||||
|
||||
_logger.LogDebug(
|
||||
"Checkpoint signature verification is unavailable for UUID {Uuid}; treating checkpoint as unverified",
|
||||
rekorUuid);
|
||||
// Verify checkpoint signature if public key is available
|
||||
var checkpointSignatureValid = false;
|
||||
if (backend.PublicKey is { Length: > 0 } publicKey &&
|
||||
!string.IsNullOrEmpty(proof.Checkpoint.SignedNote))
|
||||
{
|
||||
try
|
||||
{
|
||||
var checkpointResult = CheckpointSignatureVerifier.VerifySignedCheckpointNote(
|
||||
proof.Checkpoint.SignedNote,
|
||||
publicKey);
|
||||
|
||||
checkpointSignatureValid = checkpointResult.Verified;
|
||||
|
||||
if (checkpointSignatureValid)
|
||||
{
|
||||
_logger.LogDebug(
|
||||
"Checkpoint signature verified successfully for UUID {Uuid}",
|
||||
rekorUuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Checkpoint signature verification failed for UUID {Uuid}: {Reason}",
|
||||
rekorUuid,
|
||||
checkpointResult.FailureReason ?? "unknown");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex,
|
||||
"Checkpoint signature verification error for UUID {Uuid}",
|
||||
rekorUuid);
|
||||
}
|
||||
}
|
||||
else if (backend.PublicKey is null or { Length: 0 })
|
||||
{
|
||||
_logger.LogDebug(
|
||||
"No Rekor public key configured; checkpoint signature not verified for UUID {Uuid}",
|
||||
rekorUuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogDebug(
|
||||
"No signed checkpoint note available for UUID {Uuid}; signature not verified",
|
||||
rekorUuid);
|
||||
}
|
||||
|
||||
return RekorInclusionVerificationResult.Success(
|
||||
logIndex.Value,
|
||||
computedRootHex,
|
||||
proof.Checkpoint.RootHash,
|
||||
checkpointSignatureValid: false);
|
||||
checkpointSignatureValid);
|
||||
}
|
||||
catch (Exception ex) when (ex is FormatException or ArgumentException)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user