sln build fix (again), tests fixes, audit work and doctors work
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using StellaOps.Doctor.Models;
|
||||
using StellaOps.Doctor.Plugins;
|
||||
|
||||
namespace StellaOps.Doctor.Plugins.Cryptography.Checks;
|
||||
|
||||
/// <summary>
|
||||
/// Validates SM2/SM3/SM4 (Chinese) cryptography provider availability.
|
||||
/// </summary>
|
||||
public sealed class SmProviderCheck : IDoctorCheck
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string CheckId => "check.crypto.sm";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "SM Cryptography";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "Validates SM2/SM3/SM4 (GB/T) cryptography provider";
|
||||
|
||||
/// <inheritdoc />
|
||||
public DoctorSeverity DefaultSeverity => DoctorSeverity.Info;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<string> Tags => ["cryptography", "sm2", "sm3", "sm4", "regional", "china"];
|
||||
|
||||
/// <inheritdoc />
|
||||
public TimeSpan EstimatedDuration => TimeSpan.FromMilliseconds(100);
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanRun(DoctorPluginContext context)
|
||||
{
|
||||
// Only run if SM crypto is configured or enabled
|
||||
var smEnabled = context.Configuration.GetValue<bool?>("Cryptography:Sm:Enabled")
|
||||
?? context.Configuration.GetValue<bool?>("Cryptography:EnableSm");
|
||||
|
||||
return smEnabled == true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<DoctorCheckResult> RunAsync(DoctorPluginContext context, CancellationToken ct)
|
||||
{
|
||||
var result = context.CreateResult(CheckId, "stellaops.doctor.cryptography", DoctorCategory.Cryptography.ToString());
|
||||
|
||||
var smProvider = context.Configuration.GetValue<string>("Cryptography:Sm:Provider")
|
||||
?? "smsoft";
|
||||
|
||||
var smEndpoint = context.Configuration.GetValue<string>("Cryptography:Sm:Endpoint")
|
||||
?? context.Configuration.GetValue<string>("SmRemote:Endpoint");
|
||||
|
||||
var issues = new List<string>();
|
||||
var providerInfo = new Dictionary<string, string>();
|
||||
|
||||
// Check environment gate for SM providers
|
||||
var smSoftAllowed = Environment.GetEnvironmentVariable("SM_SOFT_ALLOWED");
|
||||
providerInfo["SM_SOFT_ALLOWED"] = smSoftAllowed ?? "(not set)";
|
||||
|
||||
switch (smProvider.ToLowerInvariant())
|
||||
{
|
||||
case "smsoft":
|
||||
CheckSmSoft(issues, providerInfo);
|
||||
break;
|
||||
|
||||
case "smremote":
|
||||
case "remote":
|
||||
CheckSmRemote(issues, providerInfo, smEndpoint);
|
||||
break;
|
||||
|
||||
case "bouncycastle":
|
||||
CheckBouncyCastleSm(issues, providerInfo);
|
||||
break;
|
||||
|
||||
default:
|
||||
issues.Add($"Unknown SM provider: {smProvider}");
|
||||
break;
|
||||
}
|
||||
|
||||
providerInfo["ConfiguredProvider"] = smProvider;
|
||||
|
||||
if (issues.Count > 0)
|
||||
{
|
||||
return Task.FromResult(result
|
||||
.Warn($"{issues.Count} SM provider issue(s)")
|
||||
.WithEvidence("SM cryptography", e =>
|
||||
{
|
||||
foreach (var kvp in providerInfo)
|
||||
{
|
||||
e.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
})
|
||||
.WithCauses(issues.ToArray())
|
||||
.WithRemediation(r => r
|
||||
.AddManualStep(1, "Set environment gate", "Set SM_SOFT_ALLOWED=1 to enable SM software providers")
|
||||
.AddManualStep(2, "Configure SmRemote", "Configure SmRemote:Endpoint for remote SM crypto service"))
|
||||
.WithVerification("stella doctor --check check.crypto.sm")
|
||||
.Build());
|
||||
}
|
||||
|
||||
return Task.FromResult(result
|
||||
.Pass("SM cryptography provider is configured")
|
||||
.WithEvidence("SM cryptography", e =>
|
||||
{
|
||||
foreach (var kvp in providerInfo)
|
||||
{
|
||||
e.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
})
|
||||
.Build());
|
||||
}
|
||||
|
||||
private static void CheckSmSoft(List<string> issues, Dictionary<string, string> providerInfo)
|
||||
{
|
||||
providerInfo["Provider"] = "SmSoft (Software Implementation)";
|
||||
|
||||
var smSoftAllowed = Environment.GetEnvironmentVariable("SM_SOFT_ALLOWED");
|
||||
if (smSoftAllowed != "1" && smSoftAllowed?.ToLowerInvariant() != "true")
|
||||
{
|
||||
issues.Add("SM_SOFT_ALLOWED environment variable not set - SmSoft provider may not be available");
|
||||
}
|
||||
|
||||
// Check if BouncyCastle is available for SM algorithms
|
||||
providerInfo["Implementation"] = "BouncyCastle (managed)";
|
||||
}
|
||||
|
||||
private static void CheckSmRemote(List<string> issues, Dictionary<string, string> providerInfo, string? endpoint)
|
||||
{
|
||||
providerInfo["Provider"] = "SmRemote (Remote Service)";
|
||||
|
||||
if (string.IsNullOrWhiteSpace(endpoint))
|
||||
{
|
||||
issues.Add("SmRemote endpoint not configured");
|
||||
providerInfo["Endpoint"] = "(not set)";
|
||||
}
|
||||
else
|
||||
{
|
||||
providerInfo["Endpoint"] = endpoint;
|
||||
|
||||
// Check if endpoint looks valid
|
||||
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out var uri))
|
||||
{
|
||||
issues.Add($"SmRemote endpoint is not a valid URI: {endpoint}");
|
||||
}
|
||||
else
|
||||
{
|
||||
providerInfo["Host"] = uri.Host;
|
||||
providerInfo["Port"] = uri.Port.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckBouncyCastleSm(List<string> issues, Dictionary<string, string> providerInfo)
|
||||
{
|
||||
providerInfo["Provider"] = "BouncyCastle";
|
||||
providerInfo["Implementation"] = "Managed .NET implementation";
|
||||
|
||||
// BouncyCastle should be available if the package is referenced
|
||||
providerInfo["Algorithms"] = "SM2, SM3, SM4";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user