pub struct KeyStore { /* private fields */ }Expand description
Thread-safe store that loads, encrypts, and caches Ed25519 signing keys.
Encryption key is derived from a passphrase using Argon2id with a random 128-bit salt. A separate 32-byte integrity key (derived from the same passphrase + salt with a different Argon2 context) is used to compute an HMAC-SHA256 over the serialised key map, protecting against file tampering. Legacy stores (pre-0.1.0) that used bare SHA-256 are automatically migrated on first write.
Implementations§
Source§impl KeyStore
impl KeyStore
Sourcepub fn open_and_migrate(
path: impl AsRef<Path>,
passphrase: &str,
) -> Result<Self>
pub fn open_and_migrate( path: impl AsRef<Path>, passphrase: &str, ) -> Result<Self>
Open the key store, run migrate_if_needed if the store uses the legacy
SHA-256 KDF, and — if migration actually ran — re-open the file so
self.cipher reflects the new Argon2id key.
This is the recommended entry point for production code. For stores
already at V2/V3 (Argon2id) it is identical to a single open call.
Sourcepub fn migrate_if_needed(&self, passphrase: &str) -> Result<bool>
pub fn migrate_if_needed(&self, passphrase: &str) -> Result<bool>
If this store was opened from a legacy format, re-encrypt all keys with the Argon2id-derived key and persist. Call this once after opening and verifying the passphrase works (e.g. by loading a key).
Returns true if migration ran, false if the store was already at
V2/V3. Use open_and_migrate in production to avoid the post-migration
cipher inconsistency (this object’s self.cipher is not updated here).
Source§impl KeyStore
impl KeyStore
Sourcepub fn archive_key(&self, key_id: &str) -> Result<()>
pub fn archive_key(&self, key_id: &str) -> Result<()>
Archive the current key under a timestamped key so it can still be used to verify older signatures after rotation.
Sourcepub fn rotate_key(&self, key_id: &str) -> Result<KeyEntry>
pub fn rotate_key(&self, key_id: &str) -> Result<KeyEntry>
Atomically rotate the key: archive the current key (kept valid so older signatures still verify) and install a fresh current key, in a single persisted write. Use for routine/hygiene rotation. Returns the new key.
Unlike calling archive_key then
generate_key, there is no intermediate on-disk
state where the archive exists but the new key does not (identity I4).
Sourcepub fn revoke_and_rotate(&self, key_id: &str) -> Result<KeyEntry>
pub fn revoke_and_rotate(&self, key_id: &str) -> Result<KeyEntry>
Atomically revoke the current key and install a fresh one. The old key
is archived but marked revoked, so crate::identity::did_builder drops it from
the published DID document and signatures it produced no longer verify.
Use this on key compromise (vs. hygiene rotation, where the old key
stays valid — see rotate_key).
Source§impl KeyStore
impl KeyStore
pub fn open(path: impl AsRef<Path>, passphrase: &str) -> Result<Self>
pub fn generate_key(&self, key_id: &str) -> Result<KeyEntry>
pub fn load_key(&self, key_id: &str) -> Result<KeyEntry>
pub fn has_key(&self, key_id: &str) -> bool
Sourcepub fn load_archived_keys(&self, key_id: &str) -> Vec<KeyEntry>
pub fn load_archived_keys(&self, key_id: &str) -> Vec<KeyEntry>
Return all archived keys for the given identifier in ascending timestamp order.