diff options
| author | J08nY | 2017-06-25 22:15:38 +0200 |
|---|---|---|
| committer | J08nY | 2017-06-25 22:15:38 +0200 |
| commit | 468cafd33d41036312b9f4408a7e5a0a45d9ce23 (patch) | |
| tree | a918029b88dcde1230edcc6ca0a87b508afc26b3 /src/mailman_pgp/pgp/mime.py | |
| parent | 8c54f50a39f1aa7513fa9d28cc15f5c9c2a50c56 (diff) | |
| download | mailman-pgp-468cafd33d41036312b9f4408a7e5a0a45d9ce23.tar.gz mailman-pgp-468cafd33d41036312b9f4408a7e5a0a45d9ce23.tar.zst mailman-pgp-468cafd33d41036312b9f4408a7e5a0a45d9ce23.zip | |
Diffstat (limited to 'src/mailman_pgp/pgp/mime.py')
| -rw-r--r-- | src/mailman_pgp/pgp/mime.py | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/src/mailman_pgp/pgp/mime.py b/src/mailman_pgp/pgp/mime.py index 04b2db2..a373a7c 100644 --- a/src/mailman_pgp/pgp/mime.py +++ b/src/mailman_pgp/pgp/mime.py @@ -17,6 +17,7 @@ """RFC1847 and RFC3156 compliant message wrapped.""" import copy +from email import message_from_string from email.encoders import encode_7or8bit from email.iterators import walk from email.mime.application import MIMEApplication @@ -34,9 +35,13 @@ from mailman_pgp.pgp.utils import copy_headers class MIMEWrapper: """PGP/MIME (RFC1847 + RFC3156) compliant wrapper.""" - _signed_subtype = 'application/pgp-signature' - _encrypted_subtype = 'application/pgp-encrypted' - _keys_subtype = 'application/pgp-keys' + _signature_subtype = 'pgp-signature' + _encryption_subtype = 'pgp-encrypted' + _keys_subtype = 'pgp-keys' + + _signed_type = 'application/' + _signature_subtype + _encrypted_type = 'application/' + _encryption_subtype + _keys_type = 'application/' + _keys_subtype def __init__(self, msg): """ @@ -66,9 +71,9 @@ class MIMEWrapper: protocol_param = collapse_rfc2231_value(self.msg.get_param('protocol')) content_subtype = self.msg.get_content_subtype() - return (second_type == MIMEWrapper._signed_subtype and + return (second_type == MIMEWrapper._signed_type and content_subtype == 'signed' and - protocol_param == MIMEWrapper._signed_subtype) + protocol_param == MIMEWrapper._signed_type) def is_encrypted(self): """ @@ -86,14 +91,14 @@ class MIMEWrapper: protocol_param = collapse_rfc2231_value(self.msg.get_param('protocol')) return ('Version: 1' in first_part and - first_type == MIMEWrapper._encrypted_subtype and + first_type == MIMEWrapper._encrypted_type and second_type == 'application/octet-stream' and content_subtype == 'encrypted' and - protocol_param == MIMEWrapper._encrypted_subtype) + protocol_param == MIMEWrapper._encrypted_type) def is_keys(self): for part in walk(self.msg): - if part.get_content_type() != MIMEWrapper._keys_subtype: + if part.get_content_type() != MIMEWrapper._keys_type: return False return True @@ -105,7 +110,7 @@ class MIMEWrapper: :rtype: bool """ for part in walk(self.msg): - if part.get_content_type() == MIMEWrapper._keys_subtype: + if part.get_content_type() == MIMEWrapper._keys_type: return True return False @@ -116,7 +121,7 @@ class MIMEWrapper: :return: A collection of keys. """ for part in walk(self.msg): - if part.get_content_type() == MIMEWrapper._keys_subtype: + if part.get_content_type() == MIMEWrapper._keys_type: key, _ = PGPKey.from_blob(part.get_payload()) yield key @@ -163,10 +168,10 @@ class MIMEWrapper: micalg = self._micalg(signature.hash_algorithm) out = MIMEMultipart('signed', micalg=micalg, - protocol=MIMEWrapper._signed_subtype) + protocol=MIMEWrapper._signed_type) second_part = MIMEApplication(_data=str(signature), - _subtype='pgp-signature', + _subtype=MIMEWrapper._signature_subtype, _encoder=encode_7or8bit) out.attach(copy.deepcopy(self.msg)) out.attach(second_part) @@ -180,19 +185,44 @@ class MIMEWrapper: :param key: The key to decrypt with. :type key: pgpy.PGPKey :return: The decrypted message. - :rtype: PGPMessage + :rtype: mailman.email.message.Message """ msg_text = self.msg.get_payload(1).get_payload() - msg = PGPMessage.from_blob(msg_text) - return key.decrypt(msg) + pmsg = PGPMessage.from_blob(msg_text) + decrypted = key.decrypt(pmsg) + out = message_from_string(decrypted.message) + copy_headers(self.msg, out) + return out def encrypt(self, *keys, cipher=SymmetricKeyAlgorithm.AES256): """ + Encrypt the message with key/s, using cipher. - :param keys: + :param keys: The key/s to encrypt with. :type keys: pgpy.PGPKey - :param cipher: + :param cipher: The symmetric cipher to use. :type cipher: SymmetricKeyAlgorithm - :return: + :return: mailman.email.message.Message """ - pass + payload = self.msg.as_string() + pmsg = PGPMessage.new(payload) + if len(keys) == 1: + pmsg = keys[0].encrypt(pmsg, cipher=cipher) + else: + session_key = cipher.gen_key() + for key in keys: + pmsg = key.encrypt(pmsg, cipher=cipher, + session_key=session_key) + del session_key + out = MIMEMultipart('encrypted', + protocol=MIMEWrapper._encrypted_type) + first_part = MIMEApplication(_data='Version: 1', + _subtype=MIMEWrapper._encryption_subtype, + _encoder=encode_7or8bit) + second_part = MIMEApplication(_data=str(pmsg), + _subtype='octet-stream', + _encoder=encode_7or8bit) + out.attach(first_part) + out.attach(second_part) + copy_headers(self.msg, out) + return out |
