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::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<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_blob: Vec<u8> = 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;
}
}

View File

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