Skip to main content

Error

Enum Error 

Source
#[non_exhaustive]
pub enum Error {
Show 16 variants DevicePublicKeyInvalid { reason: &'static str, }, DeviceSignatureInvalid { reason: &'static str, }, UnsupportedPlatform { platform: &'static str, }, HardwareUnavailable { reason: String, }, Hardware { operation: &'static str, code: i32, }, KeyNotFound { label: String, }, Jni { operation: &'static str, detail: String, }, KeyAlreadyExists { label: String, }, InvalidDigestLength { expected: usize, actual: usize, }, InvalidKeyLabel { reason: &'static str, }, InvalidPublicKey { reason: &'static str, }, InvalidSignatureLength { expected: usize, actual: usize, }, InvalidWrappedKey { reason: &'static str, code: i32, }, InvalidMasterKey { reason: &'static str, }, KeyNotExportable { reason: &'static str, }, RandomnessUnavailable,
}
Expand description

Failures that can arise from device identity handling and the platform key store.

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

DevicePublicKeyInvalid

The device public key is not a valid P-256 SEC1 uncompressed point.

Public keys arrive as external input (QR codes, the network), so this is a normal rejection path rather than an internal inconsistency.

Fields

§reason: &'static str

Opaque description for logs.

§

DeviceSignatureInvalid

The device signature is malformed, or verification failed.

§Why the two cases are merged

The caller’s response is identical (reject this authentication), and distinguishing them would give an attacker a small oracle: the difference between “malformed” and “did not verify” could be probed.

Fields

§reason: &'static str

Opaque description for logs. Must not contain the signature value itself.

§

UnsupportedPlatform

This platform has no backend implementation yet.

Do not treat it as a signal that falling back to a software key is allowed automatically. Whether software keys are acceptable is a security policy decision that requires explicit user consent; a silent fallback would leave the user believing the key is hardware-protected.

Fields

§platform: &'static str

Platform name (a compile-time constant, containing no user data).

§

HardwareUnavailable

This machine has no usable hardware key store (an implementation exists, but it is unavailable in this environment).

§It is a different thing from Error::UnsupportedPlatform

Here a different environment would work (a virtual machine without a TPM, a TPM disabled by group policy, a key store held exclusively by another process); there a different platform is required. Merging them would make the UI give the same advice for “change machine” and “change device”, which are two different user actions.

Fields

§reason: String

A fixed reason description, or text supplied by the platform.

§

Hardware

A platform API returned a failure.

Fields

§operation: &'static str

Name of the failing operation, used for diagnostics.

§code: i32

Raw platform error code.

An i32 rather than a u32: Windows NTSTATUS / SECURITY_STATUS values are signed, and many NCrypt failures are returned as negative numbers. Storing them as u32 would turn -1 into 0xFFFFFFFF, indistinguishable in a log from a genuine 0xFFFFFFFF.

§

KeyNotFound

The referenced key does not exist.

Fields

§label: String

Logical name of the key (supplied by the caller, containing no secret).

§

Jni

The platform reported a failure in its own words.

§Why this is separate from Error::Hardware

Android reports failures as Java exceptions rather than as numeric codes: the class and the message are the whole diagnosis, and there is no code to format. Collapsing the two would either invent a code that means nothing or throw the message away — and the message is what tells a user apart “this device has no secure hardware” from “this key was refused”.

The detail is the platform’s own text, naming an operation and an exception. The platform does not put key material in it.

Fields

§operation: &'static str

Name of the failing operation, used for diagnostics.

§detail: String

What the platform reported. Contains no key material.

§

KeyAlreadyExists

A key already exists under this label.

§Why this is a separate variant

crate::keystore::DeviceKeyStore::open_or_create has to distinguish it from other failures: for that method “already exists” is the desired outcome (the key can simply be opened), while a hardware fault is not. Folding it into Error::Hardware would leave that distinction to a comparison of native error codes, which are an implementation detail.

Relatedly, create never overwrites an existing key: overwriting would replace the device identity that other devices use to recognise this one.

Fields

§label: String

Logical name of the key.

§

InvalidDigestLength

The digest length passed in does not meet the requirement of the curve.

ECDSA accepts truncated digests, but the truncation rule is fixed per curve and is handled inside the implementation. Accepting a digest of the wrong length would only let the signing and verification sides disagree about how far to truncate, and such a disagreement shows up as “signatures randomly fail to verify”.

Fields

§expected: usize

Expected length.

§actual: usize

Actual length.

§

InvalidKeyLabel

The key label is invalid.

The label becomes an entry name in the system-wide key namespace, so it is validated against a whitelist. The most direct hazard is NUL truncation: if \0 were allowed, "a\0b" and "a" would be the same name to a C string, and two different labels would map to one device identity.

Fields

§reason: &'static str

Fixed reason description. Contains no raw label — it may come from user input.

§

InvalidPublicKey

The public key returned by hardware is not a valid P-256 public key.

Separate from Error::DevicePublicKeyInvalid: that one means “a public key received from a peer is invalid” (a normal rejection path), while this one means “the public key we just read back from our own hardware is invalid” — an internal inconsistency pointing at the platform backend or the parsing logic, not a user error.

The two are handled quite differently: the first only requires rejecting this connection, the second has to surface an error a developer can see.

Fields

§reason: &'static str

Fixed reason description.

§

InvalidSignatureLength

The signature length returned by hardware is wrong.

As above, this is an internal inconsistency rather than a user error.

Fields

§expected: usize

Expected length.

§actual: usize

Actual length.

§

InvalidWrappedKey

The wrapped master key could not be turned back into a master key.

§This is not a hardware fault

The bytes are damaged, or they were produced by a different key-encryption key (a restored file, a key store that was re-created, a different device). Retrying and changing machine do not help, so the variant is deliberately not classified as environmental: what the caller has to offer the user is a recovery path, not a different computer.

code is the platform’s own numeric code where it has one, and 0 where it does not (the in-memory backend). The code is kept for diagnostics for the same reason Error::Hardware keeps it: a native code is the only handle available for looking a failure up in vendor documentation.

Fields

§reason: &'static str

Fixed reason description. Contains no key material.

§code: i32

Raw platform error code, or 0 when the backend reports none.

§

InvalidMasterKey

The platform key store returned something that is not master key material.

An internal inconsistency rather than a user error: the store was asked for the material it holds, and what came back has the wrong shape. Reported instead of being truncated or padded, because a master key of the wrong length would fail later in a place that no longer points here.

Fields

§reason: &'static str

Fixed reason description. Contains no key material.

§

KeyNotExportable

The platform key store holds the entry but will not return its material.

This is the failure mode of the direct form — “the store holds the material and hands it back” — on a platform whose key store protects a key by never letting its material out. The entry is unusable for that form, and the honest answer is this error rather than a store that silently keeps something the caller can never read again. The wrapped form exists for exactly this situation.

Fields

§reason: &'static str

Fixed reason description. Contains no key material.

§

RandomnessUnavailable

The OS random source is unavailable.

Can only occur with the mock backend; real backends leave randomness to the hardware, which generates keys inside the TPM / Secure Enclave.

Implementations§

Source§

impl Error

Source

pub const fn is_missing_hardware(&self) -> bool

Whether this error means “no hardware protection is available on this machine”.

The UI can use it to decide whether to tell the user that the device identity key will be stored in software. It does not mean that falling back automatically is allowed; see Error::UnsupportedPlatform.

Source

pub const fn is_environmental(&self) -> bool

Whether this error means “a different machine or platform would solve it”.

It differs from Error::is_missing_hardware, which answers “is there hardware protection”: this one answers “would retrying help”. A platform API failure (Error::Hardware) belongs here, and it is not missing hardware — the key store may be perfectly fine and only this call failed.

Trait Implementations§

Source§

impl Debug for Error

Source§

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

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

impl Display for Error

Source§

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

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

impl Error for Error

1.30.0 · 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

Auto Trait Implementations§

§

impl Freeze for Error

§

impl RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnsafeUnpin for Error

§

impl UnwindSafe for Error

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, 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> 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 = !

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.