#[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
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.
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.
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
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
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
crate::Keystore::rotate_kdfwhich rotate in place.
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.
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.
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: DegradeReasonWhy 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.
HardwareWrapFailed
The hardware component refused to wrap a content key.
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.
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.
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.
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.
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.
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.
Trait Implementations§
Source§impl Clone for KeystoreError
impl Clone for KeystoreError
Source§fn clone(&self) -> KeystoreError
fn clone(&self) -> KeystoreError
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for KeystoreError
impl Debug for KeystoreError
Source§impl Display for KeystoreError
impl Display for KeystoreError
Source§impl Error for KeystoreError
impl Error for KeystoreError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl From<Error> for KeystoreError
impl From<Error> for KeystoreError
Source§fn from(err: Error) -> Self
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.