feat: do not read own public key from the database

We can always derive it from the secret key.
This commit is contained in:
link2xt
2026-02-24 19:36:34 +00:00
committed by l
parent 8230336936
commit c39651a8d4
2 changed files with 33 additions and 36 deletions

View File

@@ -19,7 +19,7 @@ use crate::config::Config;
use crate::context::Context; use crate::context::Context;
use crate::e2ee; use crate::e2ee;
use crate::events::EventType; use crate::events::EventType;
use crate::key::{self, DcKey, SignedPublicKey, SignedSecretKey}; use crate::key::{self, DcKey, SignedSecretKey};
use crate::log::{LogExt, warn}; use crate::log::{LogExt, warn};
use crate::pgp; use crate::pgp;
use crate::qr::DCBACKUP_VERSION; use crate::qr::DCBACKUP_VERSION;
@@ -669,38 +669,36 @@ async fn export_self_keys(context: &Context, dir: &Path) -> Result<()> {
let keys = context let keys = context
.sql .sql
.query_map_vec( .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| { |row| {
let id = row.get(0)?; let id = row.get(0)?;
let public_key_blob: Vec<u8> = row.get(1)?; let private_key_blob: Vec<u8> = row.get(1)?;
let public_key = SignedPublicKey::from_slice(&public_key_blob);
let private_key_blob: Vec<u8> = row.get(2)?;
let private_key = SignedSecretKey::from_slice(&private_key_blob); 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?; .await?;
let self_addr = context.get_primary_self_addr().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); let id = Some(id).filter(|_| is_default == 0);
if let Ok(key) = public_key { let Ok(private_key) = private_key else {
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; export_errors += 1;
} continue;
} else { };
export_errors += 1;
} if let Err(err) = export_key_to_asc_file(context, dir, &self_addr, id, &private_key).await {
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); error!(context, "Failed to export private key: {:#}.", err);
export_errors += 1; 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; export_errors += 1;
} }
} }

View File

@@ -122,10 +122,10 @@ pub trait DcKey: Serialize + Deserializable + Clone {
/// ///
/// Returns `None` if no key is generated yet. /// Returns `None` if no key is generated yet.
pub(crate) async fn load_self_public_key_opt(context: &Context) -> Result<Option<SignedPublicKey>> { pub(crate) async fn load_self_public_key_opt(context: &Context) -> Result<Option<SignedPublicKey>> {
let Some(public_key_bytes) = context let Some(secret_key_bytes) = context
.sql .sql
.query_row_optional( .query_row_optional(
"SELECT public_key "SELECT private_key
FROM keypairs FROM keypairs
WHERE id=(SELECT value FROM config WHERE keyname='key_id')", 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<Option
else { else {
return Ok(None); return Ok(None);
}; };
let public_key = SignedPublicKey::from_slice(&public_key_bytes)?; let signed_secret_key = SignedSecretKey::from_slice(&secret_key_bytes)?;
Ok(Some(public_key)) let signed_public_key = signed_secret_key.to_public_key();
Ok(Some(signed_public_key))
} }
/// Loads own public key. /// Loads own public key.
@@ -325,26 +326,24 @@ pub(crate) async fn load_keypair(context: &Context) -> Result<Option<KeyPair>> {
let res = context let res = context
.sql .sql
.query_row_optional( .query_row_optional(
"SELECT public_key, private_key "SELECT private_key
FROM keypairs FROM keypairs
WHERE id=(SELECT value FROM config WHERE keyname='key_id')", WHERE id=(SELECT value FROM config WHERE keyname='key_id')",
(), (),
|row| { |row| {
let pub_bytes: Vec<u8> = row.get(0)?; let sec_bytes: Vec<u8> = row.get(0)?;
let sec_bytes: Vec<u8> = row.get(1)?; Ok(sec_bytes)
Ok((pub_bytes, sec_bytes))
}, },
) )
.await?; .await?;
Ok(if let Some((pub_bytes, sec_bytes)) = res { let signed_secret_key = if let Some(sec_bytes) = res {
Some(KeyPair { Some(SignedSecretKey::from_slice(&sec_bytes)?)
public: SignedPublicKey::from_slice(&pub_bytes)?,
secret: SignedSecretKey::from_slice(&sec_bytes)?,
})
} else { } else {
None None
}) };
Ok(signed_secret_key.map(KeyPair::new))
} }
/// Store the keypair as an owned keypair for addr in the database. /// Store the keypair as an owned keypair for addr in the database.