summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--melib/src/email/attachment_types.rs3
-rw-r--r--melib/src/email/attachments.rs11
-rw-r--r--melib/src/email/pgp.rs19
-rw-r--r--src/components/mail/pgp.rs3
-rw-r--r--src/components/mail/view.rs4
-rw-r--r--src/components/mail/view/envelope.rs12
6 files changed, 29 insertions, 23 deletions
diff --git a/melib/src/email/attachment_types.rs b/melib/src/email/attachment_types.rs
index 0dcf5dbb..74d4e1fb 100644
--- a/melib/src/email/attachment_types.rs
+++ b/melib/src/email/attachment_types.rs
@@ -198,6 +198,7 @@ pub enum ContentType {
},
MessageRfc822,
PGPSignature,
+ CMSSignature,
Other {
tag: Vec<u8>,
name: Option<String>,
@@ -275,6 +276,7 @@ impl PartialEq<&str> for ContentType {
"multipart/signed",
) => true,
(ContentType::PGPSignature, "application/pgp-signature") => true,
+ (ContentType::CMSSignature, "application/pkcs7-signature") => true,
(ContentType::MessageRfc822, "message/rfc822") => true,
(ContentType::Other { tag, .. }, _) => {
other.eq_ignore_ascii_case(&String::from_utf8_lossy(&tag))
@@ -292,6 +294,7 @@ impl Display for ContentType {
ContentType::Multipart { kind: k, .. } => k.fmt(f),
ContentType::Other { ref tag, .. } => write!(f, "{}", String::from_utf8_lossy(tag)),
ContentType::PGPSignature => write!(f, "application/pgp-signature"),
+ ContentType::CMSSignature => write!(f, "application/pkcs7-signature"),
ContentType::MessageRfc822 => write!(f, "message/rfc822"),
ContentType::OctetStream { .. } => write!(f, "application/octet-stream"),
}
diff --git a/melib/src/email/attachments.rs b/melib/src/email/attachments.rs
index 6c6c4aa4..964183ba 100644
--- a/melib/src/email/attachments.rs
+++ b/melib/src/email/attachments.rs
@@ -202,6 +202,10 @@ impl AttachmentBuilder {
&& cst.eq_ignore_ascii_case(b"pgp-signature")
{
self.content_type = ContentType::PGPSignature;
+ } else if ct.eq_ignore_ascii_case(b"application")
+ && cst.eq_ignore_ascii_case(b"pkcs7-signature")
+ {
+ self.content_type = ContentType::CMSSignature;
} else {
let mut name: Option<String> = None;
for (n, v) in params {
@@ -384,6 +388,7 @@ impl fmt::Display for Attachment {
}
}
ContentType::PGPSignature => write!(f, "pgp signature [{}]", self.mime_type()),
+ ContentType::CMSSignature => write!(f, "S/MIME signature [{}]", self.mime_type()),
ContentType::OctetStream { .. } | ContentType::Other { .. } => {
if let Some(name) = self.filename() {
write!(
@@ -548,7 +553,7 @@ impl Attachment {
fn get_text_recursive(&self, text: &mut Vec<u8>) {
match self.content_type {
- ContentType::Text { .. } | ContentType::PGPSignature => {
+ ContentType::Text { .. } | ContentType::PGPSignature | ContentType::CMSSignature => {
text.extend(decode(self, None));
}
ContentType::Multipart {
@@ -720,7 +725,7 @@ impl Attachment {
ret.push_str(&format!("Content-Type: {}\r\n\r\n", a.content_type));
ret.push_str(&String::from_utf8_lossy(a.body()));
}
- ContentType::PGPSignature => {
+ ContentType::CMSSignature | ContentType::PGPSignature => {
ret.push_str(&format!("Content-Type: {}\r\n\r\n", a.content_type));
ret.push_str(&String::from_utf8_lossy(a.body()));
}
@@ -808,7 +813,7 @@ fn decode_rec_helper<'a, 'b>(a: &'a Attachment, filter: &mut Option<Filter<'b>>)
ContentType::OctetStream { ref name } => {
name.clone().unwrap_or_else(|| a.mime_type()).into_bytes()
}
- ContentType::PGPSignature => Vec::new(),
+ ContentType::CMSSignature | ContentType::PGPSignature => Vec::new(),
ContentType::MessageRfc822 => {
if a.content_disposition.kind.is_inline() {
let b = AttachmentBuilder::new(a.body()).build();
diff --git a/melib/src/email/pgp.rs b/melib/src/email/pgp.rs
index d3dd2ced..4f569053 100644
--- a/melib/src/email/pgp.rs
+++ b/melib/src/email/pgp.rs
@@ -20,7 +20,6 @@
*/
/*! Verification of OpenPGP signatures */
-use crate::email::parser::BytesExt;
use crate::email::{
attachment_types::{ContentType, MultipartType},
attachments::Attachment,
@@ -88,7 +87,7 @@ pub fn convert_attachment_to_rfc_spec(input: &[u8]) -> Vec<u8> {
ret
}
-pub fn verify_signature(a: &Attachment) -> Result<(Vec<u8>, &[u8])> {
+pub fn verify_signature(a: &Attachment) -> Result<(Vec<u8>, &Attachment)> {
match a.content_type {
ContentType::Multipart {
kind: MultipartType::Signed,
@@ -107,7 +106,10 @@ pub fn verify_signature(a: &Attachment) -> Result<(Vec<u8>, &[u8])> {
let signed_part: Vec<u8> = if let Some(v) = parts
.iter()
.zip(part_boundaries.iter())
- .find(|(p, _)| p.content_type != ContentType::PGPSignature)
+ .find(|(p, _)| {
+ p.content_type != ContentType::PGPSignature
+ && p.content_type != ContentType::CMSSignature
+ })
.map(|(_, s)| convert_attachment_to_rfc_spec(s.display_bytes(a.body())))
{
v
@@ -116,12 +118,11 @@ pub fn verify_signature(a: &Attachment) -> Result<(Vec<u8>, &[u8])> {
"multipart/signed attachment without a signed part".to_string(),
));
};
- let signature = if let Some(sig) = parts
- .iter()
- .find(|s| s.content_type == ContentType::PGPSignature)
- .map(|a| a.body())
- {
- sig.trim()
+ let signature = if let Some(sig) = parts.iter().find(|s| {
+ s.content_type == ContentType::PGPSignature
+ || s.content_type == ContentType::CMSSignature
+ }) {
+ sig
} else {
return Err(MeliError::new(
"multipart/signed attachment without a signature part".to_string(),
diff --git a/src/components/mail/pgp.rs b/src/components/mail/pgp.rs
index c378ca46..da31d671 100644
--- a/src/components/mail/pgp.rs
+++ b/src/components/mail/pgp.rs
@@ -25,6 +25,7 @@ use melib::email::{
};
use melib::error::*;
use melib::gpgme::*;
+use melib::parser::BytesExt;
use std::future::Future;
use std::pin::Pin;
@@ -38,7 +39,7 @@ pub async fn verify(a: Attachment) -> Result<()> {
let (data, sig) =
melib_pgp::verify_signature(&a).chain_err_summary(|| "Could not verify signature.")?;
let mut ctx = Context::new()?;
- let sig = ctx.new_data_mem(&sig)?;
+ let sig = ctx.new_data_mem(&sig.body().trim())?;
let data = ctx.new_data_mem(&data)?;
ctx.verify(sig, data)?.await
}
diff --git a/src/components/mail/view.rs b/src/components/mail/view.rs
index 121bbaf1..bce7e692 100644
--- a/src/components/mail/view.rs
+++ b/src/components/mail/view.rs
@@ -1797,7 +1797,9 @@ impl Component for MailView {
}
}
- ContentType::Text { .. } | ContentType::PGPSignature => {
+ ContentType::Text { .. }
+ | ContentType::PGPSignature
+ | ContentType::CMSSignature => {
self.mode = ViewMode::Attachment(lidx);
self.initialised = false;
self.dirty = true;
diff --git a/src/components/mail/view/envelope.rs b/src/components/mail/view/envelope.rs
index 19a45f55..d8477657 100644
--- a/src/components/mail/view/envelope.rs
+++ b/src/components/mail/view/envelope.rs
@@ -419,7 +419,9 @@ impl Component for EnvelopeView {
)));
}
- ContentType::Text { .. } => {
+ ContentType::Text { .. }
+ | ContentType::PGPSignature
+ | ContentType::CMSSignature => {
self.mode = ViewMode::Attachment(lidx);
self.dirty = true;
}
@@ -479,14 +481,6 @@ impl Component for EnvelopeView {
));
return true;
}
- ContentType::PGPSignature => {
- context.replies.push_back(UIEvent::StatusEvent(
- StatusEvent::DisplayMessage(
- "Signatures aren't supported yet".to_string(),
- ),
- ));
- return true;
- }
}
} else {
context.replies.push_back(UIEvent::StatusEvent(