Page MenuHome GnuPG

GPGME: Allow to set the keyring for a context
Closed, ResolvedPublic

Description

Usecase: Use a dedicated keyring in a program / script using gpgme.

I think this is a very legitimate usecase and also a possible solution for
issue2819 (you could import / list on a temporary keyring)

I've also needed this when writing a script for WKD generation. We have a
"employee keyring" in our company that is updated when someone joins or leaves
the company. That keyring (the whole directory containing it) is read only for
users so changing the homedir is not really an option.

Workarounds for this are to use wrapper scripts that add --no-default-keyring
--no-options and --keyring. Ugly!

Example workaround from generate-openpgpkey-hu:

if not os.path.exists(keyring):

raise KeyringError(
    "keyring '%s' not found" % keyring)

tmpdir = tempfile.mkdtemp("-hugen")
filename = os.path.join(tmpdir, "my-gpg")
gpgfile = open(filename, 'w')
for engine in pyme.core.get_engine_info():

if engine.protocol == pyme.constants.protocol.OpenPGP:
    oldgpg = engine.file_name

gpgfile.write('#!/bin/sh\nexec "%s" --no-default-keyring '

'--no-options --keyring "%s" "$@"\n' %
(oldgpg, keyring))

gpgfile.close()
os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
pyme.core.set_engine_info(pyme.constants.protocol.OpenPGP, filename)

Event Timeline

The keyring is a property of GnuPG and you should not mess around with it. Use
--export and --import to add keys. Extending the bad behaviour of using
multiple keyrings would be Bad Thing.

Besides the WKD scenario Andre describes, there are already many existing uses
of a separate keyring where having other keyrings configured via
~/.gnupg/gpg.conf already conflicts with the intended use, except when using
--no-options:

  1. /etc/apt/trusted.gpg
  2. /usr/share/keyrings/debian-keyring.gpg
  3. our company's keyring with acceptable keys for encryption of certain

sensitive information

Basically everywhere where multiple users use a single keyring, often with
"--trust-model always", where you do not want additionally configured keyrings
to disturb the result and give a false sense of security.

Please explain why this a Bad Thing[tm] and what the correct workflow would be.

I have explained this several times over the last decade. The primary reason is
that it is not possible to keep a consistent vewi on the localally availabale
keys when a user is allowed to remove and add storage at will without gpg having
any control over it. You may end up with duplicated keys and gpg will only
update one of them. The next time the keyrings are "mounted" in a different
order and key is used for update. This leads to all kinds of problems. This is
not a distributed database with a 3 -phase commit system.

I have proposed a solution gor 2.3 based a on central key managing daemon, which
then has the chance to track changes. Interesting fact is that aheinecke has
strongly opposed that idea.

Ah, I understand. I currently have two keyrings (the default keyrings and
debian-keyring.gpg) in my user account. So I will export the keys from
debian-keyring.gpg and import them into my regular keyring.

But this is a different topic from the one described here:
This issue is about allowing gpgme to use exactly one different keyring (not an
additional keyring) that is different from the default keyring or other keyrings
configured in the user's gpg.conf.

So it is just about allowing in gpgme what is already possible via the command
line. Or maybe you would prefer to allow passing command line options to gpg via
gpgme to avoid the wrapper script mentioned below?

We try to deprecate the use of the --keyring option because that is too
troublesome for many reasons. We can't remove that option from gpg proper for
compatibilty reasons. But not adding a new feature to GPGME won't raise any
compatibility problem and thus we can fortunately reject this request.

Please tell me how I should model my workflows in this case:

  • There is a a centrally managed set of public keys (currently in a keyring

file, but I'm open to suggestions)

  • Different users should be able to use this set of keys (and no others) for

certain tasks:

  1. Encrypt a file to any of those key (but no others!), but also decrypt the

file with their secret key (which is not centrally managed)

  1. Iterate over all keys and do something with them (here: publish them in the

WKD after having made changes to the set of keys)

Sign the keys and set the signing key to fully trusted.

Sign the keys and set the signing key to fully trusted.

does not solve 1.:

Encrypt a file to any of those key (but no others!),

(because people may trust other keys)

and it does not solve 2. without keeping a separate list of keys/fingerprints:

Iterate over all keys

additionally _all_ users have to regularly update _all_ these keys, otherwise
things like expired subkeys will lead to failing encryption. (This is no theory:
We've been there and don't want to have this again)

(repost, I just noticed that neal is not in the nosy list. I'll unlink the old
entry afterwards)

neal: Interesting idea, this (or for a non-gui version: a signed list of
fingerprints available from a central source and retrieving those keys) would
solve 2 (iterating over all keys) and 3 (regularly update).

For the non-gui variant I wondered about how to use --verify and check that the
file was signed by the authority key (--verify only prints the keyid,
"--keyid-format none" does not allow --verify to print fingerprints in 2.1.15,
I'll file a separate issue). I was a bit disappointed when I saw that gpg sync
just calls the command line with --keyid-format 0xlong and does screen scraping
to verify the verification.

But still, how to solve 1 with gpg itself? Of course I could "manually" verify
in the application that only the intended keys have been used, but as shown with
gpg sync's code above: This is not always easily possible.

Reported the problem mentioned here in T2835
("keyid-format none" ignored for --verify and other commands)

Regarding the original issue discussed here:
What about an option in gpg/gpgme to limit all operations to keys contained in a
"whitelist" file?

(accept --recipient keys only if they are contained in the file, --list-keys
shows only keys listed in this file, --refresh-keys only refreshes keys listed
here, etc.)

GPGME is about making GPG easy and not to cover very special use cases. I'll thus close this bug.

aheinecke reassigned this task from werner to gnupg-hackers.

As discussed: The proper solution for this is GPGK, a Pubkey deaemon for GnuPG that would cater to audited / monitored keyrings. The usecase has not gone away and from my talks with people in the community and my general experience it is not "special" and definitely not "very special". It's important for Software Developers using GPGME that want to have keyrings for their Software Seperate from the general GnuPG user setup.

We should close it if we have a solution for this Usecase without violating design principles by having GPGK.

FWIW I strongly disagree with the sentiment that GPGME should be a "dumbed down" "Easy" GnuPG API. It should be GnuPG made stable -> A stable and reliable C API for the Free Software OpenPGP implementation GnuPG. But this is off topic. SCNR. It's much easier just to use process calls in many cases but I understand why this should not be done and leads to maintenance problems / bugs.

Back to you original problem: What you are trying to do is a hack to work around properties of GnuPG. Namely, that GnuPG stores its state in a _directory_ and you are modifying parts of this state (e.g. pubring.gpg). This is why GPGME allows you to switch to another directory but obviously does not allow you to modify parts of a directory (i.e. the state).

Now, you will probably counter this with pointing to --keyring and such. These options were added on user request and I have more than once tore my hair on why I didn't stood strong and refused to support these option. The plan for 2.1 was to finally get rid of them but again I ate humble pie and kept them.

This is why I marked this bug as wont fix and I even consider to come up with a more strong tag. Closing again.

GPGME is different: It provides a _new_ API to gpg and thus it was possible to not support these misfeatures.

I think we are talking "aneinander vorbei". AFAIK we agreed (on the Osnabrück meeting) that we will cater to this usecase: Multiple different keyrings for some operations. Or "curated" keyring. Through GPGK and so we will have some API (key probably not a keyring for a context) like this in GPGME at some point in the next years. This is why I think this issue might be kept open to say: Yes we see the usecase but we will not solve it by exposing, what you call a hack, through GPGME. But we will solve it at some point with a better solution.

Well, this will be a different thing and more related to the to-be-implemented key origin feature.
I would thus suggest to open a new task for this.