From 30bd1c097544376f257d426d5feb4706fb5d3afd Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Wed, 5 Dec 2018 20:17:43 +0300 Subject: [PATCH 1/4] python: make it easier to run a limited number of tests * lang/python/tests/Makefile.am: prefer py_tests from the environment if present. -- I'm trying to make it nicer/quicker to hack on the testsuite for python bindings. With this change, if you're improving the python bindings test suite, you can selectively run only a few specific tests like so: lang/python$ make check py_tests='t-decrypt.py t-decrypt-verify.py' Signed-off-by: Daniel Kahn Gillmor --- lang/python/tests/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/python/tests/Makefile.am b/lang/python/tests/Makefile.am index d5b6e001..2c2324e8 100644 --- a/lang/python/tests/Makefile.am +++ b/lang/python/tests/Makefile.am @@ -28,7 +28,7 @@ TESTS_ENVIRONMENT = GNUPGHOME=$(GNUPGHOME) \ srcdir=$(srcdir) \ LD_LIBRARY_PATH="../../../src/.libs:$(LD_LIBRARY_PATH)" -py_tests = t-wrapper.py \ +py_tests ?= t-wrapper.py \ t-callbacks.py \ t-data.py \ t-encrypt.py \ From c5c3a9d10be415ea7bc0cd9730ad6085f16ee7a0 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Wed, 5 Dec 2018 20:31:07 +0300 Subject: [PATCH 2/4] tests: add two new types of encrypted data * tests/gpg/cipher-3.asc: add an encrypted file containing signatures (one from a known key, and one from an unknown key) * tests/gpg/cipher-no-sig.asc: add an encrypted file containing no signatures at all -- We currently aren't using these files yet, but they should be useful for exercising the library in unusual circumstances (where the bugs are). Signed-off-by: Daniel Kahn Gillmor --- tests/gpg/Makefile.am | 1 + tests/gpg/cipher-3.asc | 18 ++++++++++++++++++ tests/gpg/cipher-no-sig.asc | 13 +++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 tests/gpg/cipher-3.asc create mode 100644 tests/gpg/cipher-no-sig.asc diff --git a/tests/gpg/Makefile.am b/tests/gpg/Makefile.am index be842902..68222fa7 100644 --- a/tests/gpg/Makefile.am +++ b/tests/gpg/Makefile.am @@ -59,6 +59,7 @@ private_keys = \ EXTRA_DIST = initial.test final.test \ pubdemo.asc secdemo.asc cipher-1.asc cipher-2.asc \ + cipher-3.asc cipher-no-sig.asc \ geheim.txt pubkey-1.asc seckey-1.asc pinentry $(private_keys) BUILT_SOURCES = gpg.conf gpg-agent.conf pubring-stamp \ diff --git a/tests/gpg/cipher-3.asc b/tests/gpg/cipher-3.asc new file mode 100644 index 00000000..10125b5b --- /dev/null +++ b/tests/gpg/cipher-3.asc @@ -0,0 +1,18 @@ +-----BEGIN PGP MESSAGE----- + +hQEOA++dwnahcsiBEAQApowkbz0idxMfLIT/a1G4QbZy77cWyaYOM/qh4lH4h7ra +f19MZzbRViZYBtJeITszTFmulp31qrF++6gBy8tU7l8VfVfOtvwn1WlRvn2+bsns +SicJAXtUiwIF8fbapSrkN6qpg2l+Fnx3SYV7+lh/7Fbf93DquwVEn+GwvgkyCQkD +/j5UVU6PJ+k5E5JG7CMzLZHnpW1MtKUqKRG9sTW83SvvI5Wl9VMgjmdO6bZRPKPY +Fr5udYJ1v4CIpVTb0O/TgAaiw7/Ak4SOg6jK0H0l1vuPPRjyzx43G4Y4lZ/EoCzT +gU+0kiDD+O7xLDml5jPWTYov7LkhRMKI4Ugp37FzbF9p0sClAR1mY4WlAN23ku0W +3bw54zSi7S6sh+i/uOmjZ+ziXr/S1pHFN2TNAkpH42o6VDhJ4vYk5KIB/mn/IoP1 +G57JUhLqpSHO7LF8X45eBLT3tKC3rIaILHXcXE5PeyMiOrl1snIClrpX+Qn6dRPX +cYssX/0OQwE77bAla5QpZEy6YLOC4Ej4oTX5QU1rHNyLfvIDhwtphKMvbbssmsVI +tAMvrGQudEwLSlvNlnJsI79jqmbi5W8PYr+ssvOvrd5hWoKti7EdglWddFNVVjZl +ooJgztXUnPcufhaimQtNvX0Tj2hI8QwTxGPNO3aesPCQI0GbSUSqpvu6mlaQY2Qe +NJNkfTH23fzoG61nFxIQ0HYbuBp0hJnGOXfHtMNxyjoAs1yEJbyQ20Lso/Vrsf3J +sY7jkisFrURxTGQyBxxbnIO+nJPemOzV9Q/qo6Lj9yW0KagaffWogw/6X/xOvL4u +aM8pI7NOi48b +=mh2s +-----END PGP MESSAGE----- diff --git a/tests/gpg/cipher-no-sig.asc b/tests/gpg/cipher-no-sig.asc new file mode 100644 index 00000000..47e399c3 --- /dev/null +++ b/tests/gpg/cipher-no-sig.asc @@ -0,0 +1,13 @@ +-----BEGIN PGP MESSAGE----- + +hQEOA++dwnahcsiBEAP8CPkDWzZrcMJ1fyaPoQAhlx18p44+7vTF5zYCkMVT+i4E +X/zcIreDYDpFNHzK2orNW/LGGNpMf3ZyDAYw7eDWgPwld2PJh2/ZfR/dXoGcAEd4 +vhbhA1D/ymQn+lxgSXNLMonxaoCqFK7cKStLCHfaPMbQ0S5GXU0IRwjfSn76oxwE +AKzTa/54g8XNL9Dku9c/KATzopdDLzAzN6oBJlgRbjhc3T8mzTVJF91s+ow8dEC+ +0U2GBwkL5ZOKTFelSO3dBsH7RBNbYiJA+DbZ6nZia2KAtlLgyr4Z5vGh9bmltJl/ +1qdIdRF/La3wA/6bL10YMYF+7IJ9DiuDi/NRmSsO/ZWt0nMBXnzOeyLgxdbW1RS1 +NPWzKC/4RqvnWJmm7W3p0JG8v2ad+97O5KsOcqJnaKJOY0jKXeORrhih2DG32rpe +4bhskRTIBJBaPtPnRGevlxardQi+Spbd75yqccCLjkQF0HhCLiHW9SJiLSMdnY1U +U9th3ZR5 +=uvfB +-----END PGP MESSAGE----- From bd2d282e572b5d02669238c9e087259b85638477 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Thu, 2 May 2019 22:16:51 -0400 Subject: [PATCH 3/4] python/tests: try to decrypt and verify new test data * lang/python/tests/t-decrypt.py: test decryption of cipher-3.asc and cipher-no-sig.asc * lang/python/tests/t-decrypt-verify.py: test decryption and verification of cipher-3.asc and cipher-no-sig.asc -- note that this introduces a failed test -- decrypt-verify.py misbehaves on cipher-3.asc by throwing a BadSignature even though GnuPG-bug-id: 4276 Signed-off-by: Daniel Kahn Gillmor --- lang/python/tests/t-decrypt-verify.py | 11 +++++++++++ lang/python/tests/t-decrypt.py | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/lang/python/tests/t-decrypt-verify.py b/lang/python/tests/t-decrypt-verify.py index a0049a02..6a4fc554 100755 --- a/lang/python/tests/t-decrypt-verify.py +++ b/lang/python/tests/t-decrypt-verify.py @@ -75,3 +75,14 @@ with gpg.Context() as c: assert e.missing[0] == bob else: assert False, "Expected an error, got none" + + plaintext, _, verify_result = c.decrypt(open(support.make_filename("cipher-no-sig.asc"))) + assert len(plaintext) > 0 + assert len(verify_result.signatures) == 0 + assert plaintext.find(b'Viscosity Dispersal Thimble Saturday Flaxseed Deflected') >= 0, \ + 'unsigned Plaintext was not found' + + plaintext, _, verify_result = c.decrypt(open(support.make_filename("cipher-3.asc"))) + assert len(plaintext) > 0 + assert plaintext.find(b'Reenact Studied Thermos Bonehead Unclasp Opposing') >= 0, \ + 'second Plaintext not found' diff --git a/lang/python/tests/t-decrypt.py b/lang/python/tests/t-decrypt.py index c72b51ab..99002749 100755 --- a/lang/python/tests/t-decrypt.py +++ b/lang/python/tests/t-decrypt.py @@ -42,3 +42,13 @@ with gpg.Context() as c: assert len(plaintext) > 0 assert plaintext.find(b'Wenn Sie dies lesen k') >= 0, \ 'Plaintext not found' + + plaintext, _, _ = c.decrypt(open(support.make_filename("cipher-3.asc")), verify=False) + assert len(plaintext) > 0 + assert plaintext.find(b'Reenact Studied Thermos Bonehead Unclasp Opposing') >= 0, \ + 'second Plaintext not found' + + plaintext, _, _ = c.decrypt(open(support.make_filename("cipher-no-sig.asc")), verify=False) + assert len(plaintext) > 0 + assert plaintext.find(b'Viscosity Dispersal Thimble Saturday Flaxseed Deflected') >= 0, \ + 'third Plaintext was not found' From 4100794e305ba22241ea5a4f7b42bb5189fbd948 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Thu, 2 May 2019 23:28:11 -0400 Subject: [PATCH 4/4] python: stop raising BadSignatures from decrypt(verify=True) * src/core.py (decrypt): filter out signatures with errors from the returned verify_result, but avoid raising BadSignatures * tests/t-decrypt-verify.py: ensure that only a single signature is returned when evaluating cipher-3.asc, since the other signature is unknown. -- This change preserves the invariant that decrypt() only ever returns valid signatures in the verify_result, but it avoids unnecessary errors in the face of the presence of an additional bad signature. GnuPG-bug-id: 4276 Signed-off-by: Daniel Kahn Gillmor --- lang/python/src/core.py | 22 +++++++++------------- lang/python/tests/t-decrypt-verify.py | 1 + 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/lang/python/src/core.py b/lang/python/src/core.py index c096ee73..11af7027 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -342,10 +342,12 @@ class Context(GpgmeWrapper): Decrypt the given ciphertext and verify any signatures. If VERIFY is an iterable of keys, the ciphertext must be signed - by all those keys, otherwise an error is raised. Note: if - VERIFY is an empty iterable, that is treated the same as - passing verify=True (that is, do verify signatures, but no - specific keys are required). + by all those keys, otherwise a MissingSignatures error is + raised. Note: if VERIFY is an empty iterable, that is treated + the same as passing verify=True (that is, verify signatures + and return data about any valid signatures found, but no + signatures are required and no MissingSignatures error will be + raised). If the ciphertext is symmetrically encrypted using a passphrase, that passphrase can be given as parameter, using a @@ -361,11 +363,10 @@ class Context(GpgmeWrapper): Returns: plaintext -- the decrypted data (or None if sink is given) result -- additional information about the decryption - verify_result -- additional information about the signature(s) + verify_result -- additional information about the valid signature(s) found Raises: UnsupportedAlgorithm -- if an unsupported algorithm was used - BadSignatures -- if a bad signature is encountered MissingSignatures -- if expected signatures are missing or bad GPGMEError -- as signaled by the underlying library @@ -430,13 +431,8 @@ class Context(GpgmeWrapper): results=results) if do_sig_verification: - # FIXME: should we really throw BadSignature, even if - # we've encountered some good signatures? as above, once - # we hit this error, there is no way to accept it and - # continue to process the remaining signatures. - if any(s.status != errors.NO_ERROR - for s in verify_result.signatures): - raise errors.BadSignatures(verify_result, results=results) + # filter out all invalid signatures + verify_result.signatures = list(filter(lambda s: s.status == errors.NO_ERROR, verify_result.signatures)) if required_keys is not None: missing = [] for key in required_keys: diff --git a/lang/python/tests/t-decrypt-verify.py b/lang/python/tests/t-decrypt-verify.py index 6a4fc554..300fc713 100755 --- a/lang/python/tests/t-decrypt-verify.py +++ b/lang/python/tests/t-decrypt-verify.py @@ -84,5 +84,6 @@ with gpg.Context() as c: plaintext, _, verify_result = c.decrypt(open(support.make_filename("cipher-3.asc"))) assert len(plaintext) > 0 + assert len(verify_result.signatures) == 1 assert plaintext.find(b'Reenact Studied Thermos Bonehead Unclasp Opposing') >= 0, \ 'second Plaintext not found'