mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 17:36:29 +03:00
Securejoin: Fix adding and handling Autocrypt-Gossip headers (#3836)
- If bcc_self is set, gossip headers must be added despite of the number of group members. - If another device observes Secure-Join, instead of looking for Secure-Join-Fingerprint in "vg-member-added"/"vc-contact-confirm" messages it must use keys from Autocrypt-Gossip headers as described in the Countermitm doc (https://countermitm.readthedocs.io/en/latest/new.html#joining-a-verified-group-secure-join).
This commit is contained in:
@@ -2,9 +2,13 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Securejoin: Fix adding and handling Autocrypt-Gossip headers #3914
|
||||||
|
|
||||||
### API-Changes
|
### API-Changes
|
||||||
- jsonrpc: add verified-by information to `Contact`-Object
|
- jsonrpc: add verified-by information to `Contact`-Object
|
||||||
|
|
||||||
|
|
||||||
## 1.106.0
|
## 1.106.0
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|||||||
@@ -689,7 +689,9 @@ impl<'a> MimeFactory<'a> {
|
|||||||
.fold(message, |message, header| message.header(header));
|
.fold(message, |message, header| message.header(header));
|
||||||
|
|
||||||
// Add gossip headers in chats with multiple recipients
|
// Add gossip headers in chats with multiple recipients
|
||||||
if peerstates.len() > 1 && self.should_do_gossip(context).await? {
|
if (peerstates.len() > 1 || context.get_config_bool(Config::BccSelf).await?)
|
||||||
|
&& self.should_do_gossip(context).await?
|
||||||
|
{
|
||||||
for peerstate in peerstates.iter().filter_map(|(state, _)| state.as_ref()) {
|
for peerstate in peerstates.iter().filter_map(|(state, _)| state.as_ref()) {
|
||||||
if peerstate.peek_key(min_verified).is_some() {
|
if peerstate.peek_key(min_verified).is_some() {
|
||||||
if let Some(header) = peerstate.render_gossip_header(min_verified) {
|
if let Some(header) = peerstate.render_gossip_header(min_verified) {
|
||||||
|
|||||||
@@ -579,36 +579,98 @@ pub(crate) async fn observe_securejoin_on_other_device(
|
|||||||
.await?;
|
.await?;
|
||||||
return Ok(HandshakeMessage::Ignore);
|
return Ok(HandshakeMessage::Ignore);
|
||||||
}
|
}
|
||||||
let fingerprint: Fingerprint =
|
let addr = Contact::load_from_db(context, contact_id)
|
||||||
match mime_message.get_header(HeaderDef::SecureJoinFingerprint) {
|
.await?
|
||||||
Some(fp) => fp.parse()?,
|
.get_addr()
|
||||||
|
.to_string();
|
||||||
|
if mime_message.gossiped_addr.contains(&addr) {
|
||||||
|
let mut peerstate = match Peerstate::from_addr(context, &addr).await? {
|
||||||
|
Some(p) => p,
|
||||||
None => {
|
None => {
|
||||||
could_not_establish_secure_connection(
|
could_not_establish_secure_connection(
|
||||||
context,
|
context,
|
||||||
contact_id,
|
contact_id,
|
||||||
info_chat_id(context, contact_id).await?,
|
info_chat_id(context, contact_id).await?,
|
||||||
"Fingerprint not provided, please update Delta Chat on all your devices.",
|
&format!("No peerstate in db for '{}' at step {}", &addr, step),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
return Ok(HandshakeMessage::Ignore);
|
return Ok(HandshakeMessage::Ignore);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if mark_peer_as_verified(
|
let fingerprint = match peerstate.gossip_key_fingerprint.clone() {
|
||||||
context,
|
Some(fp) => fp,
|
||||||
&fingerprint,
|
None => {
|
||||||
Contact::load_from_db(context, contact_id)
|
could_not_establish_secure_connection(
|
||||||
.await?
|
context,
|
||||||
.get_addr()
|
contact_id,
|
||||||
.to_owned(),
|
info_chat_id(context, contact_id).await?,
|
||||||
)
|
&format!(
|
||||||
.await
|
"No gossip key fingerprint in db for '{}' at step {}",
|
||||||
.is_err()
|
&addr, step,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
return Ok(HandshakeMessage::Ignore);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if peerstate.set_verified(
|
||||||
|
PeerstateKeyType::GossipKey,
|
||||||
|
&fingerprint,
|
||||||
|
PeerstateVerifiedStatus::BidirectVerified,
|
||||||
|
addr,
|
||||||
|
) {
|
||||||
|
peerstate.prefer_encrypt = EncryptPreference::Mutual;
|
||||||
|
peerstate.save_to_db(&context.sql).await.unwrap_or_default();
|
||||||
|
} else {
|
||||||
|
could_not_establish_secure_connection(
|
||||||
|
context,
|
||||||
|
contact_id,
|
||||||
|
info_chat_id(context, contact_id).await?,
|
||||||
|
&format!(
|
||||||
|
"Could not mark peer as verified for fingerprint {} at step {}",
|
||||||
|
fingerprint.hex(),
|
||||||
|
step,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
return Ok(HandshakeMessage::Ignore);
|
||||||
|
}
|
||||||
|
} else if let Some(fingerprint) =
|
||||||
|
mime_message.get_header(HeaderDef::SecureJoinFingerprint)
|
||||||
{
|
{
|
||||||
|
// FIXME: Old versions of DC send this header instead of gossips. Remove this
|
||||||
|
// eventually.
|
||||||
|
let fingerprint = fingerprint.parse()?;
|
||||||
|
if mark_peer_as_verified(
|
||||||
|
context,
|
||||||
|
&fingerprint,
|
||||||
|
Contact::load_from_db(context, contact_id)
|
||||||
|
.await?
|
||||||
|
.get_addr()
|
||||||
|
.to_owned(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
could_not_establish_secure_connection(
|
||||||
|
context,
|
||||||
|
contact_id,
|
||||||
|
info_chat_id(context, contact_id).await?,
|
||||||
|
format!("Fingerprint mismatch on observing {}.", step).as_ref(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
return Ok(HandshakeMessage::Ignore);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
could_not_establish_secure_connection(
|
could_not_establish_secure_connection(
|
||||||
context,
|
context,
|
||||||
contact_id,
|
contact_id,
|
||||||
info_chat_id(context, contact_id).await?,
|
info_chat_id(context, contact_id).await?,
|
||||||
format!("Fingerprint mismatch on observing {}.", step).as_ref(),
|
&format!(
|
||||||
|
"No gossip header for '{}' at step {}, please update Delta Chat on all \
|
||||||
|
your devices.",
|
||||||
|
&addr, step,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
return Ok(HandshakeMessage::Ignore);
|
return Ok(HandshakeMessage::Ignore);
|
||||||
|
|||||||
Reference in New Issue
Block a user