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..2e50ee9c 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_metadata_excludes_md5_and_blake2(monkeypatch): + """Generate a valid metadata dictionary for Nexus 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..ca212a8e 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,15 @@ def metadata_dictionary(self) -> Dict[str, MetadataValue]: if self.gpg_signature is not None: data["gpg_signature"] = self.gpg_signature + # FIPS disables MD5 and Blake2, making the digest values None. Some package + # repositories don't allow null values, so this only sends non-null values. + # See also: https://github.com/pypa/twine/issues/775 + 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(