1//! An error type for the `tor-keymgr` crate.
23use tor_error::HasKind;
45use dyn_clone::DynClone;
6use tor_persist::slug::BadSlug;
78use std::error::Error as StdError;
9use std::fmt;
10use std::sync::Arc;
1112use crate::KeyPathError;
1314/// An Error type for this crate.
15#[derive(thiserror::Error, Debug, Clone)]
16#[non_exhaustive]
17pub enum Error {
18/// Detected keustore corruption.
19#[error("{0}")]
20Corruption(#[from] KeystoreCorruptionError),
2122/// An opaque error returned by a [`Keystore`](crate::Keystore).
23#[error("{0}")]
24Keystore(#[from] Arc<dyn KeystoreError>),
2526/// An error returned when the [`KeyMgr`](crate::KeyMgr) is asked to generate a key that already exists.
27 ///
28 /// Note that because there is no locking of the keystore,
29 /// this situation is not reliably detected
30 /// in the presence of concurrent tasks trying to generate the same key.
31 ///
32 /// So this error is provided to help the human user,
33 /// but mustn't be relied on for correctness.
34#[error("Key already exists")]
35KeyAlreadyExists,
3637/// Error coming from the tor-key-forgecrate
38#[error("{0}")]
39KeyForge(#[from] tor_key_forge::Error),
4041/// An error caused by an invalid certificate.
42#[error("{0}")]
43InvalidCert(#[from] tor_key_forge::InvalidCertError),
4445/// An internal error.
46#[error("Internal error")]
47Bug(#[from] tor_error::Bug),
48}
4950/// An error returned by a [`Keystore`](crate::Keystore).
51pub trait KeystoreError:
52 HasKind + StdError + DynClone + fmt::Debug + fmt::Display + Send + Sync + 'static
53{
54}
5556impl HasKind for Error {
57fn kind(&self) -> tor_error::ErrorKind {
58use tor_error::ErrorKind as EK;
59use Error as E;
6061match self {
62 E::Keystore(e) => e.kind(),
63 E::Corruption(_) => EK::KeystoreCorrupted,
64 E::KeyAlreadyExists => EK::BadApiUsage, // TODO: not strictly right
65E::KeyForge(_) => EK::BadApiUsage,
66 E::InvalidCert(_) => EK::BadApiUsage, // TODO: not strictly right
67E::Bug(e) => e.kind(),
68 }
69 }
70}
7172/// An error caused by a syntactically invalid [`ArtiPath`](crate::ArtiPath).
73///
74/// The `ArtiPath` is not in the legal syntax: it contains bad characters,
75/// or a syntactically invalid components.
76///
77/// (Does not include any errors arising from paths which are invalid
78/// *for the particular key*.)
79#[derive(thiserror::Error, Debug, Clone)]
80#[error("Invalid ArtiPath")]
81#[non_exhaustive]
82pub enum ArtiPathSyntaxError {
83/// One of the path slugs was invalid.
84#[error("{0}")]
85Slug(#[from] BadSlug),
8687/// An internal error.
88#[error("Internal error")]
89Bug(#[from] tor_error::Bug),
90}
9192/// An error caused by keystore corruption.
93#[derive(thiserror::Error, Debug, Clone)]
94#[error("Keystore corruption")]
95#[non_exhaustive]
96pub enum KeystoreCorruptionError {
97/// A keystore contains a key that has an invalid [`KeyPath`](crate::KeyPath).
98#[error("{0}")]
99KeyPath(#[from] KeyPathError),
100101/// Missing certificate for key.
102#[error("Missing certificate for key")]
103MissingCertificate,
104105/// Missing the subject key of a certificate we own.
106#[error("Subject key of certificate not found")]
107MissingSubjectKey,
108109/// Missing signing key for certificate.
110#[error("Missing signing key for certificate")]
111MissingSigningKey,
112}
113114/// An error that happens when we encounter an unknown key type.
115#[derive(thiserror::Error, PartialEq, Eq, Debug, Clone)]
116#[error("unknown key type: arti_extension={arti_extension}")]
117pub struct UnknownKeyTypeError {
118/// The extension used for keys of this type in an Arti keystore.
119pub(crate) arti_extension: String,
120}
121122#[cfg(test)]
123mod tests {
124// @@ begin test lint list maintained by maint/add_warning @@
125#![allow(clippy::bool_assert_comparison)]
126 #![allow(clippy::clone_on_copy)]
127 #![allow(clippy::dbg_macro)]
128 #![allow(clippy::mixed_attributes_style)]
129 #![allow(clippy::print_stderr)]
130 #![allow(clippy::print_stdout)]
131 #![allow(clippy::single_char_pattern)]
132 #![allow(clippy::unwrap_used)]
133 #![allow(clippy::unchecked_duration_subtraction)]
134 #![allow(clippy::useless_vec)]
135 #![allow(clippy::needless_pass_by_value)]
136//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
137use super::*;
138use tor_error::ErrorKind;
139140#[derive(Debug, Copy, Clone, PartialEq, thiserror::Error)]
141 #[error("The source of a test error")]
142struct TestErrorSource;
143144#[derive(Debug, Clone, thiserror::Error)]
145 #[error("A test error")]
146struct TestError(#[from] TestErrorSource);
147148impl KeystoreError for TestError {}
149150impl HasKind for TestError {
151fn kind(&self) -> ErrorKind {
152 ErrorKind::Other
153 }
154 }
155156#[test]
157fn error_source() {
158let e: Error = (Arc::new(TestError(TestErrorSource)) as Arc<dyn KeystoreError>).into();
159160assert_eq!(
161 e.source().unwrap().to_string(),
162 TestError(TestErrorSource).to_string()
163 );
164 }
165}