work work hard work
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using StellaOps.AirGap.Importer.Reconciliation;
|
||||
|
||||
namespace StellaOps.AirGap.Importer.Tests.Reconciliation;
|
||||
|
||||
public sealed class EvidenceReconcilerDsseSigningTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task ReconcileAsync_WhenSignOutputEnabled_WritesDeterministicDsseEnvelopeWithValidSignature()
|
||||
{
|
||||
using var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
|
||||
var pem = ecdsa.ExportPkcs8PrivateKeyPem();
|
||||
|
||||
var root = Path.Combine(Path.GetTempPath(), "stellaops-airgap-importer-tests", Guid.NewGuid().ToString("n"));
|
||||
var inputDir = Path.Combine(root, "input");
|
||||
var outputDir = Path.Combine(root, "output");
|
||||
|
||||
Directory.CreateDirectory(inputDir);
|
||||
Directory.CreateDirectory(outputDir);
|
||||
|
||||
var keyPath = Path.Combine(root, "evidence-signing-key.pem");
|
||||
await File.WriteAllTextAsync(keyPath, pem, Encoding.UTF8);
|
||||
|
||||
var reconciler = new EvidenceReconciler();
|
||||
var options = new ReconciliationOptions
|
||||
{
|
||||
GeneratedAtUtc = DateTimeOffset.UnixEpoch,
|
||||
SignOutput = true,
|
||||
SigningPrivateKeyPemPath = keyPath
|
||||
};
|
||||
|
||||
var graph1 = await reconciler.ReconcileAsync(inputDir, outputDir, options);
|
||||
var dssePath = Path.Combine(outputDir, "evidence-graph.dsse.json");
|
||||
var firstBytes = await File.ReadAllBytesAsync(dssePath);
|
||||
|
||||
var graph2 = await reconciler.ReconcileAsync(inputDir, outputDir, options);
|
||||
var secondBytes = await File.ReadAllBytesAsync(dssePath);
|
||||
|
||||
Assert.Equal(firstBytes, secondBytes);
|
||||
|
||||
using var json = JsonDocument.Parse(firstBytes);
|
||||
var rootElement = json.RootElement;
|
||||
|
||||
Assert.Equal("application/vnd.stellaops.evidence-graph+json", rootElement.GetProperty("payloadType").GetString());
|
||||
|
||||
var payloadBytes = Convert.FromBase64String(rootElement.GetProperty("payload").GetString()!);
|
||||
var signatureElement = rootElement.GetProperty("signatures")[0];
|
||||
var signatureBytes = Convert.FromBase64String(signatureElement.GetProperty("sig").GetString()!);
|
||||
|
||||
var expectedPayload = new EvidenceGraphSerializer().Serialize(graph1, pretty: false);
|
||||
Assert.Equal(expectedPayload, Encoding.UTF8.GetString(payloadBytes));
|
||||
|
||||
var pae = EncodeDssePreAuth("application/vnd.stellaops.evidence-graph+json", payloadBytes);
|
||||
Assert.True(ecdsa.VerifyData(pae, signatureBytes, HashAlgorithmName.SHA256));
|
||||
|
||||
var keyId = signatureElement.GetProperty("keyid").GetString();
|
||||
Assert.False(string.IsNullOrWhiteSpace(keyId));
|
||||
|
||||
Assert.Equal(new EvidenceGraphSerializer().Serialize(graph1, pretty: false), new EvidenceGraphSerializer().Serialize(graph2, pretty: false));
|
||||
}
|
||||
|
||||
private static byte[] EncodeDssePreAuth(string payloadType, ReadOnlySpan<byte> payload)
|
||||
{
|
||||
var payloadTypeByteCount = Encoding.UTF8.GetByteCount(payloadType);
|
||||
var header = $"DSSEv1 {payloadTypeByteCount} {payloadType} {payload.Length} ";
|
||||
var headerBytes = Encoding.UTF8.GetBytes(header);
|
||||
var buffer = new byte[headerBytes.Length + payload.Length];
|
||||
headerBytes.CopyTo(buffer.AsSpan());
|
||||
payload.CopyTo(buffer.AsSpan(headerBytes.Length));
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<UseConcelierTestInfra>false</UseConcelierTestInfra>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\\..\\StellaOps.AirGap.Importer\\StellaOps.AirGap.Importer.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user