From 0a4855d44a2cc1f19dcd6cab9f2e1d1c51c88ba5 Mon Sep 17 00:00:00 2001 From: Michał Górny Date: Fri, 27 Oct 2017 23:47:26 +0200 Subject: manifest: Support dumping a signed Manifest --- gemato/manifest.py | 28 ++++++++++++++++++++++++---- tests/test_openpgp.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/gemato/manifest.py b/gemato/manifest.py index babd3b3..96479d3 100644 --- a/gemato/manifest.py +++ b/gemato/manifest.py @@ -387,14 +387,34 @@ class ManifestFile(object): gemato.openpgp.verify_file(f, env=openpgp_env) self.openpgp_signed = True - def dump(self, f): + def dump(self, f, sign_openpgp=None, openpgp_keyid=None, + openpgp_env=None): """ Dump data into file @f. The file should be open for writing in text mode, and truncated to zero length. + + If @sign_openpgp is True, the file will include an OpenPGP + cleartext signature. If it False, the signature will be omitted. + If it is None (the default), the file will be signed if it + was originally signed with a valid signature. + + @openpgp_keyid and @openpgp_env specify the key + and the environment to use for signing. """ - - for e in self.entries: - f.write(u' '.join(e.to_list()) + '\n') + + if sign_openpgp is None: + sign_openpgp = self.openpgp_signed + + if sign_openpgp: + with io.StringIO() as data: + # get the plain data into a stream + self.dump(data, sign_openpgp=False) + data.seek(0) + gemato.openpgp.clear_sign_file(data, f, + keyid=openpgp_keyid, env=openpgp_env) + else: + for e in self.entries: + f.write(u' '.join(e.to_list()) + '\n') def find_timestamp(self): """ diff --git a/tests/test_openpgp.py b/tests/test_openpgp.py index ef8f14b..d4a40a0 100644 --- a/tests/test_openpgp.py +++ b/tests/test_openpgp.py @@ -567,3 +567,45 @@ class OpenPGPPrivateKeyTest(unittest.TestCase): self.env.clear_sign_file(f, wf, keyid=PRIVATE_KEY_ID) wf.seek(0) self.env.verify_file(wf) + + def test_dump_signed_manifest(self): + m = gemato.manifest.ManifestFile() + with io.StringIO(SIGNED_MANIFEST) as f: + m.load(f, openpgp_env=self.env) + with io.StringIO() as f: + m.dump(f, openpgp_env=self.env) + f.seek(0) + m.load(f, openpgp_env=self.env) + self.assertTrue(m.openpgp_signed) + + def test_dump_signed_manifest_keyid(self): + m = gemato.manifest.ManifestFile() + with io.StringIO(SIGNED_MANIFEST) as f: + m.load(f, openpgp_env=self.env) + with io.StringIO() as f: + m.dump(f, openpgp_keyid=PRIVATE_KEY_ID, openpgp_env=self.env) + f.seek(0) + m.load(f, openpgp_env=self.env) + self.assertTrue(m.openpgp_signed) + + def test_dump_force_signed_manifest(self): + m = gemato.manifest.ManifestFile() + with io.StringIO(SIGNED_MANIFEST) as f: + m.load(f, verify_openpgp=False, openpgp_env=self.env) + self.assertFalse(m.openpgp_signed) + with io.StringIO() as f: + m.dump(f, sign_openpgp=True, openpgp_env=self.env) + f.seek(0) + m.load(f, openpgp_env=self.env) + self.assertTrue(m.openpgp_signed) + + def test_dump_force_unsigned_manifest(self): + m = gemato.manifest.ManifestFile() + with io.StringIO(SIGNED_MANIFEST) as f: + m.load(f, openpgp_env=self.env) + self.assertTrue(m.openpgp_signed) + with io.StringIO() as f: + m.dump(f, sign_openpgp=False, openpgp_env=self.env) + f.seek(0) + m.load(f, openpgp_env=self.env) + self.assertFalse(m.openpgp_signed) -- cgit v1.2.3