From c39651a8d408e41fb9627f0d30deba794dcbed4d Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 24 Feb 2026 19:36:34 +0000 Subject: [PATCH] feat: do not read own public key from the database We can always derive it from the secret key. --- src/imex.rs | 38 ++++++++++++++++++-------------------- src/key.rs | 31 +++++++++++++++---------------- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/imex.rs b/src/imex.rs index fa371f6fe..33386aa02 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -19,7 +19,7 @@ use crate::config::Config; use crate::context::Context; use crate::e2ee; use crate::events::EventType; -use crate::key::{self, DcKey, SignedPublicKey, SignedSecretKey}; +use crate::key::{self, DcKey, SignedSecretKey}; use crate::log::{LogExt, warn}; use crate::pgp; use crate::qr::DCBACKUP_VERSION; @@ -669,38 +669,36 @@ async fn export_self_keys(context: &Context, dir: &Path) -> Result<()> { let keys = context .sql .query_map_vec( - "SELECT id, public_key, private_key, id=(SELECT value FROM config WHERE keyname='key_id') FROM keypairs;", + "SELECT id, private_key, id=(SELECT value FROM config WHERE keyname='key_id') FROM keypairs;", (), |row| { let id = row.get(0)?; - let public_key_blob: Vec = row.get(1)?; - let public_key = SignedPublicKey::from_slice(&public_key_blob); - let private_key_blob: Vec = row.get(2)?; + let private_key_blob: Vec = row.get(1)?; let private_key = SignedSecretKey::from_slice(&private_key_blob); - let is_default: i32 = row.get(3)?; + let is_default: i32 = row.get(2)?; - Ok((id, public_key, private_key, is_default)) + Ok((id, private_key, is_default)) }, ) .await?; let self_addr = context.get_primary_self_addr().await?; - for (id, public_key, private_key, is_default) in keys { + for (id, private_key, is_default) in keys { let id = Some(id).filter(|_| is_default == 0); - if let Ok(key) = public_key { - if let Err(err) = export_key_to_asc_file(context, dir, &self_addr, id, &key).await { - error!(context, "Failed to export public key: {:#}.", err); - export_errors += 1; - } - } else { + let Ok(private_key) = private_key else { + export_errors += 1; + continue; + }; + + if let Err(err) = export_key_to_asc_file(context, dir, &self_addr, id, &private_key).await { + error!(context, "Failed to export private key: {:#}.", err); export_errors += 1; } - if let Ok(key) = private_key { - if let Err(err) = export_key_to_asc_file(context, dir, &self_addr, id, &key).await { - error!(context, "Failed to export private key: {:#}.", err); - export_errors += 1; - } - } else { + + let public_key = private_key.to_public_key(); + + if let Err(err) = export_key_to_asc_file(context, dir, &self_addr, id, &public_key).await { + error!(context, "Failed to export public key: {:#}.", err); export_errors += 1; } } diff --git a/src/key.rs b/src/key.rs index edc6b5805..45a702519 100644 --- a/src/key.rs +++ b/src/key.rs @@ -122,10 +122,10 @@ pub trait DcKey: Serialize + Deserializable + Clone { /// /// Returns `None` if no key is generated yet. pub(crate) async fn load_self_public_key_opt(context: &Context) -> Result> { - let Some(public_key_bytes) = context + let Some(secret_key_bytes) = context .sql .query_row_optional( - "SELECT public_key + "SELECT private_key FROM keypairs WHERE id=(SELECT value FROM config WHERE keyname='key_id')", (), @@ -138,8 +138,9 @@ pub(crate) async fn load_self_public_key_opt(context: &Context) -> Result