I think the critical thing I missed in the original message is that
News::Article::NoCeM is constructing an inline signature by calling
pgp_sign.  The Hash header here is before the signed body, not before the
signature, which is obvious in your original message but which I failed to
pay proper attention to.

Christoph Biedl <debian.a...@manchmal.in-ulm.de> writes:

> So, a blank line doesn't help. The message by gpgv is

> | gpgv: Signature made Fri Jan  5 18:21:01 2024 UTC
> | gpgv:                using RSA key 87FB8F9D33883045A832B4FFD90D76CC97A7B20D
> | gpgv: WARNING: signature digest conflict in message
> | gpgv: Can't check signature: General error

> and this leads to an error message from perl-nocem:

> | Article <redacted>: unknown error (ID D90D76CC97A7B20D)

> where "WARNING: signature digest conflict in message" is the same as
> I had seen in the first place, when there was the hardcoded "SHA1".

> For completeness, this is gpgv 2.2.40-1.1, from Debian 12 ("bookworm").
> Also, neither the NoCeM message nor the key are publicly available.

I think this is a bug in News::Article::NoCeM.  It is constructing an
inline signed document using PGP::Sign's pgp_sign function, but pgp_sign
creates detached signatures.  Detached and inline signatures are subtly
different, which has historically been the cause of all sorts of pain and
suffering trying to deal with OpenPGP signatures.

This is explicitly called out in the PGP::Sign manual page, although it
should be clearer since it implies the only issues are with whitespace
munging, but it seems like there are more issues than just that.

    The whitespace munging support addresses the most common difference
    between cleartext and detached signatures, but does not deal with all
    of the escaping issues that are different between those two
    modes. It's likely that extracting a cleartext signature and verifying
    it with this module or using a signature from this module as a
    cleartext signature will not work in all cases.

The other use cases for PGP::Sign (control message signatures and
PGPMoose) both use detached signatures, and it does try to document that
it only deals with detached signatures:

    This module supports only two OpenPGP operations: Generate and check
    detached PGP signatures for arbitrary text data.

Again, though, I should make this clearer.

I'm not sure where that leaves this bug, though.  It's quite
understandable that News::Article::NoCeM doesn't want to implement the
annoying logic of figuring out the correct flags to call GnuPG, but if the
expectation for NoCeM messages is that they use inline signatures (which I
believe is the case, although ideally they should use multipart/signed and
application/pgp-signature), PGP::Sign doesn't do that.  I do have other
use cases for inline signatures currently, so I am not completely opposed
to adding that support, although the more correct thing for me to do with
those other use cases would be to switch to multipart/signed instead.  At
least the last time I looked, inline signatures were very poorly
documented and standardized.

It's possible that this specific bug could be fixed if there were a way to
pass the desired hash algorithm into the sign() method of PGP::Sign so
that News::Article::NoCeM can force SHA-1 as a hash algorithm, thus making
the signature match the headers.  You suggested that in your original
message.  That's a bit more within the remit of PGP::Sign and I feel more
comfortable supporting that.  But I fear that may not be a full fix, since
there's still the detached versus inline signature mismatch that I think
is quite likely to produce more problems in the future.  (And of course
there's also the problem that News::Article::NoCeM really should be using
SHA-256, but that raises backwards compatibility issues.  There are a lot
of ancient PGPs out there in Usenet world.)

> It is indeed present there, I used pgpdump to reveal the hash algorithm
> is actually SHA512. So this is a design decision I don't quite follow,
> but possibly there is or was a need to do things that way.

This is ringing a vague bell.  I think the issue with inline signatures is
that since the document is stream-processed, the hash function that should
be used for the text has to be specified *before* the signed body text.
By the time the signature is read, it's too late; the body has already
been consumed and hashed with the default hash algorithm, and the correct
hash is no longer available.

I believe what hash algorithm GnuPG uses by default is controlled by local
GnuPG configuration, and it may well default to SHA-256 these days.

Also, all of these modules should switch to a sane interface to OpenPGP
signing and verification, like sup, but that's a whole other discussion.

-- 
Russ Allbery (r...@debian.org)              <https://www.eyrie.org/~eagle/>

Reply via email to