feat: use privacy-preserving webxdc addresses (#6237)

this PR adds the address to be used by the UI for
`window.webxdc.selfAddr` to webxdc-info. UIs need to be changed
accordingly and must not use configured_addr any longer.

the address is created by sha256(private-key + rfc724_mid) , which
results in different addresses for each webxdc, without the option to
find out the real address of the user.

this also returns the same address for a multi-device-setup - sending
totally random self address around might be an alternative, however
would require connectivity (both devices may be offline on first start).

for existing app, after the change, there will be a new user, resulting
eg. in a new highscore, otherwise, things should be mostly fine. this
assumption is also important as we might change the thing another time
when it comes to multi-transport.

ftr, addresses look like
`0f187e3f420748b03e3da76543e9a84ecff822687ce7e94f250c04c7c50398bc` now

when this is merged, we need to adapt #6230 and file issues for all UI
to use `info.selfAddr`

closes #6216
This commit is contained in:
bjoern
2024-11-21 19:00:29 +01:00
committed by GitHub
parent 75e1517dcc
commit 8a0c913bbd
7 changed files with 42 additions and 2 deletions

View File

@@ -30,12 +30,14 @@ use lettre_email::PartBuilder;
use rusqlite::OptionalExtension;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use sha2::{Digest, Sha256};
use crate::chat::{self, Chat};
use crate::constants::Chattype;
use crate::contact::ContactId;
use crate::context::Context;
use crate::events::EventType;
use crate::key::{load_self_public_key, DcKey};
use crate::message::{Message, MessageState, MsgId, Viewtype};
use crate::mimefactory::wrapped_base64_encode;
use crate::mimeparser::SystemMessage;
@@ -97,6 +99,9 @@ pub struct WebxdcInfo {
/// It should request access, be encrypted
/// and sent to self for this.
pub internet_access: bool,
/// Address to be used for `window.webxdc.selfAddr` in JS land.
pub self_addr: String,
}
/// Status Update ID.
@@ -872,6 +877,8 @@ impl Message {
&& self.chat_id.is_self_talk(context).await.unwrap_or_default()
&& self.get_showpadlock();
let self_addr = self.get_webxdc_self_addr(context).await?;
Ok(WebxdcInfo {
name: if let Some(name) = manifest.name {
name
@@ -904,8 +911,16 @@ impl Message {
"".to_string()
},
internet_access,
self_addr,
})
}
async fn get_webxdc_self_addr(&self, context: &Context) -> Result<String> {
let fingerprint = load_self_public_key(context).await?.dc_fingerprint().hex();
let data = format!("{}-{}", fingerprint, self.rfc724_mid);
let hash = Sha256::digest(data.as_bytes());
Ok(format!("{:x}", hash))
}
}
#[cfg(test)]
@@ -2288,6 +2303,23 @@ sth_for_the = "future""#
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_webxdc_self_addr() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let info1 = instance.get_webxdc_info(&t).await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let info2 = instance.get_webxdc_info(&t).await?;
let real_addr = t.get_primary_self_addr().await?;
assert!(!info1.self_addr.contains(&real_addr));
assert_ne!(info1.self_addr, info2.self_addr);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_webxdc_info_summary() -> Result<()> {
let alice = TestContext::new_alice().await;