consolidation of some of the modules, localization fixes, product advisories work, qa work
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Excititor.Connectors.Abstractions.Trust;
|
||||
using StellaOps.Excititor.WebService.Contracts;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace StellaOps.Excititor.WebService.Services;
|
||||
|
||||
internal sealed class AirgapSignerTrustService
|
||||
{
|
||||
private readonly ILogger<AirgapSignerTrustService> _logger;
|
||||
private readonly string? _metadataPath;
|
||||
private ConnectorSignerMetadataSet? _metadata;
|
||||
|
||||
public AirgapSignerTrustService(ILogger<AirgapSignerTrustService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_metadataPath = Environment.GetEnvironmentVariable("STELLAOPS_CONNECTOR_SIGNER_METADATA_PATH");
|
||||
}
|
||||
|
||||
public bool Validate(AirgapImportRequest request, out string? errorCode, out string? message)
|
||||
{
|
||||
errorCode = null;
|
||||
message = null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_metadataPath) || !File.Exists(_metadataPath))
|
||||
{
|
||||
_logger.LogDebug("Airgap signer metadata not configured; skipping trust enforcement.");
|
||||
return true;
|
||||
}
|
||||
|
||||
_metadata ??= ConnectorSignerMetadataLoader.TryLoad(_metadataPath);
|
||||
if (_metadata is null)
|
||||
{
|
||||
_logger.LogWarning("Failed to load airgap signer metadata from {Path}; allowing import.", _metadataPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.Publisher))
|
||||
{
|
||||
errorCode = "AIRGAP_SOURCE_UNTRUSTED";
|
||||
message = "publisher is required for trust enforcement.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_metadata.TryGet(request.Publisher, out var connector))
|
||||
{
|
||||
errorCode = "AIRGAP_SOURCE_UNTRUSTED";
|
||||
message = $"Publisher '{request.Publisher}' is not present in trusted signer metadata.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (connector.Revoked)
|
||||
{
|
||||
errorCode = "AIRGAP_SOURCE_UNTRUSTED";
|
||||
message = $"Publisher '{request.Publisher}' is revoked.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (connector.Bundle?.Digest is { } digest && !string.IsNullOrWhiteSpace(digest))
|
||||
{
|
||||
if (!string.Equals(digest.Trim(), request.PayloadHash?.Trim(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
errorCode = "AIRGAP_PAYLOAD_MISMATCH";
|
||||
message = "Payload hash does not match trusted bundle digest.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Basic sanity: ensure at least one signer entry exists.
|
||||
if (connector.Signers.IsDefaultOrEmpty || connector.Signers.Sum(s => s.Fingerprints.Length) == 0)
|
||||
{
|
||||
errorCode = "AIRGAP_SOURCE_UNTRUSTED";
|
||||
message = $"Publisher '{request.Publisher}' has no trusted signers configured.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user