Skip to main content

tor_keymgr/keystore/arti/
err.rs

1//! An error type for [`ArtiNativeKeystore`](crate::ArtiNativeKeystore).
2
3use crate::keystore::fs_utils::FilesystemError;
4use crate::raw::RawEntryId;
5use crate::{ArtiPathSyntaxError, KeystoreError, UnknownKeyTypeError};
6use tor_error::{ErrorKind, HasKind};
7use tor_key_forge::{CertType, KeyType, SshKeyAlgorithm};
8
9use std::path::PathBuf;
10use std::sync::Arc;
11
12/// An error returned by [`ArtiNativeKeystore`](crate::ArtiNativeKeystore)'s
13/// [`Keystore`](crate::Keystore) implementation.
14#[derive(thiserror::Error, Debug, Clone)]
15pub(crate) enum ArtiNativeKeystoreError {
16    /// An error that occurred while accessing the filesystem.
17    #[error("{0}")]
18    Filesystem(#[from] FilesystemError),
19
20    /// Found a key with an invalid path.
21    //
22    // TODO: Should we expose the underlying MalformedPathError? The current
23    // message "Key has invalid path" is too vague.
24    #[error("Key has invalid path: {path}")]
25    MalformedPath {
26        /// The path of the key.
27        path: PathBuf,
28        /// The underlying error.
29        #[source]
30        err: MalformedPathError,
31    },
32
33    /// An error due to encountering an unsupported [`KeyType`].
34    #[error("{0}")]
35    UnknownKeyType(#[from] UnknownKeyTypeError),
36
37    /// Failed to parse an OpenSSH key.
38    #[error("Failed to parse OpenSSH with type {key_type:?}")]
39    SshKeyParse {
40        /// The path of the malformed key.
41        path: PathBuf,
42        /// The type of key we were trying to fetch.
43        key_type: KeyType,
44        /// The underlying error.
45        #[source]
46        err: Arc<ssh_key::Error>,
47    },
48
49    /// The OpenSSH key we retrieved is of the wrong type.
50    #[error("Unexpected OpenSSH key type: wanted {wanted_key_algo}, found {found_key_algo}")]
51    UnexpectedSshKeyType {
52        /// The path of the malformed key.
53        path: PathBuf,
54        /// The algorithm we expected the key to use.
55        wanted_key_algo: SshKeyAlgorithm,
56        /// The algorithm of the key we got.
57        found_key_algo: SshKeyAlgorithm,
58    },
59
60    /// Failed to parse an OpenSSH key.
61    #[error("Failed to parse cert with type {cert_type:?}")]
62    CertParse {
63        /// The path of the malformed key.
64        path: PathBuf,
65        /// The type of cert we were trying to fetch.
66        cert_type: CertType,
67        /// The underlying error.
68        #[source]
69        err: tor_bytes::Error,
70    },
71
72    /// Encountered a non-path `RawEntryId` variant.
73    #[error("Raw entry {:?} not supported in an Arti keystore", _0)]
74    UnsupportedRawEntry(RawEntryId),
75
76    /// An internal error.
77    #[error("Internal error")]
78    Bug(#[from] tor_error::Bug),
79}
80
81/// The keystore contained a file whose name syntactically improper
82///
83/// Keys are supposed to have pathnames consisting of an `ArtiPath`
84/// followed by a file extension.
85///
86/// See also [`KeyPathError`](crate::KeyPathError), which occurs at a higher level.
87#[derive(thiserror::Error, Debug, Clone)]
88pub(crate) enum MalformedPathError {
89    /// Found a key with a non-UTF-8 path.
90    #[error("the path is not valid UTF-8")]
91    Utf8,
92
93    /// Found a key with no extension.
94    #[error("no extension")]
95    NoExtension,
96
97    /// The file path is not a valid [`ArtiPath`](crate::ArtiPath).
98    #[error("not a valid ArtiPath")]
99    InvalidArtiPath(ArtiPathSyntaxError),
100}
101
102impl KeystoreError for ArtiNativeKeystoreError {}
103
104impl HasKind for ArtiNativeKeystoreError {
105    fn kind(&self) -> ErrorKind {
106        use ArtiNativeKeystoreError as KE;
107
108        match self {
109            KE::Filesystem(e) => e.kind(),
110            KE::MalformedPath { .. } => ErrorKind::KeystoreAccessFailed,
111            KE::UnknownKeyType(_) => ErrorKind::KeystoreAccessFailed,
112            KE::SshKeyParse { .. } | KE::UnexpectedSshKeyType { .. } | KE::CertParse { .. } => {
113                ErrorKind::KeystoreCorrupted
114            }
115            KE::UnsupportedRawEntry { .. } => ErrorKind::BadApiUsage,
116            KE::Bug(e) => e.kind(),
117        }
118    }
119}
120
121impl From<ArtiNativeKeystoreError> for crate::Error {
122    fn from(e: ArtiNativeKeystoreError) -> Self {
123        crate::Error::Keystore(Arc::new(e))
124    }
125}