• Bug#1104799: gpgparticipants-filter: Handle non-UTF-8 data in gpg outpu

    From =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=@21:1/5 to All on Tue May 6 19:20:01 2025
    Package: signing-party
    Version: 2.12-1
    Severity: normal
    Tags: patch
    X-Debbugs-Cc: ukleinek@debian.org

    Hello,

    there is (at least) one key in my keyring that makes

    gpg --list-key --with-colons DE6162B5616BA9C9CAAC03074A55C497F744F705

    emit non-UTF-8 output. I'm not sure if this is a bug in gpg as the docs
    claim that "Note that the output will be encoded in UTF-8 [...]."

    Passing that fingerprint to gpgparticipants-filter makes it barf:

    $ /usr/bin/gpgparticipants-filter DE6162B5616BA9C9CAAC03074A55C497F744F705
    Traceback (most recent call last):
    File "/usr/bin/gpgparticipants-filter", line 166, in <module>
    key_data += key_data_sets_from(gpg_output)
    File "/usr/bin/gpgparticipants-filter", line 128, in key_data_sets_from
    yield key_data_from(raw_data_set)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^
    File "/usr/bin/gpgparticipants-filter", line 120, in key_data_from
    raw_data_set.data_field_from_lines(9, b'uid'),
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
    File "/usr/bin/gpgparticipants-filter", line 61, in data_field_from_lines
    return [line.split(b':')[field_index].decode() for line in self.data if line.startswith(line_prefix)]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf8 in position 6: invalid start byte

    The following patch fixes that:

    From 4f2b31e55c909dd916bdd088bc314239cbce0f9f Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <ukleinek@debian.org>
    Date: Tue, 6 May 2025 18:59:28 +0200
    Subject: [PATCH] gpgparticipants-filter: Somewhat handle uids with non-UTF-8
    encoding

    PGP certificates with (e.g.) latin1 encoded uids result in a UnicodeDecodeError. So only decode the key id field of gpg's output.
    ---
    gpgparticipants/gpgparticipants-filter | 4 ++--
    1 file changed, 2 insertions(+), 2 deletions(-)

    diff --git a/gpgparticipants/gpgparticipants-filter b/gpgparticipants/gpgparticipants-filter
    index 7e33dc3286be..8899a28e2635 100755
    --- a/gpgparticipants/gpgparticipants-filter
    +++ b/gpgparticipants/gpgparticipants-filter
    @@ -58,7 +58,7 @@ class RawDataSet:

    def data_field_from_lines(self, field_index, line_prefix):
    """Select all lines which start with line_prefix and return the columns denoted by field_index."""
    - return [line.split(b':')[field_index].decode() for line in self.data if line.startswith(line_prefix)]
    + return [line.split(b':')[field_index] for line in self.data if line.startswith(line_prefix)]


    class KeyDataSet:
    @@ -72,7 +72,7 @@ class KeyDataSet:
    self.valid_flag = valid_flag

    def __repr__(self):
    - return self.key_id
    + return self.key_id.decode()

    def is_valid(self):
    """check that the key isn't re
  • From Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=@21:1/5 to All on Tue May 6 22:40:01 2025
    Hello,

    On Tue, May 06, 2025 at 07:15:07PM +0200, Uwe Kleine-König wrote:
    Package: signing-party
    Version: 2.12-1
    Severity: normal
    Tags: patch
    X-Debbugs-Cc: ukleinek@debian.org

    Hello,

    there is (at least) one key in my keyring that makes

    gpg --list-key --with-colons DE6162B5616BA9C9CAAC03074A55C497F744F705

    emit non-UTF-8 output. I'm not sure if this is a bug in gpg as the docs
    claim that "Note that the output will be encoded in UTF-8 [...]."

    Passing that fingerprint to gpgparticipants-filter makes it barf:

    $ /usr/bin/gpgparticipants-filter DE6162B5616BA9C9CAAC03074A55C497F744F705
    Traceback (most recent call last):
    File "/usr/bin/gpgparticipants-filter", line 166, in <module>
    key_data += key_data_sets_from(gpg_output)
    File "/usr/bin/gpgparticipants-filter", line 128, in key_data_sets_from
    yield key_data_from(raw_data_set)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^
    File "/usr/bin/gpgparticipants-filter", line 120, in key_data_from
    raw_data_set.data_field_from_lines(9, b'uid'),
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
    File "/usr/bin/gpgparticipants-filter", line 61, in data_field_from_lines
    return [line.split(b':')[field_index].decode() for line in self.data if line.startswith(line_prefix)]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf8 in position 6: invalid start byte

    The following patch fixes that:

    From 4f2b31e55c909dd916bdd088bc314239cbce0f9f Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <ukleinek@debian.org>
    Date: Tue, 6 May 2025 18:59:28 +0200
    Subject: [PATCH] gpgparticipants-filter: Somewhat handle uids with non-UTF-8
    encoding

    PGP certificates with (e.g.) latin1 encoded uids result in a UnicodeDecodeError. So only decode the key id field of gpg's output.
    ---
    gpgparticipants/gpgparticipants-filter | 4 ++--
    1 file changed, 2 insertions(+), 2 deletions(-)

    diff --git a/gpgparticipants/gpgparticipants-filter b/gpgparticipants/gpgparticipants-filter
    index 7e33dc3286be..8899a28e2635 100755
    --- a/gpgparticipants/gpgparticipants-filter
    +++ b/gpgparticipants/gpgparticipants-filter
    @@ -58,7 +58,7 @@ class RawDataSet:

    def data_field_from_lines(self, field_index, line_prefix):
    """Select all lines which start with line_prefix and return the columns denoted by field_index."""
    - return [line.split(b':')[field_index].decode() for line in self.data if line.startswith(line_prefix)]
    + return [line.split(b':')[field_index] for line in self.data if line.startswith(line_prefix)]


    class KeyDataSet:
    @@ -72,7 +72,7 @@ class KeyDataSet:
    self.valid_flag = valid_flag

    def __repr__(self):
    - return self.key_id
    + return self.key_id.decode()

    def is_valid(self):
    """check that the key isn't revoked or expired"""

    that patch has a bug, it also needs:

    diff --git a/gpgparticipants/gpgparticipants-filter b/gpgparticipants/gpgparticipants-filter
    index d2c7ac3e622a..849b8bd8018c 100755
    --- a/gpgparticipants/gpgparticipants-filter
    +++ b/gpgparticipants/gpgparticipants-filter
    @@ -76,7 +76,7 @@ class KeyDataSet:

    def is_valid(self):
    """check that the key isn't revoked or expired"""
    - return self.valid_flag not in ['e', 'r']
    + return self.valid_flag not in [b'e', b'r']


    def filter_to_gpg(filter_strings, gpg_bin, set_homedir, homedir):

    because the valid_flag is a bytestring and not a plain string any more.
    (But also see #1104814)

    Best regards
    Uwe

    -----BEGIN PGP SIGNATURE-----

    iQEzBAABCgAdFiEEP4GsaTp6HlmJrf7Tj4D7WH0S/k4FAmgacYMACgkQj4D7WH0S /k6uYAf/V8c8Hr7wLdH/vxwCRV9USY1PO//USaQgujg9nnuVlhU9Fy0yHUgRyXYE dUQ+z8mgC30cknhp5IJfI1hTqhPao73MPlI7n5BpFZni+nCbljR/GY460LQmnZBr nvsiKkEf0V9l3JeEg83oqKvwuhQnNmciFrgS5WRiWiEDpD3rWTMVnyFysN4uLNdx g6CHgcD+3RYbsjCEY9muYtVa5zOoXAdJnPsO8VKBou0aqB0jVeRspjQZJPV8OoyP QAT1j1GeuiD+ARAuuuUwmPvRv8mR3TrrvJw6RQKdazurxhZWCLOBv1vs2W1qoNPo HaK5ptNxYyUe5IybzjPr10yfUMVptw==
    =m6Qd
    -----END PGP SIGNATURE-----

    ---