Skip to main content

KeystoreError

Enum KeystoreError 

Source
#[non_exhaustive]
pub enum KeystoreError {
Show 22 variants Backend(Arc<Error>), UnknownMagic { saw: [u8; 6], }, UnsupportedFormat { found: u16, }, SchemeMismatch { expected: u16, expected_name: &'static str, found: u16, }, CrcMismatch { stored: u32, computed: u32, }, DecryptFailed, InvalidKdfParams(&'static str), UnsupportedKdf(u8), UnsupportedCipher(u8), AlreadyExists(String), InvalidPlaintext { expected: usize, got: usize, }, InvalidSeed(String), Truncated { claimed: usize, available: usize, }, HardwareRequired { reason: DegradeReason, }, HardwareProbeIndeterminate { detail: String, }, HardwareWrapFailed { detail: String, }, HardwareUnwrapFailed { detail: String, }, MalformedEnvelope { detail: String, }, UnknownHardwareClass { wire_id: u8, }, NotHardwareBound { tier: String, }, HardwareStillBound { key: String, }, HardwareKindMismatch { expected: &'static str, found: &'static str, },
}
Expand description

Errors produced by keystore operations.

The enum is Clone so errors can be fanned out through broadcast channels or bubbled through async traits. The only non-Clone primitive (std::io::Error) is wrapped in Arc to preserve clonability.

#[non_exhaustive]: this catalog grows as the crate gains capability (six variants arrived with hardware binding alone), so downstream matches must carry a wildcard arm rather than break on every addition.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Backend(Arc<Error>)

An underlying backend I/O operation failed.

This is the catch-all for filesystem errors from crate::FileBackend as well as any future backend (OS keyring / HSM). The wrapped std::io::Error preserves the original ErrorKind for callers who want to distinguish e.g. NotFound from PermissionDenied.

§

UnknownMagic

The file’s magic prefix did not match any known scheme.

First 6 bytes of a keystore file carry DIGVK1, DIGLW1, etc. If the caller pointed at a non-keystore file (or a future-version file this build doesn’t understand), decode fails here before any cryptography.

Fields

§saw: [u8; 6]

The magic bytes that were actually read.

§

UnsupportedFormat

The file’s format version is newer or older than this library understands.

Format version is stored as a big-endian u16 right after the magic. This library recognizes crate::FORMAT_VERSION_V1 only.

Fields

§found: u16

The format version byte read from the file.

§

SchemeMismatch

The file’s key-scheme id does not match the type parameter used to open it.

If the caller opens Keystore::<BlsSigning>::load(...) but the file on disk is L1WalletBls (scheme id 0x0003), we refuse. This guards against accidentally interpreting wallet master seeds as validator signing seeds, which would produce perfectly-valid-looking BLS signatures that bind to the wrong domain.

Fields

§expected: u16

The scheme expected by the caller (K::SCHEME_ID).

§expected_name: &'static str

Human-readable expected name (e.g., "BlsSigning").

§found: u16

The scheme id actually stored in the file.

§

CrcMismatch

The CRC32 checksum at the end of the file did not match.

CRC is computed over every byte of the file except the trailing 4. A mismatch indicates disk corruption, partial write, or deliberate tampering. It is NOT a cryptographic integrity check (AES-GCM’s tag is) — CRC is only a fast-fail so we don’t burn ~0.5 s on Argon2 for a file that’s clearly garbage.

Fields

§stored: u32

The CRC32 read from the file.

§computed: u32

The CRC32 computed over the preceding bytes.

§

DecryptFailed

AES-GCM authentication tag failed.

This is the single error produced for any cryptographic decryption failure: wrong password, tampered ciphertext, tampered header (AAD mismatch), or truncated payload. We intentionally do NOT distinguish these variants at the error level to avoid side-channel leaks.

§

InvalidKdfParams(&'static str)

Argon2 or AES-GCM rejected the provided parameters.

Thrown when crate::KdfParams has out-of-bounds values (e.g., memory_kib < 8192) or when the underlying argon2 crate returns an error (rare — usually only on invalid output size).

§

UnsupportedKdf(u8)

The file advertised an unsupported KDF algorithm.

Currently only 0x01 = Argon2id is recognized. Non-0x01 values are reserved for future algorithms (scrypt, bcrypt, balloon).

§

UnsupportedCipher(u8)

The file advertised an unsupported symmetric cipher.

Currently only 0x01 = AES-256-GCM is recognized. Non-0x01 values are reserved for e.g. ChaCha20-Poly1305.

§

AlreadyExists(String)

Keystore::create was called for a path that already exists.

Deliberate: overwriting a keystore file is almost always an operator error. Callers that really want to replace a keystore should crate::Keystore::delete first, or simply crate::Keystore::change_password

§

InvalidPlaintext

The decrypted plaintext has the wrong length for the key scheme.

Each crate::KeyScheme declares a fixed SECRET_LEN. If unlock decrypts successfully but the plaintext length disagrees with the scheme (e.g., file was encrypted under v1 with a 32-byte seed and this build expects 48), we reject. Normally impossible once the scheme id check has passed; included for defence in depth.

Fields

§expected: usize

Expected byte length.

§got: usize

Actual byte length read.

§

InvalidSeed(String)

The provided seed bytes were malformed (e.g., not a valid BLS seed).

Rarely thrown — chia-bls::SecretKey::from_seed accepts any byte length — but reserved for schemes where the raw bytes must pass a scheme-specific validity check (e.g., secp256k1 scalar bounds).

§

Truncated

The file’s length header claims a payload larger than the file bytes.

Indicates a truncated file (disk full mid-write, network transfer cut, etc). Should be rare since we write files atomically via rename, but guard anyway.

Fields

§claimed: usize

Bytes claimed by the header.

§available: usize

Bytes actually available.

§

HardwareRequired

The caller required hardware binding, and this host cannot provide it.

Raised by HardwarePolicy::Required rather than degrading. The DegradeReason says which negative outcome occurred — “no TPM on this machine” and “the TPM is present but unusable” lead a caller to different remedies.

Fields

§reason: DegradeReason

Why hardware binding could not be established.

§

HardwareProbeIndeterminate

The host could not be inspected, so hardware availability is unknown.

Deliberately distinct from a confident “no hardware present”: collapsing the two would turn an inspection failure into a confident negative, and a transient probe failure would then silently strip hardware protection from a machine that has it. Under the default Preferred policy this fails closed instead of degrading.

Fields

§detail: String

Non-secret detail of the probe failure.

§

HardwareWrapFailed

The hardware component refused to wrap a content key.

Fields

§detail: String

Non-secret detail of the failing operation.

§

HardwareUnwrapFailed

The hardware component could not unwrap a stored content key.

This variant means exactly one thing: the hardware refused. It is the expected error when a sealed blob is copied to a different machine — the wrapping key is non-exportable, so the copy cannot be opened — and that refusal is the guarantee, not a malfunction. Structural problems with the blob (MalformedEnvelope) and unnameable hardware (UnknownHardwareClass) are deliberately not reported here, so this variant keeps its meaning.

Fields

§detail: String

Non-secret detail of the failing operation.

§

MalformedEnvelope

A hardware envelope is structurally invalid.

A malformed blob, not a hardware refusal. Notably covers an envelope declaring a zero-length wrapped key — which asserts that no hardware key protects it, and so must never decode as a hardware envelope.

Fields

§detail: String

Non-secret detail of the structural violation.

§

UnknownHardwareClass

A hardware envelope records a hardware class this build cannot name.

A forward-compatibility case, not corruption: a newer writer may have sealed with hardware this build has no name for. Reported rather than guessed, so an unknown class can never be silently treated as a known one — or as unprotected.

Fields

§wire_id: u8

The hardware-kind wire id read from the blob.

§

NotHardwareBound

A hardware-wrapped blob was found on a host with no hardware tier.

Reported instead of returning the envelope bytes, so a copied blob fails loudly rather than being mistaken for a corrupt keystore.

Fields

§tier: String

The tier this host actually has.

§

HardwareStillBound

An unbind reported by storage as taken, but the stored blob is still a hardware envelope.

Its own variant rather than a generic write error because of what the caller does next: a user unbinds in order to safely retire the trusted component, so “unbound” over a blob that is still bound is the one message here that provokes a destructive action. The wording says STILL BOUND for that reason.

Fields

§key: String

The backend key whose blob is still wrapped.

§

HardwareKindMismatch

A hardware-wrapped blob was sealed by a different class of hardware.

Distinct from HardwareUnwrapFailed, which is another device of the same class: this is another kind of component (a blob from a Mac read on Windows), which is a migration case rather than a copied-blob case.

Fields

§expected: &'static str

The hardware class this host binds to.

§found: &'static str

The hardware class recorded in the blob.

Trait Implementations§

Source§

impl Clone for KeystoreError

Source§

fn clone(&self) -> KeystoreError

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for KeystoreError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for KeystoreError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for KeystoreError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for KeystoreError

Source§

fn from(err: Error) -> Self

Wrap an I/O error as a backend error.

Used liberally through the ? operator in crate::FileBackend and other std::io-backed code paths.

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.