diff options
author | Michał Górny <mgorny@gentoo.org> | 2022-09-16 19:09:16 +0200 |
---|---|---|
committer | Michał Górny <mgorny@gentoo.org> | 2022-09-16 19:09:16 +0200 |
commit | 4fe74c5b55f5b29ab832b61f8c0eef290c40d1e3 (patch) | |
tree | 2d9426c805967894e11100f134814a9357e7c095 | |
parent | 5306b7f83816b2273f477c413d10686aebfff57c (diff) | |
download | gemato-4fe74c5b55f5b29ab832b61f8c0eef290c40d1e3.tar.gz |
Support defaulting secure_hashes to top-level Manifest signing
Signed-off-by: Michał Górny <mgorny@gentoo.org>
-rw-r--r-- | gemato/recursiveloader.py | 23 | ||||
-rw-r--r-- | tests/test_openpgp.py | 39 |
2 files changed, 54 insertions, 8 deletions
diff --git a/gemato/recursiveloader.py b/gemato/recursiveloader.py index aea47f5..612ea2d 100644 --- a/gemato/recursiveloader.py +++ b/gemato/recursiveloader.py @@ -214,7 +214,7 @@ class ManifestRecursiveLoader: profile=DefaultProfile(), max_jobs=None, allow_xdev=True, - require_secure_hashes=False, + require_secure_hashes=None, ): """ Instantiate the loader for a Manifest tree starting at top-level @@ -268,13 +268,10 @@ class ManifestRecursiveLoader: to false. If @require_secure_hashes is True, only secure hashes can be used. + If it is False, all hashes are permitted. If it is None, secure + hashes are required if top-level Manifest is going to be signed. """ - if require_secure_hashes and hashes is not None: - insecure = list(filter(lambda x: not is_hash_secure(x), hashes)) - if insecure: - raise ManifestInsecureHashes(insecure) - self.root_directory = os.path.dirname(top_manifest_path) self.openpgp_env = openpgp_env self.sign_openpgp = sign_openpgp @@ -285,7 +282,6 @@ class ManifestRecursiveLoader: self.compress_watermark = compress_watermark self.compress_format = compress_format self.max_jobs = max_jobs - self.require_secure_hashes = require_secure_hashes self.profile.set_loader_options(self) @@ -311,6 +307,19 @@ class ManifestRecursiveLoader: self.openpgp_signed = m.openpgp_signed self.openpgp_signature = m.openpgp_signature + if require_secure_hashes is None: + if self.sign_openpgp is None: + require_secure_hashes = self.openpgp_signed + else: + require_secure_hashes = self.sign_openpgp + self.require_secure_hashes = require_secure_hashes + + if require_secure_hashes and hashes is not None: + insecure = list(filter(lambda x: not is_hash_secure(x), hashes)) + if insecure: + raise ManifestInsecureHashes(insecure) + + def load_manifest(self, relpath, verify_entry=None, diff --git a/tests/test_openpgp.py b/tests/test_openpgp.py index c57a612..6895a13 100644 --- a/tests/test_openpgp.py +++ b/tests/test_openpgp.py @@ -1,8 +1,9 @@ # gemato: OpenPGP signature support tests # vim:fileencoding=utf-8 -# (c) 2017-2020 Michał Górny +# (c) 2017-2022 Michał Górny # Licensed under the terms of 2-clause BSD license +import contextlib import datetime import io import logging @@ -26,6 +27,7 @@ from gemato.exceptions import ( OpenPGPKeyRefreshError, OpenPGPRuntimeError, OpenPGPUntrustedSigFailure, + ManifestInsecureHashes, ) from gemato.manifest import ManifestFile from gemato.openpgp import ( @@ -958,3 +960,38 @@ def test_cli_gpg_wrap(tmp_path, caplog, command, expected, match): assert retval == expected if match is not None: assert match in caplog.text + + +@pytest.mark.parametrize( + "hashes_arg,insecure", + [("MD5", True), + ("SHA1", True), + ("SHA512", False), + ("SHA1 SHA512", True), + ]) +@pytest.mark.parametrize( + "sign,require_secure", + [(None, None), + (False, None), + (True, None), + (None, False), + (True, False), + ]) +def test_recursive_manifest_loader_require_secure(tmp_path, privkey_env, + hashes_arg, insecure, + sign, require_secure): + with open(tmp_path / "Manifest", "w") as f: + f.write(SIGNED_MANIFEST) + + ctx = (pytest.raises(ManifestInsecureHashes) + if insecure and sign is not False and require_secure is not False + else contextlib.nullcontext()) + with ctx: + m = ManifestRecursiveLoader(tmp_path / "Manifest", + hashes=hashes_arg.split(), + require_secure_hashes=require_secure, + verify_openpgp=not sign, + sign_openpgp=sign, + openpgp_env=privkey_env) + if not sign: + assert m.openpgp_signed |