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