diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman_pgp/pgp/inline.py | 22 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/mime.py | 46 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/tests/data/inline_privkey.eml | 43 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/tests/data/inline_pubkey.eml | 30 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/tests/data/mime_privkey.eml | 59 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/tests/data/mime_pubkey.eml | 46 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/tests/test_inline.py | 35 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/tests/test_mime.py | 35 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/wrapper.py | 18 |
9 files changed, 319 insertions, 15 deletions
diff --git a/src/mailman_pgp/pgp/inline.py b/src/mailman_pgp/pgp/inline.py index d87b3da..a8e8004 100644 --- a/src/mailman_pgp/pgp/inline.py +++ b/src/mailman_pgp/pgp/inline.py @@ -17,7 +17,7 @@ """Strict inline PGP message wrapper.""" -from pgpy import PGPMessage +from pgpy import PGPKey, PGPMessage from pgpy.types import Armorable from public import public @@ -70,6 +70,26 @@ class InlineWrapper: # XXX: This mistakes non-cleartext signature as encrypted. return self._is_inline() and self._has_armor('MESSAGE') + def has_keys(self): + """ + Whether the message contains public or private keys. + + :return: If the message contains keys. + :rtype: bool + """ + return self._is_inline() and (self._has_armor('PUBLIC KEY BLOCK') or + self._has_armor('PRIVATE KEY BLOCK')) + + def keys(self): + """ + Get the collection of keys in this message. + + :return: A collection of keys. + """ + # TODO: potentially return all things returned from from_blob? + key, _ = PGPKey.from_blob(self._as_string()) + yield key + def verify(self, key): """ Verify the signature of this message with key. diff --git a/src/mailman_pgp/pgp/mime.py b/src/mailman_pgp/pgp/mime.py index fde9d49..3421167 100644 --- a/src/mailman_pgp/pgp/mime.py +++ b/src/mailman_pgp/pgp/mime.py @@ -16,10 +16,10 @@ # this program. If not, see <http://www.gnu.org/licenses/>. """RFC1847 and RFC3156 compliant message wrapped.""" - +from email.iterators import walk from email.utils import collapse_rfc2231_value -from pgpy import PGPMessage, PGPSignature +from pgpy import PGPKey, PGPMessage, PGPSignature from public import public @@ -29,6 +29,7 @@ class MIMEWrapper: _signed_subtype = 'application/pgp-signature' _encrypted_subtype = 'application/pgp-encrypted' + _keys_subtype = 'application/pgp-keys' def __init__(self, msg): """ @@ -58,10 +59,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 \ - content_subtype == 'signed' and \ - protocol_param == MIMEWrapper._signed_subtype + return (second_type == MIMEWrapper._signed_subtype and + content_subtype == 'signed' and + protocol_param == MIMEWrapper._signed_subtype) def is_encrypted(self): """ @@ -78,12 +78,34 @@ class MIMEWrapper: content_subtype = self.msg.get_content_subtype() protocol_param = collapse_rfc2231_value(self.msg.get_param('protocol')) - return \ - 'Version: 1' in first_part and \ - first_type == MIMEWrapper._encrypted_subtype and \ - second_type == 'application/octet-stream' and \ - content_subtype == 'encrypted' and \ - protocol_param == MIMEWrapper._encrypted_subtype + return ('Version: 1' in first_part and + first_type == MIMEWrapper._encrypted_subtype and + second_type == 'application/octet-stream' and + content_subtype == 'encrypted' and + protocol_param == MIMEWrapper._encrypted_subtype) + + def has_keys(self): + """ + Whether the message contains keys as per RFC3156 section 7. + + :return: If the message contains keys. + :rtype: bool + """ + for part in walk(self.msg): + if part.get_content_type() == MIMEWrapper._keys_subtype: + return True + return False + + def keys(self): + """ + Get the collection of keys in this message. + + :return: A collection of keys. + """ + for part in walk(self.msg): + if part.get_content_type() == MIMEWrapper._keys_subtype: + key, _ = PGPKey.from_blob(part.get_payload()) + yield key def verify(self, key): """ diff --git a/src/mailman_pgp/pgp/tests/data/inline_privkey.eml b/src/mailman_pgp/pgp/tests/data/inline_privkey.eml new file mode 100644 index 0000000..683efdd --- /dev/null +++ b/src/mailman_pgp/pgp/tests/data/inline_privkey.eml @@ -0,0 +1,43 @@ +To: nobody@example.org +From: RSA 1024b example <RSA-1024b@example.org> +Subject: Some subject. +Message-ID: <76a591ed-bfc4-d08b-73d3-fc2489148fd7@example.org> +Date: Wed, 21 Jun 2017 13:50:59 +0200 +User-Agent: Mutt/1.7.2 (2016-11-26) +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit + +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQHYBFlKWqQBBADY8dCIub6x4tcFS3SmWW1r5ctwldFixkLz8LpBdgpc+zt7iWZI +XvVWH9GYgTzgE+qEAVJcvQDG7/cX6zTopkkGEUmnwBgEFpc7Xi0D+/GYC23XleQk +IF/R2Mf0AW3FBx/UxK0kIkYfTelkuZBrag83iLh3yKXkcLm1T010eGbTWQARAQAB +AAP/ayABKrqZrQpHxfAMEmZ/TzPCIP6BzeX7wqxAtLlehapzJV3kGWF2gQgmPcm3 +byi2eWeTrYKQwytUVsXIswcFcCY1Fv6NkntMSqc6VJzGhvjKE9CTNJmgSjHlILMW +Ma/9TzhxH2DT9tNMgOEN3+FoKRqjlLrhO/OiXqYZJdkXU+8CAOQin6DGnn+qvjlN +5zw1GIpmWBt9b1S/WEqKaG1t4D/V0m0pAJBqeUbSC6MonQLA9pmIK/LbetUKRwM/ +xLNRMs8CAPNxR4NY73YIfSnlGRPdZHmOq4wMtqXYtoN1qZruHcXsrojcKHV72n8y +Hb3R+LEKVjky95RKeKGowousIhGYQVcCAKsWtTWQA/VMW2V+ydzFHZHN0xwC9eTc +uhs7G1qAqJR2POCq/0Cr3W4nXnbYSAr9wHal/YUuIKr54vNbPlXp6xqf/rQpUlNB +IDEwMjRiIGV4YW1wbGUgPFJTQS0xMDI0YkBleGFtcGxlLm9yZz6IzgQTAQgAOBYh +BNSpSIaxyiCWpkWOXEfxDAh4hLdYBQJZSlqkAhsDBQsJCAcCBhUICQoLAgQWAgMB +Ah4BAheAAAoJEEfxDAh4hLdYbQIEALBwJUxkBGJYlP5kOZYAgQHw6+rwIgdXAoPk +ldwcGPhvlBEocRYx+5KUYrx7W352dv+AgxSZ590JL7JGvWJDvMxoZGCJiRvJ7+Ve +luKRH167wT8H4hxftBJqzorTU4eyPzG8bFneuag5dw+81DdngXjWRCorEHEdaQjc +sfvVEmnhnQHYBFlKWqQBBADXLjeg+K0ZAuchhNkvMnfb8TlKoc1t1lH94unoqoj3 +L5Srf3XSo1fmuEBNr1nc5BLyH0tPDJZyuVCypfY4en9uaGvWO0U4t/OUiIWqPjBm +XbjZWDdGKksb0cQNy13cvE57EmirbuVcXCE0OdU8lcbopN2wnecKOxLKK9PaLBZ6 +9wARAQABAAP+NyRiYA9p+GdciKPtLiGeQpA6EMyPAs8x2sB8FcIh8EpSrHIw5OYz +/+2GmQHPIwKVclOfrmW45jRkICvUgZuurMmMrnDu63UT/9Pm+4EiUkPFnKfAgYFm +XwWf2SklsoHCFT2WQ31WCp/hZxWucYqfPM/5ZsE+EAToK+C8BnMicI0CAOAUhruY +JVh/7u6ES7xI6Hd7yHmU6rLr7oP2Z8cILirt5+1FgOP/qPdVEK9UGShbBcjfA+8W +u4LISyuvCm8vuyMCAPXVJmTdmJjzBvP7BZe+HbDzWfhPCN+BvepGi3DQdHonLU2t +IVOcMQsu0raaLevZ19nCKeMrOoAaIhCdjJUBGB0B/iSErQY+sNUAbjsW0zWovY2u +e+0TBMDkO3OZCFKxCr/7mEuIfsAENXvDwAmx/YDklMwN8zgUAc5BqObGtRE7BYSg +n4i2BBgBCAAgFiEE1KlIhrHKIJamRY5cR/EMCHiEt1gFAllKWqQCGwwACgkQR/EM +CHiEt1gOwQP7BuyH2oKuWPAXcVrJdl3P3fIqvm4JzKRjXCVA9j5QOdihH1W5rZFC +x3J+bUvKa1QJ1NuHoU9gYvR2NPs+CpMlTJ2wg7ksgtddlC9lsVi1ijvjJCugveBh +a/CQJt7Cl6uDkifPsD5kxyUTecmnVfYZB6Fb/nrZxJ5Cb1dKPGixDpw= +=e2xw +-----END PGP PRIVATE KEY BLOCK----- diff --git a/src/mailman_pgp/pgp/tests/data/inline_pubkey.eml b/src/mailman_pgp/pgp/tests/data/inline_pubkey.eml new file mode 100644 index 0000000..cb0d176 --- /dev/null +++ b/src/mailman_pgp/pgp/tests/data/inline_pubkey.eml @@ -0,0 +1,30 @@ +To: nobody@example.org +From: RSA 1024b example <RSA-1024b@example.org> +Subject: Some subject. +Message-ID: <76a591ed-bfc4-d08b-73d3-fc2489148fd7@example.org> +Date: Wed, 21 Jun 2017 13:50:59 +0200 +User-Agent: Mutt/1.7.2 (2016-11-26) +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mI0EWUpapAEEANjx0Ii5vrHi1wVLdKZZbWvly3CV0WLGQvPwukF2Clz7O3uJZkhe +9VYf0ZiBPOAT6oQBUly9AMbv9xfrNOimSQYRSafAGAQWlzteLQP78ZgLbdeV5CQg +X9HYx/QBbcUHH9TErSQiRh9N6WS5kGtqDzeIuHfIpeRwubVPTXR4ZtNZABEBAAG0 +KVJTQSAxMDI0YiBleGFtcGxlIDxSU0EtMTAyNGJAZXhhbXBsZS5vcmc+iM4EEwEI +ADgWIQTUqUiGscoglqZFjlxH8QwIeIS3WAUCWUpapAIbAwULCQgHAgYVCAkKCwIE +FgIDAQIeAQIXgAAKCRBH8QwIeIS3WG0CBACwcCVMZARiWJT+ZDmWAIEB8Ovq8CIH +VwKD5JXcHBj4b5QRKHEWMfuSlGK8e1t+dnb/gIMUmefdCS+yRr1iQ7zMaGRgiYkb +ye/lXpbikR9eu8E/B+IcX7QSas6K01OHsj8xvGxZ3rmoOXcPvNQ3Z4F41kQqKxBx +HWkI3LH71RJp4biNBFlKWqQBBADXLjeg+K0ZAuchhNkvMnfb8TlKoc1t1lH94uno +qoj3L5Srf3XSo1fmuEBNr1nc5BLyH0tPDJZyuVCypfY4en9uaGvWO0U4t/OUiIWq +PjBmXbjZWDdGKksb0cQNy13cvE57EmirbuVcXCE0OdU8lcbopN2wnecKOxLKK9Pa +LBZ69wARAQABiLYEGAEIACAWIQTUqUiGscoglqZFjlxH8QwIeIS3WAUCWUpapAIb +DAAKCRBH8QwIeIS3WA7BA/sG7Ifagq5Y8BdxWsl2Xc/d8iq+bgnMpGNcJUD2PlA5 +2KEfVbmtkULHcn5tS8prVAnU24ehT2Bi9HY0+z4KkyVMnbCDuSyC112UL2WxWLWK +O+MkK6C94GFr8JAm3sKXq4OSJ8+wPmTHJRN5yadV9hkHoVv+etnEnkJvV0o8aLEO +nA== +=4olM +-----END PGP PUBLIC KEY BLOCK----- diff --git a/src/mailman_pgp/pgp/tests/data/mime_privkey.eml b/src/mailman_pgp/pgp/tests/data/mime_privkey.eml new file mode 100644 index 0000000..da66247 --- /dev/null +++ b/src/mailman_pgp/pgp/tests/data/mime_privkey.eml @@ -0,0 +1,59 @@ +To: nobody@example.org +From: RSA 1024b example <RSA-1024b@example.org> +Subject: Some subject. +Message-ID: <76a591ed-bfc4-d08b-73d3-fc2489148fd7@example.org> +Date: Wed, 21 Jun 2017 13:50:59 +0200 +User-Agent: Mutt/1.7.2 (2016-11-26) +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------A851F166D50529639139DD0B" + +This is a multi-part message in MIME format. +--------------A851F166D50529639139DD0B +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 7bit + +Some other text. + +--------------A851F166D50529639139DD0B +Content-Type: application/pgp-keys; + name="0x7884B758.asc" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="0x7884B758.asc" + +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQHYBFlKWqQBBADY8dCIub6x4tcFS3SmWW1r5ctwldFixkLz8LpBdgpc+zt7iWZI +XvVWH9GYgTzgE+qEAVJcvQDG7/cX6zTopkkGEUmnwBgEFpc7Xi0D+/GYC23XleQk +IF/R2Mf0AW3FBx/UxK0kIkYfTelkuZBrag83iLh3yKXkcLm1T010eGbTWQARAQAB +AAP/ayABKrqZrQpHxfAMEmZ/TzPCIP6BzeX7wqxAtLlehapzJV3kGWF2gQgmPcm3 +byi2eWeTrYKQwytUVsXIswcFcCY1Fv6NkntMSqc6VJzGhvjKE9CTNJmgSjHlILMW +Ma/9TzhxH2DT9tNMgOEN3+FoKRqjlLrhO/OiXqYZJdkXU+8CAOQin6DGnn+qvjlN +5zw1GIpmWBt9b1S/WEqKaG1t4D/V0m0pAJBqeUbSC6MonQLA9pmIK/LbetUKRwM/ +xLNRMs8CAPNxR4NY73YIfSnlGRPdZHmOq4wMtqXYtoN1qZruHcXsrojcKHV72n8y +Hb3R+LEKVjky95RKeKGowousIhGYQVcCAKsWtTWQA/VMW2V+ydzFHZHN0xwC9eTc +uhs7G1qAqJR2POCq/0Cr3W4nXnbYSAr9wHal/YUuIKr54vNbPlXp6xqf/rQpUlNB +IDEwMjRiIGV4YW1wbGUgPFJTQS0xMDI0YkBleGFtcGxlLm9yZz6IzgQTAQgAOBYh +BNSpSIaxyiCWpkWOXEfxDAh4hLdYBQJZSlqkAhsDBQsJCAcCBhUICQoLAgQWAgMB +Ah4BAheAAAoJEEfxDAh4hLdYbQIEALBwJUxkBGJYlP5kOZYAgQHw6+rwIgdXAoPk +ldwcGPhvlBEocRYx+5KUYrx7W352dv+AgxSZ590JL7JGvWJDvMxoZGCJiRvJ7+Ve +luKRH167wT8H4hxftBJqzorTU4eyPzG8bFneuag5dw+81DdngXjWRCorEHEdaQjc +sfvVEmnhnQHYBFlKWqQBBADXLjeg+K0ZAuchhNkvMnfb8TlKoc1t1lH94unoqoj3 +L5Srf3XSo1fmuEBNr1nc5BLyH0tPDJZyuVCypfY4en9uaGvWO0U4t/OUiIWqPjBm +XbjZWDdGKksb0cQNy13cvE57EmirbuVcXCE0OdU8lcbopN2wnecKOxLKK9PaLBZ6 +9wARAQABAAP+NyRiYA9p+GdciKPtLiGeQpA6EMyPAs8x2sB8FcIh8EpSrHIw5OYz +/+2GmQHPIwKVclOfrmW45jRkICvUgZuurMmMrnDu63UT/9Pm+4EiUkPFnKfAgYFm +XwWf2SklsoHCFT2WQ31WCp/hZxWucYqfPM/5ZsE+EAToK+C8BnMicI0CAOAUhruY +JVh/7u6ES7xI6Hd7yHmU6rLr7oP2Z8cILirt5+1FgOP/qPdVEK9UGShbBcjfA+8W +u4LISyuvCm8vuyMCAPXVJmTdmJjzBvP7BZe+HbDzWfhPCN+BvepGi3DQdHonLU2t +IVOcMQsu0raaLevZ19nCKeMrOoAaIhCdjJUBGB0B/iSErQY+sNUAbjsW0zWovY2u +e+0TBMDkO3OZCFKxCr/7mEuIfsAENXvDwAmx/YDklMwN8zgUAc5BqObGtRE7BYSg +n4i2BBgBCAAgFiEE1KlIhrHKIJamRY5cR/EMCHiEt1gFAllKWqQCGwwACgkQR/EM +CHiEt1gOwQP7BuyH2oKuWPAXcVrJdl3P3fIqvm4JzKRjXCVA9j5QOdihH1W5rZFC +x3J+bUvKa1QJ1NuHoU9gYvR2NPs+CpMlTJ2wg7ksgtddlC9lsVi1ijvjJCugveBh +a/CQJt7Cl6uDkifPsD5kxyUTecmnVfYZB6Fb/nrZxJ5Cb1dKPGixDpw= +=e2xw +-----END PGP PRIVATE KEY BLOCK----- + +--------------A851F166D50529639139DD0B-- diff --git a/src/mailman_pgp/pgp/tests/data/mime_pubkey.eml b/src/mailman_pgp/pgp/tests/data/mime_pubkey.eml new file mode 100644 index 0000000..1495a41 --- /dev/null +++ b/src/mailman_pgp/pgp/tests/data/mime_pubkey.eml @@ -0,0 +1,46 @@ +To: nobody@example.org +From: RSA 1024b example <RSA-1024b@example.org> +Subject: Some subject. +Message-ID: <76a591ed-bfc4-d08b-73d3-fc2489148fd7@example.org> +Date: Wed, 21 Jun 2017 13:50:59 +0200 +User-Agent: Mutt/1.7.2 (2016-11-26) +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------A851F166D50529639139DD0B" + +This is a multi-part message in MIME format. +--------------A851F166D50529639139DD0B +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 7bit + +Some other text. + +--------------A851F166D50529639139DD0B +Content-Type: application/pgp-keys; + name="0x7884B758.asc" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="0x7884B758.asc" + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mI0EWUpapAEEANjx0Ii5vrHi1wVLdKZZbWvly3CV0WLGQvPwukF2Clz7O3uJZkhe +9VYf0ZiBPOAT6oQBUly9AMbv9xfrNOimSQYRSafAGAQWlzteLQP78ZgLbdeV5CQg +X9HYx/QBbcUHH9TErSQiRh9N6WS5kGtqDzeIuHfIpeRwubVPTXR4ZtNZABEBAAG0 +KVJTQSAxMDI0YiBleGFtcGxlIDxSU0EtMTAyNGJAZXhhbXBsZS5vcmc+iM4EEwEI +ADgWIQTUqUiGscoglqZFjlxH8QwIeIS3WAUCWUpapAIbAwULCQgHAgYVCAkKCwIE +FgIDAQIeAQIXgAAKCRBH8QwIeIS3WG0CBACwcCVMZARiWJT+ZDmWAIEB8Ovq8CIH +VwKD5JXcHBj4b5QRKHEWMfuSlGK8e1t+dnb/gIMUmefdCS+yRr1iQ7zMaGRgiYkb +ye/lXpbikR9eu8E/B+IcX7QSas6K01OHsj8xvGxZ3rmoOXcPvNQ3Z4F41kQqKxBx +HWkI3LH71RJp4biNBFlKWqQBBADXLjeg+K0ZAuchhNkvMnfb8TlKoc1t1lH94uno +qoj3L5Srf3XSo1fmuEBNr1nc5BLyH0tPDJZyuVCypfY4en9uaGvWO0U4t/OUiIWq +PjBmXbjZWDdGKksb0cQNy13cvE57EmirbuVcXCE0OdU8lcbopN2wnecKOxLKK9Pa +LBZ69wARAQABiLYEGAEIACAWIQTUqUiGscoglqZFjlxH8QwIeIS3WAUCWUpapAIb +DAAKCRBH8QwIeIS3WA7BA/sG7Ifagq5Y8BdxWsl2Xc/d8iq+bgnMpGNcJUD2PlA5 +2KEfVbmtkULHcn5tS8prVAnU24ehT2Bi9HY0+z4KkyVMnbCDuSyC112UL2WxWLWK +O+MkK6C94GFr8JAm3sKXq4OSJ8+wPmTHJRN5yadV9hkHoVv+etnEnkJvV0o8aLEO +nA== +=4olM +-----END PGP PUBLIC KEY BLOCK----- + +--------------A851F166D50529639139DD0B-- diff --git a/src/mailman_pgp/pgp/tests/test_inline.py b/src/mailman_pgp/pgp/tests/test_inline.py index f8831c9..d144991 100644 --- a/src/mailman_pgp/pgp/tests/test_inline.py +++ b/src/mailman_pgp/pgp/tests/test_inline.py @@ -88,3 +88,38 @@ class TestEncryption(PGPTestCase, unittest.TestCase): wrapped = self.wrapper(message) self.assertEqual(wrapped.decrypt(key).message, bytearray(clear, 'latin-1')) + + +class TestKeys(PGPTestCase, unittest.TestCase): + def setUp(self): + self.wrapper = InlineWrapper + + @parameterized.expand([ + (load_message('data/inline_privkey.eml'), + True), + (load_message('data/inline_pubkey.eml'), + True), + (load_message('data/clear.eml'), + False), + (load_message('data/inline_signed.eml'), + False) + ]) + def test_has_keys(self, message, has_keys): + wrapped = self.wrapper(message) + self.assertEqual(wrapped.has_keys(), has_keys) + + @parameterized.expand([ + (load_message('data/inline_privkey.eml'), + [load_key('data/rsa_1024.priv.asc')]), + (load_message('data/inline_pubkey.eml'), + [load_key('data/rsa_1024.pub.asc')]) + ]) + def test_keys(self, message, keys): + wrapped = self.wrapper(message) + loaded = list(wrapped.keys()) + loaded_fingerprints = list(map(lambda key: key.fingerprint, loaded)) + + self.assertEqual(len(loaded), len(keys)) + + fingerprints = list(map(lambda key: key.fingerprint, keys)) + self.assertListEqual(loaded_fingerprints, fingerprints) diff --git a/src/mailman_pgp/pgp/tests/test_mime.py b/src/mailman_pgp/pgp/tests/test_mime.py index cb8451d..8e00e9c 100644 --- a/src/mailman_pgp/pgp/tests/test_mime.py +++ b/src/mailman_pgp/pgp/tests/test_mime.py @@ -65,3 +65,38 @@ class TestEncryption(PGPTestCase, unittest.TestCase): def test_decrypt(self): pass + + +class TestKeys(PGPTestCase, unittest.TestCase): + def setUp(self): + self.wrapper = MIMEWrapper + + @parameterized.expand([ + (load_message('data/mime_privkey.eml'), + True), + (load_message('data/mime_pubkey.eml'), + True), + (load_message('data/clear.eml'), + False), + (load_message('data/mime_signed.eml'), + False) + ]) + def test_has_keys(self, message, has_keys): + wrapped = self.wrapper(message) + self.assertEqual(wrapped.has_keys(), has_keys) + + @parameterized.expand([ + (load_message('data/mime_privkey.eml'), + [load_key('data/rsa_1024.priv.asc')]), + (load_message('data/mime_pubkey.eml'), + [load_key('data/rsa_1024.pub.asc')]) + ]) + def test_keys(self, message, keys): + wrapped = self.wrapper(message) + loaded = list(wrapped.keys()) + loaded_fingerprints = list(map(lambda key: key.fingerprint, loaded)) + + self.assertEqual(len(loaded), len(keys)) + + fingerprints = list(map(lambda key: key.fingerprint, keys)) + self.assertListEqual(loaded_fingerprints, fingerprints) diff --git a/src/mailman_pgp/pgp/wrapper.py b/src/mailman_pgp/pgp/wrapper.py index 9a004c4..c6d8dff 100644 --- a/src/mailman_pgp/pgp/wrapper.py +++ b/src/mailman_pgp/pgp/wrapper.py @@ -57,7 +57,7 @@ class PGPWrapper(): """ if self.is_mime_signed(): return self.mime.verify(key) - else: + elif self.is_inline_signed(): return self.inline.verify(key) def is_mime_encrypted(self): @@ -80,5 +80,19 @@ class PGPWrapper(): """ if self.is_mime_encrypted(): return self.mime.decrypt(key) - else: + elif self.is_inline_encrypted(): return self.inline.decrypt(key) + + def has_keys(self): + return self.mime.has_keys() or self.inline.has_keys() + + def keys(self): + """ + Get the collection of keys in this message. + + :return: A collection of keys. + """ + if self.mime.has_keys(): + yield from self.mime.keys() + elif self.inline.has_keys(): + yield from self.inline.keys() |
