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}