using StellaOps.AirGap.Bundle.Models; using System.Text.Json; using System.Text.Json.Serialization; namespace StellaOps.AirGap.Bundle.Serialization; /// /// JSON converter for timestamp entries with explicit type discriminators. /// public sealed class TimestampEntryJsonConverter : JsonConverter { 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(document.RootElement.GetRawText(), options) ?? throw new JsonException("Failed to deserialize RFC3161 timestamp entry."), "eidas-qts" => JsonSerializer.Deserialize(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 values) { writer.WritePropertyName(name); writer.WriteStartArray(); foreach (var value in values) { writer.WriteStringValue(value); } writer.WriteEndArray(); } }