use std::sync::Arc;
use std::sync::Mutex;
use sequoia_openpgp as openpgp;
use openpgp::Result;
use openpgp::packet;
use openpgp::parse::Parse;
use crate::capnp_relay;
use crate::capnp_relay::CapnProtoRelay;
use crate::keystore;
use crate::InaccessibleDecryptionKey;
use crate::Key;
use crate::server;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Unspecified error")]
UnspecifiedError,
#[error("Unspecified protocol error")]
ProtocolError,
#[error("EOF")]
EOF,
#[error("Can't decrypt a PKESK, the candidate keys are inaccessible")]
InaccessibleDecryptionKey(Vec<InaccessibleDecryptionKey>),
#[error("Key {0} cannot be used for decryption")]
NotDecryptionCapable(String),
#[error("Key {0} cannot be used for signing")]
NotSigningCapable(String),
#[error("Internal server error")]
InternalError(String),
#[error("Internal RPC error")]
RpcError(#[from] capnp::Error),
}
#[derive(thiserror::Error, Debug)]
pub(crate) enum ServerError {
#[error("Can't decrypt a PKESK, the candidate keys are inaccessible")]
InaccessibleDecryptionKey(Vec<server::InaccessibleDecryptionKey>),
}
impl Error {
pub(crate) fn from_capnp(relay: Arc<Mutex<CapnProtoRelay>>,
captable: &mut capnp_relay::CapTable,
err: keystore::error::Reader<'_>)
-> anyhow::Error
{
let mut try_from = || {
match err.which() {
Ok(keystore::error::Unspecified(())) => Ok(Error::UnspecifiedError.into()),
Ok(keystore::error::Protocol(())) => Ok(Error::ProtocolError.into()),
Ok(keystore::error::Eof(())) => Ok(Error::EOF.into()),
Ok(keystore::error::NotDecryptionCapable(s)) => {
let s = s?.to_string()?;
Ok(Error::NotDecryptionCapable(s).into())
}
Ok(keystore::error::NotSigningCapable(s)) => {
let s = s?.to_string()?;
Ok(Error::NotSigningCapable(s).into())
}
Ok(keystore::error::InaccessibleDecryptionKey(keys)) => {
let keys = keys?.into_iter()
.map(|inaccessible_key| {
let key = inaccessible_key.get_key_descriptor()?;
let cap = key.get_handle()?;
let pk = key.get_public_key()?;
let pk = packet::Key::<packet::key::UnspecifiedParts,
packet::key::UnspecifiedRole>
::from_bytes(pk)?;
let pk = pk.parts_into_public();
let pkesk = inaccessible_key.get_pkesk()?;
let pkesk = packet::PKESK::from_bytes(pkesk)?;
Ok(InaccessibleDecryptionKey {
key: Key {
relay: Arc::clone(&relay),
cap: captable.insert(cap.client),
key: pk,
},
pkesk: pkesk,
})
})
.collect::<Result<Vec<_>>>()?;
Ok(Error::InaccessibleDecryptionKey(keys).into())
}
Ok(keystore::error::InternalError(s)) => {
let s = s?.to_string()?;
Ok(Error::InternalError(s).into())
}
Err(err) => {
log::debug!("Protocol violation while parsing error: {}",
err);
Ok(Error::ProtocolError.into())
}
}
};
match try_from() {
Ok(err) => err,
Err(err) => err,
}
}
}
impl keystore::error::Builder<'_> {
pub(crate) fn from_anyhow(&mut self, err: &anyhow::Error) {
match err.downcast_ref::<ServerError>() {
Some(ServerError::InaccessibleDecryptionKey(keys)) => {
let mut keys_wire = self
.reborrow()
.init_inaccessible_decryption_key(keys.len() as u32);
for (i, key) in keys.into_iter().enumerate() {
key.serialize(keys_wire.reborrow().get(i as u32));
}
return;
}
None => (),
}
match err.downcast_ref::<Error>() {
Some(Error::UnspecifiedError) =>
self.set_unspecified(()),
Some(Error::ProtocolError) =>
self.set_protocol(()),
Some(Error::EOF) =>
self.set_eof(()),
Some(Error::NotDecryptionCapable(fpr)) => {
let mut builder = self.reborrow()
.init_not_decryption_capable(fpr.len() as u32);
builder.push_str(&fpr);
}
Some(Error::NotSigningCapable(fpr)) => {
let mut builder = self.reborrow()
.init_not_signing_capable(fpr.len() as u32);
builder.push_str(&fpr);
}
Some(Error::InaccessibleDecryptionKey(_keys)) => {
log::debug!("Invalid attempt to serialize Error::InaccessibleDecryptionKey");
self.set_unspecified(());
}
Some(Error::InternalError(err)) => {
let mut builder = self.reborrow()
.init_internal_error(err.len() as u32);
builder.push_str(&err);
}
Some(Error::RpcError(_err)) =>
self.set_protocol(()),
None => {
self.set_unspecified(());
}
}
}
}
impl From<capnp::NotInSchema> for Error {
fn from(_: capnp::NotInSchema) -> Self {
Error::ProtocolError
}
}