Selection decryption

Werner Koch wk at gnupg.org
Tue Feb 2 18:15:46 CET 2010


Hi,

here is some code to see how the UI-server works.

  /*
   *  file.c
   *  This file is part of Mousepad
   [...]
  
  #include <gpgme.h>

You need gpgme of course.  Here is the code to write out teh encrypted
data:
  
  /* Encrypt or sign the string PLAINTEXT and write it to FP.  MODE
   * controls whether encrypt, signing or both are used.  The function
   * employs an external UI server and requires that gpgme has been
   * initialized at startup.  Returns 0 on success.  */
  static int crypt_write (const char *plaintext, CryptMode mode, FILE *fp)
  {
       gpg_error_t err;
       gpgme_ctx_t ctx;
       gpgme_data_t in, out;
  
       err = gpgme_new (&ctx);
       if (err) {
            g_debug ("error creating gpgme context: %s", gpg_strerror (err));
            return -1;
       }
  
       /* Tell GPGME to use the "UI-Server protocol".  */
       err = gpgme_set_protocol (ctx, GPGME_PROTOCOL_UISERVER);
       if (err) {
            g_debug ("gpgme does not support the UI protocol: %s",
                     gpg_strerror (err));
            gpgme_release (ctx);
            return -1;
       }
  
       /* We want the UI server to use the best encryption protocol around.  */
       err = gpgme_set_sub_protocol (ctx, GPGME_PROTOCOL_OpenPGP);
       if (err) {
            g_debug ("error asking the UI server to use the %s protocol: %s",
                     "OpenPGP", gpg_strerror (err));
            gpgme_release (ctx);
            return -1;
       }
  
       /* Wrap the data into an GPGME object.  */
       err = gpgme_data_new_from_mem (&in, plaintext, strlen (plaintext), 0);
       if (err) {
            g_debug ("error creating gpgme data object: %s",
                     gpg_strerror (err));
            gpgme_release (ctx);
            return -1;
       }

There are several other methods how to create a gpgme data objects, but
this one will probably also fit your requirements.
  
       /* Wrap the output stream into an GPGME object.  */ 
       err = gpgme_data_new_from_stream (&out, fp);
       if (err) {
            g_debug ("error creating gpgme stream data object: %s",
                     gpg_strerror (err));
            gpgme_data_release (in);
            gpgme_release (ctx);
            return -1;
       }

MODE below comes from a selector in the file dialog.
  
       /* Do whatever has been requested.  */
       if (mode == CRYPT_ENCRYPT) {
            err = gpgme_op_encrypt (ctx, NULL, 0, in, out);
            if (err)
                 g_debug ("error encrypting file: %s <%s>",
                          gpg_strerror (err), gpg_strsource (err));
       }
       else if (mode == CRYPT_SIGN) {
            err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_NORMAL);
            if (err)
                 g_debug ("error signing file: %s <%s>",
                          gpg_strerror (err), gpg_strsource (err));
       }
       else if (mode == CRYPT_SIGNENCRYPT) {
            err = gpgme_op_encrypt_sign (ctx, NULL, 0, in, out);
            if (err)
                 g_debug ("error signing and encrypting file: %s <%s>",
                          gpg_strerror (err), gpg_strsource (err));
       }
       else
            err = gpg_error (GPG_ERR_BUG);
  
       /* Cleanup.  */
       gpgme_data_release (out);
       gpgme_data_release (in);
       gpgme_release (ctx);
  
       return err? -1:0;
  }
  
The rest of the code in file.c erely adds the mentioned selector widget
and hooks into the saving procedure.  I leave that out.

Now, to test this you need to start gpa as a server:

  gpa --server

and it should just work; i.e. you get a selection dialog etc.  As I said
in my last mail you need the latest gpa version, the latest gpgme
version and thus also the latest libassuan version.  Old GnuPG versions
should do fine.  Note that you can also S/MIME encrypt if you like
(cf. gpgme_set_sub_protocol).

Decryption is similar, but I don't think I tested it.  The reason why we
have this UI-server thing is that we use it in the Windows version to do
all key selection and actual encryption stuff in our Outlook and
Explorer plugins within a usable GUI framework (GTK+ or Qt).  Thus there
is no reason not to use it in other software as well.

I'd really love to see that feature in real use.  Thus if there are any
problems, I is likely that I can help you.  if something needs to be
added to GPA, this can be done pretty quicker - or do it yourself (we
don't need copyright assignments for GPA).


Salam-Shalom,

   Werner


-- 
Die Gedanken sind frei.  Ausnahmen regelt ein Bundesgesetz.




More information about the Gnupg-devel mailing list