Skip to content

feat: public-key fingerprints, pqfe recipient commands, and full-coverage supply chain - #81

Merged
systemslibrarian merged 2 commits into
mainfrom
features/fingerprints-recipient-cli
Sep 5, 2026
Merged

systemslibrarian merged 2 commits into
mainfrom
features/fingerprints-recipient-cli

Conversation

@systemslibrarian

Copy link
Copy Markdown
Owner

Two commits, both freeze-safe (no byte meaning or reader acceptance changes):

1. Supply-chain hardening (the items unblocked by #76)

  • Release tools pinned (NuGetPackageValidation 2.0.6, CycloneDX 6.2.0) — the last floating third-party code in the release job — and persist-credentials: false on both release checkouts.
  • Attestation now covers every downloadable artifact: .nupkg + .snupkg + the SBOM files (the docs previously promised snupkg verification that failed by construction). Analyzers gets its missing SBOM.
  • Reproducibility verification: 4 → all 9 packages; binary package validation enabled in Aws/AzureKeyVault/Gcp against the published 1.7.1 baseline (all three verified packing clean against the live baseline).

2. Fingerprints + pqfe recipient (both external reviews' top feature asks)

  • GetFingerprint() on hybrid-recipient and signing public keys: pqfp1: + URL-safe Base64 SHA-256 over domain prefix + purpose tag + key bytes. Purpose-separated (recipient/signing can never collide), stable, safe to log/pin, frozen rendering pinned by precomputed test vectors. Documented in KEY-MANAGEMENT.md as the key-substitution defense.
  • The post-quantum recipient path is finally usable end-to-end from the shipped tool: recipient keygen (PQKF opt-in, 0600, CreateNew, prints fingerprint), recipient encrypt (multi-recipient), recipient decrypt (--identity, PQKF auto-detect, --untrusted), recipient fingerprint. Inherits the claim-based overwrite refusal and the unified fail-closed error contract.

Verification

  • 321×2 tests green (4 new fingerprint pins), build clean, docs guard green.
  • Cloud packages pack against the live 1.7.1 nuget.org baseline.
  • Live CLI smoke test: PQKF + raw identities, 2-recipient container round trip, wrong-key rejection shows the unified generic message and leaves no output file, overwrite refusal holds, fingerprint stdout matches keygen's print.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sym7RJ7ehNhbMXytE5rMmS

systemslibrarian and others added 2 commits September 5, 2026 01:47
…l nine packages

- Pin NuGetPackageValidation (2.0.6) and CycloneDX (6.2.0) in the release job —
  the last floating third-party code that executed there — and set
  persist-credentials: false on both release checkouts.
- Attest .snupkg symbol packages and the SBOM files alongside .nupkg (the docs
  previously promised snupkg verification that failed by construction; now the
  claim and the pipeline agree, forward from the next tag).
- Add the Analyzers package's missing SBOM.
- Extend post-release reproducibility verification from 4 to all 9 lockstep
  packages (matrix + script cases).
- Enable binary package validation in Aws/AzureKeyVault/Gcp against the
  published 1.7.1 baseline (stale pre-first-publish opt-out removed; all three
  verified packing clean against the live baseline).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sym7RJ7ehNhbMXytE5rMmS
Public-key fingerprints (both external reviews' convergent ask — the
key-substitution defense): PqHybridPublicKey.GetFingerprint() and
PqSigningPublicKey.GetFingerprint() return pqfp1: + URL-safe Base64 SHA-256
over a domain prefix, purpose tag (recipient/signing can never collide), and
the exported key bytes. Rendering frozen for the pqfp1: prefix; pinned by
FingerprintTests with precomputed vectors. Shared internal helper in the core.

pqfe recipient — the library's defining post-quantum path, usable end-to-end
from the shipped tool for the first time:
  recipient keygen  <keyfile> [--encrypt]     X25519+ML-KEM-768 pair; PQKF opt-in;
                                              prints the fingerprint; 0600, CreateNew,
                                              half-pair cleanup like signing keygen
  recipient encrypt <in> <out> --recipient p [--recipient p2 ...]   multi-recipient
  recipient decrypt <in> <out> --identity k [--untrusted]           PQKF auto-detected
  recipient fingerprint <pub>                 stdout, for scripts
Both keygen commands now print the fingerprint and warn on unencrypted keys.
Claim-based overwrite refusal and the unified fail-closed message flow through
unchanged (verified by an end-to-end smoke run: PQKF + raw identities,
2-recipient container, wrong-key rejection leaves no output file).

KEY-MANAGEMENT.md gains the fingerprint-verification section; CLI README and
usage updated; PublicAPI.Unshipped entries added. AOT closure unchanged in
kind (Signing already carried BouncyCastle).

Verified: 321x2 tests green, build clean, live CLI smoke test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sym7RJ7ehNhbMXytE5rMmS
@systemslibrarian
systemslibrarian merged commit d1ff55f into main Sep 5, 2026
11 checks passed
@systemslibrarian
systemslibrarian deleted the features/fingerprints-recipient-cli branch September 5, 2026 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant