Add SBOM, symbols, traces, and VEX files for CVE-2022-21661 SQLi case
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Created CycloneDX and SPDX SBOM files for both reachable and unreachable images. - Added symbols.json detailing function entry and sink points in the WordPress code. - Included runtime traces for function calls in both reachable and unreachable scenarios. - Developed OpenVEX files indicating vulnerability status and justification for both cases. - Updated README for evaluator harness to guide integration with scanner output.
This commit is contained in:
13
src/__Libraries/StellaOps.Cryptography/CryptoHashFactory.cs
Normal file
13
src/__Libraries/StellaOps.Cryptography/CryptoHashFactory.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
/// <summary>
|
||||
/// Factory helpers for creating crypto hash implementations outside of dependency injection scenarios.
|
||||
/// </summary>
|
||||
public static class CryptoHashFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates the default ICryptoHash implementation.
|
||||
/// </summary>
|
||||
public static ICryptoHash CreateDefault(CryptoHashOptions? options = null)
|
||||
=> new DefaultCryptoHash(options);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
public sealed class CryptoHashOptions
|
||||
{
|
||||
public string DefaultAlgorithm { get; set; } = HashAlgorithms.Sha256;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
/// <summary>
|
||||
/// Describes key material surfaced by crypto providers for diagnostics.
|
||||
/// </summary>
|
||||
public sealed record CryptoProviderKeyDescriptor(
|
||||
string Provider,
|
||||
string KeyId,
|
||||
string AlgorithmId,
|
||||
IReadOnlyDictionary<string, string?> Metadata);
|
||||
|
||||
/// <summary>
|
||||
/// Optional interface for providers that can expose key metadata without revealing private material.
|
||||
/// </summary>
|
||||
public interface ICryptoProviderDiagnostics
|
||||
{
|
||||
IEnumerable<CryptoProviderKeyDescriptor> DescribeKeys();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Metrics;
|
||||
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
internal static class CryptoProviderMetrics
|
||||
{
|
||||
private static readonly Meter Meter = new("stellaops.crypto", "1.0.0");
|
||||
private static readonly Counter<long> ProviderResolutionCounter =
|
||||
Meter.CreateCounter<long>("crypto_provider_resolutions_total", description: "Count of successful provider resolutions.");
|
||||
|
||||
private static readonly Counter<long> ProviderResolutionFailureCounter =
|
||||
Meter.CreateCounter<long>("crypto_provider_resolution_failures_total", description: "Count of failed provider resolutions.");
|
||||
|
||||
public static void RecordProviderResolution(string providerName, CryptoCapability capability, string algorithmId)
|
||||
{
|
||||
ProviderResolutionCounter.Add(1,
|
||||
new KeyValuePair<string, object?>("provider", providerName),
|
||||
new KeyValuePair<string, object?>("capability", capability.ToString()),
|
||||
new KeyValuePair<string, object?>("algorithm", algorithmId));
|
||||
}
|
||||
|
||||
public static void RecordProviderResolutionFailure(CryptoCapability capability, string algorithmId)
|
||||
{
|
||||
ProviderResolutionFailureCounter.Add(1,
|
||||
new KeyValuePair<string, object?>("capability", capability.ToString()),
|
||||
new KeyValuePair<string, object?>("algorithm", algorithmId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,10 +64,12 @@ public sealed class CryptoProviderRegistry : ICryptoProviderRegistry
|
||||
{
|
||||
if (provider.Supports(capability, algorithmId))
|
||||
{
|
||||
CryptoProviderMetrics.RecordProviderResolution(provider.Name, capability, algorithmId);
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
|
||||
CryptoProviderMetrics.RecordProviderResolutionFailure(capability, algorithmId);
|
||||
throw new InvalidOperationException(
|
||||
$"No crypto provider is registered for capability '{capability}' and algorithm '{algorithmId}'.");
|
||||
}
|
||||
@@ -88,11 +90,13 @@ public sealed class CryptoProviderRegistry : ICryptoProviderRegistry
|
||||
}
|
||||
|
||||
var signer = hinted.GetSigner(algorithmId, keyReference);
|
||||
CryptoProviderMetrics.RecordProviderResolution(hinted.Name, capability, algorithmId);
|
||||
return new CryptoSignerResolution(signer, hinted.Name);
|
||||
}
|
||||
|
||||
var provider = ResolveOrThrow(capability, algorithmId);
|
||||
var resolved = provider.GetSigner(algorithmId, keyReference);
|
||||
CryptoProviderMetrics.RecordProviderResolution(provider.Name, capability, algorithmId);
|
||||
return new CryptoSignerResolution(resolved, provider.Name);
|
||||
}
|
||||
|
||||
|
||||
169
src/__Libraries/StellaOps.Cryptography/DefaultCryptoHash.cs
Normal file
169
src/__Libraries/StellaOps.Cryptography/DefaultCryptoHash.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
public sealed class DefaultCryptoHash : ICryptoHash
|
||||
{
|
||||
private readonly IOptionsMonitor<CryptoHashOptions> options;
|
||||
private readonly ILogger<DefaultCryptoHash> logger;
|
||||
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public DefaultCryptoHash(
|
||||
IOptionsMonitor<CryptoHashOptions> options,
|
||||
ILogger<DefaultCryptoHash>? logger = null)
|
||||
{
|
||||
this.options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
this.logger = logger ?? NullLogger<DefaultCryptoHash>.Instance;
|
||||
}
|
||||
|
||||
internal DefaultCryptoHash(CryptoHashOptions? options = null)
|
||||
: this(new StaticOptionsMonitor(options ?? new CryptoHashOptions()), NullLogger<DefaultCryptoHash>.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
public byte[] ComputeHash(ReadOnlySpan<byte> data, string? algorithmId = null)
|
||||
{
|
||||
var algorithm = NormalizeAlgorithm(algorithmId);
|
||||
return algorithm switch
|
||||
{
|
||||
HashAlgorithms.Sha256 => ComputeSha256(data),
|
||||
HashAlgorithms.Sha512 => ComputeSha512(data),
|
||||
HashAlgorithms.Gost3411_2012_256 => GostDigestUtilities.ComputeDigest(data, use256: true),
|
||||
HashAlgorithms.Gost3411_2012_512 => GostDigestUtilities.ComputeDigest(data, use256: false),
|
||||
_ => throw new InvalidOperationException($"Unsupported hash algorithm {algorithm}.")
|
||||
};
|
||||
}
|
||||
|
||||
public string ComputeHashHex(ReadOnlySpan<byte> data, string? algorithmId = null)
|
||||
=> Convert.ToHexString(ComputeHash(data, algorithmId)).ToLowerInvariant();
|
||||
|
||||
public string ComputeHashBase64(ReadOnlySpan<byte> data, string? algorithmId = null)
|
||||
=> Convert.ToBase64String(ComputeHash(data, algorithmId));
|
||||
|
||||
public async ValueTask<byte[]> ComputeHashAsync(Stream stream, string? algorithmId = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(stream);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var algorithm = NormalizeAlgorithm(algorithmId);
|
||||
return algorithm switch
|
||||
{
|
||||
HashAlgorithms.Sha256 => await ComputeShaStreamAsync(HashAlgorithmName.SHA256, stream, cancellationToken).ConfigureAwait(false),
|
||||
HashAlgorithms.Sha512 => await ComputeShaStreamAsync(HashAlgorithmName.SHA512, stream, cancellationToken).ConfigureAwait(false),
|
||||
HashAlgorithms.Gost3411_2012_256 => await ComputeGostStreamAsync(use256: true, stream, cancellationToken).ConfigureAwait(false),
|
||||
HashAlgorithms.Gost3411_2012_512 => await ComputeGostStreamAsync(use256: false, stream, cancellationToken).ConfigureAwait(false),
|
||||
_ => throw new InvalidOperationException($"Unsupported hash algorithm {algorithm}.")
|
||||
};
|
||||
}
|
||||
|
||||
public async ValueTask<string> ComputeHashHexAsync(Stream stream, string? algorithmId = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var bytes = await ComputeHashAsync(stream, algorithmId, cancellationToken).ConfigureAwait(false);
|
||||
return Convert.ToHexString(bytes).ToLowerInvariant();
|
||||
}
|
||||
|
||||
private static byte[] ComputeSha256(ReadOnlySpan<byte> data)
|
||||
{
|
||||
Span<byte> buffer = stackalloc byte[32];
|
||||
SHA256.HashData(data, buffer);
|
||||
return buffer.ToArray();
|
||||
}
|
||||
|
||||
private static byte[] ComputeSha512(ReadOnlySpan<byte> data)
|
||||
{
|
||||
Span<byte> buffer = stackalloc byte[64];
|
||||
SHA512.HashData(data, buffer);
|
||||
return buffer.ToArray();
|
||||
}
|
||||
|
||||
private static async ValueTask<byte[]> ComputeShaStreamAsync(HashAlgorithmName name, Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
using var incremental = IncrementalHash.CreateHash(name);
|
||||
var buffer = ArrayPool<byte>.Shared.Rent(128 * 1024);
|
||||
try
|
||||
{
|
||||
int bytesRead;
|
||||
while ((bytesRead = await stream.ReadAsync(buffer.AsMemory(0, buffer.Length), cancellationToken).ConfigureAwait(false)) > 0)
|
||||
{
|
||||
incremental.AppendData(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
return incremental.GetHashAndReset();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private static async ValueTask<byte[]> ComputeGostStreamAsync(bool use256, Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
var digest = GostDigestUtilities.CreateDigest(use256);
|
||||
var buffer = ArrayPool<byte>.Shared.Rent(128 * 1024);
|
||||
try
|
||||
{
|
||||
int bytesRead;
|
||||
while ((bytesRead = await stream.ReadAsync(buffer.AsMemory(0, buffer.Length), cancellationToken).ConfigureAwait(false)) > 0)
|
||||
{
|
||||
digest.BlockUpdate(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
var output = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(output, 0);
|
||||
return output;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private string NormalizeAlgorithm(string? algorithmId)
|
||||
{
|
||||
var defaultAlgorithm = options.CurrentValue?.DefaultAlgorithm;
|
||||
if (!string.IsNullOrWhiteSpace(algorithmId))
|
||||
{
|
||||
return algorithmId.Trim().ToUpperInvariant();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(defaultAlgorithm))
|
||||
{
|
||||
return defaultAlgorithm.Trim().ToUpperInvariant();
|
||||
}
|
||||
|
||||
return HashAlgorithms.Sha256;
|
||||
}
|
||||
|
||||
private sealed class StaticOptionsMonitor : IOptionsMonitor<CryptoHashOptions>
|
||||
{
|
||||
private readonly CryptoHashOptions options;
|
||||
|
||||
public StaticOptionsMonitor(CryptoHashOptions options)
|
||||
=> this.options = options;
|
||||
|
||||
public CryptoHashOptions CurrentValue => options;
|
||||
|
||||
public CryptoHashOptions Get(string? name) => options;
|
||||
|
||||
public IDisposable OnChange(Action<CryptoHashOptions, string> listener)
|
||||
=> NullDisposable.Instance;
|
||||
|
||||
private sealed class NullDisposable : IDisposable
|
||||
{
|
||||
public static readonly NullDisposable Instance = new();
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ namespace StellaOps.Cryptography;
|
||||
/// <summary>
|
||||
/// Default in-process crypto provider exposing password hashing capabilities.
|
||||
/// </summary>
|
||||
public sealed class DefaultCryptoProvider : ICryptoProvider
|
||||
{
|
||||
public sealed class DefaultCryptoProvider : ICryptoProvider, ICryptoProviderDiagnostics
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, IPasswordHasher> passwordHashers;
|
||||
private readonly ConcurrentDictionary<string, CryptoSigningKey> signingKeys;
|
||||
private static readonly HashSet<string> SupportedSigningAlgorithms = new(StringComparer.OrdinalIgnoreCase)
|
||||
@@ -105,8 +105,38 @@ public sealed class DefaultCryptoProvider : ICryptoProvider
|
||||
return signingKeys.TryRemove(keyId, out _);
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<CryptoSigningKey> GetSigningKeys()
|
||||
=> signingKeys.Values.ToArray();
|
||||
public IReadOnlyCollection<CryptoSigningKey> GetSigningKeys()
|
||||
=> signingKeys.Values.ToArray();
|
||||
|
||||
public IEnumerable<CryptoProviderKeyDescriptor> DescribeKeys()
|
||||
{
|
||||
foreach (var key in signingKeys.Values)
|
||||
{
|
||||
var metadata = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
["kind"] = key.Kind.ToString(),
|
||||
["createdAt"] = key.CreatedAt.UtcDateTime.ToString("O"),
|
||||
["providerHint"] = key.Reference.ProviderHint,
|
||||
["provider"] = Name
|
||||
};
|
||||
|
||||
if (key.ExpiresAt.HasValue)
|
||||
{
|
||||
metadata["expiresAt"] = key.ExpiresAt.Value.UtcDateTime.ToString("O");
|
||||
}
|
||||
|
||||
foreach (var pair in key.Metadata)
|
||||
{
|
||||
metadata[$"meta.{pair.Key}"] = pair.Value;
|
||||
}
|
||||
|
||||
yield return new CryptoProviderKeyDescriptor(
|
||||
Name,
|
||||
key.Reference.KeyId,
|
||||
key.AlgorithmId,
|
||||
metadata);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureSigningSupported(string algorithmId)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
public static class GostDigestUtilities
|
||||
{
|
||||
public static byte[] ComputeDigest(ReadOnlySpan<byte> data, bool use256)
|
||||
{
|
||||
IDigest digest = CreateDigestInstance(use256);
|
||||
var buffer = data.ToArray();
|
||||
digest.BlockUpdate(buffer, 0, buffer.Length);
|
||||
var output = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(output, 0);
|
||||
return output;
|
||||
}
|
||||
|
||||
public static IDigest CreateDigest(bool use256)
|
||||
=> CreateDigestInstance(use256);
|
||||
|
||||
private static IDigest CreateDigestInstance(bool use256)
|
||||
=> use256 ? new Gost3411_2012_256Digest() : new Gost3411_2012_512Digest();
|
||||
}
|
||||
12
src/__Libraries/StellaOps.Cryptography/HashAlgorithms.cs
Normal file
12
src/__Libraries/StellaOps.Cryptography/HashAlgorithms.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
/// <summary>
|
||||
/// Well-known digest algorithm identifiers supported by <see cref="ICryptoHash"/>.
|
||||
/// </summary>
|
||||
public static class HashAlgorithms
|
||||
{
|
||||
public const string Sha256 = "SHA256";
|
||||
public const string Sha512 = "SHA512";
|
||||
public const string Gost3411_2012_256 = "GOST3411-2012-256";
|
||||
public const string Gost3411_2012_512 = "GOST3411-2012-512";
|
||||
}
|
||||
19
src/__Libraries/StellaOps.Cryptography/ICryptoHash.cs
Normal file
19
src/__Libraries/StellaOps.Cryptography/ICryptoHash.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
public interface ICryptoHash
|
||||
{
|
||||
byte[] ComputeHash(ReadOnlySpan<byte> data, string? algorithmId = null);
|
||||
|
||||
string ComputeHashHex(ReadOnlySpan<byte> data, string? algorithmId = null);
|
||||
|
||||
string ComputeHashBase64(ReadOnlySpan<byte> data, string? algorithmId = null);
|
||||
|
||||
ValueTask<byte[]> ComputeHashAsync(Stream stream, string? algorithmId = null, CancellationToken cancellationToken = default);
|
||||
|
||||
ValueTask<string> ComputeHashHexAsync(Stream stream, string? algorithmId = null, CancellationToken cancellationToken = default);
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
/// <summary>
|
||||
/// Known signature algorithm identifiers.
|
||||
/// </summary>
|
||||
public static class SignatureAlgorithms
|
||||
{
|
||||
public const string Es256 = "ES256";
|
||||
public const string Es384 = "ES384";
|
||||
public const string Es512 = "ES512";
|
||||
public const string Ed25519 = "ED25519";
|
||||
public const string EdDsa = "EdDSA";
|
||||
}
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
/// <summary>
|
||||
/// Known signature algorithm identifiers.
|
||||
/// </summary>
|
||||
public static class SignatureAlgorithms
|
||||
{
|
||||
public const string Es256 = "ES256";
|
||||
public const string Es384 = "ES384";
|
||||
public const string Es512 = "ES512";
|
||||
public const string Ed25519 = "ED25519";
|
||||
public const string EdDsa = "EdDSA";
|
||||
public const string GostR3410_2012_256 = "GOST12-256";
|
||||
public const string GostR3410_2012_512 = "GOST12-512";
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
<PropertyGroup Condition="'$(StellaOpsCryptoSodium)' == 'true'">
|
||||
<DefineConstants>$(DefineConstants);STELLAOPS_CRYPTO_SODIUM</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.1" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.14.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.1" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.14.0" />
|
||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0-rc.2.25502.107" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
| ID | Status | Owner | Description | Dependencies | Exit Criteria |
|
||||
|----|--------|-------|-------------|--------------|---------------|
|
||||
| SEC-CRYPTO-90-001 | DONE (2025-11-07) | Security Guild | Produce RootPack_RU sovereign crypto implementation plan, identify provider strategy (CryptoPro + PKCS#11), and slot work into Sprint 190 with task breakdown. | None | Plan captured in `SPRINT_190_ops_offline.md` + this board; risks/assumptions logged. |
|
||||
| SEC-CRYPTO-90-002 | DONE (2025-11-07) | Security Guild | Extend signature/catalog constants and configuration schema to recognize `GOST12-256/512`, regional crypto profiles, and provider preference ordering. | SEC-CRYPTO-90-001 | New alg IDs wired, configs validated, docs updated. |
|
||||
| SEC-CRYPTO-90-003 | DONE (2025-11-07) | Security Guild | Implement `StellaOps.Cryptography.Plugin.CryptoPro` provider (sign/verify/JWK export) using CryptoPro CSP/GostCryptography with deterministic logging + tests. | SEC-CRYPTO-90-002 | Provider registered, unit/integration tests (skippable if CSP absent) passing. |
|
||||
| SEC-CRYPTO-90-004 | DONE (2025-11-07) | Security Guild | Implement `StellaOps.Cryptography.Plugin.Pkcs11Gost` provider (Rutoken/JaCarta) via Pkcs11Interop, configurable slot/pin/module management, and disposal safeguards. | SEC-CRYPTO-90-002 | Provider registered, token smoke tests + error handling documented. |
|
||||
| SEC-CRYPTO-90-005 | DONE (2025-11-08) | Security Guild | Add configuration-driven provider selection (`crypto.regionalProfiles`), CLI/diagnostic verb to list providers/keys, and deterministic telemetry for usage. | SEC-CRYPTO-90-003, SEC-CRYPTO-90-004 | CLI lists providers, configs switch ordering without code changes, telemetry events emitted. |
|
||||
| SEC-CRYPTO-90-006 | DONE (2025-11-08) | Security Guild | Build deterministic test harness (Streebog + signature vectors), manual runbooks for hardware validation, and capture RootPack audit metadata. | SEC-CRYPTO-90-003, SEC-CRYPTO-90-004 | `scripts/crypto/run-rootpack-ru-tests.sh` emits deterministic logs/TRX; validation runbook updated with harness + hardware guidance; audit metadata artifacts enumerated. |
|
||||
| SEC-CRYPTO-90-007 | DONE (2025-11-08) | Security Guild | Package RootPack_RU artifacts (plugin binaries, config templates, trust anchors) and document deployment/install steps + compliance evidence. | SEC-CRYPTO-90-005, SEC-CRYPTO-90-006 | `scripts/crypto/package-rootpack-ru.sh` builds bundle with docs/config/trust anchors; `rootpack_ru_package.md` guides ops/air-gap workflows. |
|
||||
| SEC-CRYPTO-90-008 | DONE (2025-11-08) | Security Guild | Audit repository for any cryptography usage bypassing `StellaOps.Cryptography` (direct libsodium/BouncyCastle callers, TLS custom code) and file remediation tasks to route via providers. | SEC-CRYPTO-90-002 | Audit report updated with remediation IDs; module TASKS boards now include `*-CRYPTO-90-001` follow-ups; backlog ready for implementation. |
|
||||
> Remark (2025-10-14): Cleanup service wired to store; background sweep + invite audit tests added.
|
||||
> Remark (2025-10-14): Token usage metadata persisted with replay audits + handler/unit coverage.
|
||||
> Remark (2025-10-14): Analyzer surfaces warnings during CLI load; docs updated with mitigation steps.
|
||||
|
||||
Reference in New Issue
Block a user