WIP, untested: Sending side of transferring the secret in member-added message

This commit is contained in:
Hocuri
2025-08-06 16:34:27 +02:00
parent 410048a9e1
commit 0978a46ab6
4 changed files with 50 additions and 4 deletions

View File

@@ -4067,7 +4067,7 @@ pub(crate) async fn add_contact_to_chat_ex(
let contact_addr = contact.get_addr().to_lowercase();
let added_by = if from_handshake && chat.is_out_broadcast() {
// The contact was added via a QR code rather than explicit user action,
// and there is added information in saying 'You added member Alice'
// and there is no useful information in saying 'You added member Alice'
// if self is the only one who can add members.
ContactId::UNDEFINED
} else {
@@ -4079,6 +4079,12 @@ pub(crate) async fn add_contact_to_chat_ex(
msg.param.set_int(Param::Arg2, from_handshake.into());
msg.param
.set_int(Param::ContactAddedRemoved, contact.id.to_u32() as i32);
if chat.is_out_broadcast() {
let secret = load_broadcast_shared_secret(context, chat_id)
.await?
.context("Failed to find broadcast shared secret")?;
msg.param.set(Param::Arg3, secret);
}
send_msg(context, chat_id, &mut msg).await?;
sync = Nosync;

View File

@@ -94,6 +94,11 @@ pub enum HeaderDef {
/// This message obsoletes the text of the message defined here by rfc724_mid.
ChatEdit,
/// The secret shared amongst all recipients of this broadcast channel,
/// used to encrypt and decrypt messages.
/// This secret is sent to a new member in the member-addition message.
ChatBroadcastSecret,
/// [Autocrypt](https://autocrypt.org/) header.
Autocrypt,
AutocryptGossip,

View File

@@ -834,7 +834,7 @@ impl MimeFactory {
}
}
if let Loaded::Message { chat, .. } = &self.loaded {
if let Loaded::Message { msg, chat } = &self.loaded {
if chat.typ == Chattype::OutBroadcast || chat.typ == Chattype::InBroadcast {
headers.push((
"List-ID",
@@ -844,6 +844,15 @@ impl MimeFactory {
))
.into(),
));
if msg.param.get_cmd() == SystemMessage::MemberAddedToGroup {
if let Some(secret) = msg.param.get(Param::Arg3) {
headers.push((
"Chat-Broadcast-Secret",
mail_builder::headers::text::Text::new(secret.to_string()).into(),
));
}
}
}
}
@@ -1024,6 +1033,15 @@ impl MimeFactory {
} else {
unprotected_headers.push(header.clone());
}
} else if header_name == "chat-broadcast-secret" {
if is_encrypted {
protected_headers.push(header.clone());
} else {
warn!(
context,
"Message is unnecrypted, not including broadcast secret"
);
}
} else if is_encrypted {
protected_headers.push(header.clone());

View File

@@ -106,12 +106,29 @@ pub enum Param {
Arg = b'E',
/// For Messages
///
/// For `BobHandshakeMsg::Request`, this is the `Secure-Join-Invitenumber` header.
///
/// For `BobHandshakeMsg::RequestWithAuth`, this is the `Secure-Join-Auth` header.
///
/// For [`SystemMessage::MultiDeviceSync`], this contains the ids that are synced.
///
/// For [`SystemMessage::MemberAddedToGroup`],
/// this is '1' if it was added because of a securejoin-handshake, and '0' otherwise.
Arg2 = b'F',
/// `Secure-Join-Fingerprint` header for `{vc,vg}-request-with-auth` messages.
/// For Messages
///
/// For `BobHandshakeMsg::RequestWithAuth`,
/// this contains the `Secure-Join-Fingerprint` header.
///
/// For [`SystemMessage::MemberAddedToGroup`] that add to a broadcast channel,
/// this contains the broadcast channel's shared secret.
Arg3 = b'G',
/// Deprecated `Secure-Join-Group` header for messages.
/// For Messages
///
/// Deprecated `Secure-Join-Group` header for `BobHandshakeMsg::RequestWithAuth` messages.
Arg4 = b'H',
/// For Messages