diff --git a/CHANGELOG.md b/CHANGELOG.md index 85c8062..a73ceaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,76 @@ All notable changes to sigil are documented here. The project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.9.0] — 2026-05-20 + +Cleanup-cycle release: a criterion benchmark regression gate and a +fail-closed hardening of Sigstore certificate pinning. Minor-versioned +because the keyless client constructors now return a `Result` — a +breaking change for code that uses `wsc` as a library. + +### Added + +- **Criterion benchmark regression gate** (#89, PR #122). New + `.github/workflows/benchmarks.yml`: a fast sample-reduced sanity run + on every PR touching `src/lib`, plus a full nightly run that uploads + the criterion output as an artifact. The benchmark code already + existed (`src/lib/benches/verification_benchmarks.rs` — four groups: + Ed25519 verify, DSSE parse+verify, Merkle validation, cert-chain + validation); this adds the CI gate that turns it into a regression + guard for the signature-verification hot path. + +### Changed (breaking) + +- **Sigstore certificate pinning is now fail-closed** (#95, PR #123). + TLS-layer pin enforcement was already in place — `PinnedCertVerifier` + implements `rustls::ServerCertVerifier`, so a pin mismatch aborts the + handshake. The residual gap was in agent *construction*: + `create_agent_with_optional_pinning` silently fell back to an + unpinned standard agent on failure, and the `RekorClient` / + `FulcioClient` constructors swallowed even the hard error. Now, + whenever a non-empty pin set is supplied, pinning is mandatory — + construction failure propagates as an error, never a silent + downgrade. This closes audit finding C-4. + - **API change:** `FulcioClient::{new, with_url}` and + `RekorClient::{new, with_url}` now return `Result`; + the `Default` impls (which assumed an infallible `new()`) are + removed. Direct library callers must handle the `Result`. + - `WSC_REQUIRE_CERT_PINNING` is redundant for the Sigstore + production path (pinning is unconditional there); retained for + backwards compatibility, documented as deprecated. + - Corrects the v0.8.4 "Audit observation": pinning **is** enforced + at the rustls handshake layer today, not post-handshake. + +### Deferred + +- **#88 — Kani harness for the signature-section parser.** The varint + and DSSE harnesses already exist; the signature-parser harness is + blocked on `SignatureForHashes::deserialize` building an 8 KiB + `BufReader` internally, which is intractable for Kani's bounded + model checker (a single one-symbolic-byte harness ran 24+ minutes). + Needs a `deserialize` refactor exposing a `BufRead`-taking entry + point. Tracked on #88. +- **#46 — SLH-DSA / FIPS 205 post-quantum backend.** Blocked upstream: + usable `slh-dsa` versions need either a `signature` pre-release or + `signature 3.x`, and the matching `ecdsa 0.17` / `p256 0.14` crates + have no stable release yet — only release candidates. Integrating + now would put RC crypto on the production Sigstore signing path. + Tracked on #46 with the precise unblock condition. + +### Closed without code + +- **#91 — MIRAI abstract-interpretation prototype.** The MIRAI + repository is archived (last commit 2024-08, pinned to an + 18-month-old nightly); its property classes are already covered by + the existing Kani and Verus harnesses. + +### Contributors + +PRs in this release: #121 (gitignore audit notes), #122 (benchmark +gate), #123 (cert-pinning fail-closed). + +[0.9.0]: https://github.com/pulseengine/sigil/compare/v0.8.4...v0.9.0 + ## [0.8.4] — 2026-05-19 Hotfix release. Single-commit content: rotate the pinned Fulcio leaf diff --git a/Cargo.lock b/Cargo.lock index f7478ea..fd94916 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4721,7 +4721,7 @@ checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wsc" -version = "0.8.4" +version = "0.9.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -4771,7 +4771,7 @@ dependencies = [ [[package]] name = "wsc-attestation" -version = "0.8.4" +version = "0.9.0" dependencies = [ "base64 0.22.1", "chrono", @@ -4787,7 +4787,7 @@ dependencies = [ [[package]] name = "wsc-cli" -version = "0.8.4" +version = "0.9.0" dependencies = [ "clap", "env_logger", @@ -4800,7 +4800,7 @@ dependencies = [ [[package]] name = "wsc-component" -version = "0.8.4" +version = "0.9.0" dependencies = [ "wit-bindgen 0.47.0", "wsc", diff --git a/Cargo.toml b/Cargo.toml index 0ff427c..3bbf034 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ exclude = [ ] [workspace.package] -version = "0.8.4" +version = "0.9.0" edition = "2024" authors = ["Frank Denis ", "Ralf Anton Beier "] license = "MIT" diff --git a/MODULE.bazel b/MODULE.bazel index d5ff031..76e5861 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -3,7 +3,7 @@ module( name = "wsc", # Keep in sync with [workspace.package].version in Cargo.toml. - version = "0.8.4", + version = "0.9.0", ) # Dependencies diff --git a/src/cli/BUILD.bazel b/src/cli/BUILD.bazel index 9f7932d..8990212 100644 --- a/src/cli/BUILD.bazel +++ b/src/cli/BUILD.bazel @@ -15,7 +15,7 @@ package(default_visibility = ["//visibility:public"]) # Version info - keep in sync with [workspace.package].version in Cargo.toml # and with the `version` field in MODULE.bazel. -VERSION = "0.8.4" +VERSION = "0.9.0" rust_binary( name = "wasmsign_cli", diff --git a/src/cli/Cargo.toml b/src/cli/Cargo.toml index a4df850..358c3b8 100644 --- a/src/cli/Cargo.toml +++ b/src/cli/Cargo.toml @@ -32,5 +32,5 @@ regex = "1.12.2" # HTTP client for keyless signing ureq = { version = "3.1.2" } wasi = { version = "0.14.7" } -wsc = { version = "0.8.0", path = "../lib" } +wsc = { version = "0.9.0", path = "../lib" } serde_json = "1.0" diff --git a/src/component/Cargo.toml b/src/component/Cargo.toml index 4c970bd..866a12f 100644 --- a/src/component/Cargo.toml +++ b/src/component/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib"] [dependencies] # Core signing library -wsc = { version = "0.8.0", path = "../lib" } +wsc = { version = "0.9.0", path = "../lib" } # WIT bindings generation wit-bindgen = { version = "0.47.0", default-features = false, features = ["realloc"] } diff --git a/src/crypto/Cargo.toml b/src/crypto/Cargo.toml index b95f02f..351c550 100644 --- a/src/crypto/Cargo.toml +++ b/src/crypto/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib"] [dependencies] # Core signing library (provides platform module) -wsc = { version = "0.8.0", path = "../lib", features = ["software-keys"] } +wsc = { version = "0.9.0", path = "../lib", features = ["software-keys"] } # WIT bindings generation wit-bindgen = { version = "0.47.0", default-features = false, features = ["realloc"] } diff --git a/src/lib/Cargo.toml b/src/lib/Cargo.toml index 026b6cb..0a01974 100644 --- a/src/lib/Cargo.toml +++ b/src/lib/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "wasm"] [dependencies] # Re-export attestation types from minimal crate -wsc-attestation = { version = "0.8.0", path = "../attestation" } +wsc-attestation = { version = "0.9.0", path = "../attestation" } anyhow = "1.0.100" ct-codecs = "1.1.6" ed25519-compact = { version = "2.1.1", features = ["pem"] }