From 9d44862908f521850eaf420cfcdac733d030113d Mon Sep 17 00:00:00 2001 From: Thais Siqueira Date: Mon, 16 May 2016 17:38:46 -0300 Subject: [bug] verify signature of encrypted email from Apple Mail Fix verify signature on encrypted email from Apple Mail, adding a step to verify signature after decrypt the email because the keymananger could not verify signature when decrypting it --- mail/src/leap/mail/incoming/service.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mail/src/leap/mail/incoming/service.py b/mail/src/leap/mail/incoming/service.py index c7d194d6..f60921aa 100644 --- a/mail/src/leap/mail/incoming/service.py +++ b/mail/src/leap/mail/incoming/service.py @@ -524,10 +524,20 @@ class IncomingMail(Service): self._add_decrypted_header(msg) return (msg, signkey) + def verify_signature_after_decrypt_an_email(res): + decrdata, signkey = res + if not isinstance(signkey, OpenPGPKey): + try: + return self._verify_signature_not_encrypted_msg(decrdata, senderAddress) + except: + pass + return res + d = self._keymanager.decrypt( encdata, self._userid, OpenPGPKey, verify=senderAddress) d.addCallbacks(build_msg, self._decryption_error, errbackArgs=(msg,)) + d.addCallbacks(verify_signature_after_decrypt_an_email) return d def _maybe_decrypt_inline_encrypted_msg(self, origmsg, encoding, -- cgit v1.2.3 From 4c8cc737d205231c475000f2f7399262829630a3 Mon Sep 17 00:00:00 2001 From: Caio Carrara Date: Tue, 24 May 2016 15:56:00 -0300 Subject: [tests] add test to validate signature from apple mail This change adds test to validate signature of encrypted email created by apple mail. It's important to note that apple mail has a specific way to encrypt signed messages. First it sign the email and then encrypt the previous signed message. It was also added a message file with the expected data. --- mail/src/leap/mail/incoming/service.py | 12 +++-- .../tests/rfc822.multi-encrypt-signed.message | 61 ++++++++++++++++++++++ .../leap/mail/incoming/tests/test_incoming_mail.py | 18 +++++++ 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 mail/src/leap/mail/incoming/tests/rfc822.multi-encrypt-signed.message diff --git a/mail/src/leap/mail/incoming/service.py b/mail/src/leap/mail/incoming/service.py index f60921aa..bf850b57 100644 --- a/mail/src/leap/mail/incoming/service.py +++ b/mail/src/leap/mail/incoming/service.py @@ -458,10 +458,8 @@ class IncomingMail(Service): self.LEAP_SIGNATURE_HEADER, self.LEAP_SIGNATURE_INVALID) else: - decrmsg.add_header( - self.LEAP_SIGNATURE_HEADER, - self.LEAP_SIGNATURE_VALID, - pubkey=signkey.fingerprint) + self._add_verified_signature_header(decrmsg, + signkey.fingerprint) return decrmsg.as_string() if msg.get_content_type() == MULTIPART_ENCRYPTED: @@ -475,6 +473,12 @@ class IncomingMail(Service): d.addCallback(add_leap_header) return d + def _add_verified_signature_header(self, decrmsg, fingerprint): + decrmsg.add_header( + self.LEAP_SIGNATURE_HEADER, + self.LEAP_SIGNATURE_VALID, + pubkey=fingerprint) + def _add_decrypted_header(self, msg): msg.add_header(self.LEAP_ENCRYPTION_HEADER, self.LEAP_ENCRYPTION_DECRYPTED) diff --git a/mail/src/leap/mail/incoming/tests/rfc822.multi-encrypt-signed.message b/mail/src/leap/mail/incoming/tests/rfc822.multi-encrypt-signed.message new file mode 100644 index 00000000..98304f24 --- /dev/null +++ b/mail/src/leap/mail/incoming/tests/rfc822.multi-encrypt-signed.message @@ -0,0 +1,61 @@ +Content-Type: multipart/encrypted; + boundary="Apple-Mail=_C01A1464-6C43-43BF-8F62-157335B7E25B"; + protocol="application/pgp-encrypted"; +Subject: Enc signed +Mime-Version: 1.0 (Mac OS X Mail 9.3 \(3124\)) +From: Leap Test Key +Date: Tue, 24 May 2016 11:47:24 -0300 +Content-Description: OpenPGP encrypted message +To: leap@leap.se + +This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156) +--Apple-Mail=_C01A1464-6C43-43BF-8F62-157335B7E25B +Content-Type: application/pgp-encrypted +Content-Description: PGP/MIME Versions Identification + +--Apple-Mail=_C01A1464-6C43-43BF-8F62-157335B7E25B +Content-Disposition: inline; + filename=encrypted.asc +Content-Type: application/octet-stream; + name=encrypted.asc +Content-Description: OpenPGP encrypted message + +-----BEGIN PGP MESSAGE----- +Version: GnuPG v2 + +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 +=tEyc +-----END PGP MESSAGE----- + +--Apple-Mail=_C01A1464-6C43-43BF-8F62-157335B7E25B-- \ No newline at end of file diff --git a/mail/src/leap/mail/incoming/tests/test_incoming_mail.py b/mail/src/leap/mail/incoming/tests/test_incoming_mail.py index 754df9f0..91f25566 100644 --- a/mail/src/leap/mail/incoming/tests/test_incoming_mail.py +++ b/mail/src/leap/mail/incoming/tests/test_incoming_mail.py @@ -22,6 +22,7 @@ Test case for leap.mail.incoming.service @license: GPLv3, see included LICENSE file """ +import os import json from email.mime.application import MIMEApplication @@ -295,6 +296,23 @@ subject: independence of cyberspace self._do_fetch(message.as_string())) return d + def testValidateSignatureFromEncryptedEmailFromAppleMail(self): + CURRENT_PATH = os.path.split(os.path.abspath(__file__))[0] + enc_signed_file = os.path.join(CURRENT_PATH, + 'rfc822.multi-encrypt-signed.message') + self.fetcher._add_verified_signature_header = Mock() + + def add_verified_signature_header_called(_): + self.assertTrue(self.fetcher._add_verified_signature_header.called, + "There was some errors verifying signature") + + with open(enc_signed_file) as f: + enc_signed_raw = f.read() + + d = self._do_fetch(enc_signed_raw) + d.addCallback(add_verified_signature_header_called) + return d + def testListener(self): self.called = False -- cgit v1.2.3 From 16257201db63a8f65b2afe278414690980d0d358 Mon Sep 17 00:00:00 2001 From: Caio Carrara Date: Wed, 25 May 2016 16:11:34 -0300 Subject: [refactor] change the check to validate signature from Apple Mail It changes the way that incoming service checks if a additional verification is needed to validate signature. The way before was checking by the type of signature object and calling the verify signature method if the type is different from OpenPGPKey. However it could be more readable if we check the type of decrypted message. If it's a multipart/signed message and not a plain/text we need to verify the signature because keymanager couldn't do it during the decryption process. --- mail/src/leap/mail/incoming/service.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mail/src/leap/mail/incoming/service.py b/mail/src/leap/mail/incoming/service.py index bf850b57..58a19c81 100644 --- a/mail/src/leap/mail/incoming/service.py +++ b/mail/src/leap/mail/incoming/service.py @@ -530,11 +530,9 @@ class IncomingMail(Service): def verify_signature_after_decrypt_an_email(res): decrdata, signkey = res - if not isinstance(signkey, OpenPGPKey): - try: - return self._verify_signature_not_encrypted_msg(decrdata, senderAddress) - except: - pass + if decrdata.get_content_type() == MULTIPART_SIGNED: + res = self._verify_signature_not_encrypted_msg(decrdata, + senderAddress) return res d = self._keymanager.decrypt( -- cgit v1.2.3