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
119 lines
3.3 KiB
C#
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);
|