security(format): wire provenance verify_dataset into the clawhdf5 read path

verify_dataset existed and was tested, but was only ever called from
clawhdf5-format's own test files — no reader path in clawhdf5-io or the
clawhdf5 facade called it, so a corrupted dataset was silently readable
even though the write-side SHA-256 hash machinery (gated on the
provenance feature) had already written what it needed to detect that.

Add Dataset::verify_provenance() to the clawhdf5 facade, gated behind a
new `provenance` feature (on by default, forwarding to
clawhdf5-format/provenance which is already default-on). It surfaces a
typed VerifyResult (Ok/Mismatch/NoHash) via the existing Error type
rather than panicking. Deliberately NOT called automatically on
open()/dataset() — it decodes and hashes the entire dataset, which would
regress every read path (including the zero-copy/mmap ones) if run
unconditionally; callers opt in per dataset where the cost is
acceptable (e.g. a periodic integrity sweep).

Also re-export clawhdf5_format::provenance from the facade crate so
VerifyResult is reachable without depending on clawhdf5-format directly.

INT-08
This commit is contained in:
ClawHDF5 Coding Agent
2026-08-17 00:54:44 +00:00
parent ab283d2759
commit 5db1008eb7
5 changed files with 101 additions and 1 deletions
+5 -1
View File
@@ -30,7 +30,7 @@ name = "parallel_bench"
harness = false
[features]
default = ["mmap", "fast-deflate"]
default = ["mmap", "fast-deflate", "provenance"]
mmap = ["clawhdf5-io/mmap"]
parallel = ["clawhdf5-format/parallel", "rayon"]
fast-deflate = ["clawhdf5-format/fast-deflate"]
@@ -39,6 +39,10 @@ zstd = ["clawhdf5-format/zstd"]
blake3_hash = ["clawhdf5-format/blake3_hash"]
lz4 = ["clawhdf5-format/lz4"]
pcodec = ["clawhdf5-format/pcodec"]
# Dataset::verify_provenance() — recompute a dataset's SHA-256 and compare
# against its stored _provenance_sha256 attribute. On by default, matching
# clawhdf5-format's own default-on `provenance` feature.
provenance = ["clawhdf5-format/provenance"]
[package.metadata.docs.rs]
features = ["mmap"]