Skip to main content

identity_kit/keys/
error.rs

1//! Error type of the `keys` module.
2
3use std::error::Error;
4use std::path::PathBuf;
5
6use super::KeyId;
7use crate::jose::{JwsAlgorithm, KeyType};
8
9/// Why a [`KeyStore`](super::KeyStore) operation failed.
10///
11/// The first variants are the contract every backend follows (the test suite checks them); the
12/// file variants are reported by [`SoftwareKeyStore`](super::SoftwareKeyStore), and
13/// [`Backend`](Self::Backend) carries whatever a remote backend reports.
14#[derive(Debug, thiserror::Error)]
15#[non_exhaustive]
16pub enum KeyStoreError {
17    /// No key has this id.
18    #[error("key `{0}` not found")]
19    NotFound(KeyId),
20    /// A key with this id exists already, so it cannot be generated or imported.
21    #[error("key `{0}` already exists")]
22    AlreadyExists(KeyId),
23    /// The key signs with another algorithm than the one requested.
24    #[error("key `{key}` signs with {key_alg}, not {requested}")]
25    AlgorithmMismatch {
26        /// The key.
27        key: KeyId,
28        /// The algorithm the key was created for.
29        key_alg: JwsAlgorithm,
30        /// The algorithm that was requested.
31        requested: JwsAlgorithm,
32    },
33    /// The backend does not implement this operation (`generate` or `delete`).
34    #[error("key store does not support `{0}`")]
35    Unsupported(&'static str),
36    /// The backend does not sign with this algorithm; see
37    /// [`KeyStoreCapabilities::algorithms`](super::KeyStoreCapabilities::algorithms).
38    #[error("key store does not support {0}")]
39    UnsupportedAlgorithm(JwsAlgorithm),
40    /// The backend cannot generate keys of this type.
41    #[error("key store does not support {0:?} keys")]
42    UnsupportedKeyType(KeyType),
43    /// The algorithm of a [`KeySpec`](super::KeySpec) does not fit its key type, for example
44    /// `ES256` with an Ed25519 key.
45    #[error("{alg} cannot be used with {key_type:?} keys")]
46    InvalidSpec {
47        /// The requested key type.
48        key_type: KeyType,
49        /// The requested algorithm.
50        alg: JwsAlgorithm,
51    },
52    /// The key exists but its material cannot be used: it does not decode, the public part does
53    /// not match the private part, the type is unknown, and so on.
54    #[error("key `{key}` is unusable: {reason}")]
55    InvalidKey {
56        /// The key.
57        key: KeyId,
58        /// What is wrong with it.
59        reason: String,
60    },
61    /// Reading or writing the key store file failed.
62    #[error("key store file `{}`: {source}", path.display())]
63    Io {
64        /// The file.
65        path: PathBuf,
66        /// The I/O error.
67        #[source]
68        source: std::io::Error,
69    },
70    /// The key store file is readable or writable by other users.
71    #[error(
72        "key store file `{}` has mode {mode:04o}; make it private (0600) or opt in with `allow_insecure_permissions`",
73        path.display()
74    )]
75    InsecurePermissions {
76        /// The file.
77        path: PathBuf,
78        /// Its permission bits.
79        mode: u32,
80    },
81    /// The key store file is not a usable JWK set.
82    #[error("key store file `{}` is not a usable JWK set: {reason}", path.display())]
83    InvalidKeySet {
84        /// The file.
85        path: PathBuf,
86        /// What is wrong with it.
87        reason: String,
88    },
89    /// An error of a remote backend (an HSM, a cloud service).
90    #[error("key store backend error: {0}")]
91    Backend(#[source] Box<dyn Error + Send + Sync + 'static>),
92}
93
94impl KeyStoreError {
95    /// Wraps a backend's own error as [`KeyStoreError::Backend`].
96    pub fn backend<E: Error + Send + Sync + 'static>(error: E) -> Self {
97        Self::Backend(Box::new(error))
98    }
99}