From d00010ef04c0fe1353756b04cba257d2a75e5db9 Mon Sep 17 00:00:00 2001 From: Michael Greene Date: Mon, 29 Sep 2014 13:36:52 -0700 Subject: [PATCH] primary/subkey binding now fully works - closes #104; removed FileLoader class; renamed Exportable to Armorable; removed requests from requirements.txt; updated README.rst - closes #127; progress --- README.rst | 6 +- docs/source/progress.rst | 16 ++--- pgpy/decorators.py | 10 +++ pgpy/packet/subpackets/signature.py | 4 +- pgpy/pgp.py | 48 +++++++------- pgpy/types.py | 99 ++++------------------------- requirements.txt | 1 - tests/test_4_PGPKeyring.py | 57 +++++++++++++---- tests/test_5_actions.py | 68 ++++++++++++-------- 9 files changed, 147 insertions(+), 162 deletions(-) diff --git a/README.rst b/README.rst index 197f478e..df4ab599 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ PGPy: Pretty Good Privacy for Python Homepage: None yet. -`PGPy` is a Python (2 and 3) library for implementing Pretty Good Privacy into Python programs. +`PGPy` is a Python (2 and 3) library for implementing Pretty Good Privacy into Python programs, conforming to the OpenPGP specification per RFC 4880. Features -------- @@ -45,12 +45,12 @@ Requirements Tested with: 3.4, 3.3, 3.2, 2.7 -- `Requests `_ - - `Cryptography `_ - `enum34 `_ +- `singledispatch `_ + - `six `_ License diff --git a/docs/source/progress.rst b/docs/source/progress.rst index d80fb2ce..27ce1cb9 100644 --- a/docs/source/progress.rst +++ b/docs/source/progress.rst @@ -77,16 +77,16 @@ PGPy is focused on eventually reaching complete OpenPGP implementation, adhering - Sign, True, Certify User IDs using DSA - Sign, True, Certify User Attribute packets using RSA - Sign, True, Certify User Attribute packets using DSA - - Sign, False, Generate key binding signatures using RSA - - Sign, False, Generate key binding signatures using DSA - - Sign, False, Generate signatures directly on a key using RSA - - Sign, False, Generate signatures directly on a key using DSA + - Sign, True, Generate key binding signatures using RSA + - Sign, True, Generate key binding signatures using DSA + - Sign, True, Generate signatures directly on a key using RSA + - Sign, True, Generate signatures directly on a key using DSA - Sign, True, Revoke certifications using RSA - Sign, True, Revoke certifications using DSA - - Sign, False, Revoke key using RSA - - Sign, False, Revoke key using DSA - - Sign, False, Revoke subkey using RSA - - Sign, False, Revoke subkey using DSA + - Sign, True, Revoke key using RSA + - Sign, True, Revoke key using DSA + - Sign, True, Revoke subkey using RSA + - Sign, True, Revoke subkey using DSA - Sign, True, Generate timestamp signatures using RSA - Sign, True, Generate timestamp signatures using DSA - Sign, False, Generate third party confirmation signatures using RSA diff --git a/pgpy/decorators.py b/pgpy/decorators.py index 5d0d2a94..6f3cf9de 100644 --- a/pgpy/decorators.py +++ b/pgpy/decorators.py @@ -90,6 +90,16 @@ def _preiter(first, iterable): def __call__(self, action): @functools.wraps(action) def _action(key, *args, **kwargs): + ignore_usage = kwargs.pop('ignore_usage', False) + if ignore_usage: + for prop, expected in self.conditions.items(): + if getattr(key, prop) != expected: + raise PGPError("Expected: {prop:s} == {eval:s}. Got: {got:s}" + "".format(prop=prop, eval=str(expected), got=str(getattr(key, prop)))) + + # do the thing + return action(key, *args, **kwargs) + with self.usage(key) as _key: # check properties for prop, expected in self.conditions.items(): diff --git a/pgpy/packet/subpackets/signature.py b/pgpy/packet/subpackets/signature.py index d92ee7fe..eb4ff35f 100644 --- a/pgpy/packet/subpackets/signature.py +++ b/pgpy/packet/subpackets/signature.py @@ -826,7 +826,9 @@ def _sig(self): @_sig.setter def _sig(self, val): - self._sig = val + val.header = EmbeddedSignatureHeader() + val.update_hlen() + self._sigpkt = val @property def sigtype(self): diff --git a/pgpy/pgp.py b/pgpy/pgp.py index 578cc36e..4fe9d5ef 100644 --- a/pgpy/pgp.py +++ b/pgpy/pgp.py @@ -64,7 +64,7 @@ from .packet.types import Opaque -from .types import Exportable +from .types import Armorable from .types import PGPObject from .types import SignatureVerification @@ -113,7 +113,7 @@ def _deque_resort(seq, item): raise ValueError -class PGPSignature(PGPObject, Exportable): +class PGPSignature(PGPObject, Armorable): @property def __sig__(self): return self._signature.signature.__sig__() @@ -296,8 +296,7 @@ def hashdata(self, subject): For binary document signatures (type 0x00), the document data is hashed directly. """ - _s = self.load(subject) - _data += _s + _data += bytearray(subject) if self.type == SignatureType.CanonicalDocument: """ @@ -410,7 +409,7 @@ def make_onepass(self): return onepass def parse(self, packet): - unarmored = self.ascii_unarmor(self.load(packet)) + unarmored = self.ascii_unarmor(packet) data = unarmored['body'] if unarmored['magic'] is not None and unarmored['magic'] != 'SIGNATURE': @@ -546,7 +545,7 @@ def __add__(self, other): "".format(self.__class__.__name__, other.__class__.__name__)) -class PGPMessage(PGPObject, Exportable): +class PGPMessage(PGPObject, Armorable): @staticmethod def dash_unescape(text): return re.subn(r'^- -', '-', text, flags=re.MULTILINE)[0] @@ -722,12 +721,13 @@ def new(cls, message, **kwargs): prefs.update(kwargs) if prefs['cleartext']: - _m = cls.load(message).decode('latin-1') + # _m = cls.load(message).decode('latin-1') + _m = message else: # load literal data lit = LiteralData() - lit._contents = cls.load(message) + lit._contents = bytearray(six.b(message)) lit.format = prefs['format'] if os.path.isfile(message): @@ -805,7 +805,7 @@ def decrypt(self, passphrase): return decmsg def parse(self, packet): - unarmored = self.ascii_unarmor(self.load(packet)) + unarmored = self.ascii_unarmor(packet) data = unarmored['body'] if unarmored['magic'] is not None and unarmored['magic'] not in ['MESSAGE', 'SIGNATURE']: @@ -831,7 +831,7 @@ def parse(self, packet): self += Packet(data) -class PGPKey(PGPObject, Exportable): +class PGPKey(PGPObject, Armorable): """ 11.1. Transferable Public Keys @@ -1182,17 +1182,18 @@ def sign(self, subject, **prefs): legal(id='revoke', types=PGPKey, criteria=[getattr(subject, 'is_primary', None) is False], sigtypes={SignatureType.SubkeyRevocation}), legal(id='selfcertify', types=(PGPUID, PGPKey), - criteria=[ (getattr(subject, 'fingerprint', None) if isinstance(subject, PGPKey) - else getattr(getattr(subject, '_parent', None), 'fingerprint', None)) == self.fingerprint], + criteria=[ (getattr(subject, 'fingerprint', None) if isinstance(subject, PGPKey) else + getattr(getattr(subject, '_parent', None), 'fingerprint', None)) == self.fingerprint], sigtypes=SignatureType.certifications ^ {SignatureType.CertRevocation}), legal(id='bind_sub', types=PGPKey, criteria=[getattr(subject, 'is_primary', None) is False, getattr(getattr(subject, '_parent', None), 'fingerprint', None) == self.fingerprint], sigtypes={SignatureType.Subkey_Binding}), - # legal(id='bind_pri', types=PGPKey, - # criteria=[getattr(subject, 'is_primary', None) is True, - # getattr(self, '_parent', None) is not None, - # getattr(subject, 'fingerprint', None) == self._parent.fingerprint]), + legal(id='bind_pri', types=PGPKey, + criteria=[getattr(subject, 'is_primary', None) is True, + getattr(self, '_parent', None) is not None, + getattr(subject, 'fingerprint', None) == getattr(self._parent, 'fingerprint', False)], + sigtypes={SignatureType.PrimaryKey_Binding}), legal(id='certify', types=PGPUID, criteria=[], sigtypes=SignatureType.certifications ^ {SignatureType.CertRevocation}), legal(id='directkey', types=PGPKey, criteria=[], sigtypes={SignatureType.DirectlyOnKey})] @@ -1202,9 +1203,6 @@ def sign(self, subject, **prefs): if combo is None: raise PGPError('SignatureType.{:s} not supported on subject type {}'.format(sig.type.name, str(type(subject)))) - if combo.id == 'load': - subject = self.load(subject) - if combo.id == 'msg': subject = subject.message @@ -1217,9 +1215,9 @@ def sign(self, subject, **prefs): usage_flags = prefs.pop('usage', []) sig._signature.subpackets.addnew('KeyFlags', hashed=True, flags=usage_flags) - # if combo.id == 'bind_sub' and subject.key_algorithm.can_sign: - # esig = self.subkeys[subject.fingerprint.keyid].sign(self, sigtype=SignatureType.PrimaryKey_Binding) - # sig._signature.subpackets.addnew('EmbeddedSignature', hashed=False, _sig=esig._signature) + if combo.id == 'bind_sub' and subject.key_algorithm.can_sign: + esig = self.subkeys[subject.fingerprint.keyid].sign(self, ignore_usage=True, sigtype=SignatureType.PrimaryKey_Binding) + sig._signature.subpackets.addnew('EmbeddedSignature', hashed=False, _sig=esig._signature) if combo.id in ['selfcertify', 'directkey']: flag_opts = [('cipherprefs', 'PreferredSymmetricAlgorithms'), @@ -1279,8 +1277,8 @@ def verify(self, subject, signature=None): raise ValueError("Unexpected signature value: {:s}".format(str(type(signature)))) # load the signature subject if necessary - if isinstance(subject, (six.string_types, bytes, bytearray)): - subject = self.load(subject) + # if isinstance(subject, (six.string_types, bytes, bytearray)): + # subject = self.load(subject) def _filter_sigs(sigs): _ids = {self.fingerprint.keyid} | set(self.subkeys) @@ -1425,7 +1423,7 @@ def decrypt(self, message): return decmsg def parse(self, data): - unarmored = self.ascii_unarmor(self.load(data)) + unarmored = self.ascii_unarmor(data) data = unarmored['body'] if unarmored['magic'] is not None and 'KEY' not in unarmored['magic']: diff --git a/pgpy/types.py b/pgpy/types.py index 4e197018..b89ae750 100644 --- a/pgpy/types.py +++ b/pgpy/types.py @@ -14,8 +14,6 @@ from enum import EnumMeta from enum import IntEnum -import requests - import six from ._author import __version__ @@ -28,7 +26,16 @@ re.ASCII = 0 -class FileLoader(object): +class Armorable(six.with_metaclass(abc.ABCMeta)): + __crc24_init__ = 0x0B704CE + __crc24_poly__ = 0x1864CFB + + __armor_fmt__ = '-----BEGIN PGP {block_type}-----\n' \ + '{headers}\n' \ + '{packet}\n' \ + '={crc}\n' \ + '-----END PGP {block_type}-----\n' + @staticmethod def is_ascii(text): if not isinstance(text, (str, bytes, bytearray)): @@ -55,85 +62,13 @@ def is_path(ppath): return False - @classmethod - def load(cls, lf): - _bytes = bytearray() - - # None means nothing to load - if lf is None: - pass - - # This is a file-like object - elif hasattr(lf, "readinto") and hasattr(lf, "fileno"): - _bytes = bytearray(os.stat(lf.fileno).st_size) - lf.readinto(_bytes) - - elif hasattr(lf, "read"): - _bytes = bytearray(lf.read()) - - # this could be a path - elif cls.is_path(lf): - lf = os.path.expanduser(lf) - # this is a URI - if "://" in lf: - r = requests.get(lf, verify=True) - - if not r.ok: - raise FileNotFoundError(lf) - - _bytes = r.content - - # this is an existing file - elif os.path.isfile(lf): - with open(lf, 'rb') as lf: - _bytes = bytearray(lf.read()) - - # this is a new file - elif os.path.isdir(os.path.dirname(lf)): - pass - - # this is all wrong - else: - raise FileNotFoundError(lf) - - # this is probably data we want to load directly - elif isinstance(lf, bytearray): - _bytes = lf - - elif isinstance(lf, six.binary_type): - _bytes = bytearray(lf) - - elif isinstance(lf, six.text_type): - _bytes = bytearray(lf.encode('latin-1')) - - # something else entirely - else: - raise TypeError(type(lf)) - - return _bytes - - def __init__(self): - super(FileLoader, self).__init__() - self._path = '' - - -class Exportable(six.with_metaclass(abc.ABCMeta, FileLoader)): - __crc24_init__ = 0x0B704CE - __crc24_poly__ = 0x1864CFB - - __armor_fmt__ = '-----BEGIN PGP {block_type}-----\n' \ - '{headers}\n' \ - '{packet}\n' \ - '={crc}\n' \ - '-----END PGP {block_type}-----\n' - @abc.abstractproperty def magic(self): """The magic string identifier for the current PGP type""" return "" def __init__(self): - super(Exportable, self).__init__() + super(Armorable, self).__init__() self.ascii_headers = collections.OrderedDict() self.ascii_headers['Version'] = 'PGPy v' + __version__ # Default value @@ -162,7 +97,7 @@ def ascii_unarmor(text): :raises: """ m = {'magic': None, 'headers': None, 'body': bytearray(), 'crc': None} - if not FileLoader.is_ascii(text): + if not Armorable.is_ascii(text): m['body'] = bytearray(text) return m @@ -237,16 +172,6 @@ def crc24(self, data=None): return crc & 0xFFFFFF -class Signable(six.with_metaclass(abc.ABCMeta, object)): - ##TODO: this - pass - - -class SignatureContainer(object): - ##TODO: this - pass - - class PGPObject(six.with_metaclass(abc.ABCMeta, object)): __metaclass__ = abc.ABCMeta diff --git a/requirements.txt b/requirements.txt index e7f3da3c..a84f45a0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ cryptography==0.5.4 -requests enum34 six singledispatch diff --git a/tests/test_4_PGPKeyring.py b/tests/test_4_PGPKeyring.py index 4e4b4a8b..12934517 100644 --- a/tests/test_4_PGPKeyring.py +++ b/tests/test_4_PGPKeyring.py @@ -13,7 +13,11 @@ class TestPGPKeyring(object): def test_load(self): kr = PGPKeyring() - keys = kr.load(glob.glob('tests/testdata/*test.asc')) + kc = [] + for kf in glob.glob('tests/testdata/*test.asc'): + with open(kf, 'r') as kff: + kc.append(kff.read()) + keys = kr.load(kc) # keys assert all(isinstance(k, Fingerprint) for k in keys) @@ -57,7 +61,11 @@ def test_load(self): assert rvt[1].is_public def test_select_fingerprint(self): - kr = PGPKeyring(glob.glob('tests/testdata/*test.asc')) + kc = [] + for kf in glob.glob('tests/testdata/*test.asc'): + with open(kf, 'r') as kff: + kc.append(kff.read()) + kr = PGPKeyring(kc) with kr.key("F429 4BC8 094A 7E05 85C8 5E86 3747 3B37 58C4 4F36") as rsa: assert rsa.userids[0].name == "RSA von TestKey" @@ -66,7 +74,11 @@ def test_select_fingerprint(self): assert dsa.userids[0].name == "DSA von TestKey" def test_select_keyid(self): - kr = PGPKeyring(glob.glob('tests/testdata/*test.asc')) + kc = [] + for kf in glob.glob('tests/testdata/*test.asc'): + with open(kf, 'r') as kff: + kc.append(kff.read()) + kr = PGPKeyring(kc) with kr.key("37473B3758C44F36") as rsa: assert rsa.userids[0].name == "RSA von TestKey" @@ -75,7 +87,11 @@ def test_select_keyid(self): assert dsa.userids[0].name == "DSA von TestKey" def test_select_shortid(self): - kr = PGPKeyring(glob.glob('tests/testdata/*test.asc')) + kc = [] + for kf in glob.glob('tests/testdata/*test.asc'): + with open(kf, 'r') as kff: + kc.append(kff.read()) + kr = PGPKeyring(kc) with kr.key("58C44F36") as rsa: assert rsa.userids[0].name == "RSA von TestKey" @@ -84,7 +100,11 @@ def test_select_shortid(self): assert dsa.userids[0].name == "DSA von TestKey" def test_select_name(self): - kr = PGPKeyring(glob.glob('tests/testdata/*test.asc')) + kc = [] + for kf in glob.glob('tests/testdata/*test.asc'): + with open(kf, 'r') as kff: + kc.append(kff.read()) + kr = PGPKeyring(kc) with kr.key("RSA von TestKey") as rsa: assert rsa.userids[0].name == "RSA von TestKey" @@ -93,7 +113,11 @@ def test_select_name(self): assert dsa.userids[0].name == "DSA von TestKey" def test_select_comment(self): - kr = PGPKeyring(glob.glob('tests/testdata/*test.asc')) + kc = [] + for kf in glob.glob('tests/testdata/*test.asc'): + with open(kf, 'r') as kff: + kc.append(kff.read()) + kr = PGPKeyring(kc) with kr.key("2048-bit RSA") as rsa: assert rsa.userids[0].name == "RSA von TestKey" @@ -102,7 +126,11 @@ def test_select_comment(self): assert dsa.userids[0].name == "DSA von TestKey" def test_select_email(self): - kr = PGPKeyring(glob.glob('tests/testdata/*test.asc')) + kc = [] + for kf in glob.glob('tests/testdata/*test.asc'): + with open(kf, 'r') as kff: + kc.append(kff.read()) + kr = PGPKeyring(kc) with kr.key("rsa@test.key") as rsa: assert rsa.userids[0].name == "RSA von TestKey" @@ -111,18 +139,25 @@ def test_select_email(self): assert dsa.userids[0].name == "DSA von TestKey" def test_select_pgpsignature(self): - kr = PGPKeyring('tests/testdata/signatures/debian-sid.key.asc') + with open('tests/testdata/signatures/debian-sid.key.asc', 'r') as dskf: + kr = PGPKeyring(dskf.read()) sig = PGPSignature() - sig.parse('tests/testdata/signatures/debian-sid.sig.asc') + with open('tests/testdata/signatures/debian-sid.sig.asc', 'r') as sigf: + sig.parse(sigf.read()) with kr.key(sig) as sigkey: assert sigkey.fingerprint.keyid == sig.signer def test_select_pgpmessage(self): - kr = PGPKeyring(glob.glob('tests/testdata/*test.asc')) + kc = [] + for kf in glob.glob('tests/testdata/*test.asc'): + with open(kf, 'r') as kff: + kc.append(kff.read()) + kr = PGPKeyring(kc) m1 = PGPMessage() - m1.parse('tests/testdata/messages/message.rsa.cast5.asc') + with open('tests/testdata/messages/message.rsa.cast5.asc', 'r') as m1f: + m1.parse(m1f.read()) with kr.key(m1) as rsakey: assert rsakey.fingerprint == "00EC FAF5 48AE B655 F861 8193 EEE0 97A0 17B9 79CA" diff --git a/tests/test_5_actions.py b/tests/test_5_actions.py index 92f28fab..2fd3c1bf 100644 --- a/tests/test_5_actions.py +++ b/tests/test_5_actions.py @@ -26,29 +26,42 @@ def _pgpmessage(f): msg = PGPMessage() - msg.parse(f) + with open(f, 'r') as ff: + msg.parse(ff.read()) + return msg + +def _pgpmessage_new(f): + with open(f, 'r') as ff: + msg = PGPMessage.new(ff.read()) return msg def _pgpkey(f): key = PGPKey() - key.parse(f) + with open(f, 'r') as ff: + key.parse(ff.read()) return key def _pgpsignature(f): sig = PGPSignature() - sig.parse(f) + with open(f, 'r') as ff: + sig.parse(ff.read()) return sig +def _read(f, mode='r'): + with open(f, mode) as ff: + return ff.read() + class TestPGPMessage(object): params = { 'comp_alg': [ CompressionAlgorithm.Uncompressed, CompressionAlgorithm.ZIP, CompressionAlgorithm.ZLIB, CompressionAlgorithm.BZ2 ], 'enc_msg': [ _pgpmessage(f) for f in glob.glob('tests/testdata/messages/message*.pass*.asc') ], - 'lit': [ PGPMessage.new('tests/testdata/lit') ], + 'lit': [ _pgpmessage_new('tests/testdata/lit') ], } def test_new_message(self, comp_alg, write_clean, gpg_import, gpg_print): - msg = PGPMessage.new('tests/testdata/lit', compression=comp_alg) + with open('tests/testdata/lit', 'r') as litf: + msg = PGPMessage.new(litf.read(), compression=comp_alg) assert msg.type == 'literal' assert msg.message.decode('latin-1') == 'This is stored, literally\!\n\n' @@ -115,7 +128,7 @@ class TestPGPKey(object): 'rsa_encmsg': [ _pgpmessage(f) for f in sorted(glob.glob('tests/testdata/messages/message*.rsa*.asc')) ], 'sigkey': [ _pgpkey(f) for f in sorted(glob.glob('tests/testdata/signatures/*.key.asc')) ], 'sigsig': [ _pgpsignature(f) for f in sorted(glob.glob('tests/testdata/signatures/*.sig.asc')) ], - 'sigsubj': sorted(glob.glob('tests/testdata/signatures/*.subj')) + 'sigsubj': sorted(glob.glob('tests/testdata/signatures/*.subj')), } targettes = [ _pgpkey(f) for f in sorted(glob.glob('tests/testdata/keys/targette*.asc')) ] ikeys = [os.path.join(*f.split(os.path.sep)[-2:]) for f in glob.glob('tests/testdata/keys/*.pub.asc')] @@ -140,9 +153,11 @@ def test_unlock(self, enc, sec): assert not enc.is_unlocked assert not sec.is_protected + lit = _read('tests/testdata/lit') + # try to sign without unlocking with pytest.raises(PGPError): - enc.sign('tests/testdata/lit') + enc.sign(lit) # try to unlock with the wrong password enc.unlock('ClearlyTheWrongPassword') @@ -151,13 +166,13 @@ def test_unlock(self, enc, sec): with enc.unlock('QwertyUiop'), self.assert_warnings(): assert enc.is_unlocked # sign lit - sig = enc.sign('tests/testdata/lit') + sig = enc.sign(lit) # verify with the unlocked key and its unprotected friend - assert enc.verify('tests/testdata/lit', sig) - assert sec.verify('tests/testdata/lit', sig) + assert enc.verify(lit, sig) + assert sec.verify(lit, sig) def test_verify_detached(self, sigkey, sigsig, sigsubj): - assert sigkey.verify(sigsubj, sigsig) + assert sigkey.verify(_read(sigsubj), sigsig) def test_verify_message(self, msg): with self.assert_warnings(): @@ -173,7 +188,7 @@ def test_verify_self(self, pub): def test_verify_revochiio(self): k = PGPKey() - k.parse('tests/testdata/revochiio.asc') + k.parse(_read('tests/testdata/revochiio.asc')) with self.assert_warnings(): sv = k.verify(k) @@ -191,25 +206,26 @@ def test_verify_revochiio(self): def test_verify_wrongkey(self): wrongkey = PGPKey() - wrongkey.parse('tests/testdata/signatures/aptapproval-test.key.asc') + wrongkey.parse(_read('tests/testdata/signatures/aptapproval-test.key.asc')) sig = PGPSignature() - sig.parse('tests/testdata/signatures/debian-sid.sig.asc') + sig.parse(_read('tests/testdata/signatures/debian-sid.sig.asc')) with pytest.raises(PGPError): - wrongkey.verify('tests/testdata/signatures/debian-sid.subj', sig) + wrongkey.verify(_read('tests/testdata/signatures/debian-sid.subj'), sig) def test_verify_invalid(self, sec): with self.assert_warnings(): - sig = sec.sign('tests/testdata/lit') - assert not sec.verify('tests/testdata/lit2', sig) + sig = sec.sign(_read('tests/testdata/lit')) + assert not sec.verify(_read('tests/testdata/lit2'), sig) def test_sign_detach(self, sec, write_clean, gpg_import, gpg_verify): + lit = _read('tests/testdata/lit') with self.assert_warnings(): - sig = sec.sign('tests/testdata/lit') + sig = sec.sign(lit) # Verify with PGPy - assert sec.verify('tests/testdata/lit', sig) + assert sec.verify(lit, sig) # verify with GPG with write_clean('tests/testdata/lit.sig', 'w', str(sig)), \ @@ -217,7 +233,7 @@ def test_sign_detach(self, sec, write_clean, gpg_import, gpg_verify): assert gpg_verify('./lit', './lit.sig', keyid=sig.signer) def test_sign_cleartext(self, write_clean, gpg_import, gpg_verify): - msg = PGPMessage.new('tests/testdata/lit_de', cleartext=True) + msg = PGPMessage.new(_read('tests/testdata/lit_de'), cleartext=True) with self.assert_warnings(): for sec in self.params['sec']: @@ -235,7 +251,7 @@ def test_sign_cleartext(self, write_clean, gpg_import, gpg_verify): assert gpg_verify('./lit_de.asc') def test_onepass_sign_message(self, write_clean, gpg_import, gpg_verify): - msg = PGPMessage.new('tests/testdata/lit') + msg = PGPMessage.new(_read('tests/testdata/lit')) with self.assert_warnings(): for sec in self.params['sec']: msg += sec.sign(msg) @@ -424,7 +440,7 @@ def test_bind_subkey(self, sec, pub, write_clean, gpg_import, gpg_check_sigs): def test_decrypt_rsa_message(self, rsa_encmsg): key = PGPKey() - key.parse('tests/testdata/keys/rsa.1.sec.asc') + key.parse(_read('tests/testdata/keys/rsa.1.sec.asc')) with self.assert_warnings(): decmsg = key.decrypt(rsa_encmsg) @@ -434,10 +450,10 @@ def test_decrypt_rsa_message(self, rsa_encmsg): def test_encrypt_rsa_message(self, write_clean, gpg_import, gpg_decrypt): pub = PGPKey() - pub.parse('tests/testdata/keys/rsa.1.pub.asc') + pub.parse(_read('tests/testdata/keys/rsa.1.pub.asc')) sec = PGPKey() - sec.parse('tests/testdata/keys/rsa.1.sec.asc') - msg = PGPMessage.new('tests/testdata/lit') + sec.parse(_read('tests/testdata/keys/rsa.1.sec.asc')) + msg = PGPMessage.new(_read('tests/testdata/lit')) with self.assert_warnings(): encmsg = pub.encrypt(msg) @@ -455,7 +471,7 @@ def test_encrypt_rsa_message(self, write_clean, gpg_import, gpg_decrypt): assert gpg_decrypt('./aemsg.asc') == 'This is stored, literally\!\n\n' def test_encrypt_rsa_multi(self, write_clean, gpg_import, gpg_decrypt): - msg = PGPMessage.new('tests/testdata/lit') + msg = PGPMessage.new(_read('tests/testdata/lit')) with self.assert_warnings(): sk = SymmetricKeyAlgorithm.AES256.gen_key()