diff --git a/src/contact.rs b/src/contact.rs index 9492ffd09..be3bbd105 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -25,7 +25,7 @@ use crate::config::Config; use crate::constants::{Blocked, Chattype, DC_GCL_ADD_SELF, DC_GCL_VERIFIED_ONLY}; use crate::context::Context; use crate::events::EventType; -use crate::key::{DcKey, SignedPublicKey}; +use crate::key::{load_self_public_key, DcKey}; use crate::login_param::LoginParam; use crate::message::MessageState; use crate::mimeparser::AvatarAction; @@ -1009,7 +1009,7 @@ impl Contact { let finger_prints = stock_str::finger_prints(context).await; ret += &format!("{stock_message}.\n{finger_prints}:"); - let fingerprint_self = SignedPublicKey::load_self(context) + let fingerprint_self = load_self_public_key(context) .await? .fingerprint() .to_string(); diff --git a/src/context.rs b/src/context.rs index 8209f445f..a6d649c76 100644 --- a/src/context.rs +++ b/src/context.rs @@ -19,7 +19,7 @@ use crate::constants::DC_VERSION_STR; use crate::contact::Contact; use crate::debug_logging::DebugLogging; use crate::events::{Event, EventEmitter, EventType, Events}; -use crate::key::{DcKey, SignedPublicKey}; +use crate::key::{load_self_public_key, DcKey as _}; use crate::login_param::LoginParam; use crate::message::{self, MessageState, MsgId}; use crate::quota::QuotaInfo; @@ -580,7 +580,7 @@ impl Context { .sql .count("SELECT COUNT(*) FROM acpeerstates;", ()) .await?; - let fingerprint_str = match SignedPublicKey::load_self(self).await { + let fingerprint_str = match load_self_public_key(self).await { Ok(key) => key.fingerprint().hex(), Err(err) => format!(""), }; diff --git a/src/e2ee.rs b/src/e2ee.rs index 2addaf56d..6a966b488 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -6,7 +6,7 @@ use num_traits::FromPrimitive; use crate::aheader::{Aheader, EncryptPreference}; use crate::config::Config; use crate::context::Context; -use crate::key::{DcKey, SignedPublicKey, SignedSecretKey}; +use crate::key::{load_self_public_key, load_self_secret_key, SignedPublicKey}; use crate::peerstate::{Peerstate, PeerstateVerifiedStatus}; use crate::pgp; @@ -23,7 +23,7 @@ impl EncryptHelper { EncryptPreference::from_i32(context.get_config_int(Config::E2eeEnabled).await?) .unwrap_or_default(); let addr = context.get_primary_self_addr().await?; - let public_key = SignedPublicKey::load_self(context).await?; + let public_key = load_self_public_key(context).await?; Ok(EncryptHelper { prefer_encrypt, @@ -115,7 +115,7 @@ impl EncryptHelper { keyring.push(key); } keyring.push(self.public_key.clone()); - let sign_key = SignedSecretKey::load_self(context).await?; + let sign_key = load_self_secret_key(context).await?; let raw_message = mail_to_encrypt.build().as_string().into_bytes(); @@ -131,7 +131,7 @@ impl EncryptHelper { context: &Context, mail: lettre_email::PartBuilder, ) -> Result<(lettre_email::MimeMessage, String)> { - let sign_key = SignedSecretKey::load_self(context).await?; + let sign_key = load_self_secret_key(context).await?; let mime_message = mail.build(); let signature = pgp::pk_calc_signature(mime_message.as_string().as_bytes(), &sign_key)?; Ok((mime_message, signature)) @@ -146,7 +146,7 @@ impl EncryptHelper { /// private key will be present. // TODO, remove this once deltachat::key::Key no longer exists. pub async fn ensure_secret_key_exists(context: &Context) -> Result<()> { - SignedPublicKey::load_self(context).await?; + load_self_public_key(context).await?; Ok(()) } @@ -154,6 +154,7 @@ pub async fn ensure_secret_key_exists(context: &Context) -> Result<()> { mod tests { use super::*; use crate::chat; + use crate::key::DcKey; use crate::message::{Message, Viewtype}; use crate::param::Param; use crate::test_utils::{bob_keypair, TestContext}; diff --git a/src/imex.rs b/src/imex.rs index f7f0dcfb1..94c9c97a5 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -19,7 +19,9 @@ use crate::contact::ContactId; use crate::context::Context; use crate::e2ee; use crate::events::EventType; -use crate::key::{self, DcKey, DcSecretKey, SignedPublicKey, SignedSecretKey}; +use crate::key::{ + self, load_self_secret_key, DcKey, DcSecretKey, SignedPublicKey, SignedSecretKey, +}; use crate::log::LogExt; use crate::message::{Message, MsgId, Viewtype}; use crate::mimeparser::SystemMessage; @@ -186,7 +188,7 @@ pub async fn render_setup_file(context: &Context, passphrase: &str) -> Result None, true => Some(("Autocrypt-Prefer-Encrypt", "mutual")), diff --git a/src/key.rs b/src/key.rs index 8f2be2d83..9e2076bc6 100644 --- a/src/key.rs +++ b/src/key.rs @@ -3,11 +3,9 @@ use std::collections::BTreeMap; use std::fmt; use std::io::Cursor; -use std::pin::Pin; use anyhow::{ensure, Context as _, Result}; use base64::Engine as _; -use futures::Future; use num_traits::FromPrimitive; use pgp::composed::Deserializable; pub use pgp::composed::{SignedPublicKey, SignedSecretKey}; @@ -49,11 +47,6 @@ pub trait DcKey: Serialize + Deserializable + KeyTrait + Clone { Self::from_armor_single(Cursor::new(bytes)).context("rPGP error") } - /// Load the users' default key from the database. - fn load_self<'a>( - context: &'a Context, - ) -> Pin> + 'a + Send>>; - /// Serialise the key as bytes. fn to_bytes(&self) -> Vec { // Not using Serialize::to_bytes() to make clear *why* it is @@ -84,38 +77,55 @@ pub trait DcKey: Serialize + Deserializable + KeyTrait + Clone { } } -impl DcKey for SignedPublicKey { - fn load_self<'a>( - context: &'a Context, - ) -> Pin> + 'a + Send>> { - Box::pin(async move { - let addr = context.get_primary_self_addr().await?; - match context - .sql - .query_row_optional( - r#" - SELECT public_key - FROM keypairs - WHERE addr=? - AND is_default=1; - "#, - (addr,), - |row| { - let bytes: Vec = row.get(0)?; - Ok(bytes) - }, - ) - .await? - { - Some(bytes) => Self::from_slice(&bytes), - None => { - let keypair = generate_keypair(context).await?; - Ok(keypair.public) - } - } - }) +pub(crate) async fn load_self_public_key(context: &Context) -> Result { + match context + .sql + .query_row_optional( + r#"SELECT public_key + FROM keypairs + WHERE addr=(SELECT value FROM config WHERE keyname="configured_addr") + AND is_default=1"#, + (), + |row| { + let bytes: Vec = row.get(0)?; + Ok(bytes) + }, + ) + .await? + { + Some(bytes) => SignedPublicKey::from_slice(&bytes), + None => { + let keypair = generate_keypair(context).await?; + Ok(keypair.public) + } } +} +pub(crate) async fn load_self_secret_key(context: &Context) -> Result { + match context + .sql + .query_row_optional( + r#"SELECT private_key + FROM keypairs + WHERE addr=(SELECT value FROM config WHERE keyname="configured_addr") + AND is_default=1"#, + (), + |row| { + let bytes: Vec = row.get(0)?; + Ok(bytes) + }, + ) + .await? + { + Some(bytes) => SignedSecretKey::from_slice(&bytes), + None => { + let keypair = generate_keypair(context).await?; + Ok(keypair.secret) + } + } +} + +impl DcKey for SignedPublicKey { fn to_asc(&self, header: Option<(&str, &str)>) -> String { // Not using .to_armored_string() to make clear *why* it is // safe to ignore this error. @@ -134,36 +144,6 @@ impl DcKey for SignedPublicKey { } impl DcKey for SignedSecretKey { - fn load_self<'a>( - context: &'a Context, - ) -> Pin> + 'a + Send>> { - Box::pin(async move { - match context - .sql - .query_row_optional( - r#" - SELECT private_key - FROM keypairs - WHERE addr=(SELECT value FROM config WHERE keyname="configured_addr") - AND is_default=1; - "#, - (), - |row| { - let bytes: Vec = row.get(0)?; - Ok(bytes) - }, - ) - .await? - { - Some(bytes) => Self::from_slice(&bytes), - None => { - let keypair = generate_keypair(context).await?; - Ok(keypair.secret) - } - } - }) - } - fn to_asc(&self, header: Option<(&str, &str)>) -> String { // Not using .to_armored_string() to make clear *why* it is // safe to do these unwraps. @@ -521,9 +501,9 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD async fn test_load_self_existing() { let alice = alice_keypair(); let t = TestContext::new_alice().await; - let pubkey = SignedPublicKey::load_self(&t).await.unwrap(); + let pubkey = load_self_public_key(&t).await.unwrap(); assert_eq!(alice.public, pubkey); - let seckey = SignedSecretKey::load_self(&t).await.unwrap(); + let seckey = load_self_secret_key(&t).await.unwrap(); assert_eq!(alice.secret, seckey); } @@ -533,7 +513,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) .await .unwrap(); - let key = SignedPublicKey::load_self(&t).await; + let key = load_self_public_key(&t).await; assert!(key.is_ok()); } @@ -543,7 +523,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) .await .unwrap(); - let key = SignedSecretKey::load_self(&t).await; + let key = load_self_secret_key(&t).await; assert!(key.is_ok()); } @@ -560,7 +540,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD thread::spawn(move || { tokio::runtime::Runtime::new() .unwrap() - .block_on(SignedPublicKey::load_self(&ctx)) + .block_on(load_self_public_key(&ctx)) }) }; let thr1 = { @@ -568,7 +548,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD thread::spawn(move || { tokio::runtime::Runtime::new() .unwrap() - .block_on(SignedPublicKey::load_self(&ctx)) + .block_on(load_self_public_key(&ctx)) }) }; let res0 = thr0.join().unwrap(); diff --git a/src/mimeparser.rs b/src/mimeparser.rs index bd0879398..50678419b 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::{DcKey, Fingerprint, SignedPublicKey, SignedSecretKey}; +use crate::key::{load_self_secret_key, DcKey, Fingerprint, SignedPublicKey}; use crate::message::{self, set_msg_failed, update_msg_state, MessageState, MsgId, Viewtype}; use crate::param::{Param, Params}; use crate::peerstate::Peerstate; @@ -275,7 +275,7 @@ impl MimeMessage { headers.remove("chat-verified"); let from = from.context("No from in message")?; - let private_keyring = vec![SignedSecretKey::load_self(context) + let private_keyring = vec![load_self_secret_key(context) .await .context("Failed to get own key")?]; diff --git a/src/securejoin.rs b/src/securejoin.rs index ba4b9743c..1312dec66 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -14,7 +14,7 @@ use crate::context::Context; use crate::e2ee::ensure_secret_key_exists; use crate::events::EventType; use crate::headerdef::HeaderDef; -use crate::key::{DcKey, Fingerprint, SignedPublicKey}; +use crate::key::{load_self_public_key, DcKey, Fingerprint}; use crate::message::{Message, Viewtype}; use crate::mimeparser::{MimeMessage, SystemMessage}; use crate::param::Param; @@ -130,7 +130,7 @@ pub async fn get_securejoin_qr(context: &Context, group: Option) -> Resu } async fn get_self_fingerprint(context: &Context) -> Option { - match SignedPublicKey::load_self(context).await { + match load_self_public_key(context).await { Ok(key) => Some(key.fingerprint()), Err(_) => { warn!(context, "get_self_fingerprint(): failed to load key"); @@ -884,10 +884,7 @@ mod tests { "vc-request-with-auth" ); assert!(msg.get_header(HeaderDef::SecureJoinAuth).is_some()); - let bob_fp = SignedPublicKey::load_self(&bob.ctx) - .await - .unwrap() - .fingerprint(); + let bob_fp = load_self_public_key(&bob.ctx).await.unwrap().fingerprint(); assert_eq!( *msg.get_header(HeaderDef::SecureJoinFingerprint).unwrap(), bob_fp.hex() @@ -1029,7 +1026,7 @@ mod tests { let bob = tcm.bob().await; // Ensure Bob knows Alice_FP - let alice_pubkey = SignedPublicKey::load_self(&alice.ctx).await?; + let alice_pubkey = load_self_public_key(&alice.ctx).await?; let peerstate = Peerstate { addr: "alice@example.org".into(), last_seen: 10, @@ -1083,7 +1080,7 @@ mod tests { "vc-request-with-auth" ); assert!(msg.get_header(HeaderDef::SecureJoinAuth).is_some()); - let bob_fp = SignedPublicKey::load_self(&bob.ctx).await?.fingerprint(); + let bob_fp = load_self_public_key(&bob.ctx).await?.fingerprint(); assert_eq!( *msg.get_header(HeaderDef::SecureJoinFingerprint).unwrap(), bob_fp.hex() @@ -1254,7 +1251,7 @@ mod tests { "vg-request-with-auth" ); assert!(msg.get_header(HeaderDef::SecureJoinAuth).is_some()); - let bob_fp = SignedPublicKey::load_self(&bob.ctx).await?.fingerprint(); + let bob_fp = load_self_public_key(&bob.ctx).await?.fingerprint(); assert_eq!( *msg.get_header(HeaderDef::SecureJoinFingerprint).unwrap(), bob_fp.hex() diff --git a/src/securejoin/bobstate.rs b/src/securejoin/bobstate.rs index 2c48c54f2..b46b45bed 100644 --- a/src/securejoin/bobstate.rs +++ b/src/securejoin/bobstate.rs @@ -17,7 +17,7 @@ use crate::contact::{Contact, Origin}; use crate::context::Context; use crate::events::EventType; use crate::headerdef::HeaderDef; -use crate::key::{DcKey, SignedPublicKey}; +use crate::key::{load_self_public_key, DcKey}; use crate::message::{Message, Viewtype}; use crate::mimeparser::{MimeMessage, SystemMessage}; use crate::param::Param; @@ -448,7 +448,7 @@ async fn send_handshake_message( }; // Sends our own fingerprint in the Secure-Join-Fingerprint header. - let bob_fp = SignedPublicKey::load_self(context).await?.fingerprint(); + let bob_fp = load_self_public_key(context).await?.fingerprint(); msg.param.set(Param::Arg3, bob_fp.hex()); // Sends the grpid in the Secure-Join-Group header.