Skip to content

Harden Keypair::seed_bytes: route seed access through the zeroizing wrapper #41

@beardthelion

Description

@beardthelion

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:126open_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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions