sequoia_keystore/
error.rs1use std::sync::Arc;
2
3use sequoia_openpgp as openpgp;
4use openpgp::Result;
5use openpgp::packet;
6use openpgp::parse::Parse;
7
8use crate::capnp_relay;
9use crate::capnp_relay::CapnProtoRelay;
10
11use crate::keystore;
12use crate::InaccessibleDecryptionKey;
13use crate::Key;
14use crate::server;
15
16#[derive(thiserror::Error, Debug)]
17pub enum Error {
22 #[error("Error: {}",
29 .0.as_deref().unwrap_or("an unspecified error occurred"))]
30 GenericError(Option<String>),
31
32 #[error("Unspecified protocol error: something went wrong")]
34 ProtocolError,
35
36 #[error("EOF")]
41 EOF,
42
43 #[error("Can't decrypt a PKESK, the candidate keys are inaccessible")]
50 InaccessibleDecryptionKey(Vec<InaccessibleDecryptionKey>),
51
52 #[error("Key {0} cannot be used for decryption")]
54 NotDecryptionCapable(String),
55
56 #[error("Key {0} cannot be used for signing")]
58 NotSigningCapable(String),
59
60 #[error("Internal server error")]
62 InternalError(String),
63
64 #[error("Can't import keys into the backend: {}",
74 .0.as_deref().unwrap_or("use another tool to import keys \
75 into this backend"))]
76 ExternalImportRequired(Option<String>),
77
78 #[error("Can't export secret key material key: {}",
87 .0.as_deref().unwrap_or("use another tool to import keys \
88 into this backend"))]
89 SecretKeyMaterialSealed(Option<String>),
90
91 #[error("Can't unlock using an inline password{}{}",
97 .0.as_ref().map(|_| ": ").unwrap_or(""),
98 .0.as_deref().map(|msg| msg).unwrap_or(""))]
99 NoInlinePassword(Option<String>),
100
101 #[error("External password entry is not supported{}{}",
106 .0.as_ref().map(|_| ": ").unwrap_or(""),
107 .0.as_deref().map(|msg| msg).unwrap_or(""))]
108 NoExternalPassword(Option<String>),
109
110 #[error("Internal RPC error")]
114 RpcError(#[from] capnp::Error),
115
116 }
119
120#[derive(thiserror::Error, Debug)]
123pub(crate) enum ServerError {
124 #[error("Can't decrypt a PKESK, the candidate keys are inaccessible")]
131 InaccessibleDecryptionKey(Vec<server::InaccessibleDecryptionKey>),
132}
133
134impl Error {
135 pub(crate) fn from_capnp(relay: Arc<CapnProtoRelay>,
138 captable: &mut capnp_relay::CapTable,
139 err: keystore::error::Reader<'_>)
140 -> anyhow::Error
141 {
142 let mut try_from = || {
143 match err.which() {
144 Ok(keystore::error::GenericError(msg)) => {
145 let msg = msg?;
146 if msg.is_empty() {
147 Ok(Error::GenericError(None).into())
148 } else if let Ok(msg) = msg.to_string() {
149 Ok(Error::GenericError(Some(msg)).into())
150 } else {
151 Ok(Error::GenericError(
154 Some("Error parsing error message".into())).into())
155 }
156 },
157 Ok(keystore::error::Protocol(())) => Ok(Error::ProtocolError.into()),
158 Ok(keystore::error::Eof(())) => Ok(Error::EOF.into()),
159 Ok(keystore::error::NotDecryptionCapable(s)) => {
160 let s = s?.to_string()?;
161 Ok(Error::NotDecryptionCapable(s).into())
162 }
163 Ok(keystore::error::NotSigningCapable(s)) => {
164 let s = s?.to_string()?;
165 Ok(Error::NotSigningCapable(s).into())
166 }
167 Ok(keystore::error::InaccessibleDecryptionKey(keys)) => {
168 let keys = keys?.into_iter()
169 .map(|inaccessible_key| {
170 let key = inaccessible_key.get_key_descriptor()?;
171
172 let cap = key.get_handle()?;
173
174 let pk = key.get_public_key()?;
175 let pk = packet::Key::<packet::key::UnspecifiedParts,
176 packet::key::UnspecifiedRole>
177 ::from_bytes(pk)?;
178 let pk = pk.parts_into_public();
179
180 let pkesk = inaccessible_key.get_pkesk()?;
181 let pkesk = packet::PKESK::from_bytes(pkesk)?;
182
183 Ok(InaccessibleDecryptionKey {
184 key: Key {
185 relay: Arc::clone(&relay),
186 cap: captable.insert(cap.client),
187 key: pk,
188 },
189 pkesk: pkesk,
190 })
191 })
192 .collect::<Result<Vec<_>>>()?;
193 Ok(Error::InaccessibleDecryptionKey(keys).into())
194 }
195 Ok(keystore::error::InternalError(s)) => {
196 let s = s?.to_string()?;
197 Ok(Error::InternalError(s).into())
198 }
199 Ok(keystore::error::ExternalImportRequired(msg)) => {
200 let msg = msg?;
201 if msg.is_empty() {
202 Ok(Error::ExternalImportRequired(None).into())
203 } else if let Ok(msg) = msg.to_string() {
204 Ok(Error::ExternalImportRequired(Some(msg)).into())
205 } else {
206 Ok(Error::ExternalImportRequired(None).into())
209 }
210 }
211 Ok(keystore::error::SecretKeyMaterialSealed(msg)) => {
212 let msg = msg?;
213 if msg.is_empty() {
214 Ok(Error::SecretKeyMaterialSealed(None).into())
215 } else if let Ok(msg) = msg.to_string() {
216 Ok(Error::SecretKeyMaterialSealed(Some(msg)).into())
217 } else {
218 Ok(Error::SecretKeyMaterialSealed(None).into())
221 }
222 }
223 Ok(keystore::error::NoInlinePassword(msg)) => {
224 let msg = msg?;
225 if msg.is_empty() {
226 Ok(Error::NoInlinePassword(None).into())
227 } else if let Ok(msg) = msg.to_string() {
228 Ok(Error::NoInlinePassword(Some(msg)).into())
229 } else {
230 Ok(Error::NoInlinePassword(None).into())
233 }
234 }
235 Ok(keystore::error::NoExternalPassword(msg)) => {
236 let msg = msg?;
237 if msg.is_empty() {
238 Ok(Error::NoExternalPassword(None).into())
239 } else if let Ok(msg) = msg.to_string() {
240 Ok(Error::NoExternalPassword(Some(msg)).into())
241 } else {
242 Ok(Error::NoExternalPassword(None).into())
245 }
246 }
247 Err(err) => {
248 log::debug!("Protocol violation while parsing error: {}",
251 err);
252 Ok(Error::ProtocolError.into())
253 }
254 }
255 };
256
257 match try_from() {
258 Ok(err) => err,
259 Err(err) => err,
260 }
261 }
262}
263
264impl keystore::error::Builder<'_> {
265 pub(crate) fn from_anyhow(&mut self, err: &anyhow::Error) {
273 match err.downcast_ref::<ServerError>() {
274 Some(ServerError::InaccessibleDecryptionKey(keys)) => {
275 let mut keys_wire = self
276 .reborrow()
277 .init_inaccessible_decryption_key(keys.len() as u32);
278 for (i, key) in keys.into_iter().enumerate() {
279 key.serialize(keys_wire.reborrow().get(i as u32));
280 }
281
282 return;
283 }
284 None => (),
285 }
286
287 match err.downcast_ref::<Error>() {
288 Some(Error::GenericError(msg)) =>
289 self.set_generic_error(msg.as_deref().unwrap_or("")),
290 Some(Error::ProtocolError) =>
291 self.set_protocol(()),
292 Some(Error::EOF) =>
293 self.set_eof(()),
294 Some(Error::NotDecryptionCapable(fpr)) => {
295 let mut builder = self.reborrow()
296 .init_not_decryption_capable(fpr.len() as u32);
297 builder.push_str(&fpr);
298 }
299 Some(Error::NotSigningCapable(fpr)) => {
300 let mut builder = self.reborrow()
301 .init_not_signing_capable(fpr.len() as u32);
302 builder.push_str(&fpr);
303 }
304 Some(Error::InaccessibleDecryptionKey(_keys)) => {
305 log::debug!("Invalid attempt to serialize Error::InaccessibleDecryptionKey");
309 self.set_internal_error("InaccessibleDecryptionKey shouldn't \
310 be returned in this context");
311 }
312 Some(Error::InternalError(err)) => {
313 let mut builder = self.reborrow()
314 .init_internal_error(err.len() as u32);
315 builder.push_str(&err);
316 }
317 Some(Error::ExternalImportRequired(msg)) => {
318 self.set_external_import_required(msg.as_deref().unwrap_or(""));
319 }
320 Some(Error::SecretKeyMaterialSealed(msg)) => {
321 self.set_secret_key_material_sealed(msg.as_deref().unwrap_or(""));
322 }
323 Some(Error::NoInlinePassword(msg)) => {
324 self.set_no_inline_password(msg.as_deref().unwrap_or(""));
325 }
326 Some(Error::NoExternalPassword(msg)) => {
327 self.set_no_external_password(msg.as_deref().unwrap_or(""));
328 }
329 Some(Error::RpcError(_err)) =>
330 self.set_protocol(()),
331 None => {
332 self.set_generic_error(err.to_string());
334 }
335 }
336 }
337}
338
339impl From<capnp::NotInSchema> for Error {
340 fn from(_: capnp::NotInSchema) -> Self {
341 Error::ProtocolError
342 }
343}