[GPGME] gpgme_get_key vs. gpgme_op_keylist_start

Marcus Brinkmann marcus.brinkmann at ruhr-uni-bochum.de
Sat May 27 13:30:32 CEST 2006

At Tue, 2 May 2006 14:09:24 +0200,
Stephan Menzel <stephan-menzel at web.de> wrote:
> I am about to check S/MIME signatures using GPGME which already works fine.
> Now I would like to get further information about a certificate which was used 
> to sign a key.
> As I understand the manual, the easiest way to get this is:
> gpgme_key_t  key;
> gpgme_get_key(_ctx, fingerprint, &key, 0)
> However, this gives me always NULL in the key which means as much 
> as 'fingerprint not found'

Mmh.  What string do you pass in fingerprint?
> When I try this:
> gpgme_op_keylist_start(ctx, 0, 0);
> while ((gpgme_op_keylist_next(ctx, &key) != GPG_ERR_EOF) && key) {
>    fprintf(stderr, "key found:\n");
>    fprintf(stderr, "issuer   : %s\n", key->issuer_name);
>    fprintf(stderr, "serial   : %s\n", key->issuer_serial);
>    fprintf(stderr, "chain id : %s\n", key->chain_id);
> }
> The key shows up, but I cannot see the fingerprint in this struct gpgme_key_t. 
> There is only a chain ID which is different from the keys fingerprint.

Can you also try the keylist_start with your fingerprint as search
pattern?  This may at least give you an indication why gpgme_get_key

The fingerprint is in key->subkeys->fpr and key->subkeys->keyid.  The
first subkey is always the primary key (and should always be there).

> So what is the difference here? Why does gpgme_get_key not give me the key?
> Or am I completely wrong here?

I suspect that the search pattern fails.  If you look into the code
keylist.c::gpgme_get_key, you will see that it is a simple wrapper
around keylist_start.  Actually, do you use an engine configuration
for the context?  I am just realizing that the engine configuration is
not copied over to the cloned context that gpgme_get_key is using.  If
you are relying on this feature, please try out the patch below.

2006-05-27  Marcus Brinkmann  <marcus at g10code.de>

	* keylist.c (gpgme_get_key): Also clone the engine info.

Index: keylist.c
--- keylist.c	(revision 1170)
+++ keylist.c	(working copy)
@@ -939,8 +939,22 @@
   err = gpgme_new (&listctx);
   if (err)
     return err;
-  gpgme_set_protocol (listctx, gpgme_get_protocol (ctx));
-  gpgme_set_keylist_mode (listctx, ctx->keylist_mode);
+  {
+    gpgme_protocol_t proto;
+    gpgme_engine_info_t info;
+    /* Clone the relevant state.  */
+    proto = gpgme_get_protocol (ctx);
+    gpgme_set_protocol (listctx, proto);
+    gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
+    info = gpgme_ctx_get_engine_info (ctx);
+    while (info && info->protocol != proto)
+      info = info->next;
+    if (info)
+      gpgme_ctx_set_engine_info (listctx, proto,
+				 info->file_name, info->home_dir);
+  }
   err = gpgme_op_keylist_start (listctx, fpr, secret);
   if (!err)
     err = gpgme_op_keylist_next (listctx, r_key);

More information about the Gnupg-devel mailing list