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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
//! An error type for [C Tor](crate::keystore::ctor) keystores.
use crate::KeystoreError;
use crate::keystore::fs_utils;
use tor_error::{ErrorKind, HasKind};
use tor_hscrypto::pk::HsIdParseError;
use tor_key_forge::KeystoreItemType;
use std::path::PathBuf;
use std::sync::Arc;
/// An error returned by a C Tor
/// [`Keystore`](crate::Keystore) implementation.
#[derive(thiserror::Error, Debug, Clone)]
pub(crate) enum CTorKeystoreError {
/// An error that occurred while accessing the filesystem.
#[error("{0}")]
Filesystem(#[from] fs_utils::FilesystemError),
/// Found a malformed.
#[error("Key {path} is malformed")]
MalformedKey {
/// The path of the key.
path: PathBuf,
/// The underlying error.
#[source]
err: MalformedKeyError,
},
/// An unsupported operation.
#[error("Operation not supported: {action}")]
NotSupported {
/// The action we were trying to perform.
action: &'static str,
},
/// Key type and specifier mismatch.
#[error("Invalid item type {item_type:?} for {item}")]
InvalidKeystoreItemType {
/// The item type.
item_type: KeystoreItemType,
/// The item we tried to access.
item: String,
},
/// An internal error.
#[error("Internal error")]
Bug(#[from] tor_error::Bug),
}
/// Encountered a malformed C Tor key.
#[derive(thiserror::Error, Debug, Clone)]
pub(crate) enum MalformedKeyError {
/// A malformed hidden service key.
#[error("{0}")]
Service(#[from] MalformedServiceKeyError),
/// A malformed hidden service client key.
#[error("{0}")]
Client(#[from] MalformedClientKeyError),
}
/// Encountered a malformed C Tor service key.
#[derive(thiserror::Error, Debug, Clone)]
pub(crate) enum MalformedServiceKeyError {
/// Found a key with an invalid tag
#[error("invalid key length: {len} (expected {expected_len})")]
InvalidKeyLen {
/// The length of the invalid key.
len: usize,
/// The expected length of this key.
expected_len: usize,
},
/// Found a key with an invalid tag
#[error("invalid tag: {tag:?} (expected {expected_tag:?})")]
InvalidTag {
/// The invalid tag.
tag: Vec<u8>,
/// The expected value of the tag.
expected_tag: Vec<u8>,
},
/// Found an entry that cannot be recognized as a key
/// (i.e.: a key that doesn't provide a valid
/// [`CTorPath`](crate::CTorPath))
#[error("unrecognized key")]
NotAKey,
/// Found an invalid ed25519 public key
#[error("invalid ed25519 public key")]
Ed25519Public(#[from] Arc<signature::Error>),
/// Found an invalid ed25519 keypair
//
// Note: this error doesn't have any context, because we use
// ed25519::ExpandedKeypair::from_secret_key_bytes to parse the key,
// which returns `None` if the key can't be parsed
// (so we don't have any information about what actually went wrong).
#[error("invalid ed25519 keypair")]
Ed25519Keypair,
/// An internal error.
#[error("Internal error")]
Bug(#[from] tor_error::Bug),
}
/// Encountered a malformed C Tor client key.
#[derive(thiserror::Error, Debug, Clone)]
pub(crate) enum MalformedClientKeyError {
/// The auth type is not "descriptor".
#[error("Invalid auth type {0}")]
InvalidAuthType(String),
/// The key type is not "x25519".
#[error("Invalid key type {0}")]
InvalidKeyType(String),
/// The key is not in the `<auth-type>:x25519:<base32-encoded-public-key>` format.
#[error("Invalid key format")]
InvalidFormat,
/// The encoded key material is invalid.
#[error("Invalid key material")]
InvalidKeyMaterial,
/// Base32 decoding failed.
#[error("Invalid base32 in client key")]
InvalidBase32(#[from] data_encoding::DecodeError),
/// Failed to parse the HsId.
#[error("Invalid HsId client key")]
InvalidHsId(#[from] HsIdParseError),
}
impl KeystoreError for CTorKeystoreError {}
impl HasKind for CTorKeystoreError {
fn kind(&self) -> ErrorKind {
use CTorKeystoreError as KE;
match self {
KE::Filesystem(e) => e.kind(),
KE::MalformedKey { .. } => ErrorKind::KeystoreCorrupted,
KE::NotSupported { .. } => ErrorKind::BadApiUsage,
KE::InvalidKeystoreItemType { .. } => ErrorKind::BadApiUsage,
KE::Bug(e) => e.kind(),
}
}
}
impl From<CTorKeystoreError> for crate::Error {
fn from(e: CTorKeystoreError) -> Self {
crate::Error::Keystore(Arc::new(e))
}
}
|