feat: add filesystem-based PkiStore reference implementation

Introduce a deterministic filesystem-backed PkiStore implementation
under zeroecho.pki.impl.fs.

Key characteristics:
- write-once semantics for immutable objects with explicit failure on
  overwrite
- history tracking for mutable records with full audit trail
- atomic writes using NIO (temp + move) with best-effort durability
- strict snapshot export supporting time-travel reconstruction
- configurable history retention (ON_WRITE policy)
- no secrets logged; JUL-only diagnostics for anomalies

Includes comprehensive JUnit 5 tests validating:
- write-once enforcement
- history creation and overwrite semantics
- strict snapshot export (failure and positive selection cases)
- deterministic on-disk layout and structure

This implementation is intentionally non-public and serves as a
reference and validation baseline for future persistence backends.

Signed-off-by: Leo Galambos <lg@hq.egothor.org>
This commit is contained in:
2025-12-28 01:15:46 +01:00
parent 7673e7d82f
commit cab1eeefe7
14 changed files with 2556 additions and 38 deletions

View File

@@ -48,10 +48,9 @@ import zeroecho.core.spi.AsymmetricKeyBuilder;
*
* <p>
* This builder maps {@link SlhDsaKeyGenSpec} to the appropriate
* {@code org.bouncycastle.jcajce.spec.SLHDSAParameterSpec} constant.
* :contentReference[oaicite:3]{index=3} Reflection is used to avoid a hard
* dependency on any particular set of parameter constants across provider
* versions.
* {@code org.bouncycastle.jcajce.spec.SLHDSAParameterSpec} constant. Reflection
* is used to avoid a hard dependency on any particular set of parameter
* constants across provider versions.
* </p>
*
* @since 1.0
@@ -103,7 +102,6 @@ public final class SlhDsaKeyGenBuilder implements AsymmetricKeyBuilder<SlhDsaKey
// Optional pre-hash suffix used by BC:
// _with_sha256/_with_sha512/_with_shake128/_with_shake256
// :contentReference[oaicite:4]{index=4}
String suffix = "";
if (spec.preHash() != SlhDsaKeyGenSpec.PreHash.NONE) {
suffix = "_with_" + spec.preHash().name().toLowerCase(Locale.ROOT);

View File

@@ -106,7 +106,6 @@ public final class SlhDsaKeyGenSpec implements AlgorithmKeySpec {
* <p>
* Bouncy Castle exposes "with hash" variants as distinct parameter specs, for
* example {@code slh_dsa_sha2_128s_with_sha256}.
* :contentReference[oaicite:1]{index=1}
* </p>
*
* <p>
@@ -183,7 +182,6 @@ public final class SlhDsaKeyGenSpec implements AlgorithmKeySpec {
* <p>
* This bypasses automatic mapping. The name must match a static field in
* {@code org.bouncycastle.jcajce.spec.SLHDSAParameterSpec}.
* :contentReference[oaicite:2]{index=2}
* </p>
*
* @param name field name in {@code SLHDSAParameterSpec}