Summary
Keypair::seed_bytes() (crates/gitlawb-core/src/identity.rs) returns the raw 32-byte Ed25519 seed as a plain [u8; 32], so the private key material is copied out without zeroization and lives in caller stack/locals until the values happen to be overwritten.
A safe sibling already exists in the same type:
pub fn seed_bytes(&self) -> [u8; 32] { self.signing_key.to_bytes() } // raw, not zeroized
pub fn to_seed(&self) -> Zeroizing<[u8; 32]> { Zeroizing::new(self.signing_key.to_bytes()) } // zeroized on drop
zeroize is already a dependency, so this is purely about routing seed access through the zeroizing wrapper.
Proposed change
Drop seed_bytes() and migrate callers to to_seed() (or, if the name is preferred, change seed_bytes() to return Zeroizing<[u8; 32]>). Either way the plain-array return goes away. Zeroizing<[u8; 32]> derefs to [u8; 32], so call sites that need &[u8; 32] use &*seed.
Call sites to update:
crates/gitlawb-core/src/encrypt.rs:126 — open_blob, x25519_secret_from_seed(&keypair.seed_bytes())
crates/gitlawb-node/src/api/repos.rs:672 — node seed for the encrypted-blob recipients tag
crates/gitlawb-core/src/encrypt.rs:188 — a test
Notes
Defense-in-depth hardening, not a known live exploit; the seed is already held in memory by the keypair. Surfaced during review of #40 (which added a seed_bytes() caller). Deferred from that PR to keep its scope to recipient-set blinding, since changing the return type touches pre-existing callers.
Summary
Keypair::seed_bytes()(crates/gitlawb-core/src/identity.rs) returns the raw 32-byte Ed25519 seed as a plain[u8; 32], so the private key material is copied out without zeroization and lives in caller stack/locals until the values happen to be overwritten.A safe sibling already exists in the same type:
zeroizeis already a dependency, so this is purely about routing seed access through the zeroizing wrapper.Proposed change
Drop
seed_bytes()and migrate callers toto_seed()(or, if the name is preferred, changeseed_bytes()to returnZeroizing<[u8; 32]>). Either way the plain-array return goes away.Zeroizing<[u8; 32]>derefs to[u8; 32], so call sites that need&[u8; 32]use&*seed.Call sites to update:
crates/gitlawb-core/src/encrypt.rs:126—open_blob,x25519_secret_from_seed(&keypair.seed_bytes())crates/gitlawb-node/src/api/repos.rs:672— node seed for the encrypted-blob recipients tagcrates/gitlawb-core/src/encrypt.rs:188— a testNotes
Defense-in-depth hardening, not a known live exploit; the seed is already held in memory by the keypair. Surfaced during review of #40 (which added a
seed_bytes()caller). Deferred from that PR to keep its scope to recipient-set blinding, since changing the return type touches pre-existing callers.