103 lines
3.8 KiB
C#
103 lines
3.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using StellaOps.Provenance;
|
|
using Xunit;
|
|
|
|
using StellaOps.TestKit;
|
|
namespace StellaOps.Provenance.Tests;
|
|
|
|
public sealed class ProvenanceExtensionsTests
|
|
{
|
|
[Trait("Category", TestCategories.Unit)]
|
|
[Fact]
|
|
public void AttachDsseProvenance_WritesNestedDocuments()
|
|
{
|
|
var document = new DocumentObject
|
|
{
|
|
{ "kind", "VEX" },
|
|
{ "subject", new DocumentObject("digest", new DocumentObject("sha256", "sha256:abc")) }
|
|
};
|
|
|
|
var dsse = new DsseProvenance
|
|
{
|
|
EnvelopeDigest = "sha256:deadbeef",
|
|
PayloadType = "application/vnd.in-toto+json",
|
|
Key = new DsseKeyInfo
|
|
{
|
|
KeyId = "cosign:SHA256-PKIX:TEST",
|
|
Issuer = "fulcio",
|
|
Algo = "ECDSA"
|
|
},
|
|
Rekor = new DsseRekorInfo
|
|
{
|
|
LogIndex = 123,
|
|
Uuid = Guid.Parse("2d4d5f7c-1111-4a01-b9cb-aa42022a0a8c").ToString(),
|
|
IntegratedTime = 1_699_999_999,
|
|
MirrorSeq = 10
|
|
},
|
|
Chain = new List<DsseChainLink>
|
|
{
|
|
new()
|
|
{
|
|
Type = "build",
|
|
Id = "att:build#1",
|
|
Digest = "sha256:chain"
|
|
}
|
|
}
|
|
};
|
|
|
|
var trust = new TrustInfo
|
|
{
|
|
Verified = true,
|
|
Verifier = "Authority@stella",
|
|
Witnesses = 2,
|
|
PolicyScore = 0.9
|
|
};
|
|
|
|
document.AttachDsseProvenance(dsse, trust);
|
|
|
|
var provenanceDoc = (DocumentObject)((DocumentObject)document["provenance"])["dsse"];
|
|
Assert.Equal("sha256:deadbeef", ((DocumentString)provenanceDoc["envelopeDigest"]).Value);
|
|
Assert.Equal(123L, ((DocumentInt64)((DocumentObject)provenanceDoc["rekor"])["logIndex"]).Value);
|
|
Assert.Equal("att:build#1", ((DocumentString)((DocumentObject)((DocumentArray)provenanceDoc["chain"])[0])["id"]).Value);
|
|
|
|
var trustDoc = (DocumentObject)document["trust"];
|
|
Assert.True((bool)((DocumentBoolean)trustDoc["verified"]).Value!);
|
|
Assert.Equal(2, ((DocumentInt32)trustDoc["witnesses"]).Value);
|
|
Assert.Equal(0.9, ((DocumentDouble)trustDoc["policyScore"]).Value);
|
|
}
|
|
|
|
[Trait("Category", TestCategories.Unit)]
|
|
[Fact]
|
|
public void BuildProvenVexFilter_TargetsKindSubjectAndVerified()
|
|
{
|
|
var filter = ProvenanceExtensions.BuildProvenVexFilter("VEX", "sha256:123");
|
|
|
|
Assert.Equal("VEX", ((DocumentString)filter["kind"]).Value);
|
|
Assert.Equal("sha256:123", ((DocumentString)filter["subject.digest.sha256"]).Value);
|
|
Assert.True(filter.ContainsKey("provenance.dsse.rekor.logIndex"));
|
|
Assert.True(filter.ContainsKey("trust.verified"));
|
|
}
|
|
|
|
[Trait("Category", TestCategories.Unit)]
|
|
[Fact]
|
|
public void BuildUnprovenEvidenceFilter_FlagsMissingTrustOrRekor()
|
|
{
|
|
var filter = ProvenanceExtensions.BuildUnprovenEvidenceFilter(new[] { "SBOM", "VEX" });
|
|
|
|
var kindClause = (DocumentArray)((DocumentObject)filter["kind"])["$in"];
|
|
Assert.Contains("SBOM", kindClause.Select(v => ((DocumentString)v).Value));
|
|
Assert.Contains("VEX", kindClause.Select(v => ((DocumentString)v).Value));
|
|
|
|
var orConditions = (DocumentArray)filter["$or"];
|
|
Assert.Equal(2, orConditions.Count);
|
|
|
|
var trustCondition = (DocumentObject)orConditions[0];
|
|
Assert.Equal("$ne", ((DocumentObject)trustCondition["trust.verified"]).Keys.Single());
|
|
|
|
var rekorCondition = (DocumentObject)orConditions[1];
|
|
Assert.Equal("$exists", ((DocumentObject)rekorCondition["provenance.dsse.rekor.logIndex"]).Keys.Single());
|
|
Assert.False((bool)((DocumentBoolean)((DocumentObject)rekorCondition["provenance.dsse.rekor.logIndex"])["$exists"]).Value!);
|
|
}
|
|
}
|