From 1eda4012c5350efae02fcc058e0a36cc71ad62fd Mon Sep 17 00:00:00 2001
From: Chris Lamb <lamby@debian.org>
Date: Fri, 9 Feb 2024 10:43:18 -0800
Subject: [PATCH] Use a determistic name instead of trusting gpg's
 --use-embedded-filenames. (Closes: reproducible-builds/diffoscope#361)

... but also expose the embedded name by attaching the ("unstable") output of
--list-packets.

Many thanks to Daniel Kahn Gillmor <dkg@debian.org> for reporting this issue
and providing feedback.

Upstream-Status: Backport
[https://salsa.debian.org/reproducible-builds/diffoscope/-/commit/458f7f04bc053a0066aa7d2fd3251747d4899476]

CVE: CVE-2024-25711

Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
---
 diffoscope/comparators/pgp.py | 34 +++++++++++++++++++++++++++++-----
 tests/comparators/test_pgp.py |  3 ++-
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/diffoscope/comparators/pgp.py b/diffoscope/comparators/pgp.py
index eea997b..9215664 100644
--- a/diffoscope/comparators/pgp.py
+++ b/diffoscope/comparators/pgp.py
@@ -32,6 +32,8 @@ from .utils.command import Command, our_check_output
 
 logger = logging.getLogger(__name__)
 
+re_name = re.compile(r", created \d+, name=\"(?P<name>[^\"]+)\",")
+
 
 class Pgpdump(Command):
     @tool_required("pgpdump")
@@ -46,21 +48,31 @@ class Pgpdump(Command):
         )
 
 
+class GpgListPackets(Command):
+    @tool_required("gpg")
+    def cmdline(self):
+        return (
+            "gpg",
+            "--no-keyring",
+            "--list-packets",
+            self.path,
+        )
+
+
 class PGPContainer(Archive):
     @tool_required("gpg")
     def open_archive(self):
-        # Extract to a fresh temporary directory so that we can use the
-        # embedded filename.
-
+        # Extract to a fresh temporary directory.
         self._temp_dir = get_temporary_directory(suffix="pgp")
 
         try:
             our_check_output(
                 (
                     "gpg",
-                    "--use-embedded-filename",
                     "--decrypt",
                     "--no-keyring",
+                    "--output",
+                    os.path.join(self._temp_dir.name, "contents"),
                     os.path.abspath(self.source.path),
                 ),
                 cwd=self._temp_dir.name,
@@ -75,7 +87,7 @@ class PGPContainer(Archive):
         self._temp_dir.cleanup()
 
     def get_member_names(self):
-        # Will only return one filename, taken from the signature file itself.
+        # Will only ever return one filename
         return os.listdir(self._temp_dir.name)
 
     def extract(self, member_name, dest_dir):
@@ -136,4 +148,16 @@ class PgpSignature(TextFile):
             ]
         )
 
+        # ... as well as gpg --list-packets
+        difference.add_details(
+            [
+                Difference.from_operation(
+                    GpgListPackets,
+                    self.path,
+                    other.path,
+                    source="gpg --list-packets",
+                )
+            ]
+        )
+
         return difference
diff --git a/tests/comparators/test_pgp.py b/tests/comparators/test_pgp.py
index 8652ea9..49b3fa0 100644
--- a/tests/comparators/test_pgp.py
+++ b/tests/comparators/test_pgp.py
@@ -80,8 +80,9 @@ def test_pgp_signature_identification(signature1, signature2):
 def test_pgp_signature(signature1, signature2):
     difference = signature1.compare(signature2)
     assert_diff(difference, "pgp_signature_expected_diff")
+    assert len(difference.details) == 2
     assert difference.details[0].source1 == "pgpdump"
-    assert len(difference.details) == 1
+    assert difference.details[1].source1 == "gpg --list-packets"
 
 
 @skip_unless_tools_exist("pgpdump")
-- 
2.25.1

