diff --git a/src/decrypt.rs b/src/decrypt.rs index 0ced2671c1..475f981960 100644 --- a/src/decrypt.rs +++ b/src/decrypt.rs @@ -12,7 +12,7 @@ use crate::authres::{self, DkimResults}; use crate::contact::addr_cmp; use crate::context::Context; use crate::headerdef::{HeaderDef, HeaderDefMap}; -use crate::key::{self, DcKey, Fingerprint, SignedPublicKey, SignedSecretKey}; +use crate::key::{DcKey, Fingerprint, SignedPublicKey, SignedSecretKey}; use crate::peerstate::Peerstate; use crate::pgp; @@ -69,25 +69,26 @@ pub(crate) async fn prepare_decryption( }); } - let autocrypt_header = - if let Some(autocrypt_header_value) = mail.headers.get_header_value(HeaderDef::Autocrypt) { - match Aheader::from_str(&autocrypt_header_value) { - Ok(header) if addr_cmp(&header.addr, from) => Some(header), - Ok(header) => { - warn!( - context, - "Autocrypt header address {:?} is not {:?}.", header.addr, from - ); - None - } - Err(err) => { - warn!(context, "Failed to parse Autocrypt header: {:#}.", err); - None - } + let autocrypt_header = if context.is_self_addr(from).await? { + None + } else if let Some(aheader_value) = mail.headers.get_header_value(HeaderDef::Autocrypt) { + match Aheader::from_str(&aheader_value) { + Ok(header) if addr_cmp(&header.addr, from) => Some(header), + Ok(header) => { + warn!( + context, + "Autocrypt header address {:?} is not {:?}.", header.addr, from + ); + None } - } else { - None - }; + Err(err) => { + warn!(context, "Failed to parse Autocrypt header: {:#}.", err); + None + } + } + } else { + None + }; let dkim_results = handle_authres(context, mail, from, message_time).await?; @@ -265,21 +266,16 @@ pub(crate) fn validate_detached_signature<'a, 'b>( } /// Returns public keyring for `peerstate`. -pub(crate) async fn keyring_from_peerstate( - context: &Context, - peerstate: Option<&Peerstate>, -) -> Result> { +pub(crate) fn keyring_from_peerstate(peerstate: Option<&Peerstate>) -> Vec { let mut public_keyring_for_validate = Vec::new(); if let Some(peerstate) = peerstate { if let Some(key) = &peerstate.public_key { public_keyring_for_validate.push(key.clone()); } else if let Some(key) = &peerstate.gossip_key { public_keyring_for_validate.push(key.clone()); - } else if context.is_self_addr(&peerstate.addr).await? { - public_keyring_for_validate = key::load_self_public_keyring(context).await?; } } - Ok(public_keyring_for_validate) + public_keyring_for_validate } /// Applies Autocrypt header to Autocrypt peer state and saves it into the database. diff --git a/src/mimeparser.rs b/src/mimeparser.rs index ba13b4640f..9d6b7a9d40 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -27,7 +27,7 @@ use crate::decrypt::{ use crate::dehtml::dehtml; use crate::events::EventType; use crate::headerdef::{HeaderDef, HeaderDefMap}; -use crate::key::{load_self_secret_keyring, DcKey, Fingerprint, SignedPublicKey}; +use crate::key::{self, load_self_secret_keyring, DcKey, Fingerprint, SignedPublicKey}; use crate::message::{ self, set_msg_failed, update_msg_state, Message, MessageState, MsgId, Viewtype, }; @@ -304,8 +304,11 @@ impl MimeMessage { hop_info += "\n\n"; hop_info += &decryption_info.dkim_results.to_string(); - let public_keyring = - keyring_from_peerstate(context, decryption_info.peerstate.as_ref()).await?; + let incoming = !context.is_self_addr(&from.addr).await?; + let public_keyring = match decryption_info.peerstate.is_none() && !incoming { + true => key::load_self_public_keyring(context).await?, + false => keyring_from_peerstate(decryption_info.peerstate.as_ref()), + }; let (mail, mut signatures, encrypted) = match tokio::task::block_in_place(|| { try_decrypt(&mail, &private_keyring, &public_keyring) }) { @@ -430,7 +433,6 @@ impl MimeMessage { } } - let incoming = !context.is_self_addr(&from.addr).await?; let mut parser = MimeMessage { parts: Vec::new(), headers, diff --git a/src/peerstate.rs b/src/peerstate.rs index d44abbf3b7..609dde1211 100644 --- a/src/peerstate.rs +++ b/src/peerstate.rs @@ -16,7 +16,6 @@ use crate::message::Message; use crate::mimeparser::SystemMessage; use crate::sql::Sql; use crate::stock_str; -use crate::tools; /// Type of the public key stored inside the peerstate. #[derive(Debug)] @@ -167,7 +166,7 @@ impl Peerstate { /// Loads peerstate corresponding to the given address from the database. pub async fn from_addr(context: &Context, addr: &str) -> Result> { if context.is_self_addr(addr).await? { - return Ok(Some(Peerstate::get_self_stub(addr))); + return Ok(None); } let query = "SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, \ gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, \ @@ -212,7 +211,7 @@ impl Peerstate { addr: &str, ) -> Result> { if context.is_self_addr(addr).await? { - return Ok(Some(Peerstate::get_self_stub(addr))); + return Ok(None); } let query = "SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, \ gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, \ @@ -229,34 +228,6 @@ impl Peerstate { Self::from_stmt(context, query, (&fp, &addr, &fp)).await } - /// Returns peerstate stub for self `addr`. - /// - /// Needed for [`crate::decrypt::keyring_from_peerstate()`] which returns a keyring of all our - /// pubkeys for such a stub so that we can check if a message is signed by us. - fn get_self_stub(addr: &str) -> Self { - let now = tools::time(); - // We can have multiple pubkeys, just make the corresponding fields None. - Self { - addr: addr.to_string(), - last_seen: now, - last_seen_autocrypt: now, - prefer_encrypt: EncryptPreference::Mutual, - public_key: None, - public_key_fingerprint: None, - gossip_key: None, - gossip_key_fingerprint: None, - gossip_timestamp: 0, - verified_key: None, - verified_key_fingerprint: None, - verifier: None, - secondary_verified_key: None, - secondary_verified_key_fingerprint: None, - secondary_verifier: None, - backward_verified_key_id: None, - fingerprint_changed: false, - } - } - async fn from_stmt( context: &Context, query: &str,