gpg vs gpgv and trustedkeys

Daniel Kahn Gillmor dkg at fifthhorseman.net
Sun Mar 3 17:53:49 CET 2019


On Sat 2019-03-02 11:31:44 +0100, Olliver Schinagl wrote:
> Well the actualy firmware image validation will be done via a script
> there, so no worries on that regard. But if an engineer is tasked with
> modifying any of these scripts, they may struggle to know what's going
> on when invoking the tools themselves.

right.  If you have the capacity to make a thoughtful design of the
internal image validation script (both its API and its internal
codebase), then the validation script itself can serve as useful
tooling and explanatory guideposts for your engineers.

> gpgv should really remove this feature all together. E.g.  always
> point to a keyring.

This is an interesting suggestion, and i wonder whether GnuPG upstream
would be willing to consider it for some API-breaking new revision of
gpgv (or some alternate signature-verifying tool).

I've proposed a new process-level OpenPGP signature-verifying API over
here:

    https://bugs.debian.org/872271

and you're right, it doesn't assume a default keyring, but rather
requires an explicit designation of which keys are acceptable.

I agree with you that the documentation should be improved, and i think
that upstream would welcome patches to that effect.

I've just submitted one improvement (to documentation about gpgv's
keyring selection) here:  https://dev.gnupg.org/T4386

One path toward actually deprecating the default keyring would be to
warn if the default keyring is used, probably in main() in
g10/gpgv.c.

> The trustedkeys file is just confusing (and the internet is only
> filled with confusion surounding this filename).  Many suggest to even
> just symlink the trustedkeys file to the pubkey files.

yikes.  I can imagine some unusual circumstances where that would be
reasonable, but it sounds particularly dangerous in contexts where you
care about who the signature comes from.


> Having said that, I'll didn't check/try; but what IS the best way to get
> a key into a system. I can do gpg --import and move + package the file
> of course; but is there a cleaner solution to get the file, into say
> /etc/keys for example? (Without using the --keyring paramater of gpg, as
> that paramater has come and gone in certain versions, so not sure how
> reliable that one is). Or is it really the only and recommended way.


The best way to create a set of keys that can validate is to explictly
and deliberately *export* (not import!) the keys that you know you care
about into a file.

so, verify that you get *only* the keys you want:

    gpg --list-keys $FINGERPRINT

and then if it looks good:

    gpg --output curated.pgp --export $FINGERPRINT

then you can pass curated.pgp to gpgv's --keyring argument.

Note that gpgv has weird non-standard semantics for its --keyring
argument, though -- if the filename has no "/" in it, it's assumed to be
found in the homedir (typically, ~/.gnupg/), rather than in the current
working directory, so i always specify keyrings with an absolute path.
in the shell, you can often launder it through realpath(1), so this
should be safe, regardless of how $KEYRING gets set:


    KEYRING=curated.pgp
    […]
    gpgv --keyring "$(realpath "$KEYRING")" "$signature" "$object"

Note also that the semantics of gpgv's return value may not match what
you want.  In particular, they make it difficult to ship additional
signatures during a time of key transition, because gpgv will return
non-zero if *any* discovered signatures are "bad" [0]. Additionally, gpgv
has some odd semantics around key creation time, expiry, revocation,
etc:

    https://dev.gnupg.org/T1537

So you really do want to use --status-fd and parse its output to
determine what happened, and not just rely on its return code.

          --dkg

[0] explanation of the lifecycle of a signed series of updates:

 * at time T, clients fetch update U_T with signature bundle S_T.  the
   clients all verify that S_T is signed by one of the keys they know
   about.

 * initially, all clients know only about signing key K_0.

 * So, at early time A, a client fetches update U_A and signature S_A
   and verifies that S_A is made by K_0.

 * at some future time B, the authors introduce a new signing key K_1,
   but not all clients know about it yet.  S_B contains signatures from
   both K_0 and K_1.  Unupdated clients verify S_B over U_B based on
   K_0, while updated clients verify S_B over U_B based on K_1.

 * later, at time C, once all clients are known to be updated (or are
   explictly unsupported), the authors drop or revoke or destroy K_0,
   and sign new updates only with K_1.

between times B and C, any verification mechanism that depends on gpgv's
return code will break for clients that don't know about *both* K_0 and
K_1.  This requires software vendors to ship their preferred signing
keys well before they start actually distributing signatures with them,
which is a surprising workflow.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 227 bytes
Desc: not available
URL: <https://lists.gnupg.org/pipermail/gnupg-users/attachments/20190303/06c13af9/attachment.sig>


More information about the Gnupg-users mailing list