Skip to content

Commit f1688d2

Browse files
authored
fix: Mark the gossip keys from the message as verified, not the ones from the db (#5247)
1 parent 693045b commit f1688d2

File tree

4 files changed

+54
-63
lines changed

4 files changed

+54
-63
lines changed

src/mimeparser.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,10 @@ pub(crate) struct MimeMessage {
8282
/// If a message is not encrypted or the signature is not valid,
8383
/// this set is empty.
8484
pub signatures: HashSet<Fingerprint>,
85-
/// The set of mail recipient addresses for which gossip headers were applied, regardless of
86-
/// whether they modified any peerstates.
87-
pub gossiped_addr: HashSet<String>,
85+
/// The mail recipient addresses for which gossip headers were applied
86+
/// and their respective gossiped keys,
87+
/// regardless of whether they modified any peerstates.
88+
pub gossiped_keys: HashMap<String, SignedPublicKey>,
8889

8990
/// True if the message is a forwarded message.
9091
pub is_forwarded: bool,
@@ -282,7 +283,7 @@ impl MimeMessage {
282283

283284
// Memory location for a possible decrypted message.
284285
let mut mail_raw = Vec::new();
285-
let mut gossiped_addr = Default::default();
286+
let mut gossiped_keys = Default::default();
286287
let mut from_is_signed = false;
287288
hop_info += "\n\n";
288289
hop_info += &decryption_info.dkim_results.to_string();
@@ -322,7 +323,7 @@ impl MimeMessage {
322323
// but only if the mail was correctly signed. Probably it's ok to not require
323324
// encryption here, but let's follow the standard.
324325
let gossip_headers = mail.headers.get_all_values("Autocrypt-Gossip");
325-
gossiped_addr = update_gossip_peerstates(
326+
gossiped_keys = update_gossip_peerstates(
326327
context,
327328
message_time,
328329
&from.addr,
@@ -413,7 +414,7 @@ impl MimeMessage {
413414

414415
// only non-empty if it was a valid autocrypt message
415416
signatures,
416-
gossiped_addr,
417+
gossiped_keys,
417418
is_forwarded: false,
418419
mdn_reports: Vec::new(),
419420
is_system_message: SystemMessage::Unknown,
@@ -1728,9 +1729,9 @@ async fn update_gossip_peerstates(
17281729
from: &str,
17291730
recipients: &[SingleInfo],
17301731
gossip_headers: Vec<String>,
1731-
) -> Result<HashSet<String>> {
1732+
) -> Result<HashMap<String, SignedPublicKey>> {
17321733
// XXX split the parsing from the modification part
1733-
let mut gossiped_addr: HashSet<String> = Default::default();
1734+
let mut gossiped_keys: HashMap<String, SignedPublicKey> = Default::default();
17341735

17351736
for value in &gossip_headers {
17361737
let header = match value.parse::<Aheader>() {
@@ -1774,10 +1775,10 @@ async fn update_gossip_peerstates(
17741775
.handle_fingerprint_change(context, message_time)
17751776
.await?;
17761777

1777-
gossiped_addr.insert(header.addr.to_lowercase());
1778+
gossiped_keys.insert(header.addr.to_lowercase(), header.public_key);
17781779
}
17791780

1780-
Ok(gossiped_addr)
1781+
Ok(gossiped_keys)
17811782
}
17821783

17831784
/// Message Disposition Notification (RFC 8098)

src/peerstate.rs

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -457,59 +457,44 @@ impl Peerstate {
457457
Ok(backward_verified)
458458
}
459459

460-
/// Set this peerstate to verified
461-
/// Make sure to call `self.save_to_db` to save these changes
460+
/// Set this peerstate to verified;
461+
/// make sure to call `self.save_to_db` to save these changes.
462+
///
462463
/// Params:
463-
/// verifier:
464+
///
465+
/// * key: The new verified key.
466+
/// * fingerprint: Only set to verified if the key's fingerprint matches this.
467+
/// * verifier:
464468
/// The address which introduces the given contact.
465469
/// If we are verifying the contact, use that contacts address.
466470
pub fn set_verified(
467471
&mut self,
468-
which_key: PeerstateKeyType,
472+
key: SignedPublicKey,
469473
fingerprint: Fingerprint,
470474
verifier: String,
471475
) -> Result<()> {
472-
match which_key {
473-
PeerstateKeyType::PublicKey => {
474-
if self.public_key_fingerprint.is_some()
475-
&& self.public_key_fingerprint.as_ref().unwrap() == &fingerprint
476-
{
477-
self.verified_key = self.public_key.clone();
478-
self.verified_key_fingerprint = Some(fingerprint);
479-
self.verifier = Some(verifier);
480-
Ok(())
481-
} else {
482-
Err(Error::msg(format!(
483-
"{fingerprint} is not peer's public key fingerprint",
484-
)))
485-
}
486-
}
487-
PeerstateKeyType::GossipKey => {
488-
if self.gossip_key_fingerprint.is_some()
489-
&& self.gossip_key_fingerprint.as_ref().unwrap() == &fingerprint
490-
{
491-
self.verified_key = self.gossip_key.clone();
492-
self.verified_key_fingerprint = Some(fingerprint);
493-
self.verifier = Some(verifier);
494-
Ok(())
495-
} else {
496-
Err(Error::msg(format!(
497-
"{fingerprint} is not peer's gossip key fingerprint",
498-
)))
499-
}
500-
}
476+
if key.fingerprint() == fingerprint {
477+
self.verified_key = Some(key);
478+
self.verified_key_fingerprint = Some(fingerprint);
479+
self.verifier = Some(verifier);
480+
Ok(())
481+
} else {
482+
Err(Error::msg(format!(
483+
"{fingerprint} is not peer's key fingerprint",
484+
)))
501485
}
502486
}
503487

504-
/// Sets current gossiped key as the secondary verified key.
488+
/// Sets the gossiped key as the secondary verified key.
505489
///
506490
/// If gossiped key is the same as the current verified key,
507491
/// do nothing to avoid overwriting secondary verified key
508492
/// which may be different.
509-
pub fn set_secondary_verified_key_from_gossip(&mut self, verifier: String) {
510-
if self.gossip_key_fingerprint != self.verified_key_fingerprint {
511-
self.secondary_verified_key = self.gossip_key.clone();
512-
self.secondary_verified_key_fingerprint = self.gossip_key_fingerprint.clone();
493+
pub fn set_secondary_verified_key(&mut self, gossip_key: SignedPublicKey, verifier: String) {
494+
let fingerprint = gossip_key.fingerprint();
495+
if self.verified_key_fingerprint.as_ref() != Some(&fingerprint) {
496+
self.secondary_verified_key = Some(gossip_key);
497+
self.secondary_verified_key_fingerprint = Some(fingerprint);
513498
self.secondary_verifier = Some(verifier);
514499
}
515500
}

src/receive_imf.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::message::{
3131
};
3232
use crate::mimeparser::{parse_message_ids, AvatarAction, MimeMessage, SystemMessage};
3333
use crate::param::{Param, Params};
34-
use crate::peerstate::{Peerstate, PeerstateKeyType};
34+
use crate::peerstate::Peerstate;
3535
use crate::reaction::{set_msg_reaction, Reaction};
3636
use crate::securejoin::{self, handle_securejoin_handshake, observe_securejoin_on_other_device};
3737
use crate::simplify;
@@ -440,7 +440,7 @@ pub(crate) async fn receive_imf_inner(
440440
&& mime_parser
441441
.recipients
442442
.iter()
443-
.all(|recipient| mime_parser.gossiped_addr.contains(&recipient.addr))
443+
.all(|recipient| mime_parser.gossiped_keys.contains_key(&recipient.addr))
444444
{
445445
info!(
446446
context,
@@ -2572,7 +2572,7 @@ async fn mark_recipients_as_verified(
25722572

25732573
for (to_addr, is_verified) in rows {
25742574
// mark gossiped keys (if any) as verified
2575-
if mimeparser.gossiped_addr.contains(&to_addr.to_lowercase()) {
2575+
if let Some(gossiped_key) = mimeparser.gossiped_keys.get(&to_addr.to_lowercase()) {
25762576
if let Some(mut peerstate) = Peerstate::from_addr(context, &to_addr).await? {
25772577
// If we're here, we know the gossip key is verified.
25782578
//
@@ -2587,7 +2587,7 @@ async fn mark_recipients_as_verified(
25872587
if !is_verified {
25882588
info!(context, "{verifier_addr} has verified {to_addr}.");
25892589
if let Some(fp) = peerstate.gossip_key_fingerprint.clone() {
2590-
peerstate.set_verified(PeerstateKeyType::GossipKey, fp, verifier_addr)?;
2590+
peerstate.set_verified(gossiped_key.clone(), fp, verifier_addr)?;
25912591
peerstate.backward_verified_key_id =
25922592
Some(context.get_config_i64(Config::KeyId).await?).filter(|&id| id > 0);
25932593
peerstate.save_to_db(&context.sql).await?;
@@ -2609,7 +2609,7 @@ async fn mark_recipients_as_verified(
26092609
} else {
26102610
// The contact already has a verified key.
26112611
// Store gossiped key as the secondary verified key.
2612-
peerstate.set_secondary_verified_key_from_gossip(verifier_addr);
2612+
peerstate.set_secondary_verified_key(gossiped_key.clone(), verifier_addr);
26132613
peerstate.save_to_db(&context.sql).await?;
26142614
}
26152615
}

src/securejoin.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::key::{load_self_public_key, DcKey, Fingerprint};
1818
use crate::message::{Message, Viewtype};
1919
use crate::mimeparser::{MimeMessage, SystemMessage};
2020
use crate::param::Param;
21-
use crate::peerstate::{Peerstate, PeerstateKeyType};
21+
use crate::peerstate::Peerstate;
2222
use crate::qr::check_qr;
2323
use crate::securejoin::bob::JoinerProgress;
2424
use crate::stock_str;
@@ -229,11 +229,13 @@ async fn verify_sender_by_fingerprint(
229229
.filter(|&fp| fp == fingerprint)
230230
.is_some()
231231
{
232-
let verifier = contact.get_addr().to_owned();
233-
peerstate.set_verified(PeerstateKeyType::PublicKey, fingerprint.clone(), verifier)?;
234-
peerstate.prefer_encrypt = EncryptPreference::Mutual;
235-
peerstate.save_to_db(&context.sql).await?;
236-
return Ok(true);
232+
if let Some(public_key) = &peerstate.public_key {
233+
let verifier = contact.get_addr().to_owned();
234+
peerstate.set_verified(public_key.clone(), fingerprint.clone(), verifier)?;
235+
peerstate.prefer_encrypt = EncryptPreference::Mutual;
236+
peerstate.save_to_db(&context.sql).await?;
237+
return Ok(true);
238+
}
237239
}
238240
}
239241

@@ -599,7 +601,7 @@ pub(crate) async fn observe_securejoin_on_other_device(
599601
.get_addr()
600602
.to_lowercase();
601603

602-
if !mime_message.gossiped_addr.contains(&addr) {
604+
let Some(key) = mime_message.gossiped_keys.get(&addr) else {
603605
could_not_establish_secure_connection(
604606
context,
605607
contact_id,
@@ -612,7 +614,7 @@ pub(crate) async fn observe_securejoin_on_other_device(
612614
)
613615
.await?;
614616
return Ok(HandshakeMessage::Ignore);
615-
}
617+
};
616618

617619
let Some(mut peerstate) = Peerstate::from_addr(context, &addr).await? else {
618620
could_not_establish_secure_connection(
@@ -638,7 +640,7 @@ pub(crate) async fn observe_securejoin_on_other_device(
638640
.await?;
639641
return Ok(HandshakeMessage::Ignore);
640642
};
641-
peerstate.set_verified(PeerstateKeyType::GossipKey, fingerprint, addr)?;
643+
peerstate.set_verified(key.clone(), fingerprint, addr)?;
642644
peerstate.prefer_encrypt = EncryptPreference::Mutual;
643645
peerstate.save_to_db(&context.sql).await?;
644646

@@ -714,7 +716,10 @@ async fn mark_peer_as_verified(
714716
let Some(ref mut peerstate) = Peerstate::from_fingerprint(context, &fingerprint).await? else {
715717
return Ok(false);
716718
};
717-
peerstate.set_verified(PeerstateKeyType::PublicKey, fingerprint, verifier)?;
719+
let Some(ref public_key) = peerstate.public_key else {
720+
return Ok(false);
721+
};
722+
peerstate.set_verified(public_key.clone(), fingerprint, verifier)?;
718723
peerstate.prefer_encrypt = EncryptPreference::Mutual;
719724
if backward_verified {
720725
peerstate.backward_verified_key_id =

0 commit comments

Comments
 (0)