diff --git a/changelog/776.bugfix.rst b/changelog/776.bugfix.rst new file mode 100644 index 00000000..222d4b67 --- /dev/null +++ b/changelog/776.bugfix.rst @@ -0,0 +1,3 @@ +Do not include md5_digest or blake2_256_digest if FIPS mode is enabled on the +host. This removes those fields from the metadata before sending the metadata +to the repository. diff --git a/tests/test_package.py b/tests/test_package.py index 45cc420b..0e261f0f 100644 --- a/tests/test_package.py +++ b/tests/test_package.py @@ -262,6 +262,24 @@ def test_fips_hash_manager_blake2(monkeypatch): assert hasher.hexdigest() == hashes +def test_fips_packagefile(monkeypatch): + """Generate a metadata dictionary when FIPS is enabled. + + See also: https://github.com/pypa/twine/issues/775 + """ + replaced_blake2b = pretend.raiser(ValueError("fipsmode")) + replaced_md5 = pretend.raiser(ValueError("fipsmode")) + monkeypatch.setattr(package_file.hashlib, "md5", replaced_md5) + monkeypatch.setattr(package_file.hashlib, "blake2b", replaced_blake2b) + + filename = "tests/fixtures/twine-1.5.0-py2.py3-none-any.whl" + pf = package_file.PackageFile.from_filename(filename, None) + + mddict = pf.metadata_dictionary() + assert "md5_digest" not in mddict + assert "blake2_256_digest" not in mddict + + def test_pkginfo_returns_no_metadata(monkeypatch): """Raise an exception when pkginfo can't interpret the metadata. diff --git a/twine/package.py b/twine/package.py index a2da7612..22c05944 100644 --- a/twine/package.py +++ b/twine/package.py @@ -152,9 +152,7 @@ def metadata_dictionary(self) -> Dict[str, MetadataValue]: "download_url": meta.download_url, "supported_platform": meta.supported_platforms, "comment": self.comment, - "md5_digest": self.md5_digest, "sha256_digest": self.sha2_digest, - "blake2_256_digest": self.blake2_256_digest, # PEP 314 "provides": meta.provides, "requires": meta.requires, @@ -174,6 +172,14 @@ def metadata_dictionary(self) -> Dict[str, MetadataValue]: if self.gpg_signature is not None: data["gpg_signature"] = self.gpg_signature + # FIPS will make us send None/null to a package repository and some of + # them don't appreciate that. FIPS disables both MD5 and Blake2 + if self.md5_digest: + data["md5_digest"] = self.md5_digest + + if self.blake2_256_digest: + data["blake2_256_digest"] = self.blake2_256_digest + return data def add_gpg_signature(