using System.Security.Cryptography; using ZB.MOM.WW.ScadaBridge.Commons.Types.Transport; namespace ZB.MOM.WW.ScadaBridge.Transport.Serialization; /// /// Outcome of validating a against the supplied /// raw content bytes. Distinct values let the importer surface a precise /// rejection reason to the operator. /// public enum ManifestValidationResult { Ok, UnsupportedFormatVersion, ContentHashMismatch, MalformedManifest } /// /// Inspects a deserialized manifest plus the raw content bytes recovered from /// the bundle ZIP and reports the first integrity failure (or ). /// public sealed class ManifestValidator { /// Validates a deserialized bundle manifest against the raw content bytes and returns the first integrity failure, or . /// The deserialized manifest to validate. /// The raw content bytes extracted from the bundle ZIP. /// A indicating success or the specific failure kind. public ManifestValidationResult Validate(BundleManifest manifest, byte[] contentBytes) { if (manifest is null || contentBytes is null) { return ManifestValidationResult.MalformedManifest; } if (string.IsNullOrEmpty(manifest.SourceEnvironment) || manifest.Contents is null) { return ManifestValidationResult.MalformedManifest; } if (manifest.BundleFormatVersion != ManifestBuilder.CurrentBundleFormatVersion) { return ManifestValidationResult.UnsupportedFormatVersion; } var expected = "sha256:" + Convert.ToHexString(SHA256.HashData(contentBytes)).ToLowerInvariant(); if (!string.Equals(expected, manifest.ContentHash, StringComparison.Ordinal)) { return ManifestValidationResult.ContentHashMismatch; } return ManifestValidationResult.Ok; } }