mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 21:06:31 +03:00
feat: Remove detached signature validation
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
//! Helper functions for decryption.
|
//! Helper functions for decryption.
|
||||||
//! The actual decryption is done in the [`crate::pgp`] module.
|
//! The actual decryption is done in the [`crate::pgp`] module.
|
||||||
|
|
||||||
use std::collections::HashSet;
|
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use anyhow::{Context as _, Result, bail};
|
use anyhow::{Context as _, Result, bail};
|
||||||
@@ -19,8 +18,8 @@ use crate::chat::ChatId;
|
|||||||
use crate::constants::Chattype;
|
use crate::constants::Chattype;
|
||||||
use crate::contact::ContactId;
|
use crate::contact::ContactId;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
use crate::key::load_self_secret_keyring;
|
||||||
use crate::key::self_fingerprint;
|
use crate::key::self_fingerprint;
|
||||||
use crate::key::{Fingerprint, SignedPublicKey, load_self_secret_keyring};
|
|
||||||
use crate::token::Namespace;
|
use crate::token::Namespace;
|
||||||
|
|
||||||
/// Tries to decrypt the message,
|
/// Tries to decrypt the message,
|
||||||
@@ -335,36 +334,6 @@ fn get_autocrypt_mime<'a, 'b>(mail: &'a ParsedMail<'b>) -> Option<&'a ParsedMail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validates signatures of Multipart/Signed message part, as defined in RFC 1847.
|
|
||||||
///
|
|
||||||
/// Returns the signed part and the set of key
|
|
||||||
/// fingerprints for which there is a valid signature.
|
|
||||||
///
|
|
||||||
/// Returns None if the message is not Multipart/Signed or doesn't contain necessary parts.
|
|
||||||
pub(crate) fn validate_detached_signature<'a, 'b>(
|
|
||||||
mail: &'a ParsedMail<'b>,
|
|
||||||
public_keyring_for_validate: &[SignedPublicKey],
|
|
||||||
) -> Option<(&'a ParsedMail<'b>, HashSet<Fingerprint>)> {
|
|
||||||
if mail.ctype.mimetype != "multipart/signed" {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let [first_part, second_part] = &mail.subparts[..] {
|
|
||||||
// First part is the content, second part is the signature.
|
|
||||||
let content = first_part.raw_bytes;
|
|
||||||
let ret_valid_signatures = match second_part.get_body_raw() {
|
|
||||||
Ok(signature) => {
|
|
||||||
crate::pgp::pk_validate(content, &signature, public_keyring_for_validate)
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
Err(_) => Default::default(),
|
|
||||||
};
|
|
||||||
Some((first_part, ret_valid_signatures))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use crate::config::Config;
|
|||||||
use crate::constants;
|
use crate::constants;
|
||||||
use crate::contact::{ContactId, import_public_key};
|
use crate::contact::{ContactId, import_public_key};
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::decrypt::{self, validate_detached_signature};
|
use crate::decrypt::{self};
|
||||||
use crate::dehtml::dehtml;
|
use crate::dehtml::dehtml;
|
||||||
use crate::download::PostMsgMetadata;
|
use crate::download::PostMsgMetadata;
|
||||||
use crate::events::EventType;
|
use crate::events::EventType;
|
||||||
@@ -487,17 +487,6 @@ impl MimeMessage {
|
|||||||
HashMap::new()
|
HashMap::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mail = mail.as_ref().map(|mail| {
|
|
||||||
let (content, signatures_detached) = validate_detached_signature(mail, &public_keyring)
|
|
||||||
.unwrap_or((mail, Default::default()));
|
|
||||||
let signatures_detached = signatures_detached
|
|
||||||
.into_iter()
|
|
||||||
.map(|fp| (fp, Vec::new()))
|
|
||||||
.collect::<HashMap<_, _>>();
|
|
||||||
signatures.extend(signatures_detached);
|
|
||||||
content
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(expected_sender_fingerprint) = expected_sender_fingerprint {
|
if let Some(expected_sender_fingerprint) = expected_sender_fingerprint {
|
||||||
ensure!(
|
ensure!(
|
||||||
!signatures.is_empty(),
|
!signatures.is_empty(),
|
||||||
@@ -513,7 +502,7 @@ impl MimeMessage {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (Ok(mail), true) = (mail, is_encrypted) {
|
if let (Ok(mail), true) = (&mail, is_encrypted) {
|
||||||
if !signatures.is_empty() {
|
if !signatures.is_empty() {
|
||||||
// Unsigned "Subject" mustn't be prepended to messages shown as encrypted
|
// Unsigned "Subject" mustn't be prepended to messages shown as encrypted
|
||||||
// (<https://github.com/deltachat/deltachat-core-rust/issues/1790>).
|
// (<https://github.com/deltachat/deltachat-core-rust/issues/1790>).
|
||||||
@@ -538,7 +527,7 @@ impl MimeMessage {
|
|||||||
&mut inner_from,
|
&mut inner_from,
|
||||||
&mut list_post,
|
&mut list_post,
|
||||||
&mut chat_disposition_notification_to,
|
&mut chat_disposition_notification_to,
|
||||||
mail,
|
&mail,
|
||||||
);
|
);
|
||||||
|
|
||||||
if !signatures.is_empty() {
|
if !signatures.is_empty() {
|
||||||
@@ -582,7 +571,7 @@ impl MimeMessage {
|
|||||||
signatures.clear();
|
signatures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (Ok(mail), true) = (mail, is_encrypted)
|
if let (Ok(mail), true) = (&mail, is_encrypted)
|
||||||
&& let Some(post_msg_rfc724_mid) =
|
&& let Some(post_msg_rfc724_mid) =
|
||||||
mail.headers.get_header_value(HeaderDef::ChatPostMessageId)
|
mail.headers.get_header_value(HeaderDef::ChatPostMessageId)
|
||||||
{
|
{
|
||||||
@@ -640,7 +629,7 @@ impl MimeMessage {
|
|||||||
from,
|
from,
|
||||||
incoming,
|
incoming,
|
||||||
chat_disposition_notification_to,
|
chat_disposition_notification_to,
|
||||||
decryption_error: mail.err().map(|err| format!("{err:#}")),
|
decryption_error: mail.as_ref().err().map(|err| format!("{err:#}")),
|
||||||
|
|
||||||
// only non-empty if it was a valid autocrypt message
|
// only non-empty if it was a valid autocrypt message
|
||||||
signature,
|
signature,
|
||||||
@@ -666,9 +655,9 @@ impl MimeMessage {
|
|||||||
pre_message,
|
pre_message,
|
||||||
};
|
};
|
||||||
|
|
||||||
match mail {
|
match &mail {
|
||||||
Ok(mail) => {
|
Ok(mail) => {
|
||||||
parser.parse_mime_recursive(context, mail, false).await?;
|
parser.parse_mime_recursive(context, &mail, false).await?;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let txt = "[This message cannot be decrypted.\n\n• It might already help to simply reply to this message and ask the sender to send the message again.\n\n• If you just re-installed Delta Chat then it is best if you re-setup Delta Chat now and choose \"Add as second device\" or import a backup.]";
|
let txt = "[This message cannot be decrypted.\n\n• It might already help to simply reply to this message and ask the sender to send the message again.\n\n• If you just re-installed Delta Chat then it is best if you re-setup Delta Chat now and choose \"Add as second device\" or import a backup.]";
|
||||||
|
|||||||
Reference in New Issue
Block a user