fix(sphragis): redact SharedSecret's Debug and retrofit SealError location - #33
Merged
Merged
Conversation
added 4 commits
August 15, 2026 18:31
…ation
SharedSecret was a bare `pub type SharedSecret = Zeroizing<[u8; 32]>`
alias, so it inherited [u8; 32]'s derived Debug: `{:?}` printed the live
X-Wing shared secret. Zeroizing protects memory on drop, not the value
while it is alive. Replace the alias with a newtype carrying a manual,
redacting Debug ("SharedSecret([REDACTED])"), matching
DecapsulationKey's existing pattern; zeroize-on-drop is unchanged since
the newtype still wraps Zeroizing. An as_slice() accessor preserves
every existing call site (derive_wrap_key, the KAT assertions).
Also finishes the SealError location retrofit #16/#28 started: every
variant now carries a snafu implicit location field, and every
construction site that built the enum directly (map_err closures, a
bare return Err) now goes through its context selector so the field
actually populates.
Part of #25
Part of #26
…ants
snafu's `.context()` requires the context selector's associated `Source`
type to equal the original Result's error type — that only holds for a
variant that actually declares a `source` field (like `Entropy`, wrapping
`rand_core::Error`). `HkdfExpand`, `AeadSeal`, `AeadOpen`, `InvalidMlKem`,
and `WrongLength` carry no `source` field, so `.context()` failed to
type-check for all of them (CI: E0271, Source == NoneError / InvalidLength
/ TryFromSliceError / etc.). Switch those call sites to
`.map_err(|_| XSnafu { .. }.build())`, matching the pattern already used
for `Serialization`. The implicit `location` field still populates
correctly through `.build()`.
Part of #25
Part of #26
EncapsulationKey is intentionally not Debug (it holds key-derived material). unwrap_err() requires T: Debug even on the Err path, so it does not compile. Match on a reference to the Result instead, mirroring tests/entropy_failure.rs's existing pattern for the same reason. Part of #26
The let-else panic! branch trips the crate's deny(clippy::panic) under -D warnings. entropy_failure.rs already expects this lint for the same reason (an unmatched variant IS the test failure); apply the same expect here. Part of #26
This was referenced Aug 15, 2026
forkwright
pushed a commit
that referenced
this pull request
Aug 16, 2026
🤖 I have created a release *beep* *boop* --- ## [0.2.0](v0.1.2...v0.2.0) (2026-08-16) ### ⚠ BREAKING CHANGES * **sphragis:** make deterministic encapsulation private ([#31](#31)) ### Features * **sphragis:** define revocation as key rotation, not re-wrapping ([#34](#34)) ([37ba8e3](37ba8e3)) * **sphragis:** narrow the public API to the envelope profile, define the adapter seam ([#32](#32)) ([d0a0bb8](d0a0bb8)) ### Bug Fixes * **sphragis:** bind the KAT gate to a machine-readable crypto provenance lock ([#27](#27)) ([65e3433](65e3433)) * **sphragis:** bound and fully consume untrusted CBOR before accepting a wrapped key ([#24](#24)) ([d165e5b](d165e5b)) * **sphragis:** make deterministic encapsulation private ([#31](#31)) ([cf48668](cf48668)) * **sphragis:** redact SharedSecret's Debug and retrofit SealError location ([#33](#33)) ([11216eb](11216eb)) * **sphragis:** return typed entropy failures instead of panicking ([#28](#28)) ([2ff3a08](2ff3a08)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SharedSecretwas a barepub type SharedSecret = Zeroizing<[u8; 32]>alias, so it inherited[u8; 32]'s derivedDebug—{:?}printed the live X-Wing shared secret.Zeroizingprotects memory on drop, not the value while it is alive. Replaced with a newtype carrying a manual, redactingDebug("SharedSecret([REDACTED])"), matchingDecapsulationKey's existing pattern. Zeroize-on-drop is unchanged (the newtype still wrapsZeroizing). Anas_slice()accessor preserves every existing call site (derive_wrap_key, the KAT assertions) — no behavior change beyond theDebugsurface.#[snafu(implicit)] locationretrofit ontoSealErrorthat Return typed entropy failures instead of panicking in cryptographic operations #16/fix(sphragis): return typed entropy failures instead of panicking #28 started: every remaining variant (WrongLength,InvalidMlKem,HkdfExpand,AeadSeal,AeadOpen,UnsupportedVersion,Serialization,EnvelopeTooLarge,TrailingData) now carries a location, and every construction site that built the enum directly (map_errclosures, a barereturn Err(..)) now goes through its context selector (.context()/.build()/.fail()) so the field actually populates.Tests
shared_secret_debug_is_redacted(tests/known_answer_vectors.rs): formats a realSharedSecretobtained fromencapsulate(), asserts the output contains"REDACTED"and does not contain the hex-encoded secret bytes. This is the mandatory negative-case fixture — a type-compiles check would prove nothing.wrong_length_ek_and_ct_rejectedto capture oneSealError::WrongLengthand assertlocation.file.ends_with("hybrid.rs"), mirroring the patterntests/entropy_failure.rsalready uses forSealError::Entropy.SealErrorconstruction now goes through context selectors instead of struct literals, but every variant's fields (other than the newlocation) are identical.Notes
Closes #25
Closes #26