gpgme: encrypt/decrypt

Werner Koch wk at
Thu Aug 18 11:39:17 CEST 2005

On Tue, 16 Aug 2005 16:49:15 -0700, Michael Nguyen said:

> So, I've read my test public key into a string that's a member of a user
> struct called z.gpgPublic


> err = gpgme_data_new_from_mem (&pubKey, z.gpgPublic, strlen(z.gpgPublic),
> 1);
> err = gpgme_op_import (ctx, pubKey);

> So, will this really import the key?  It seems to because I can find my
> email address:

Yes.  If you need to know what keys are actually imported, you may
want to call 

/* Retrieve a pointer to the result of the import operation.  */
gpgme_import_result_t gpgme_op_import_result (gpgme_ctx_t ctx);

which returns a structure with the stats similar to the one seen when
running gpg on the command line.  Further result->imports ist the head
of a linked list describing each imported key.

struct _gpgme_import_status
  struct _gpgme_import_status *next;

  /* Fingerprint.  */
  char *fpr;

  /* If a problem occured, the reason why the key could not be
     imported.  Otherwise GPGME_No_Error.  */
  gpgme_error_t result;

  /* The result of the import, the GPGME_IMPORT_* values bit-wise
     ORed.  0 means the key was already known and no new components
     have been added.  */
  unsigned int status;

>   while (!(err = gpgme_op_keylist_next (ctx, &key)))
>   {
>         if(strcmp(z.primaryEmail, key->uids->email) == 0)
>                 {
>                 printf ("%s\n", key->uids->email);
>                 }
>   }

Well this would work too but is slower.

> Basically I take this loop and I say "If you see the email address of the
> user, print it".  It always comes up so it seems to work.  So, am I going
> about this the right way so far?  If so, how do I correctly call
> gpgme_op_encrypt() at this point?

If you already know the fingerprint of the key (from the import stats)
you may use the convenience function

  /* Get the key with the fingerprint FPR from the crypto backend.  If
     SECRET is true, get the secret key.  */
  gpgme_error_t gpgme_get_key (gpgme_ctx_t ctx,
                               const char *fpr,
                               gpgme_key_t *r_key,
                               int secret)    

Using your search by email works too, however this might return
several keys if it happens that there are several keys with the same
email address.  In genereal, using the fingerprint is the best way.

Encryption (from tests/gpg/t-encrypt.c):

  main (int argc, char *argv[])
    gpgme_ctx_t ctx;
    gpgme_error_t err;
    gpgme_data_t in, out;
    gpgme_key_t key[3] = { NULL, NULL, NULL };
    gpgme_encrypt_result_t result;
    init_gpgme (GPGME_PROTOCOL_OpenPGP);
    err = gpgme_new (&ctx);
    fail_if_err (err);
    gpgme_set_armor (ctx, 1);
    err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0);
    fail_if_err (err);
    err = gpgme_data_new (&out);
    fail_if_err (err);
    /* Put the keys into the array.   Two keys in this example. Make
       sure that the last entry in the array is NULL (done by the
       intialization above). */
    err = gpgme_get_key (ctx, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
  		       &key[0], 0);
    fail_if_err (err);
    err = gpgme_get_key (ctx, "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2",
  		       &key[1], 0);
    fail_if_err (err);
    err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
    fail_if_err (err);
    result = gpgme_op_encrypt_result (ctx);
    if (result->invalid_recipients)
        fprintf (stderr, "Invalid recipient encountered: %s\n",
        exit (1);
    print_data (out);
    gpgme_key_unref (key[0]);
    gpgme_key_unref (key[1]);
    gpgme_data_release (in);
    gpgme_data_release (out);
    gpgme_release (ctx);
    return 0;



More information about the Gnupg-devel mailing list