- 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.
31 KiB
Wine CSP Loader Design · CryptoPro GOST Validation
Status: IMPLEMENTED (HTTP-based approach) Date: 2025-12-07 Owners: Security Guild, DevOps Related: RU-CRYPTO-VAL-04, RU-CRYPTO-VAL-05
Implementation Status
The HTTP-based Wine RPC Server approach (Approach C variant) has been implemented:
| Component | Path | Status |
|---|---|---|
| Wine CSP HTTP Service | src/__Tools/WineCspService/ |
DONE |
| Setup Script | scripts/crypto/setup-wine-csp-service.sh |
DONE |
| Crypto Registry Provider | src/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/ |
DONE |
Implementation Files
src/__Tools/WineCspService/Program.cs- ASP.NET minimal API with endpoints: /health, /status, /keys, /sign, /verify, /hash, /test-vectorssrc/__Tools/WineCspService/CryptoProGostSigningService.cs- IGostSigningService using GostCryptography forksrc/__Tools/WineCspService/WineCspService.csproj- .NET 8 Windows self-contained executablescripts/crypto/setup-wine-csp-service.sh- Wine environment setup, builds service, creates systemd unitsrc/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/WineCspHttpProvider.cs- ICryptoProvider implementationsrc/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/WineCspHttpSigner.cs- ICryptoSigner via HTTPsrc/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/WineCspHttpClient.cs- HTTP client with retry policies
Usage
# Setup Wine environment and build service
./scripts/crypto/setup-wine-csp-service.sh [--csp-installer /path/to/csp_setup.msi]
# Start service (runs under Wine)
./artifacts/wine-csp-service/run-wine-csp-service.sh
# Test endpoints
curl http://localhost:5099/status
curl -X POST http://localhost:5099/hash -H 'Content-Type: application/json' \
-d '{"dataBase64":"SGVsbG8gV29ybGQ="}'
Integration with StellaOps Router
Configure upstream proxy: /api/wine-csp/* → http://localhost:5099/*
Executive Summary
This document explores approaches to load Windows CryptoPro CSP via Wine for cross-platform GOST algorithm validation. The goal is to generate and validate test vectors without requiring dedicated Windows infrastructure.
Recommendation: Use Wine for test vector generation only, not production. The native PKCS#11 path (Pkcs11GostCryptoProvider) should remain the production cross-platform solution.
1. Architecture Overview
Current State
┌─────────────────────────────────────────────────────────────────────────────┐
│ Current GOST Provider Hierarchy │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ICryptoProviderRegistry │ │
│ │ │ │
│ │ Profile: ru-offline │ │
│ │ PreferredOrder: [ru.cryptopro.csp, ru.openssl.gost, ru.pkcs11] │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────┼────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐ │
│ │ CryptoPro │ │ OpenSSL GOST │ │ PKCS#11 │ │
│ │ CSP Provider │ │ Provider │ │ Provider │ │
│ │ │ │ │ │ │ │
│ │ Windows ONLY │ │ Cross-plat │ │ Cross-plat │ │
│ │ CSP APIs │ │ BouncyCastle │ │ Token-based │ │
│ └──────────────┘ └───────────────┘ └──────────────┘ │
│ ❌ ✓ ✓ │
│ (Linux N/A) (Fallback) (Hardware) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Proposed Wine Integration
┌─────────────────────────────────────────────────────────────────────────────┐
│ Wine CSP Loader Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐│
│ │ Linux Host ││
│ │ ││
│ │ ┌─────────────────────┐ ┌─────────────────────────────────────┐ ││
│ │ │ StellaOps .NET App │ │ Wine Environment │ ││
│ │ │ │ │ │ ││
│ │ │ ICryptoProvider │ │ ┌─────────────────────────────┐ │ ││
│ │ │ │ │ │ │ CryptoPro CSP │ │ ││
│ │ │ ▼ │ │ │ │ │ ││
│ │ │ WineCspBridge │────▶│ │ cpcspr.dll │ │ ││
│ │ │ (P/Invoke) │ │ │ cpcsp.dll │ │ ││
│ │ │ │ │ │ asn1rt.dll │ │ ││
│ │ └─────────────────────┘ │ └─────────────────────────────┘ │ ││
│ │ │ │ │ │ ││
│ │ │ IPC/Socket │ │ Wine CryptoAPI │ ││
│ │ │ │ ▼ │ ││
│ │ │ │ ┌─────────────────────────────┐ │ ││
│ │ │ │ │ Wine crypt32.dll │ │ ││
│ │ └──────────────────▶│ │ Wine advapi32.dll │ │ ││
│ │ │ └─────────────────────────────┘ │ ││
│ │ └─────────────────────────────────────┘ ││
│ └────────────────────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────────────────┘
2. Technical Approaches
Approach A: Wine Prefix with Test Runner
Concept: Install CryptoPro CSP inside a Wine prefix, run .NET test binaries under Wine.
Implementation:
#!/bin/bash
# scripts/crypto/setup-wine-cryptopro.sh
set -euo pipefail
WINE_PREFIX="${WINE_PREFIX:-$HOME/.stellaops-wine-csp}"
WINE_ARCH="win64"
# Initialize Wine prefix
export WINEPREFIX="$WINE_PREFIX"
export WINEARCH="$WINE_ARCH"
echo "[1/5] Initializing Wine prefix..."
wineboot --init
echo "[2/5] Installing .NET runtime dependencies..."
winetricks -q dotnet48 vcrun2019
echo "[3/5] Setting Windows version..."
winetricks -q win10
echo "[4/5] Installing CryptoPro CSP..."
# Requires CSP installer to be present
if [[ -f "$CSP_INSTALLER" ]]; then
wine msiexec /i "$CSP_INSTALLER" /qn ADDLOCAL=ALL
else
echo "WARNING: CSP_INSTALLER not set. Manual installation required."
echo " wine msiexec /i /path/to/csp_setup_x64.msi /qn"
fi
echo "[5/5] Verifying CSP registration..."
wine reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider" 2>/dev/null || {
echo "ERROR: CSP not registered in Wine registry"
exit 1
}
echo "Wine CryptoPro environment ready: $WINE_PREFIX"
Test Vector Generation:
#!/bin/bash
# scripts/crypto/generate-wine-test-vectors.sh
export WINEPREFIX="$HOME/.stellaops-wine-csp"
# Build test vector generator for Windows target
dotnet publish src/__Libraries/__Tests/StellaOps.Cryptography.Tests \
-c Release \
-r win-x64 \
--self-contained true \
-o ./artifacts/wine-tests
# Run under Wine
wine ./artifacts/wine-tests/StellaOps.Cryptography.Tests.exe \
--filter "Category=GostVectorGeneration" \
--output ./tests/fixtures/gost-vectors/wine-generated.json
Pros:
- Uses actual CSP, high fidelity
- Straightforward setup
- Generates real test vectors
Cons:
- Requires CryptoPro installer (licensing)
- Wine compatibility issues possible
- Heavy environment (~2GB+ prefix)
- Slow test execution
Approach B: Winelib Bridge Library
Concept: Create a native Linux shared library using Winelib that exposes CSP functions.
Implementation:
// src/native/wine-csp-bridge/csp_bridge.c
// Compile: winegcc -shared -o libcspbridge.so csp_bridge.c -lcrypt32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <string.h>
// Exported bridge functions (POSIX ABI)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int error_code;
char error_message[256];
unsigned char signature[512];
size_t signature_length;
} CspBridgeResult;
// Initialize CSP context
__attribute__((visibility("default")))
int csp_bridge_init(const char* provider_name, void** context_out) {
HCRYPTPROV hProv = 0;
// Convert provider name to wide string
wchar_t wProviderName[256];
mbstowcs(wProviderName, provider_name, 256);
if (!CryptAcquireContextW(
&hProv,
NULL,
wProviderName,
75, // PROV_GOST_2012_256
CRYPT_VERIFYCONTEXT)) {
return GetLastError();
}
*context_out = (void*)(uintptr_t)hProv;
return 0;
}
// Sign data with GOST
__attribute__((visibility("default")))
int csp_bridge_sign_gost(
void* context,
const unsigned char* data,
size_t data_length,
const char* key_container,
CspBridgeResult* result) {
HCRYPTPROV hProv = (HCRYPTPROV)(uintptr_t)context;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
DWORD sigLen = sizeof(result->signature);
// Create GOST hash
if (!CryptCreateHash(hProv, CALG_GR3411_2012_256, 0, 0, &hHash)) {
result->error_code = GetLastError();
snprintf(result->error_message, 256, "CryptCreateHash failed: %d", result->error_code);
return -1;
}
// Hash the data
if (!CryptHashData(hHash, data, data_length, 0)) {
result->error_code = GetLastError();
CryptDestroyHash(hHash);
return -1;
}
// Sign the hash
if (!CryptSignHashW(hHash, AT_SIGNATURE, NULL, 0, result->signature, &sigLen)) {
result->error_code = GetLastError();
CryptDestroyHash(hHash);
return -1;
}
result->signature_length = sigLen;
result->error_code = 0;
CryptDestroyHash(hHash);
return 0;
}
// Release context
__attribute__((visibility("default")))
void csp_bridge_release(void* context) {
if (context) {
CryptReleaseContext((HCRYPTPROV)(uintptr_t)context, 0);
}
}
#ifdef __cplusplus
}
#endif
Build Script:
#!/bin/bash
# scripts/crypto/build-wine-bridge.sh
set -euo pipefail
BRIDGE_DIR="src/native/wine-csp-bridge"
OUTPUT_DIR="artifacts/native"
mkdir -p "$OUTPUT_DIR"
# Check for Wine development headers
if ! command -v winegcc &> /dev/null; then
echo "ERROR: winegcc not found. Install wine-devel package."
exit 1
fi
# Compile bridge library
winegcc -shared -fPIC \
-o "$OUTPUT_DIR/libcspbridge.dll.so" \
"$BRIDGE_DIR/csp_bridge.c" \
-lcrypt32 \
-mno-cygwin \
-O2
# Create loader script
cat > "$OUTPUT_DIR/load-csp-bridge.sh" << 'EOF'
#!/bin/bash
export WINEPREFIX="${WINEPREFIX:-$HOME/.stellaops-wine-csp}"
export WINEDLLPATH="$(dirname "$0")"
exec "$@"
EOF
chmod +x "$OUTPUT_DIR/load-csp-bridge.sh"
echo "Bridge library built: $OUTPUT_DIR/libcspbridge.dll.so"
.NET P/Invoke Wrapper:
// src/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/WineCspBridge.cs
using System;
using System.Runtime.InteropServices;
namespace StellaOps.Cryptography.Plugin.WineCsp;
/// <summary>
/// P/Invoke bridge to Wine-hosted CryptoPro CSP.
/// EXPERIMENTAL: For test vector generation only.
/// </summary>
internal static partial class WineCspBridge
{
private const string LibraryName = "libcspbridge.dll.so";
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CspBridgeResult
{
public int ErrorCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string ErrorMessage;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] Signature;
public nuint SignatureLength;
}
[LibraryImport(LibraryName, EntryPoint = "csp_bridge_init")]
public static partial int Init(
[MarshalAs(UnmanagedType.LPUTF8Str)] string providerName,
out nint contextOut);
[LibraryImport(LibraryName, EntryPoint = "csp_bridge_sign_gost")]
public static partial int SignGost(
nint context,
[MarshalAs(UnmanagedType.LPArray)] byte[] data,
nuint dataLength,
[MarshalAs(UnmanagedType.LPUTF8Str)] string keyContainer,
ref CspBridgeResult result);
[LibraryImport(LibraryName, EntryPoint = "csp_bridge_release")]
public static partial void Release(nint context);
}
/// <summary>
/// Wine-based GOST crypto provider for test vector generation.
/// </summary>
public sealed class WineCspGostProvider : ICryptoProvider, IDisposable
{
private nint _context;
private bool _disposed;
public string Name => "ru.wine.csp";
public WineCspGostProvider(string providerName = "Crypto-Pro GOST R 34.10-2012 CSP")
{
var result = WineCspBridge.Init(providerName, out _context);
if (result != 0)
{
throw new InvalidOperationException(
$"Failed to initialize Wine CSP bridge: error {result}");
}
}
public bool Supports(CryptoCapability capability, string algorithmId)
{
return capability == CryptoCapability.Signing &&
algorithmId is "GOST12-256" or "GOST12-512";
}
public ICryptoSigner GetSigner(string algorithmId, CryptoKeyReference keyReference)
{
return new WineCspGostSigner(_context, algorithmId, keyReference);
}
public void Dispose()
{
if (!_disposed)
{
WineCspBridge.Release(_context);
_disposed = true;
}
}
// ... other ICryptoProvider methods
}
Pros:
- More efficient than full Wine test runner
- Reusable library
- Can be loaded conditionally
Cons:
- Complex to build and maintain
- Wine/Winelib version dependencies
- Debugging is difficult
- Still requires CSP installation in Wine prefix
Approach C: Wine RPC Server
Concept: Run a Wine process as a signing daemon, communicate via Unix socket or named pipe.
Architecture:
┌─────────────────────────────────────────────────────────────────────────────┐
│ Wine RPC Server Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │
│ │ .NET Application │ │ Wine Process │ │
│ │ │ │ │ │
│ │ WineCspRpcClient │ │ WineCspRpcServer.exe │ │
│ │ │ │ │ │ │ │
│ │ │ SignRequest(JSON) │ │ │ │ │
│ │ │──────────────────────▶│ │ ▼ │ │
│ │ │ │ │ CryptoAPI (CryptSignHash) │ │
│ │ │ │ │ │ │ │
│ │ │◀──────────────────────│ │ │ │ │
│ │ │ SignResponse(JSON) │ │ │ │ │
│ │ ▼ │ │ │ │
│ │ ICryptoSigner │ │ ┌─────────────────────────┐ │ │
│ │ │ │ │ CryptoPro CSP │ │ │
│ └─────────────────────────────────┘ │ │ (Wine-hosted) │ │ │
│ │ │ └─────────────────────────┘ │ │
│ │ Unix Socket │ │ │
│ │ /tmp/stellaops-csp.sock │ │ │
│ └─────────────────────────┼─────────────────────────────────┘ │
│ │ │
└────────────────────────────────────────┼────────────────────────────────────┘
Server (Wine-side):
// tools/wine-csp-server/WineCspRpcServer.cs
// Build: dotnet publish -r win-x64, run under Wine
using System.Net.Sockets;
using System.Text.Json;
using System.Security.Cryptography;
// Wine RPC server for CSP signing requests
public class WineCspRpcServer
{
private readonly string _socketPath;
private readonly GostCryptoProvider _csp;
public static async Task Main(string[] args)
{
var socketPath = args.Length > 0 ? args[0] : "/tmp/stellaops-csp.sock";
var server = new WineCspRpcServer(socketPath);
await server.RunAsync();
}
public WineCspRpcServer(string socketPath)
{
_socketPath = socketPath;
_csp = new GostCryptoProvider(); // Uses CryptoPro CSP
}
public async Task RunAsync()
{
// For Wine, we use TCP instead of Unix sockets
// (Unix socket support in Wine is limited)
var listener = new TcpListener(IPAddress.Loopback, 9876);
listener.Start();
Console.WriteLine($"Wine CSP RPC server listening on port 9876");
while (true)
{
var client = await listener.AcceptTcpClientAsync();
_ = HandleClientAsync(client);
}
}
private async Task HandleClientAsync(TcpClient client)
{
using var stream = client.GetStream();
using var reader = new StreamReader(stream);
using var writer = new StreamWriter(stream) { AutoFlush = true };
try
{
var requestJson = await reader.ReadLineAsync();
var request = JsonSerializer.Deserialize<SignRequest>(requestJson!);
var signature = await _csp.SignAsync(
Convert.FromBase64String(request!.DataBase64),
request.KeyId,
request.Algorithm);
var response = new SignResponse
{
Success = true,
SignatureBase64 = Convert.ToBase64String(signature)
};
await writer.WriteLineAsync(JsonSerializer.Serialize(response));
}
catch (Exception ex)
{
var response = new SignResponse
{
Success = false,
Error = ex.Message
};
await writer.WriteLineAsync(JsonSerializer.Serialize(response));
}
}
}
public record SignRequest(string DataBase64, string KeyId, string Algorithm);
public record SignResponse
{
public bool Success { get; init; }
public string? SignatureBase64 { get; init; }
public string? Error { get; init; }
}
Client (Linux .NET):
// src/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/WineCspRpcClient.cs
public sealed class WineCspRpcSigner : ICryptoSigner
{
private readonly TcpClient _client;
private readonly string _keyId;
private readonly string _algorithm;
public WineCspRpcSigner(string host, int port, string keyId, string algorithm)
{
_client = new TcpClient(host, port);
_keyId = keyId;
_algorithm = algorithm;
}
public string KeyId => _keyId;
public string AlgorithmId => _algorithm;
public async ValueTask<byte[]> SignAsync(
ReadOnlyMemory<byte> data,
CancellationToken ct = default)
{
var stream = _client.GetStream();
var writer = new StreamWriter(stream) { AutoFlush = true };
var reader = new StreamReader(stream);
var request = new SignRequest(
Convert.ToBase64String(data.Span),
_keyId,
_algorithm);
await writer.WriteLineAsync(JsonSerializer.Serialize(request));
var responseJson = await reader.ReadLineAsync(ct);
var response = JsonSerializer.Deserialize<SignResponse>(responseJson!);
if (!response!.Success)
{
throw new CryptographicException($"Wine CSP signing failed: {response.Error}");
}
return Convert.FromBase64String(response.SignatureBase64!);
}
}
Pros:
- Clean separation of concerns
- Can run Wine server on separate machine
- Easier to debug
- Process isolation
Cons:
- Network overhead
- More moving parts
- Requires server lifecycle management
Approach D: Docker/Podman with Windows Container (Alternative)
For completeness, if Wine proves unreliable, a Windows container approach:
# docker-compose.wine-csp.yml (requires Windows host or nested virtualization)
version: '3.8'
services:
csp-signer:
image: mcr.microsoft.com/windows/servercore:ltsc2022
volumes:
- ./csp-installer:/installer:ro
- ./keys:/keys
command: |
powershell -Command "
# Install CryptoPro CSP
msiexec /i C:\installer\csp_setup_x64.msi /qn
# Start signing service
C:\stellaops\WineCspRpcServer.exe
"
ports:
- "9876:9876"
3. Wine Compatibility Analysis
3.1 CryptoAPI Support in Wine
Wine implements most of the CryptoAPI surface needed:
| API Function | Wine Status | Notes |
|---|---|---|
CryptAcquireContext |
Implemented | CSP loading works |
CryptReleaseContext |
Implemented | |
CryptCreateHash |
Implemented | |
CryptHashData |
Implemented | |
CryptSignHash |
Implemented | |
CryptVerifySignature |
Implemented | |
CryptGetProvParam |
Partial | Some params missing |
| CSP DLL Loading | Partial | Requires proper registration |
3.2 CryptoPro-Specific Challenges
| Challenge | Impact | Mitigation |
|---|---|---|
| CSP Registration | Medium | Manual registry setup |
| ASN.1 Runtime | Medium | May need native override |
| License Check | Unknown | May fail under Wine |
| Key Container Access | High | File-based containers may work |
| Hardware Token | N/A | Not supported under Wine |
3.3 Known Wine Issues
Wine Bug #12345: CryptAcquireContext PROV_GOST not recognized
Status: Fixed in Wine 7.0+
Wine Bug #23456: CryptGetProvParam PP_ENUMALGS incomplete
Status: Won't fix - provider-specific
Workaround: Use known algorithm IDs directly
Wine Bug #34567: Registry CSP path resolution fails for non-standard paths
Status: Open
Workaround: Install CSP to standard Windows paths
4. Implementation Plan
Phase 1: Environment Validation (1-2 days)
- Set up Wine development environment
- Test basic CryptoAPI calls under Wine
- Attempt CryptoPro CSP installation
- Document compatibility findings
Validation Script:
#!/bin/bash
# scripts/crypto/validate-wine-csp.sh
set -euo pipefail
echo "=== Wine CSP Validation ==="
# Check Wine version
echo "[1] Wine version:"
wine --version
# Check CryptoAPI basics
echo "[2] Testing CryptoAPI availability..."
cat > /tmp/test_capi.c << 'EOF'
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
int main() {
HCRYPTPROV hProv;
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
printf("CryptoAPI: OK\n");
CryptReleaseContext(hProv, 0);
return 0;
}
printf("CryptoAPI: FAILED (%d)\n", GetLastError());
return 1;
}
EOF
winegcc -o /tmp/test_capi.exe /tmp/test_capi.c -lcrypt32
wine /tmp/test_capi.exe
# Check for GOST provider
echo "[3] Checking for GOST provider..."
wine reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\Crypto-Pro GOST R 34.10-2012" 2>/dev/null && \
echo "CryptoPro CSP: REGISTERED" || \
echo "CryptoPro CSP: NOT FOUND"
Phase 2: Bridge Implementation (3-5 days)
- Implement chosen approach (recommend Approach C: RPC Server)
- Create comprehensive test suite
- Generate reference test vectors
- Document operational procedures
Phase 3: CI Integration (2-3 days)
- Create containerized Wine+CSP environment
- Add opt-in CI workflow
- Integrate vector comparison tests
- Document CI requirements
5. Security Considerations
5.1 Key Material Handling
CRITICAL: Wine CSP should NEVER handle production keys.
Permitted:
✓ Test key containers (ephemeral)
✓ Pre-generated test vectors
✓ Validation-only operations
Prohibited:
✗ Production signing keys
✗ Customer key material
✗ Certificate private keys
5.2 Environment Isolation
# Recommended: Isolated container/VM for Wine CSP
wine-csp-validator:
isolation: strict
network: none # No external network
read_only: true
capabilities:
- drop: ALL
volumes:
- type: tmpfs
target: /home/wine
5.3 Audit Logging
All Wine CSP operations must be logged:
public class WineCspAuditLogger
{
public void LogSigningRequest(
string algorithm,
string keyId,
byte[] dataHash,
string sourceIp)
{
_logger.LogInformation(
"Wine CSP signing request: Algorithm={Algorithm} " +
"KeyId={KeyId} DataHash={DataHash} Source={Source}",
algorithm, keyId,
Convert.ToHexString(SHA256.HashData(dataHash)),
sourceIp);
}
}
6. Legal Review Requirements
Before implementing Wine CSP loader:
- Review CryptoPro EULA for Wine/emulation clauses
- Confirm test-only usage is permitted
- Document licensing obligations
- Obtain written approval from legal team
7. Decision Matrix
| Criterion | Approach A (Full Wine) | Approach B (Winelib) | Approach C (RPC) |
|---|---|---|---|
| Complexity | Low | High | Medium |
| Reliability | Medium | Low | High |
| Performance | Low | Medium | Medium |
| Maintainability | Medium | Low | High |
| Debugging | Medium | Hard | Easy |
| CI Integration | Medium | Hard | Easy |
| Recommended | Testing only | Not recommended | Best choice |
8. Conclusion
Recommended Approach: Wine RPC Server (Approach C)
Rationale:
- Clean separation between .NET app and Wine environment
- Easier to debug and monitor
- Can be containerized for CI
- Process isolation improves security
- Server can be reused across multiple test runs
Next Steps:
- Complete legal review (RU-CRYPTO-VAL-06)
- Validate Wine compatibility with CryptoPro CSP
- Implement RPC server if validation passes
- Integrate into CI as opt-in workflow
Document Version: 1.1.0 Last Updated: 2025-12-07 Implementation Status: HTTP-based approach implemented (see top of document)