unit test cleanups and additions

This commit is contained in:
Michael Greene
2017-02-27 10:05:23 -08:00
parent 6977939da5
commit c9d39e3ebc
10 changed files with 146 additions and 97 deletions

View File

@@ -1500,7 +1500,7 @@ class PGPKey(Armorable, ParentRef, PGPObject):
if sib is None:
self._sibling = None
else:
else: # pragma: no cover
sib.__or__(copy.copy(other), True)
return self
@@ -2103,11 +2103,6 @@ class PGPKey(Armorable, ParentRef, PGPObject):
# collect signature(s)
if signature is None:
if isinstance(signature, PGPSignature):
if signature.signer != self.fingerprint.keyid and signature.signer not in self.subkeys:
raise PGPError("Incorrect key. Expected: {:s}".format(signature.signer))
sspairs.append((signature, subject))
if isinstance(subject, PGPMessage):
sspairs += [ (sig, subject.message) for sig in _filter_sigs(subject.signatures) ]
@@ -2131,7 +2126,7 @@ class PGPKey(Armorable, ParentRef, PGPObject):
# finally, start verifying signatures
sigv = SignatureVerification()
for sig, subj in sspairs:
if self.fingerprint.keyid != sig.signer:
if self.fingerprint.keyid != sig.signer and sig.signer in self.subkeys:
warnings.warn("Signature was signed with this key's subkey: {:s}. "
"Verifying with subkey...".format(sig.signer),
stacklevel=2)

View File

@@ -2,12 +2,10 @@
import pytest
import contextlib
# import functools
import glob
import os
import re
import select
# import six
import subprocess
import sys
import time
@@ -59,39 +57,6 @@ def _run(bin, *binargs, **pkw):
return cmdo, cmde
# # now import stuff from fixtures so it can be imported by test modules
# # from fixtures import TestFiles, gpg_getfingerprint, pgpdump, gpg_verify, gpg_fingerprint
#
#
# class CWD_As(object):
# def __init__(self, newwd):
# if not os.path.exists(newwd):
# raise FileNotFoundError(newwd + " not found within " + os.getcwd())
#
# self.oldwd = os.getcwd()
# self.newwd = newwd
#
# def __call__(self, func):
# @functools.wraps(func)
# def setcwd(*args, **kwargs):
# # set new working directory
# os.chdir(self.newwd)
#
# # fallback value
# fo = None
#
# try:
# fo = func(*args, **kwargs)
#
# finally:
# # always return to self.oldwd even if there was a failure
# os.chdir(self.oldwd)
#
# return fo
#
# return setcwd
_gpg_bin = _which('gpg2')
_gpg_args = ('--options', './pgpy.gpg.conf', '--expert', '--status-fd')
_gpg_env = {}
@@ -115,7 +80,6 @@ def _gpg(*gpg_args, **popen_kwargs):
if sys.version_info >= (3, 4):
os.set_inheritable(_gpgfd, True)
# args = _gpg_args + (str(_gpgfd),) + gpg_args
args = (_gpg_bin,) + _gpg_args + (str(_gpgfd),) + gpg_args
kwargs = _gpg_kwargs.copy()
kwargs.update(popen_kwargs)
@@ -159,7 +123,7 @@ def gpg_import():
os.mkdir('tests/testdata/private-keys-v1.d')
time.sleep(0.5)
gpgc, gpgo, gpge = _gpg('--import', *list(keypaths))
gpgc, gpgo, gpge = _gpg('--batch', '--import', *list(keypaths))
try:
yield gpgo
@@ -241,30 +205,6 @@ def gpg_decrypt():
status = sfd_decrypt.match(gpgc)
return gpgo
# gpg_args = [_gpg_bin] + _gpg_args[:]
# gpg_kwargs = _gpg_kwargs.copy()
# gpg_kwargs['stderr'] = subprocess.PIPE
# _comargs = ()
#
# if passphrase is not None:
# gpg_args += ['--batch', '--passphrase-fd', '0']
# gpg_kwargs['stdin'] = subprocess.PIPE
# _comargs = (passphrase.encode(),)
#
# if keyid is not None:
# gpg_args += ['--recipient', keyid]
#
# gpg_args += ['--decrypt', encmsgpath]
#
# gpgdec = subprocess.Popen(gpg_args, **gpg_kwargs)
# gpgo, gpge = gpgdec.communicate(*_comargs)
# gpgdec.wait()
#
# return sfd_decrypt.search(gpgo.decode()).group('text')
#
# # return gpgo.decode() if gpgo is not None else gpge
#
return _gpg_decrypt
@@ -289,10 +229,6 @@ def gpg_print():
def gpg_keyid_file():
def _gpg_keyid_file(infile):
c, o, e = _gpg('--list-packets', infile)
# gpg_args = _gpg_args + ['--list-packets', infile]
# gpg_kwargs = _gpg_kwargs.copy()
#
# gpgo, _ = _run(_gpg_bin, *gpg_args, **gpg_kwargs)
return re.findall(r'^\s+keyid: ([0-9A-F]+)', o, flags=re.MULTILINE)
return _gpg_keyid_file

View File

@@ -22,7 +22,11 @@ modules = ['pgpy.constants',
def get_module_objs(module):
# return a set of strings that represent the names of objects defined in that module
return { n for n, o in inspect.getmembers(module) if (inspect.getmodule(o) is module) }
return { n for n, o in inspect.getmembers(module, lambda m: inspect.getmodule(m) is module) } | ({'FlagEnum',} if module is importlib.import_module('pgpy.types') else set()) # dirty workaround until six fixes metaclass stuff to support EnumMeta in Python >= 3.6
def get_module_all(module):
return set(getattr(module, '__all__', set()))
def test_pgpy_all():
@@ -35,8 +39,4 @@ def test_pgpy_all():
def test_exports(modname):
module = importlib.import_module(modname)
modall = getattr(module, '__all__', None)
if modall is None:
pytest.skip('__all__ not defined')
assert set(modall) == get_module_objs(module)
assert get_module_all(module) == get_module_objs(module)

View File

@@ -5,20 +5,28 @@ import pytest
import glob
import os
from datetime import datetime
#
# from pgpy.constants import CompressionAlgorithm
from pgpy.constants import HashAlgorithm
# from pgpy.constants import KeyFlags
from pgpy.constants import PubKeyAlgorithm
from pgpy.constants import SignatureType
# from pgpy.constants import SymmetricKeyAlgorithm
from pgpy.pgp import PGPKey
from pgpy.pgp import PGPMessage
from pgpy.pgp import PGPSignature
blocks = sorted(glob.glob('tests/testdata/blocks/*.asc'))
block_attrs = {
'tests/testdata/blocks/message.ascii.asc':
[('encrypters', set()),
('filename', 'ascii'),
('is_compressed', False),
('is_encrypted', False),
('is_signed', False),
('issuers', set()),
('message', "This is stored, textually!\r\n"),
('signers', set()),
('type', 'literal'),],
'tests/testdata/blocks/message.compressed.asc':
[('encrypters', set()),
('filename', 'lit'),
@@ -227,6 +235,28 @@ block_attrs = {
('parent', None),
('signers', set()),],
'tests/testdata/blocks/dsaseckey.asc':
[('created', datetime(2017, 2, 21, 19, 21, 41)),
('expires_at', None),
('fingerprint', "2B5B BB14 3BA0 B290 DCEE 6668 B798 AE89 9087 7201"),
('is_expired', False),
('is_primary', True),
('is_protected', True),
('is_public', False),
('is_unlocked', False),
('key_algorithm', PubKeyAlgorithm.DSA),],
'tests/testdata/blocks/dsapubkey.asc':
[('created', datetime(2017, 2, 21, 19, 21, 41)),
('expires_at', None),
('fingerprint', "2B5B BB14 3BA0 B290 DCEE 6668 B798 AE89 9087 7201"),
('is_expired', False),
('is_primary', True),
('is_protected', False),
('is_public', True),
('is_unlocked', True),
('key_algorithm', PubKeyAlgorithm.DSA),],
'tests/testdata/blocks/openpgp.js.pubkey.asc':
[('created', datetime(2016, 6, 2, 21, 57, 13)),
('expires_at', None),
@@ -258,6 +288,10 @@ block_attrs = {
'tests/testdata/blocks/signature.expired.asc':
[('created', datetime(2014, 9, 28, 20, 54, 42)),
('is_expired', True),],
'tests/testdata/blocks/signature.non-exportable.asc':
[('created', datetime(2017, 2, 21, 20, 43, 34)),
('exportable', False),]
}

View File

@@ -1,12 +1,10 @@
""" test the functionality of PGPKeyring
"""
import pytest
#
import glob
import os
import six
import pgpy
from pgpy import PGPKey
from pgpy import PGPKeyring
from pgpy import PGPMessage

View File

@@ -11,28 +11,21 @@ import os
import six
import tempfile
import time
# from contextlib import contextmanager
from datetime import datetime, timedelta
# from warnings import catch_warnings
#
from pgpy import PGPKey
from pgpy import PGPMessage
from pgpy import PGPSignature
from pgpy import PGPUID
from pgpy.constants import CompressionAlgorithm
from pgpy.constants import EllipticCurveOID
from pgpy.constants import Features
from pgpy.constants import HashAlgorithm
from pgpy.constants import ImageEncoding
from pgpy.constants import KeyFlags
from pgpy.constants import KeyServerPreferences
from pgpy.constants import PubKeyAlgorithm
from pgpy.constants import RevocationReason
from pgpy.constants import SignatureType
from pgpy.constants import SymmetricKeyAlgorithm
from pgpy.constants import TrustLevel
from pgpy.errors import PGPDecryptionError
from pgpy.errors import PGPError
from pgpy.packet import Packet
from pgpy.packet.packets import PrivKeyV4
from pgpy.packet.packets import PrivSubKeyV4
@@ -234,6 +227,8 @@ class TestPGPKey_Management(object):
else:
key.add_uid(uid, hashes=[HashAlgorithm.SHA224])
assert uid in key
# self-verify the key
assert key.verify(key)
self.keys[(alg, size)] = key
@@ -329,6 +324,19 @@ class TestPGPKey_Management(object):
@pytest.mark.run(after='test_add_photo')
@pytest.mark.parametrize('pkspec', pkeyspecs, ids=[str(a) for a, s in pkeyspecs])
def test_revoke_altuid(self, pkspec):
if pkspec not in self.keys:
pytest.skip('Keyspec {} not in keys; must not have generated'.format(pkspec))
# add revoke altuid
key = self.keys[pkspec]
altuid = key.get_uid('T. Keyerson')
revsig = key.revoke(altuid)
altuid |= revsig
@pytest.mark.run(after='test_remove_altuid')
@pytest.mark.parametrize('pkspec', pkeyspecs, ids=[str(a) for a, s in pkeyspecs])
def test_remove_altuid(self, pkspec):
if pkspec not in self.keys:
pytest.skip('Keyspec {} not in keys; must not have generated'.format(pkspec))
@@ -348,7 +356,10 @@ class TestPGPKey_Management(object):
# add a revocation key
rev = self.keys[next(pks for pks in pkeyspecs if pks != pkspec)]
key = self.keys[pkspec]
key |= key.revoker(rev)
revsig = key.revoker(rev)
key |= revsig
assert revsig in key
# try to verify with GPG
self.gpg_verify_key(key)
@@ -586,11 +597,14 @@ class TestPGPKey_Actions(object):
user=targette_sec.userids[0].name,
expires=timedelta(seconds=30),
revocable=False,
notation={'Testing': 'This signature was generated during unit testing'},
notation={'Testing': 'This signature was generated during unit testing',
'cooldude': bytearray(b'\xc0\x01\xd0\x0d')},
policy_uri='about:blank')
assert sig.type == SignatureType.BinaryDocument
assert sig.notation == {'Testing': 'This signature was generated during unit testing'}
assert sig.notation == {'Testing': 'This signature was generated during unit testing',
'cooldude': bytearray(b'\xc0\x01\xd0\x0d')}
assert sig.revocable is False
assert sig.policy_uri == 'about:blank'
# assert sig.sig.signer_uid == "{:s}".format(sec.userids[0])
@@ -739,7 +753,11 @@ class TestPGPKey_Actions(object):
def test_certify_uid(self, sec, abe):
# sign the uid
userid = abe.userids[0]
sig = sec.certify(userid, SignatureType.Casual_Cert, trust=(1, 60))
# test with all possible subpackets
sig = sec.certify(userid, SignatureType.Casual_Cert,
trust=(1, 60),
regex='(.*)',
exportable=True,)
userid |= sig
assert sig.type == SignatureType.Casual_Cert

24
tests/testdata/blocks/dsapubkey.asc vendored Normal file
View File

@@ -0,0 +1,24 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGiBFisk0URBACkc86J1iRa6gV0nQvuZve9WkbGkJWT0kopILrB5H0SckXkLwOx
kR+T+f/+S1GG+7qB39E0tCNDPEQlm06hfof0sKZ594GSNFDfWvcIYNksxyIJ3dHM
obkt7LbrWVqm/QzwhJqnvQEdNPD2tZYmJYlDEFvL3buPfyiczf7LRBVa2wCgmG43
XQ2TbbBl3oVnnpaWMRuo3RMD/27hIJ+ww3zXkH9Nd/4vC3jKsMk/DSxR/MKfcbam
LxRon409/k3c31LDskBz7secNgscvlTzsWwsib2ACw1Cr3cUWke28kypVAJlwVqt
F2OVFjSO9OKjHOwACF/N1tMjulcKHqDRW4EkkNBZpzKwn37UycDbhnxpaeHAjGOe
rPyTA/43OSP/P2WJw1hramsfHV9BAS2jd2+qz3dPdhaB2BdLa7OuZVkik2bnMyp8
IGtblORz2f1Vuc+0Wp3FL4zsrakN3L7VZwla1Gp+FkNpY3Mgfn7Ts69Pl57Y5+Cm
CTRa2lKflL3yM+nf8a/1tCHuOtl/iaQQhLoMkRSpHdrYiIQqzLQeRFNBIHZvbiBU
ZXN0S2V5IDxkc2FAdGVzdC5rZXk+iHgEExECADgWIQQrW7sUO6CykNzuZmi3mK6J
kIdyAQUCWKyTRQIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRC3mK6JkIdy
AdNGAJ9T8hKPVWoG0UJFQo2/6Cr9okRSZACeNxxJ92pOU/LEo9TgtqQqbmk73SK5
AQ0EWKyTRRAEAMXlraLYYWCNoMa0s6aeRvmlQHZiXqcB3ECI+hO4EivzisXAQhg1
BQPDn6IMCE4pX69Q/z2LOk6aeD1htMymWzGbyzG7jFRX8Q9US9ooul+nvSVf3xVW
UjeLGKi8Z3yD2lK8efB/bGxxx7xdNlrk2AyucnHjyc+HOcyKoNA8TAW3AAURA/9D
dpz9M1Rsb9vR4QFHh03fcFh46dhFMjT94ShwMVaJSWy0gHNnTp0MmDzQAdBSFJYE
rdZV7YCex6HoHfGS7btpEX//YoxL/nsoP73y34PgYmmqYLZ95cCLdn+YuYPhNAQT
klCNR4fjtZme83oZLgzd4Hkl5maVixRmA1n8TOB7QYhfBBgRAgAgFiEEK1u7FDug
spDc7mZot5iuiZCHcgEFAlisk0UCGwwACgkQt5iuiZCHcgE5wgCbB5EYVFft5QPK
KiUE3NMzKCik1pEAmOO+qvoi2g6DG2mmEU5Y56IoiSQ=
=wk7s
-----END PGP PUBLIC KEY BLOCK-----

27
tests/testdata/blocks/dsaseckey.asc vendored Normal file
View File

@@ -0,0 +1,27 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQHpBFisk0URBACkc86J1iRa6gV0nQvuZve9WkbGkJWT0kopILrB5H0SckXkLwOx
kR+T+f/+S1GG+7qB39E0tCNDPEQlm06hfof0sKZ594GSNFDfWvcIYNksxyIJ3dHM
obkt7LbrWVqm/QzwhJqnvQEdNPD2tZYmJYlDEFvL3buPfyiczf7LRBVa2wCgmG43
XQ2TbbBl3oVnnpaWMRuo3RMD/27hIJ+ww3zXkH9Nd/4vC3jKsMk/DSxR/MKfcbam
LxRon409/k3c31LDskBz7secNgscvlTzsWwsib2ACw1Cr3cUWke28kypVAJlwVqt
F2OVFjSO9OKjHOwACF/N1tMjulcKHqDRW4EkkNBZpzKwn37UycDbhnxpaeHAjGOe
rPyTA/43OSP/P2WJw1hramsfHV9BAS2jd2+qz3dPdhaB2BdLa7OuZVkik2bnMyp8
IGtblORz2f1Vuc+0Wp3FL4zsrakN3L7VZwla1Gp+FkNpY3Mgfn7Ts69Pl57Y5+Cm
CTRa2lKflL3yM+nf8a/1tCHuOtl/iaQQhLoMkRSpHdrYiIQqzP4HAwKXqnH0U/4k
KO7U5CKhvfx/ux6nw+SCR7BF68Slo2Emzu1u1ytu3YJul8WsfNW8DIfe43m3LYhf
Eqkaw+PS8BnQLqLFtB5EU0Egdm9uIFRlc3RLZXkgPGRzYUB0ZXN0LmtleT6IeAQT
EQIAOBYhBCtbuxQ7oLKQ3O5maLeYromQh3IBBQJYrJNFAhsDBQsJCAcCBhUICQoL
AgQWAgMBAh4BAheAAAoJELeYromQh3IB00YAn1PyEo9VagbRQkVCjb/oKv2iRFJk
AJ43HEn3ak5T8sSj1OC2pCpuaTvdIp0BYARYrJNFEAQAxeWtothhYI2gxrSzpp5G
+aVAdmJepwHcQIj6E7gSK/OKxcBCGDUFA8OfogwITilfr1D/PYs6Tpp4PWG0zKZb
MZvLMbuMVFfxD1RL2ii6X6e9JV/fFVZSN4sYqLxnfIPaUrx58H9sbHHHvF02WuTY
DK5ycePJz4c5zIqg0DxMBbcABRED/0N2nP0zVGxv29HhAUeHTd9wWHjp2EUyNP3h
KHAxVolJbLSAc2dOnQyYPNAB0FIUlgSt1lXtgJ7Hoegd8ZLtu2kRf/9ijEv+eyg/
vfLfg+Biaapgtn3lwIt2f5i5g+E0BBOSUI1Hh+O1mZ7zehkuDN3geSXmZpWLFGYD
WfxM4HtB/gcDAnepsPge3rKk7rHlUAbFtKH0vOu4HJQb5iPRzy6UHbDbQ0lN7qMX
pjHwCKQ5/Lmx8T8IIF4Cajzk31Gucb9xUJ0OxvPjCWOQ6D7jEEt9m9SIXwQYEQIA
IBYhBCtbuxQ7oLKQ3O5maLeYromQh3IBBQJYrJNFAhsMAAoJELeYromQh3IBOcIA
mweRGFRX7eUDyiolBNzTMygopNaRAJjjvqr6ItoOgxtpphFOWOeiKIkk
=MJIx
-----END PGP PRIVATE KEY BLOCK-----

View File

@@ -0,0 +1,5 @@
-----BEGIN PGP MESSAGE-----
yyd0BWFzY2lpWKyiRVRoaXMgaXMgc3RvcmVkLCB0ZXh0dWFsbHkhDQo=
=PmSE
-----END PGP MESSAGE-----

View File

@@ -0,0 +1,12 @@
-----BEGIN PGP SIGNATURE-----
Version: PGPy v0.5.0
iQE2BBABCAAgFiEE9ClLyAlKfgWFyF6GN0c7N1jETzYFAlispnYCBAAACgkQN0c7
N1jETzbkhgf/cMR8dJObANItbQD6V96zoC/fSPSntE7XyVGNEl3efGY8CMIx0a9n
y+pOLgnKQcYdUi39U4U0KllnmulV4Z3HJvn6OqA77iQKdpQ3zEhWNA0/5QWIZja5
uI1zRSITfr5KMYJPni+ET09bsYkT8RB+yw5ZOUY6hFyZhuMmk2+FqF2ZS2xUf8yY
aQc6twqRo6tEck6c9zI5fO/MJQE7Zn55ijZp6Qk1yYDFfn3nq0oVp/lBkPXWiM5R
OMDrOYMqAJIliBxcab33dGU/e+afm4vNdOtidAw1CCQtwFF/R2LVei3ba2ceaj8T
ak7da9ht6w9wxU3wjgPd6iz6FIIIv4UqaQ==
=LNt/
-----END PGP SIGNATURE-----