feat: Implement Wine CSP HTTP provider for GOST cryptographic operations
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
- Added WineCspHttpProvider class to interface with Wine-hosted CryptoPro CSP. - Implemented ICryptoProvider, ICryptoProviderDiagnostics, and IDisposable interfaces. - Introduced WineCspHttpSigner and WineCspHttpHasher for signing and hashing operations. - Created WineCspProviderOptions for configuration settings including service URL and key options. - Developed CryptoProGostSigningService to handle GOST signing operations and key management. - Implemented HTTP service for the Wine CSP with endpoints for signing, verification, and hashing. - Added Swagger documentation for API endpoints. - Included health checks and error handling for service availability. - Established DTOs for request and response models in the service.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace StellaOps.Signals.Options;
|
||||
@@ -9,18 +10,144 @@ namespace StellaOps.Signals.Options;
|
||||
public sealed class SignalsArtifactStorageOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Root directory used to persist raw callgraph artifacts.
|
||||
/// Storage driver: "filesystem" (default) or "rustfs".
|
||||
/// </summary>
|
||||
public string Driver { get; set; } = SignalsStorageDrivers.FileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Root directory used to persist raw callgraph artifacts (filesystem driver).
|
||||
/// </summary>
|
||||
public string RootPath { get; set; } = Path.Combine(AppContext.BaseDirectory, "callgraph-artifacts");
|
||||
|
||||
/// <summary>
|
||||
/// Bucket name for CAS storage (RustFS driver).
|
||||
/// Per CAS contract, signals uses "signals-data" bucket.
|
||||
/// </summary>
|
||||
public string BucketName { get; set; } = "signals-data";
|
||||
|
||||
/// <summary>
|
||||
/// Root prefix within the bucket for callgraph artifacts.
|
||||
/// </summary>
|
||||
public string RootPrefix { get; set; } = "callgraphs";
|
||||
|
||||
/// <summary>
|
||||
/// RustFS-specific options.
|
||||
/// </summary>
|
||||
public SignalsRustFsOptions RustFs { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Additional headers to include in storage requests.
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Headers { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the filesystem driver is configured.
|
||||
/// </summary>
|
||||
public bool IsFileSystemDriver()
|
||||
=> string.Equals(Driver, SignalsStorageDrivers.FileSystem, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the RustFS driver is configured.
|
||||
/// </summary>
|
||||
public bool IsRustFsDriver()
|
||||
=> string.Equals(Driver, SignalsStorageDrivers.RustFs, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Validates the configured values.
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(RootPath))
|
||||
if (!IsFileSystemDriver() && !IsRustFsDriver())
|
||||
{
|
||||
throw new InvalidOperationException("Signals artifact storage path must be configured.");
|
||||
throw new InvalidOperationException($"Signals storage driver '{Driver}' is not supported. Use '{SignalsStorageDrivers.FileSystem}' or '{SignalsStorageDrivers.RustFs}'.");
|
||||
}
|
||||
|
||||
if (IsFileSystemDriver() && string.IsNullOrWhiteSpace(RootPath))
|
||||
{
|
||||
throw new InvalidOperationException("Signals artifact storage path must be configured for filesystem driver.");
|
||||
}
|
||||
|
||||
if (IsRustFsDriver())
|
||||
{
|
||||
RustFs ??= new SignalsRustFsOptions();
|
||||
RustFs.Validate();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(BucketName))
|
||||
{
|
||||
throw new InvalidOperationException("Signals storage bucket name must be configured for RustFS driver.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RustFS-specific configuration options.
|
||||
/// </summary>
|
||||
public sealed class SignalsRustFsOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Base URL for the RustFS service (e.g., http://localhost:8180/api/v1).
|
||||
/// </summary>
|
||||
public string BaseUrl { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Allow insecure TLS connections (development only).
|
||||
/// </summary>
|
||||
public bool AllowInsecureTls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// API key for authentication.
|
||||
/// </summary>
|
||||
public string? ApiKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header name for the API key (e.g., "X-API-Key").
|
||||
/// </summary>
|
||||
public string ApiKeyHeader { get; set; } = "X-API-Key";
|
||||
|
||||
/// <summary>
|
||||
/// HTTP request timeout.
|
||||
/// </summary>
|
||||
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(60);
|
||||
|
||||
/// <summary>
|
||||
/// Validates the configured values.
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(BaseUrl))
|
||||
{
|
||||
throw new InvalidOperationException("RustFS baseUrl must be configured.");
|
||||
}
|
||||
|
||||
if (!Uri.TryCreate(BaseUrl, UriKind.Absolute, out var uri))
|
||||
{
|
||||
throw new InvalidOperationException("RustFS baseUrl must be an absolute URI.");
|
||||
}
|
||||
|
||||
if (!string.Equals(uri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase)
|
||||
&& !string.Equals(uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException("RustFS baseUrl must use HTTP or HTTPS.");
|
||||
}
|
||||
|
||||
if (Timeout <= TimeSpan.Zero)
|
||||
{
|
||||
throw new InvalidOperationException("RustFS timeout must be greater than zero.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(ApiKeyHeader) && string.IsNullOrWhiteSpace(ApiKey))
|
||||
{
|
||||
throw new InvalidOperationException("RustFS API key header name requires a non-empty API key.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supported storage driver names.
|
||||
/// </summary>
|
||||
public static class SignalsStorageDrivers
|
||||
{
|
||||
public const string FileSystem = "filesystem";
|
||||
public const string RustFs = "rustfs";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user