• Bug#1105820: Gnupg-in-debian considers comment packets invalid

    From Sune Stolborg Vuorela@21:1/5 to All on Thu May 15 13:00:02 2025
    Package: gnupg
    Version: 2.4.6-7
    Severity: important

    Hi

    Since https://salsa.debian.org/debian/gnupg2/-/blob/debian/unstable/debian/patches/ freepg/0019-Disallow-compressed-signatures-and-certificates.patch? ref_type=heads#L188

    GnuPG-in-debian has stopped accepting comment packets in detached signatures. That should be fully valid and there is no good reason to consider them bad.

    It is at least used by poppler to pad signature fields when adding a detached gpg signature in a pdf document, and these can't be re-validated on a Debian system.

    This change also breaks the part of Poppler's CI system that is based off randomly regenerated Debian containers. (and they were very recent regenerated)

    Please quickly fix this also for the trixie release.

    /Sune
    --
    I didn’t stop pretending when I became an adult, it’s just that when I was a
    kid I was pretending that I fit into the rules and structures of this world. And now that I’m an adult, I pretend that those rules and structures exist.
    - zefrank

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sune Stolborg Vuorela@21:1/5 to All on Thu May 15 14:30:01 2025
    On Thursday, May 15, 2025 12:19:32 PM CEST Sune Stolborg Vuorela wrote:
    Since https://salsa.debian.org/debian/gnupg2/-/blob/debian/unstable/debian/patches / freepg/0019-Disallow-compressed-signatures-and-certificates.patch? ref_type=heads#L188

    This change also breaks the part of Poppler's CI system that is based off randomly regenerated Debian containers. (and they were very recent regenerated)

    Also, occasionally the poppler test suite actually still passes, so there is something fishy in that 0019 patch.

    Rebuilding without that patch makes it consistently succeed.

    A data file is used here, and the signature can be cut out with pdfsig.

    https://gitlab.freedesktop.org/poppler/test/-/raw/ 91ee031c882634c36f2f0f2f14eb6646dd542fb9/unittestcases/some-text- pgp_signed.pdf?inline=false

    The signature blob is a detached signature packet followed by a finite length comment packet.

    /Sune

    --
    I didn’t stop pretending when I became an adult, it’s just that when I was a
    kid I was pretending that I fit into the rules and structures of this world. And now that I’m an adult, I pretend that those rules and structures exist.
    - zefrank

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sune Stolborg Vuorela@21:1/5 to All on Fri May 16 12:10:01 2025
    On Thursday, May 15, 2025 2:04:43 PM CEST Sune Stolborg Vuorela wrote:
    The signature blob is a detached signature packet followed by a finite
    length comment packet.

    A comment package here is what GnuPG calls PKT_COMMENT, it has datavalue 61. And in most/all openpgp (and librepgp) specs this is in the private / experimental range, so they should not be rejected 'just because'.

    This was btw introduces in GnuPG in 1998 and has been in use for things ever since.

    /Sune
    --
    I didn’t stop pretending when I became an adult, it’s just that when I was a
    kid I was pretending that I fit into the rules and structures of this world. And now that I’m an adult, I pretend that those rules and structures exist.
    - zefrank

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Daniel Kahn Gillmor@21:1/5 to Sune Stolborg Vuorela on Fri May 16 16:40:01 2025
    Hi Sune--

    Thanks for this report. Do you know what tooling is generating these
    packets for poppler?

    In GnuPG right now (even without the patch you identified), those
    packets are generally ignored.

    On Fri 2025-05-16 12:01:38 +0200, Sune Stolborg Vuorela wrote:
    On Thursday, May 15, 2025 2:04:43 PM CEST Sune Stolborg Vuorela wrote:
    The signature blob is a detached signature packet followed by a finite
    length comment packet.

    A comment package here is what GnuPG calls PKT_COMMENT, it has
    datavalue 61. And in most/all openpgp (and librepgp) specs this is in
    the private / experimental range, so they should not be rejected 'just because'.

    The OpenPGP packet grammar in RFC 4880 doesn't describe a detached
    signature object at all, so it was really anyone's guess what a detached embedded signature is supposed to be. There is no obligation on any
    OpenPGP parser to accept arbitrary packets in arbitrary locations.

    The OpenPGP working group collaboratively described what a detached
    signature in RFC 9580:
    https://www.rfc-editor.org/rfc/rfc9580.html#section-10.4 if there was
    some other grammar being used by someone, there were literally years for
    them to speak up.

    Looking at your sample PDF (thanks for the link!) it appears that it is
    a comment packet of length 0x24d4 containing all zeros. What is the
    purpose of this packet? Why is it being included?

    Rather than increasing the attack surface of GnuPG, maybe whatever implementation is producing this thing shouldn't emit a
    private/experimental packet sequence.

    This was btw introduces in GnuPG in 1998 and has been in use for
    things ever since.

    This is the first place i've seen these particular experimental packets
    show up. If there are other places where you know of it being used,
    please let me know!

    --dkg

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

    iHUEARYKAB0WIQRjrBGOWy5dZsiKhad4C4VO2cK0lgUCaCdMuQAKCRB4C4VO2cK0 ltDKAQDr9jBpriBgLPO198p6d+r9L1VcGn/xp1eFsWpX6/wcbgD+LZ6D7t405Ds5 3UVWwZekYqMi7HlgTB1mhyAvA8EpMg8=
    =4RTq
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Daniel Kahn Gillmor@21:1/5 to Daniel Kahn Gillmor on Fri May 16 17:00:01 2025
    Hi Sune--

    On Fri 2025-05-16 10:33:28 -0400, Daniel Kahn Gillmor wrote:
    Looking at your sample PDF (thanks for the link!) it appears that it is
    a comment packet of length 0x24d4 containing all zeros. What is the
    purpose of this packet? Why is it being included?

    Rather than increasing the attack surface of GnuPG, maybe whatever implementation is producing this thing shouldn't emit a
    private/experimental packet sequence.

    I just found:

    https://gitlab.freedesktop.org/poppler/poppler/-/commit/f0316ba62df9ce6d8e17a9349934b4a06df87e69

    It looks like this was added very recently, well after RFC 9580 came
    out, and injects these arbitrary private/experimental packets, strictly
    for padding purposes.

    Why is padding needed in this case?

    In section 10.4, RFC 9580 explicitly observes that for detached
    signatures (which i think is the closest characterization of the thing
    you're looking to add to the PDF standard here):

    In addition, a Marker packet (Section 5.8) and a Padding packet
    (Section 5.14) can appear anywhere in the sequence.

    If padding is what's needed here, i recommend using standardized padding
    that any compliant OpenPGP implementation will accept. Presumably the
    goal is for arbitrary OpenPGP consumers to be able to verify the
    signature of the PDF, right?

    Alternately, if you want to pad a signature packet, you can also inject arbitrary non-critical subpackets into the unhashed subpacket area of
    the signature itself; those subpackets should be ignored by every
    OpenPGP implementation i'm aware of.

    All of this padding flexibility, of course, enables the production of an arbitrary covert sidechannel in these signature formats. But as you
    say, those sidechannels have been part of OpenPGP for ages.

    The GnuPG patchset offered by Demi Marie tightens up OpenPGP's packet
    grammar significantly, reducing the attack surface.

    I'd really prefer to not drop that security enhancement to accomodate
    recently introduced changes in unrelated software that are themselves
    not compliant with any standards i'm aware of.

    --dkg

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

    iHUEARYKAB0WIQRjrBGOWy5dZsiKhad4C4VO2cK0lgUCaCdRtgAKCRB4C4VO2cK0 lud2AQCeiqJWsE46GcN69C4i7XTs86m9YORpg4LrQqtYQCTZEAD/SCt3umBbi2OA uhKPxOBWuzOrK4Zj/fzFqsw8rQhrdAs=
    =8aFz
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sune Stolborg Vuorela@21:1/5 to All on Fri May 16 19:50:01 2025
    Hi Daniel

    Thank you for your reply.

    I'm not sure why all of this matters; there are others that expects gnupg in Debian to validate and fail things in a similar way to gnupg-from-upstream and gnupg-in-other distributions.

    I don't think that is an unreasonable request.

    And poppler is released, used by others. Not only in Debian, but also in other places, and it generates these documents. We should not reject them just because we can.
    It has also been implemented based on user requests.

    But nevertheless, let me try to at least address some of your questions. Given that I actually wrote and pushed the code in question to poppler, I actually know about a lot of 'why'.

    On Friday, May 16, 2025 4:54:46 PM CEST Daniel Kahn Gillmor wrote:
    It looks like this was added very recently, well after RFC 9580 came
    out, and injects these arbitrary private/experimental packets, strictly
    for padding purposes.

    Note that it is using GpgME to talk to GnuPG, not to do RFC9580 which GnuPG does not support, so all references to RFC9580 is not relevant here.

    Also note that this is more or less piggy-backing on top of the S/Mime (X509) implementation that talks to gpg for S/Mime (X509) handling.

    And these private packets are fully compliant. It is in the spec after all. And as I wrote, these packets have been around since 1998, which is at least way before I heard of GnuPG, let alone co-maintained it in Debian.

    Why is padding needed in this case?

    In a the signed part of a PDF file, it is described that the signature is stored in a specific part of a PDF file (The signature covers bytes A to B and C
    to D (and the signature needs to be stored between B and C)), so there this hole that contains the signature, but given the location in the file needs to be specified before signing the data, it must be bigger than the expected signature size.

    There was more or less 4 ways of doing it
    1) Do a gpg packet parser in poppler to only pass the actual signature part of the signature area on to GnuPG
    2) Wrap it in an extra level of indirection with some kind of (datasize, data) structure
    3) Use something the underlying implementation would happily accept and discard of a variable size to make it fit in the middle of the pdf file.
    4) Sign some dummy data first with the key in question, check the size of the signature and hope that a repeat signature of different data will have the exact same size.

    4) involves the word 'hope' and is thus a bad idea. Also for people not using an agent to remember passphrases or using some kind of touch-to-sign smartcard, it is an annoying and surprising workflow ("Why do I need to sign twice").

    Given that there already is a battle tested package parser in GnuPG, makes 3) a much better choice than 1.

    Using 3) would also make it easier for e.g. pdfsig or just 'cut' to dump the signature into something that one manually can process with GnuPG, just like how you can do it with S/Mime signatures and process it manually with openssl, gpgsm or whatever tool you want to do without any other faffing around, so that
    kind of is points against 2.

    One could maybe use multiple 'marker' packets, but they seem to be fixed length
    packets just complicating it again.

    So simplicity was chosen. Towards the library-implementation that was already in the stack.

    If padding is what's needed here, i recommend using standardized padding
    that any compliant OpenPGP implementation will accept. Presumably the
    goal is for arbitrary OpenPGP consumers to be able to verify the
    signature of the PDF, right?

    Currently, the goal is for users to be able to sign and validate documents without having a properly issued (likely governmental) S/Mime certificate on multiple operating systems.

    Alternately, if you want to pad a signature packet, you can also inject arbitrary non-critical subpackets into the unhashed subpacket area of
    the signature itself; those subpackets should be ignored by every
    OpenPGP implementation i'm aware of.

    But that would require understanding the packets rather than just passing it on to the underlying implementation, thus complicating the code and increase complexity of poppler.

    A packet parser alone would likely double the amount of code needed in Poppler for this feature.



    /Sune
    --
    I didn’t stop pretending when I became an adult, it’s just that when I was a
    kid I was pretending that I fit into the rules and structures of this world. And now that I’m an adult, I pretend that those rules and structures exist.
    - zefrank

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Daniel Kahn Gillmor@21:1/5 to Sune Stolborg Vuorela on Sat May 17 00:30:02 2025
    Hi Sune--

    Thanks for following up here.

    On Fri 2025-05-16 19:41:54 +0200, Sune Stolborg Vuorela wrote:
    I'm not sure why all of this matters; there are others that expects gnupg in Debian to validate and fail things in a similar way to gnupg-from-upstream and
    gnupg-in-other distributions.

    Debian also has a responsibility to reduce the attack surface of the
    software it ships, even when upstream ignores reported risks and vulnerabilities.

    I'm going to walk through the timeline here, in case it's useful for
    someone reading the archive.

    The patch that you identified as problematic was offered to upstream,
    and a CVE was indicated, with the intent to reduce the attack surface of
    GnuPG. There was no substantive response to this post for about three
    years on the upstream bugtracker:

    https://dev.gnupg.org/T5993

    Soon after Demi Marie reported the concern and offered a fix which
    pushed back on accepting arbitrary packets, GnuPG upstream was publicly
    warning against accepting *any* sort of padding-style packet, despite
    the OpenPGP working group explicitly trying to adopt such a mechanism:

    https://mailarchive.ietf.org/arch/msg/openpgp/npCHOnOWEWVfvztmrkqs0w00NLk#

    From that thread:

    Having [padding packets] in the protocol is a problem because
    applications taking care not to leak too much information will need
    to reject such messages and inform the user about a possible
    problem.

    So it appears that to the extent that GnuPG upstream wants to avoid
    leaks, they will *reject* padding packets that could serve as a side
    channel.

    Meanwhile, Werner had an opportunity during that discussion, to propose
    that we should accept either packet type ID 16 (known in GnuPG as PKT_OLD_COMMENT) or *any* experimental packet codepoint as a padding
    packet. But he didn't, leading me to believe that GnuPG would be
    rejecting extra channels.

    Your poppler changes stem from commits a few months ago, that *adopt* a
    padding packet, in contravention of GnuPG's stated intentions:

    https://gitlab.freedesktop.org/poppler/poppler/-/commit/f0316ba62df9ce6d8e17a9349934b4a06df87e69

    And, it looks like at least parts of Demi Marie's proposed fix from
    T5993 are flowing into GnuPG upstream now, but not all of it. At least
    part of what is being held out (not adopted) is exactly the part that implements what Werner suggested a careful OpenPGP implementation should
    do. And poppler is taking advantage of that gap between intention and
    action.

    Am i missing anything from this timeline?

    And poppler is released, used by others. Not only in Debian, but also
    in other places, and it generates these documents. We should not
    reject them just because we can.

    How long as poppler been released with this functionality? Who is using
    it? Has it been tested against any other PDF + OpenPGP implementation?

    Note that it is using GpgME to talk to GnuPG, not to do RFC9580 which GnuPG does not support, so all references to RFC9580 is not relevant here.

    The codebase says "PGP signatures". yes, i agree that it's using GpgME,
    but if we're talking about PGP, let's keep the terms straight. The hope
    is to be interoperable with other PGP implementations, right?

    And these private packets are fully compliant. It is in the spec after
    all.

    What is in the spec? Public key packets are *also* in the spec, but
    they don't belong in a detached signature, which is what is described
    here. Nothing in any OpenPGP specification i've ever read suggests that arbitrary packets can be included in any position in a detached
    signature. Indeed, GnuPG itself wouldn't accept private/experimental
    packet 62 in that position, if i'm reading the code right.

    And as I wrote, these packets have been around since 1998, which is at least way before I heard of GnuPG, let alone co-maintained it in Debian.

    Where were they in 1998? The ones you're raising as a must-fix scenario
    about look fairly novel to me, less than a year old in Poppler,
    apparently released without interoperability testing.

    In a the signed part of a PDF file, it is described that the signature is stored in a specific part of a PDF file (The signature covers bytes A to B and C
    to D (and the signature needs to be stored between B and C)), so there this hole that contains the signature, but given the location in the file needs to
    be specified before signing the data, it must be bigger than the expected signature size.

    Thanks for this breakdown. I agree it seems like a challenging
    engineering problem with a bunch of finicky constraints. It seems like
    the discussion on how to do it safely in poppler might belong over on https://gitlab.freedesktop.org/poppler/poppler/-/issues/1595

    Given that there already is a battle tested package parser in GnuPG

    The point of T5993 is that it is *not* in fact a battle-tested packet
    parser. Rather, GnuPG has been shipping a much broader attack surface
    than it needs to for years, *and* has been declining to reduce the
    attack surface even following sensible recommendations from their lead developer. Please don't use recent changes in Poppler to discourage
    further improvements in GnuPG or other OpenPGP implementations.

    Currently, the goal is for users to be able to sign and validate documents without having a properly issued (likely governmental) S/Mime certificate on multiple operating systems.

    I fully support this goal, and i'd love to see it happen in a way that
    is effective and interoperable. Happy to follow up on https://gitlab.freedesktop.org/poppler/poppler/-/issues/1595 if you'd
    like to try to figure out how to do that safely.

    But that would require understanding the packets rather than just passing it on to the underlying implementation, thus complicating the code and increase complexity of poppler.

    yes, agreed. It looks like you're now working for g10code. Perhaps the
    way to improve this is to update GnuPG to be able to specify a target
    size of the emitted packet?

    A packet parser alone would likely double the amount of code needed in Poppler
    for this feature.

    I agree that asking Poppler to manually parse OpenPGP packets would be a mistake.

    Regards,

    --dkg

    --=-=-Content-Type: application/pgp-signature; name="signature.asc"

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

    iHUEARYKAB0WIQRjrBGOWy5dZsiKhad4C4VO2cK0lgUCaCe7XAAKCRB4C4VO2cK0 lhcaAQCLPJV11UIo1yeeQWdo8kFg7Kdf/mg2B+kGHN5yQqewQwD7B1zD1qEUKhO1 3VkobOSGQx9IAzZHnZt97Bf99yNd4QI=U4pc
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sune Stolborg Vuorela@21:1/5 to All on Sat May 17 20:10:01 2025
    On Saturday, May 17, 2025 12:25:31 AM CEST Daniel Kahn Gillmor wrote:
    Hi Sune--

    Thanks for following up here.

    Let me ask you a completely different question. What is - to you - the purpose of the reserved packet space around 61-63 in any of the pgp related standards? What's the purpose of X-foo headers in emails? of X-foo http headers?

    This is not about poppler or rfc9580 or any other things. This is about GnuPG- in-debian adding a patch that was rejected upstream for likely breaking things.

    I consider this in the same family as if an email server started to reject emails with a X-foo header, a http client refusing to continue downloading after a X-foo header.


    /Sune
    --
    I didn’t stop pretending when I became an adult, it’s just that when I was a
    kid I was pretending that I fit into the rules and structures of this world. And now that I’m an adult, I pretend that those rules and structures exist.
    - zefrank

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Daniel Kahn Gillmor@21:1/5 to Sune Stolborg Vuorela on Sun May 18 05:20:01 2025
    Hi Sune--

    On Sat 2025-05-17 20:01:48 +0200, Sune Stolborg Vuorela wrote:
    What is - to you - the purpose of the reserved packet space around
    61-63 in any of the pgp related standards?

    It's not really up to me, for what it's worth. I'm basing my answers
    on:

    https://www.rfc-editor.org/rfc/rfc9580.html#section-12.10

    which references:

    https://www.rfc-editor.org/rfc/rfc8126.html#section-4.1 (Private use)
    https://www.rfc-editor.org/rfc/rfc8126.html#section-4.2 (Experimental use)

    (or, if you prefer the obsoleted RFC 4880,

    https://datatracker.ietf.org/doc/html/rfc4880#section-13.10

    which references: https://datatracker.ietf.org/doc/html/rfc2434#page-5 )

    But if you want my short paraphrase, it's this:

    - Private means "i will use this only when talking to other people
    within the same administrative domain, and i don't care about
    interoperability."

    - Experimental means "i might at some point want to bother with
    interoperability, but i need to experiment with some functionality
    without burning a finite codepoint; i don't intend these generated
    objects to have any permanence or persistence."

    For example, the OpenPGP WG made good use of the experimental range in
    the OpenPGP Pubkey Algorithms registry over the past year when
    developing draft-ietf-openpgp-pqc (just now coming out of WGLC, yay!)

    Once development branches of multiple implementations could confirm that
    they were able to interoperate using the experimental codepoints for new algorithms, the specification was adjusted to use non-experimental
    codepoints so that the experimental codepoints could be reused for the
    next wave of experimentation. All the participating implementers needed
    to do was to adjust one constant in their development branches before
    moving to production.

    Poppler wants to create interoperable OpenPGP signatures for PDF
    documents, right? If that's the case, I don't think Poppler's proposed
    use here falls into either of these two categories.

    What's the purpose of X-foo headers in emails? of X-foo http headers?

    This seems like an entirely different question to me, because the X-foo
    style MIME or HTTP headers represent an open-ended string-based
    registry, while the reserved codepoint ranges in OpenPGP are a very
    limited fixed set of numeric identifiers (typically constrained to a
    single octet; with packet types, constrained to only 6 bits!)

    By the way, using an X- header is deprecated in open-ended namespaces,
    for a variety of reasons that i won't re-hash in this message, but i do recommend anyone read if they're interested in helping to evolve
    protocols used on the open Internet:

    https://www.rfc-editor.org/rfc/rfc6648

    At any rate, i don't think questions about the X-header are relevant to https://bugs.debian.org/1105820.

    This is not about poppler or rfc9580 or any other things. This is about GnuPG-
    in-debian adding a patch that was rejected upstream for likely breaking things.

    This isn't how i see it (and by the way, it's not just Debian who has
    adopted these patches in the face of upstream delay).

    This situation was apparently triggered by poppler, some few months ago, starting to emit what are ostensibly OpenPGP signatures. But they
    include packets assigned to private or experimental codepoints. This
    suggests that there is no expectation of interoperability with any
    OpenPGP implementation, including non-GnuPG implementations, and
    potentially any future versions of GnuPG that decide to limit exposure
    to their message parser in a detached signature context.

    I don't think poppler's choice of private or experimental use packets is
    a good idea, as i've noted in https://gitlab.freedesktop.org/poppler/poppler/-/issues/1595

    I consider this in the same family as if an email server started to reject emails with a X-foo header, a http client refusing to continue downloading after a X-foo header.

    I don't think this is the same situation at all.

    I'd be happy to help you fix poppler to not emit experimental
    codepoints, if you would find that useful. Let's follow up over on https://gitlab.freedesktop.org/poppler/poppler/-/issues/1595

    Regards,

    --dkg

    --=-=-Content-Type: application/pgp-signature; name="signature.asc"

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

    iHUEARYKAB0WIQRjrBGOWy5dZsiKhad4C4VO2cK0lgUCaClQIQAKCRB4C4VO2cK0 lqTqAP0c67CfQ+CrXPLoGkfHQVoZUl/n/dpz1WIyV5MTCtNQzwD/TeIHw0E7hYqX HG2KsPDy9EpgsGl0hHGkYnphxtybkgU=mFif
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sune Stolborg Vuorela@21:1/5 to All on Sun May 18 20:10:01 2025
    On Sunday, May 18, 2025 5:12:33 AM CEST Daniel Kahn Gillmor wrote:
    potentially any future versions of GnuPG that decide to limit exposure
    to their message parser in a detached signature context.

    Before this change in poppler, the GnuPG backend already required a functioning GnuPG suite setup.

    This work in poppler has been done in full cooperation with GnuPG upstream, it is in the GnuPG backend of poppler and these signatures is created in g10code's namespace in the pdf files. (g10c.pgp.signature.detached)

    The packets used here has, as written, been available since 1998 and given all of that, I don't expect GnuPG upstream to remove the support for it.

    /Sune
    --
    I didn’t stop pretending when I became an adult, it’s just that when I was a
    kid I was pretending that I fit into the rules and structures of this world. And now that I’m an adult, I pretend that those rules and structures exist.
    - zefrank

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)