From e0eb8fb4a57f17818e70836e596d32f185076767 Mon Sep 17 00:00:00 2001 From: Ignas Kiela Date: Wed, 20 Apr 2022 17:53:29 +0300 Subject: [PATCH] Default to 3DES when preferred algorithms don't have any supporting algorithm As per RFC 4880 13.2, "Since TripleDES is the MUST-implement algorithm, if it is not explicitly in the list, it is tacitly at the end." Some keys in the wild do not have it explicitly in the list, so put it there as a default. --- pgpy/pgp.py | 2 +- tests/test_99_regressions.py | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pgpy/pgp.py b/pgpy/pgp.py index 92bb5b2..52ec7bd 100644 --- a/pgpy/pgp.py +++ b/pgpy/pgp.py @@ -2437,7 +2437,7 @@ class PGPKey(Armorable, ParentRef, PGPObject): uid = next(iter(self.userids), None) if uid is None and self.parent is not None: uid = next(iter(self.parent.userids), None) - pref_cipher = next(c for c in uid.selfsig.cipherprefs if c.is_supported) + pref_cipher = next((c for c in uid.selfsig.cipherprefs if c.is_supported), SymmetricKeyAlgorithm.TripleDES) cipher_algo = prefs.pop('cipher', pref_cipher) if cipher_algo not in uid.selfsig.cipherprefs: diff --git a/tests/test_99_regressions.py b/tests/test_99_regressions.py index 41944b5..c99106f 100644 --- a/tests/test_99_regressions.py +++ b/tests/test_99_regressions.py @@ -583,3 +583,25 @@ cjMX82ahGPUVlyMP4A== key = PGPKey.from_file('tests/testdata/keys/rsa.1.pub.asc')[0] message = PGPMessage.from_blob(message_data) assert key.verify(message) + +@pytest.mark.regression(issue=393) +def test_preference_no_supported_ciphers(): + from pgpy import PGPMessage + keyblob = '''-----BEGIN PGP PUBLIC KEY BLOCK----- + +xo0EYmAayAEEAPQ0oYaLBPIF7bOA71X6kI0j7xnevfaHWfRzCoOJcDH4WJIRDbXD +cUkcKJoc710mRZREQm6HYcd61DBsohW3HT96h0/1HE4E1SbgN1GIAjh9rFiNy9F4 +/M5LHtn+KzsG1yB4eTOyOw5nr+y6DEVaw0a3dnTC541x1LnMplU0HAW3ABEBAAHN +G3Rlc3Qga2V5IDx0ZXN0QGV4YW1wbGUuY29tPsK8BBMBAgAmBQJiYBrLAhsvAhUC +Ah4BFiEErFJI/ShgHoPluKoDdK7/b7+9sGcACgkQdK7/b7+9sGcNlgP8D8hL8g3e +wP0HNxs7lXHyWT/uv6d02qEu/ZZ0fqf3CbEJ0aJQqDL61/utWK9hOt6nwTh+YvQP +VSigo9gDqyHdbq8fvKxeiKJIkCZmESN0RpSjf+JQrBLs9DSOWh4bLQ9EiE6GfgdL +n1hJ4Wx1aFL7WuPz/wj69MxPLh3nrG6i4iw= +=aDo/ +-----END PGP PUBLIC KEY BLOCK-----''' + + pubkey, _ = PGPKey.from_blob(keyblob) + msg = PGPMessage.new('asdf') + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + pubkey.encrypt(msg)