Skip to content

Commit

Permalink
Avoid double encrypting PGP parts encoded as plain text (fixes #1083)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdecimus committed Jan 11, 2025
1 parent 5af0fb4 commit 013c580
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 16 deletions.
36 changes: 33 additions & 3 deletions crates/jmap/src/email/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use common::{auth::AccessToken, Server};
use directory::backend::internal::manage;
use jmap_proto::types::{collection::Collection, property::Property};
use mail_builder::{encoders::base64::base64_encode_mime, mime::make_boundary};
use mail_parser::{decoders::base64::base64_decode, Message, MessageParser, MimeHeaders};
use mail_parser::{decoders::base64::base64_decode, Message, MessageParser, MimeHeaders, PartType};
use openpgp::{
parse::Parse,
serialize::stream,
Expand Down Expand Up @@ -372,7 +372,7 @@ impl EncryptMessage for Message<'_> {
}

fn is_encrypted(&self) -> bool {
self.content_type().is_some_and(|ct| {
if self.content_type().is_some_and(|ct| {
let main_type = ct.c_type.as_ref();
let sub_type = ct
.c_subtype
Expand All @@ -390,7 +390,37 @@ impl EncryptMessage for Message<'_> {
}))))
|| (main_type.eq_ignore_ascii_case("multipart")
&& sub_type.eq_ignore_ascii_case("encrypted"))
})
}) {
return true;
}

if self.parts.len() <= 2 {
let mut text_part = None;
let mut is_multipart = false;

for part in &self.parts {
match &part.body {
PartType::Text(text) => {
text_part = Some(text.as_ref());
}
PartType::Multipart(_) => {
is_multipart = true;
}
_ => (),
}
}

match text_part {
Some(text) if self.parts.len() == 1 || is_multipart => {
if text.trim_start().starts_with("-----BEGIN PGP MESSAGE-----") {
return true;
}
}
_ => (),
}
}

false
}
}

Expand Down
134 changes: 122 additions & 12 deletions tests/resources/crypto/is_encrypted.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ Content-Type: multipart/encrypted;
boundary="17778885806d6b28_46555a54adda6fa5_d83705f326a6b951"

body
---
!!!
Subject: FALSE
Content-Type: multipart/signed;
protocol="application/pkcs7-signature";
boundary="17778885806d6b28_46555a54adda6fa5_d83705f326a6b951"

body
---
!!!
Subject: TRUE
Content-Type: application/pkcs7-mime;
name="smime.p7m";
Expand All @@ -21,7 +21,7 @@ Content-Disposition: attachment;
Content-Transfer-Encoding: base64

body
---
!!!
Subject: TRUE
Content-Type: application/pkcs7-signature;
name="smime.p7s"; smime-type="signed-data"
Expand All @@ -30,7 +30,7 @@ Content-Disposition: attachment;
Content-Transfer-Encoding: base64

body
---
!!!
Subject: TRUE
Content-Type: application/octet-stream;
name="smime.p7m"
Expand All @@ -39,63 +39,173 @@ Content-Disposition: attachment;
Content-Transfer-Encoding: base64

body
---
!!!
Subject: TRUE
Content-Type: application/octet-stream;
name="smime.p7m"
Content-Transfer-Encoding: base64

body
---
!!!
Subject: TRUE
Content-Type: application/octet-stream
Content-Disposition: attachment;
filename="smime.p7m"
Content-Transfer-Encoding: base64

body
---
!!!
Subject: TRUE
Content-Type: application/octet-stream
Content-Disposition: attachment;
filename="smime.p7s"
Content-Transfer-Encoding: base64

body
---
!!!
Subject: TRUE
Content-Type: application/octet-stream
Content-Disposition: attachment;
filename="smime.p7c"
Content-Transfer-Encoding: base64

body
---
!!!
Subject: TRUE
Content-Type: application/octet-stream
Content-Disposition: attachment;
filename="smime.p7z"
Content-Transfer-Encoding: base64

body
---
!!!
Subject: FALSE
Content-Type: application/octet-stream
Content-Disposition: attachment;
filename="file.gz"
Content-Transfer-Encoding: base64

body
---
!!!
Subject: FALSE
Content-Type: application/octet-stream
Content-Disposition: attachment
Content-Transfer-Encoding: base64

body
---
!!!
Subject: FALSE
Content-Type: multipart/mixed;
boundary="17778885806d6b28_46555a54adda6fa5_d83705f326a6b951"

body
!!!
Subject: TRUE
Content-Type: multipart/mixed; boundary="----sinikael-?=_1-17364333937490.28304631087789"

------sinikael-?=_1-17364333937490.28304631087789
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable


-----BEGIN PGP MESSAGE-----
Version: Mailvelope v6.0.1
Comment: https://mailvelope.com

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
5fkw+PwLe2vPtuObvuY+ezbJGb1jV0tWZFXF
=3DaQyM
-----END PGP MESSAGE-----

------sinikael-?=_1-17364333937490.28304631087789--
!!!
Subject: TRUE
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable



-----BEGIN PGP MESSAGE-----
Version: Mailvelope v6.0.1
Comment: https://mailvelope.com

wcFMAy3n9oegk2NSARAApgl4nuztm5uxuCe+7ISW9Ox+315/pCHZmOUibORX
xGEbUs+ZgTqKIdYMet3+zSS70ykgjZDvh+cLm1oGmD5ZzLxSMjhgLpqrA0tG
3GB3gus844irLGBjVwgTuwAKhRz/CYaqlKGOloQkvcwRwy3N8UY8KG/WqD63
g9WQKYc+8+cR4wfQ0PSzZL6HexdT2LE2mWgKxStwDbbkwZumR0qZy4OvyI6O
zFCZSaz3F3VnDGbQgo5hK8Iynf25sC54P/E0ykdG6QpJZPo/ASoWePv0XyT6
wRiqq2cx366P6lxB3CJyjn+qRCfcXz0XXYejHmuI++S6ucNS4JcIhpuoi+tv
8b7pSy/6yQEKLyUhPfUmvFLxBm10bu8E9uhsmZnpiSnBsEGkLm/l9TFbOOSd
9nK0NeEVfqfIi25bxVJtRcYryf7BpjmgEdKlmF8Efeb1RpaI8IwVc6E7AhYB
c1vz1gN6BQ5ePtlHDFKxFV3jIqBKck8h2GSFGEYOXyTT+3tgFkqv/SuAUed9
X0bCjy7v578nsNieoyy/133X1+mu7L8rdADEAHhU/WLQ9VY/xu6GhNA0vzU8
yVQfSEJ1DJ4awU9Cn1mrbVg3vD/jpQzs67Sd33gC8xMqA9ZFOmXrnR4V1wkz
Y8XobC+UY6o9qn/Oz5mEtZG8rItYJ/bPOSSlFP6kXVrBwUwD8GquMWN8AUEB
D/9IVPN/qCtuhF+9jIjrxiw+agmeqUPWBEmLLZYL6xivP7Bn5bOJb6wwgU4e
IRIoh3Q5AKLvqN26BPePM16yZ6Z6qxTP/CFT5mOQQbj+3TH6fYD1ui74FoyR
+szTfntIdUOShKqogSKoRytMXheR+4TW7/D525ohRUsz71pfdCxqYC+k/vXr
ffl7lkv/V7GkPJ5fT+CantgLqXVevCIKOMVDVBT6G92t8Zn0klqv+MfVsZ3V
6FbwcqS+GxsCNezSdT1+K2yPja0fZffQOHD6nLDyIZmcr8KrCmP1MPY5LKJw
bMVCbYz0CrRl9d6JJGZOq+yapVOc0CDxWmxhGJP3M9OiCvGoPz3l+fDdNJ0f
dmxEv8c/I5t+AELxLMBa4aPuGE3pZQj4zyzhC3gnK5n9bqFecHl2+Kz+aVsi
4B1xZXIPT+XmlXM4rgCtuMlKZ6YkGRWiAnC8jok/k4iPaN7mfKbos0xwa187
haMjKKFVP8YvXlYpGeuvP3C2/oBxwsw9WihqL2tLTEE60ZgDEKWcZ3zwVKjl
bSNeDsWXlj+vIletdDyH/AMhyDOnUDc4bTkRW7W8ntq3fi8XmpQjHzW02BEd
Wq1Y/bV7nlh97Y7d3z5zlLhQnKrrP5IyQdOkd2WGpU39cDZe6XE6arQZKGVT
upnuX3Q48Hm6oSga+cydngjShtLCFQF/MFCZVYydjhe+KtzZCYBZ8nCMRxcV
PTuACJtUqOR/z5aPgRjM14accCYDwJ0Dm51h5LuEzYFDJjcdFbVSVfvnCy5a
b9h6VBCpWieI6ubAzYKKJxGwp/OcoaQyYPjwlNQyTSb7omZPsAtFpTALNXbU
CIM2cFnD/MMvgEHCuqPZoKh0YdQxYV50p36Wa/rMvTfW+S1T2neWGD6kMDWZ
I651K+HBCQV6INrJk5ugvCt26/l8+Y75cnGEKbkyJgt+NGjULX3jjPawhvwN
0EKx8hYwASuJ3E71iAXga7oSMRemDk4ZXoz+PDngoWtcoXcdQNMiVymOt6iZ
P5ImSQXkId1XZYjS3+1t+Sk8WgUi5kvu4WP3hm1Ovjd1kXTy3lqXpfci23si
eZofjs9DLldkV5xtOwWVx/B1UkqvtD2BuwcDWgvGEm2LEn4/eXkHUTzHLs4j
T9s454HasmVfd+4/koBdD6ASDqFf5Ue14OonsXvIvLop2CgUHxDVffr1onSk
K9r0kKxe9iAFZ8KYpf2Do/FPTL8BIXjHC2vfJ05wl262xs7uNMdgWm4+NP/q
uVNOoXByZIDEPixx7jimKhlEIZx36AbsI+OB5cV1Pr5SSbO3w205ALol+xKN
TPJiaQDH8qNXX+9j4JfO8uWvDmhPUe83bm/mHg4wf/39+PNQptwmhLH9iXtC
Czqgmr1vUNd/8dLgQuqVn/R3uUbGeWmKD9cqURWcvumbq+rFWPl1N7T7VRfc
XGDnMBNBmLke2YO8XUY561lqKekfS/2fekSdz005sI2cnGmy5LLh+kPN6opz
0pA2kSskbfSQqJmEdjKQU3oGEzEgwvOXjFwT7cChevgLEmDBkQXTDuEeo3Kb
KnwaNPnodzaNXAfZh/NylEgcUFjEx6crZMN3ztl8zsvAvP4P0BPmixZ89G80
5fkw+PwLe2vPtuObvuY+ezbJGb1jV0tWZFXF
=3DaQyM
-----END PGP MESSAGE-----
2 changes: 1 addition & 1 deletion tests/src/jmap/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ pub fn check_is_encrypted() {
)
.unwrap();

for raw_message in messages.split("---") {
for raw_message in messages.split("!!!") {
let is_encrypted = raw_message.contains("TRUE");
let message = MessageParser::new()
.parse(raw_message.trim().as_bytes())
Expand Down

0 comments on commit 013c580

Please sign in to comment.