sopv-gpgpv: an implementation of the verification-only subset of the Stateless OpenPGP CLI using gpgv as a backend

Daniel Kahn Gillmor dkg at fifthhorseman.net
Tue Jul 30 11:35:22 CEST 2024


Hi Todd--

On Mon 2024-07-29 15:47:09 -0400, Todd Zullinger via Gnupg-users wrote:
> Particularly, using sopv-gpgv would introduce more
> dependencies to the buildroot (the python stack,
> specifically) which is unlikely to be something folks like
> Fedora want, after spending time to minimize the default
> buildroot.  (I don't care too much about Fedora anymore, as
> I'm migrating away from anything Red Hat based, but it's
> still what I'm most familiar with.)

If anyone wants to propose a version of sopv-gpgv that has no additional
external dependencies, i'd be happy to review it and merge it if it's
good :) i'm not sold on sopv-gpgv needing to be python, i just chose
that languagte as a reasonable option to do rapid development, sensible
argument handling, and not-too-dangerous parsing of gpgv's status file,
which seems obligatory to get the answer that most folks want out of .

> Fedora does have the Sequoia SOP command available, but it
> doesn't work out of the box (nor does it provide an option
> to be more verbose, AFAICT).

The fact that sqop or sqopv can't verify the material you're looking at
suggests a problem with the data presented to it.

I found the files you're testing with at:

https://www.kernel.org/pub/software/scm/git/git-2.46.0.tar.sign
https://www.kernel.org/pub/software/scm/git/git-2.46.0.tar.xz

and i used my copy of Junio's OpenPGP certificate, which i keep up to
date from the various keyserver networks.   I'm not sure where you got
it from, but i've attached it to this e-mail.

i first decompresed the .xz to a raw tarball, then ran the same tests as
you did, and i got the same results.

>     [root at 6e3fc2ac22a3 tmp]# /usr/lib/rpm/redhat/gpgverify \
>         --keyring=gpgkey-junio.asc --signature=git-2.46.0.tar.sign \
>         --data=git-2.46.0.tar
>     gpgv: Signature made Mon Jul 29 14:27:21 2024 UTC
>     gpgv:                using RSA key E1F036B1FEE7221FC778ECEFB0B5E88696AFE6CB
>     gpgv: Good signature from "Junio C Hamano <gitster at pobox.com>"
>     gpgv:                 aka "Junio C Hamano <junio at pobox.com>"
>     gpgv:                 aka "Junio C Hamano <jch at google.com>"
>
>     [root at 6e3fc2ac22a3 tmp]# /tmp/sopv-gpgv verify git-2.46.0.tar.sign \
>         gpgkey-junio.asc <git-2.46.0.tar
>     2024-07-29T14:07:21Z E1F036B1FEE7221FC778ECEFB0B5E88696AFE6CB 96E07AF25771955980DAD10020D04E5A713660A7 mode:binary
>
>     [root at 6e3fc2ac22a3 tmp]# sqop verify git-2.46.0.tar.sign \
>         gpgkey-junio.asc <git-2.46.0.tar
> 	       No acceptable signatures found

A bit of digging further suggests that sqop is rejecting Junio's OpenPGP
certificate because it does not have a valid direct key self-signature
or user ID self-certification at the time that the signature was made.

In particular, the User ID self-certifications that are present in the
certificate depend on SHA-1, which has been explicitly deprecated and
marked for legacy use only as far back in 2011, when Junio's certificate
claims to have been created:

   https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-131a.pdf
  
(i'm not saying you have to agree with NIST's specifications; just
observing that Junio's certificate was weaker than it should have been
when it was created, and *really* should have been updated by now)

gpgv didn't catch this, even with a warning. ☹

> Using /usr/lib/rpm/redhat/gpgverify -- which is a small
> shell script wrapper for gpgv -- avoids new dependencies and
> produces quite readable output which is handy in build logs.

is this the source for gpgverify that you're using?

https://src.fedoraproject.org/rpms/redhat-rpm-config/blob/main/f/gpgverify

This depends explicitly on the return code for gpgv, which is known to
be brittle.  (it also depends on gpg itself, not just on gpgv, as you
noted earlier, for the dearmoring)

For example, if the detached signature contains multiple signatures, and
gpgv can't verify one of them, it will return a non-zero error code,
even if it *can* verify the other signature.  This means every tool that
depends on gpgverify is going to make it difficult to migrate the
ecosystem to new cryptographic algorithms.

The usual approach for that would be to sign the file with both the old
and new algorithms, and put them both in the detached signature file.
That way, existing implementations can continue to verify the old
algorithm, and newer implementations can verify the new one.

However, that won't work for clients that rely on gpgverify, because
they'll return a non-zero status because they can't verify the new
signature, even if the legacy algorithm (which it does know about)
validates just fine. ☹

> Using an SOP command would still require some wrapper to
> provide useful error output.  That's all fixable, but it's
> going to take some time before that's in place and
> acceptable by many distributions.

What error output do you think would be useful?  The most important goal
is to only accept things that should be acceptable and to only reject
things would not be unacceptable.  If there's a rejection, there could
be dozens of possible reasons, each represented by a single
counterfactual.  How many of those counterfactuals should be emitted?

Regards,

        --dkg

-------------- next part --------------
A non-text attachment was scrubbed...
Name: junio.pgp
Type: application/pgp-keys
Size: 9297 bytes
Desc: not available
URL: <https://lists.gnupg.org/pipermail/gnupg-users/attachments/20240730/ede7fe39/attachment-0001.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 324 bytes
Desc: not available
URL: <https://lists.gnupg.org/pipermail/gnupg-users/attachments/20240730/ede7fe39/attachment-0001.sig>


More information about the Gnupg-users mailing list