diff --git a/src/key.rs b/src/key.rs index cbf93dad0..6d05d48a2 100644 --- a/src/key.rs +++ b/src/key.rs @@ -4,46 +4,22 @@ use std::collections::BTreeMap; use std::fmt; use std::io::Cursor; +use anyhow::{format_err, Result}; use async_trait::async_trait; use num_traits::FromPrimitive; use pgp::composed::Deserializable; use pgp::ser::Serialize; use pgp::types::{KeyTrait, SecretKeyTrait}; -use thiserror::Error; use crate::config::Config; use crate::constants::KeyGenType; use crate::context::Context; -use crate::dc_tools::{time, EmailAddress, InvalidEmailError}; +use crate::dc_tools::{time, EmailAddress}; // Re-export key types pub use crate::pgp::KeyPair; pub use pgp::composed::{SignedPublicKey, SignedSecretKey}; -/// Error type for deltachat key handling. -#[derive(Debug, thiserror::Error)] -#[non_exhaustive] -pub enum Error { - #[error("Could not decode base64")] - Base64Decode(#[from] base64::DecodeError), - #[error("rPGP error: {}", _0)] - Pgp(#[from] pgp::errors::Error), - #[error("Failed to generate PGP key: {}", _0)] - Keygen(#[from] crate::pgp::PgpKeygenError), - #[error("Failed to save generated key: {}", _0)] - StoreKey(#[from] SaveKeyError), - #[error("No address configured")] - NoConfiguredAddr, - #[error("Configured address is invalid: {}", _0)] - InvalidConfiguredAddr(#[from] InvalidEmailError), - #[error("no data provided")] - Empty, - #[error("{0}")] - Other(#[from] anyhow::Error), -} - -pub type Result = std::result::Result; - /// Convenience trait for working with keys. /// /// This trait is implemented for rPGP's [SignedPublicKey] and @@ -74,7 +50,8 @@ pub trait DcKey: Serialize + Deserializable + KeyTrait + Clone { /// the ASCII-armored representation. fn from_asc(data: &str) -> Result<(Self::KeyType, BTreeMap)> { let bytes = data.as_bytes(); - Self::KeyType::from_armor_single(Cursor::new(bytes)).map_err(Error::Pgp) + Self::KeyType::from_armor_single(Cursor::new(bytes)) + .map_err(|err| format_err!("rPGP error: {}", err)) } /// Load the users' default key from the database. @@ -225,7 +202,7 @@ async fn generate_keypair(context: &Context) -> Result { let addr = context .get_config(Config::ConfiguredAddr) .await? - .ok_or(Error::NoConfiguredAddr)?; + .ok_or_else(|| format_err!("No address configured"))?; let addr = EmailAddress::new(&addr)?; let _guard = context.generating_key_mutex.lock().await; @@ -284,24 +261,6 @@ pub enum KeyPairUse { ReadOnly, } -/// Error saving a keypair to the database. -#[derive(Debug, thiserror::Error)] -#[error("SaveKeyError: {message}")] -pub struct SaveKeyError { - message: String, - #[source] - cause: anyhow::Error, -} - -impl SaveKeyError { - fn new(message: impl Into, cause: impl Into) -> Self { - Self { - message: message.into(), - cause: cause.into(), - } - } -} - /// Store the keypair as an owned keypair for addr in the database. /// /// This will save the keypair as keys for the given address. The @@ -318,7 +277,7 @@ pub async fn store_self_keypair( context: &Context, keypair: &KeyPair, default: KeyPairUse, -) -> std::result::Result<(), SaveKeyError> { +) -> Result<()> { // Everything should really be one transaction, more refactoring // is needed for that. let public_key = DcKey::to_bytes(&keypair.public); @@ -330,13 +289,13 @@ pub async fn store_self_keypair( paramsv![public_key, secret_key], ) .await - .map_err(|err| SaveKeyError::new("failed to remove old use of key", err))?; + .map_err(|err| err.context("failed to remove old use of key"))?; if default == KeyPairUse::Default { context .sql .execute("UPDATE keypairs SET is_default=0;", paramsv![]) .await - .map_err(|err| SaveKeyError::new("failed to clear default", err))?; + .map_err(|err| err.context("failed to clear default"))?; } let is_default = match default { KeyPairUse::Default => true as i32, @@ -354,7 +313,7 @@ pub async fn store_self_keypair( paramsv![addr, is_default, public_key, secret_key, t], ) .await - .map_err(|err| SaveKeyError::new("failed to insert keypair", err))?; + .map_err(|err| err.context("failed to insert keypair"))?; Ok(()) } @@ -364,10 +323,10 @@ pub async fn store_self_keypair( pub struct Fingerprint(Vec); impl Fingerprint { - pub fn new(v: Vec) -> std::result::Result { + pub fn new(v: Vec) -> Result { match v.len() { 20 => Ok(Fingerprint(v)), - _ => Err(FingerprintError::WrongLength), + _ => Err(format_err!("Wrong fingerprint length")), } } @@ -406,7 +365,7 @@ impl fmt::Display for Fingerprint { /// Parse a human-readable or otherwise formatted fingerprint. impl std::str::FromStr for Fingerprint { - type Err = FingerprintError; + type Err = anyhow::Error; fn from_str(input: &str) -> std::result::Result { let hex_repr: String = input @@ -420,21 +379,11 @@ impl std::str::FromStr for Fingerprint { } } -#[derive(Debug, Error)] -pub enum FingerprintError { - #[error("Invalid hex characters")] - NotHex(#[from] hex::FromHexError), - #[error("Incorrect fingerprint lengths")] - WrongLength, -} - #[cfg(test)] mod tests { use super::*; use crate::test_utils::{alice_keypair, TestContext}; - use std::error::Error; - use async_std::sync::Arc; use once_cell::sync::Lazy; @@ -676,13 +625,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD .unwrap(); assert_eq!(fp, res); - let err = "1".parse::().err().unwrap(); - match err { - FingerprintError::NotHex(_) => (), - _ => panic!("Wrong error"), - } - let src_err = err.source().unwrap().downcast_ref::(); - assert_eq!(src_err, Some(&hex::FromHexError::OddLength)); + assert!("1".parse::().is_err()); } #[test] diff --git a/src/keyring.rs b/src/keyring.rs index e1a79f112..aba4d2d33 100644 --- a/src/keyring.rs +++ b/src/keyring.rs @@ -3,7 +3,7 @@ use anyhow::Result; use crate::context::Context; -use crate::key::{self, DcKey}; +use crate::key::DcKey; /// An in-memory keyring. /// @@ -27,14 +27,14 @@ where } /// Create a new keyring with the the user's secret key loaded. - pub async fn new_self(context: &Context) -> Result, key::Error> { + pub async fn new_self(context: &Context) -> Result> { let mut keyring: Keyring = Keyring::new(); keyring.load_self(context).await?; Ok(keyring) } /// Load the user's key into the keyring. - pub async fn load_self(&mut self, context: &Context) -> Result<(), key::Error> { + pub async fn load_self(&mut self, context: &Context) -> Result<()> { self.add(T::load_self(context).await?); Ok(()) } diff --git a/src/peerstate.rs b/src/peerstate.rs index 2931064a0..5ec14cdf7 100644 --- a/src/peerstate.rs +++ b/src/peerstate.rs @@ -493,12 +493,6 @@ impl Peerstate { } } -impl From for rusqlite::Error { - fn from(_source: crate::key::FingerprintError) -> Self { - Self::InvalidColumnType(0, "Invalid fingerprint".into(), rusqlite::types::Type::Text) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/qr.rs b/src/qr.rs index a551fea05..4954e3f1a 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -86,11 +86,7 @@ async fn decode_openpgp(context: &Context, qr: &str) -> Lot { }; let fingerprint: Fingerprint = match fingerprint.parse() { Ok(fp) => fp, - Err(err) => { - return Error::new(err) - .context("Failed to parse fingerprint in QR code") - .into() - } + Err(err) => return err.context("Failed to parse fingerprint in QR code").into(), }; let param: BTreeMap<&str, &str> = fragment diff --git a/src/securejoin.rs b/src/securejoin.rs index 9af6175bb..0c7b868f6 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -17,7 +17,7 @@ use crate::context::Context; use crate::e2ee::ensure_secret_key_exists; use crate::events::EventType; use crate::headerdef::HeaderDef; -use crate::key::{self, DcKey, Fingerprint, SignedPublicKey}; +use crate::key::{DcKey, Fingerprint, SignedPublicKey}; use crate::message::Message; use crate::mimeparser::{MimeMessage, SystemMessage}; use crate::param::Param; @@ -355,12 +355,6 @@ async fn securejoin(context: &Context, qr: &str) -> Result { #[error("Failed sending handshake message")] pub struct SendMsgError(#[from] anyhow::Error); -impl From for SendMsgError { - fn from(source: key::Error) -> Self { - Self(anyhow::Error::new(source)) - } -} - async fn send_handshake_msg( context: &Context, contact_chat_id: ChatId, diff --git a/src/securejoin/qrinvite.rs b/src/securejoin/qrinvite.rs index 8d9204896..9a9602f06 100644 --- a/src/securejoin/qrinvite.rs +++ b/src/securejoin/qrinvite.rs @@ -9,7 +9,7 @@ use std::convert::TryFrom; use anyhow::Result; -use crate::key::{Fingerprint, FingerprintError}; +use crate::key::Fingerprint; use crate::lot::{Lot, LotState}; /// Represents the data from a QR-code scan. @@ -103,8 +103,6 @@ impl TryFrom for QrInvite { pub enum QrError { #[error("Unsupported protocol in QR-code")] UnsupportedProtocol, - #[error("Failed to read fingerprint")] - InvalidFingerprint(#[from] FingerprintError), #[error("Missing fingerprint")] MissingFingerprint, #[error("Missing invitenumber")]