This commit is contained in:
StellaOps Bot
2025-12-09 00:20:52 +02:00
parent 3d01bf9edc
commit bc0762e97d
261 changed files with 14033 additions and 4427 deletions

View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace StellaOps.Cryptography.DependencyInjection;
/// <summary>
/// Validates and normalises crypto provider registry options for RU/GOST baselines.
/// </summary>
public static class CryptoProviderRegistryValidator
{
private static readonly StringComparer OrdinalIgnoreCase = StringComparer.OrdinalIgnoreCase;
public static void EnforceRuLinuxDefaults(CryptoProviderRegistryOptions options)
{
ArgumentNullException.ThrowIfNull(options);
var enableOpenSsl = GetEnvFlag("STELLAOPS_CRYPTO_ENABLE_RU_OPENSSL", defaultValue: OperatingSystem.IsLinux());
var enablePkcs11 = GetEnvFlag("STELLAOPS_CRYPTO_ENABLE_RU_PKCS11", defaultValue: true);
var enableWineCsp = GetEnvFlag("STELLAOPS_CRYPTO_ENABLE_RU_WINECSP", defaultValue: false);
#if STELLAOPS_CRYPTO_PRO
var enableCryptoPro = GetEnvFlag("STELLAOPS_CRYPTO_ENABLE_RU_CSP", defaultValue: OperatingSystem.IsWindows());
#endif
options.ActiveProfile = string.IsNullOrWhiteSpace(options.ActiveProfile)
? "ru-offline"
: options.ActiveProfile;
EnsureBaselineProfiles(options);
EnsureDefaultPreferred(options.PreferredProviders, enableOpenSsl, enablePkcs11, enableWineCsp
#if STELLAOPS_CRYPTO_PRO
, enableCryptoPro
#endif
);
if (options.Profiles.TryGetValue(options.ActiveProfile, out var profile))
{
EnsureDefaultPreferred(profile.PreferredProviders, enableOpenSsl, enablePkcs11, enableWineCsp
#if STELLAOPS_CRYPTO_PRO
, enableCryptoPro
#endif
);
}
var resolved = options.ResolvePreferredProviders();
if (resolved.Count == 0)
{
throw new InvalidOperationException("Crypto provider registry cannot be empty. Configure at least one provider for RU deployments.");
}
if (OperatingSystem.IsLinux() && enableOpenSsl &&
!resolved.Contains("ru.openssl.gost", OrdinalIgnoreCase))
{
throw new InvalidOperationException("Linux RU baseline requires provider 'ru.openssl.gost' (set STELLAOPS_CRYPTO_ENABLE_RU_OPENSSL=0 to override explicitly).");
}
if (OperatingSystem.IsLinux() && !enableOpenSsl && !enablePkcs11)
{
throw new InvalidOperationException("RU Linux baseline is misconfigured: both ru.openssl.gost and ru.pkcs11 are disabled via environment. Enable at least one provider.");
}
}
private static bool GetEnvFlag(string name, bool defaultValue)
{
var raw = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrWhiteSpace(raw))
{
return defaultValue;
}
return raw.Equals("1", StringComparison.OrdinalIgnoreCase) ||
raw.Equals("true", StringComparison.OrdinalIgnoreCase) ||
raw.Equals("yes", StringComparison.OrdinalIgnoreCase);
}
private static void EnsureBaselineProfiles(CryptoProviderRegistryOptions options)
{
if (!options.PreferredProviders.Any())
{
options.PreferredProviders.Add("default");
}
if (!options.Profiles.TryGetValue("ru-offline", out var ruOffline))
{
ruOffline = new CryptoProviderProfileOptions();
options.Profiles["ru-offline"] = ruOffline;
}
if (!options.Profiles.ContainsKey("ru-linux-soft"))
{
options.Profiles["ru-linux-soft"] = new CryptoProviderProfileOptions();
}
}
private static void EnsureDefaultPreferred(
IList<string> providers,
bool enableOpenSsl,
bool enablePkcs11,
bool enableWineCsp
#if STELLAOPS_CRYPTO_PRO
, bool enableCryptoPro
#endif
)
{
InsertIfMissing(providers, "default");
if (enableOpenSsl)
{
InsertIfMissing(providers, "ru.openssl.gost");
}
if (enablePkcs11)
{
InsertIfMissing(providers, "ru.pkcs11");
}
if (enableWineCsp)
{
InsertIfMissing(providers, "ru.winecsp.http");
}
#if STELLAOPS_CRYPTO_PRO
if (enableCryptoPro && OperatingSystem.IsWindows())
{
InsertIfMissing(providers, "ru.cryptopro.csp");
}
#endif
}
private static void InsertIfMissing(IList<string> providers, string name)
{
for (var i = 0; i < providers.Count; i++)
{
if (string.Equals(providers[i], name, StringComparison.OrdinalIgnoreCase))
{
return;
}
}
providers.Insert(0, name);
}
}

View File

@@ -10,6 +10,7 @@ using StellaOps.Cryptography.Plugin.CryptoPro;
#endif
using StellaOps.Cryptography.Plugin.Pkcs11Gost;
using StellaOps.Cryptography.Plugin.OpenSslGost;
using StellaOps.Cryptography.Plugin.SmRemote;
using StellaOps.Cryptography.Plugin.SmSoft;
using StellaOps.Cryptography.Plugin.PqSoft;
using StellaOps.Cryptography.Plugin.WineCsp;
@@ -69,7 +70,17 @@ public static class CryptoServiceCollectionExtensions
services.TryAddSingleton<ICryptoHash, DefaultCryptoHash>();
services.TryAddSingleton<ICryptoHmac, DefaultCryptoHmac>();
services.AddOptions<SmRemoteProviderOptions>();
services.AddHttpClient<SmRemoteHttpClient>((sp, httpClient) =>
{
var opts = sp.GetService<IOptions<SmRemoteProviderOptions>>()?.Value;
if (opts is not null && !string.IsNullOrWhiteSpace(opts.BaseAddress))
{
httpClient.BaseAddress = new Uri(opts.BaseAddress);
}
});
services.TryAddEnumerable(ServiceDescriptor.Singleton<ICryptoProvider, SmSoftCryptoProvider>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<ICryptoProvider, StellaOps.Cryptography.Plugin.SmRemote.SmRemoteHttpProvider>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<ICryptoProvider, PqSoftCryptoProvider>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<ICryptoProvider, FipsSoftCryptoProvider>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<ICryptoProvider, EidasSoftCryptoProvider>());
@@ -171,41 +182,8 @@ public static class CryptoServiceCollectionExtensions
}
#endif
services.PostConfigure<CryptoProviderRegistryOptions>(options =>
{
EnsurePreferred(options.PreferredProviders);
foreach (var profile in options.Profiles.Values)
{
EnsurePreferred(profile.PreferredProviders);
}
});
services.PostConfigure<CryptoProviderRegistryOptions>(CryptoProviderRegistryValidator.EnforceRuLinuxDefaults);
return services;
static void EnsurePreferred(IList<string> providers)
{
InsertIfMissing(providers, "ru.pkcs11");
InsertIfMissing(providers, "ru.openssl.gost");
InsertIfMissing(providers, "ru.winecsp.http");
#if STELLAOPS_CRYPTO_PRO
if (OperatingSystem.IsWindows())
{
InsertIfMissing(providers, "ru.cryptopro.csp");
}
#endif
}
static void InsertIfMissing(IList<string> providers, string name)
{
for (var i = 0; i < providers.Count; i++)
{
if (string.Equals(providers[i], name, StringComparison.OrdinalIgnoreCase))
{
return;
}
}
providers.Insert(0, name);
}
}
}

View File

@@ -13,6 +13,7 @@
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.Pkcs11Gost\StellaOps.Cryptography.Plugin.Pkcs11Gost.csproj" />
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.OpenSslGost\StellaOps.Cryptography.Plugin.OpenSslGost.csproj" />
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.SmSoft\StellaOps.Cryptography.Plugin.SmSoft.csproj" />
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.SmRemote\StellaOps.Cryptography.Plugin.SmRemote.csproj" />
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.PqSoft\StellaOps.Cryptography.Plugin.PqSoft.csproj" />
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.WineCsp\StellaOps.Cryptography.Plugin.WineCsp.csproj" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.0" />