license switch agpl -> busl1, sprints work, new product advisories

This commit is contained in:
master
2026-01-20 15:32:20 +02:00
parent 4903395618
commit c32fff8f86
1835 changed files with 38630 additions and 4359 deletions

View File

@@ -18,7 +18,11 @@ public static class BundleManifestSerializer
WriteIndented = false,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Converters =
{
new TimestampEntryJsonConverter()
}
};
public static string Serialize(BundleManifest manifest)
@@ -36,12 +40,23 @@ public static class BundleManifestSerializer
public static string ComputeDigest(BundleManifest manifest)
{
var withoutDigest = manifest with { BundleDigest = null };
var withoutDigest = manifest with
{
BundleDigest = null,
CanonicalManifestHash = null
};
var json = Serialize(withoutDigest);
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(json));
return Convert.ToHexString(hash).ToLowerInvariant();
}
public static BundleManifest WithDigest(BundleManifest manifest)
=> manifest with { BundleDigest = ComputeDigest(manifest) };
{
var digest = ComputeDigest(manifest);
return manifest with
{
BundleDigest = digest,
CanonicalManifestHash = digest
};
}
}

View File

@@ -0,0 +1,65 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using StellaOps.AirGap.Bundle.Models;
namespace StellaOps.AirGap.Bundle.Serialization;
/// <summary>
/// JSON converter for timestamp entries with explicit type discriminators.
/// </summary>
public sealed class TimestampEntryJsonConverter : JsonConverter<TimestampEntry>
{
public override TimestampEntry Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var document = JsonDocument.ParseValue(ref reader);
if (!document.RootElement.TryGetProperty("type", out var typeProperty))
{
throw new NotSupportedException("Timestamp entry is missing a type discriminator.");
}
var type = typeProperty.GetString();
return type switch
{
"rfc3161" => JsonSerializer.Deserialize<Rfc3161TimestampEntry>(document.RootElement.GetRawText(), options)
?? throw new JsonException("Failed to deserialize RFC3161 timestamp entry."),
"eidas-qts" => JsonSerializer.Deserialize<EidasQtsTimestampEntry>(document.RootElement.GetRawText(), options)
?? throw new JsonException("Failed to deserialize eIDAS QTS timestamp entry."),
_ => throw new NotSupportedException($"Unsupported timestamp entry type '{type}'.")
};
}
public override void Write(Utf8JsonWriter writer, TimestampEntry value, JsonSerializerOptions options)
{
switch (value)
{
case Rfc3161TimestampEntry rfc3161:
writer.WriteStartObject();
writer.WriteString("type", "rfc3161");
WriteStringArray(writer, "tsaChainPaths", rfc3161.TsaChainPaths);
WriteStringArray(writer, "ocspBlobs", rfc3161.OcspBlobs);
WriteStringArray(writer, "crlBlobs", rfc3161.CrlBlobs);
writer.WriteString("tstBase64", rfc3161.TstBase64);
writer.WriteEndObject();
break;
case EidasQtsTimestampEntry eidas:
writer.WriteStartObject();
writer.WriteString("type", "eidas-qts");
writer.WriteString("qtsMetaPath", eidas.QtsMetaPath);
writer.WriteEndObject();
break;
default:
throw new NotSupportedException($"Unsupported timestamp entry type '{value.GetType().Name}'.");
}
}
private static void WriteStringArray(Utf8JsonWriter writer, string name, IReadOnlyCollection<string> values)
{
writer.WritePropertyName(name);
writer.WriteStartArray();
foreach (var value in values)
{
writer.WriteStringValue(value);
}
writer.WriteEndArray();
}
}