Skip to main content

KeyStore

Struct KeyStore 

Source
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

Source

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.

Source

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

Source

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.

Source

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).

Source

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 dpp_vc::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

Source

pub fn open(path: impl AsRef<Path>, passphrase: &str) -> Result<Self>

Open a store, refusing one that predates any of the current security properties.

§Why this refuses rather than accommodates

Every legacy shape UpgradeNeeded names was previously accepted here silently: a store with kdf absent opened under the unsalted SHA-256 KDF, and a store with no hmac opened with no integrity check at all — which left the plaintext revoked flag unauthenticated, and that flag is what dpp-vc’s did:web builder reads to drop a compromised key from the published DID document.

Accepting a weaker shape on read means an attacker who can write the file can choose the weaker shape. The tolerance was for stores written by older versions of this crate, and refusing them here does not strand one: Self::open_and_migrate upgrades and opens them. What changes is that the weak path now requires a caller who asked for it by name.

§Errors

Names the specific property the store predates, and points at open_and_migrate.

Source

pub fn generate_key(&self, key_id: &str) -> Result<KeyEntry>

Source

pub fn load_key(&self, key_id: &str) -> Result<KeyEntry>

Source

pub fn has_key(&self, key_id: &str) -> bool

Source

pub fn public_key(&self, key_id: &str) -> Option<PublicKeyInfo>

The public key and revocation state of the current key under key_id, without decrypting the private key. Returns None if no such key exists.

pub rather than pub(crate) because the did:web document builder lives in dpp-vc and needs exactly this: public key material and revocation state, never the private key.

Source

pub fn archived_public_keys(&self, key_id: &str) -> Vec<PublicKeyInfo>

Public keys of all archived records for key_id, in the same ascending timestamp order as Self::load_archived_keys, without decrypting any private key material.

Source

pub fn load_archived_keys(&self, key_id: &str) -> Vec<KeyEntry>

Return all archived keys for the given identifier in ascending timestamp order.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more