Files
git.stella-ops.org/ops/cryptopro/linux-csp-service/Program.cs
StellaOps Bot 108d1c64b3
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
cryptopro-linux-csp / build-and-test (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
sm-remote-ci / build-and-test (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
up
2025-12-09 09:38:09 +02:00

119 lines
3.3 KiB
C#

using System.Diagnostics;
using System.Text.Json.Serialization;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Services.ConfigureHttpJsonOptions(opts =>
{
opts.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
var app = builder.Build();
const string CsptestPath = "/opt/cprocsp/bin/amd64/csptest";
app.MapGet("/health", () =>
{
if (!File.Exists(CsptestPath))
{
return Results.Problem(statusCode: 500, detail: "csptest not found; ensure CryptoPro CSP is installed");
}
return Results.Ok(new { status = "ok", csptest = CsptestPath });
});
app.MapGet("/license", () =>
{
var result = RunProcess([CsptestPath, "-keyset", "-info"], allowFailure: true);
return Results.Json(result);
});
app.MapPost("/hash", async (HashRequest request) =>
{
byte[] data;
try
{
data = Convert.FromBase64String(request.DataBase64);
}
catch (FormatException)
{
return Results.BadRequest(new { error = "Invalid base64" });
}
var inputPath = Path.GetTempFileName();
var outputPath = Path.GetTempFileName();
await File.WriteAllBytesAsync(inputPath, data);
var result = RunProcess([CsptestPath, "-hash", "-alg", "GOST12_256", "-in", inputPath, "-out", outputPath], allowFailure: true);
string? digestBase64 = null;
if (File.Exists(outputPath))
{
var digestBytes = await File.ReadAllBytesAsync(outputPath);
digestBase64 = Convert.ToBase64String(digestBytes);
}
TryDelete(inputPath);
TryDelete(outputPath);
return Results.Json(new
{
result.ExitCode,
result.Output,
digest_b64 = digestBase64
});
});
app.MapPost("/keyset/init", (KeysetRequest request) =>
{
var name = string.IsNullOrWhiteSpace(request.Name) ? "default" : request.Name!;
var result = RunProcess([CsptestPath, "-keyset", "-newkeyset", "-container", name, "-keytype", "none"], allowFailure: true);
return Results.Json(result);
});
app.Run("http://0.0.0.0:8080");
static void TryDelete(string path)
{
try { File.Delete(path); } catch { /* ignore */ }
}
static ProcessResult RunProcess(string[] args, bool allowFailure = false)
{
try
{
var psi = new ProcessStartInfo
{
FileName = args[0],
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
ArgumentList = { }
};
for (var i = 1; i < args.Length; i++)
{
psi.ArgumentList.Add(args[i]);
}
using var proc = Process.Start(psi)!;
var output = proc.StandardOutput.ReadToEnd();
output += proc.StandardError.ReadToEnd();
proc.WaitForExit();
if (proc.ExitCode != 0 && !allowFailure)
{
throw new InvalidOperationException($"Command failed with exit {proc.ExitCode}: {output}");
}
return new ProcessResult(proc.ExitCode, output);
}
catch (Exception ex)
{
if (!allowFailure)
{
throw;
}
return new ProcessResult(-1, ex.ToString());
}
}
sealed record HashRequest([property: JsonPropertyName("data_b64")] string DataBase64);
sealed record KeysetRequest([property: JsonPropertyName("name")] string? Name);
sealed record ProcessResult(int ExitCode, string Output);