Inmplement import from keys for GPGSM.
authorWerner Koch <wk@gnupg.org>
Tue, 7 Jul 2009 14:33:10 +0000 (14:33 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 7 Jul 2009 14:33:10 +0000 (14:33 +0000)
Add option --cms to run-keylist test program.

src/ChangeLog
src/engine-gpg.c
src/engine-gpgsm.c
tests/ChangeLog
tests/run-keylist.c

index eca549a..feebbdc 100644 (file)
@@ -1,5 +1,12 @@
 2009-07-07  Werner Koch  <wk@g10code.com>
 
+       * engine-gpgsm.c (struct engine_gpgsm): Add fields
+       input_helper_data and input_helper_memory.
+       (close_notify_handler): Release these new fields.
+       (gpgsm_import): Implement the keyarray feature.
+
+       * engine-gpg.c (gpg_import): Actually return GPG_ERR_INV_VALUE.
+
        * engine-gpgsm.c (gpgsm_import): Return an error for unknown data
        encodings.
 
index a3b9467..dba49a9 100644 (file)
@@ -1914,7 +1914,7 @@ gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
   gpgme_data_encoding_t dataenc;
 
   if (keydata && keyarray)
-    gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
+    return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
 
   dataenc = gpgme_data_get_encoding (keydata);
 
index 52915d3..4067b99 100644 (file)
@@ -70,6 +70,8 @@ struct engine_gpgsm
 
   /* Input, output etc are from the servers perspective.  */
   iocb_data_t input_cb;
+  gpgme_data_t input_helper_data;  /* Input helper data object.  */
+  void *input_helper_memory;       /* Input helper memory block.  */
 
   iocb_data_t output_cb;
 
@@ -141,6 +143,16 @@ close_notify_handler (int fd, void *opaque)
        (*gpgsm->io_cbs.remove) (gpgsm->input_cb.tag);
       gpgsm->input_cb.fd = -1;
       gpgsm->input_cb.tag = NULL;
+      if (gpgsm->input_helper_data)
+        {
+          gpgme_data_release (gpgsm->input_helper_data);
+          gpgsm->input_helper_data = NULL;
+        }
+      if (gpgsm->input_helper_memory)
+        {
+          free (gpgsm->input_helper_memory);
+          gpgsm->input_helper_memory = NULL;
+        }
     }
   else if (gpgsm->output_cb.fd == fd)
     {
@@ -1545,18 +1557,79 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
   engine_gpgsm_t gpgsm = engine;
   gpgme_error_t err;
   gpgme_data_encoding_t dataenc;
+  int idx;
 
   if (!gpgsm)
     return gpg_error (GPG_ERR_INV_VALUE);
 
   if (keydata && keyarray)
-    gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
+    return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
 
   dataenc = gpgme_data_get_encoding (keydata);
 
   if (keyarray)
     {
-      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      size_t buflen;
+      char *buffer, *p;
+
+      /* Fist check whether the engine already features the
+         --re-import option.  */
+      err = gpgsm_assuan_simple_command 
+        (gpgsm->assuan_ctx, 
+         "GETINFO cmd_has_option IMPORT re-import", NULL, NULL);
+      if (err)
+       return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+      /* Create an internal data object with a list of all
+         fingerprints.  The data object and its memory (to avoid an
+         extra copy by gpgme_data_new_from_mem) are stored in two
+         variables which are released by the close_notify_handler.  */
+      for (idx=0, buflen=0; keyarray[idx]; idx++)
+        {
+          if (keyarray[idx]->protocol == GPGME_PROTOCOL_CMS
+              && keyarray[idx]->subkeys
+              && keyarray[idx]->subkeys->fpr 
+              && *keyarray[idx]->subkeys->fpr)
+            buflen += strlen (keyarray[idx]->subkeys->fpr) + 1;
+        }
+      /* Allocate a bufer with extra space for the trailing Nul
+         introduced by the use of stpcpy.  */
+      buffer = malloc (buflen+1);
+      if (!buffer)
+        return gpg_error_from_syserror ();
+      for (idx=0, p = buffer; keyarray[idx]; idx++)
+        {
+          if (keyarray[idx]->protocol == GPGME_PROTOCOL_CMS
+              && keyarray[idx]->subkeys
+              && keyarray[idx]->subkeys->fpr 
+              && *keyarray[idx]->subkeys->fpr)
+            p = stpcpy (stpcpy (p, keyarray[idx]->subkeys->fpr), "\n");
+        }
+      
+      err = gpgme_data_new_from_mem (&gpgsm->input_helper_data,
+                                     buffer, buflen, 0);
+      if (err)
+        {
+          free (buffer);
+          return err;
+        }
+      gpgsm->input_helper_memory = buffer;
+
+      gpgsm->input_cb.data = gpgsm->input_helper_data;
+      err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
+      if (err)
+        {
+          gpgme_data_release (gpgsm->input_helper_data);
+          gpgsm->input_helper_data = NULL;
+          free (gpgsm->input_helper_memory);
+          gpgsm->input_helper_memory = NULL;
+          return err;
+        }
+      gpgsm_clear_fd (gpgsm, OUTPUT_FD);
+      gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+      gpgsm->inline_data = NULL;
+
+      return start (gpgsm, "IMPORT --re-import");
     }
   else if (dataenc == GPGME_DATA_ENCODING_URL
            || dataenc == GPGME_DATA_ENCODING_URL0
@@ -1573,10 +1646,9 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
       gpgsm_clear_fd (gpgsm, OUTPUT_FD);
       gpgsm_clear_fd (gpgsm, MESSAGE_FD);
       gpgsm->inline_data = NULL;
-    }
 
-  err = start (gpgsm, "IMPORT");
-  return err;
+      return start (gpgsm, "IMPORT");
+    }
 }
 
 
index 9e68d51..926771a 100644 (file)
@@ -1,5 +1,7 @@
 2009-07-07  Werner Koch  <wk@g10code.com>
 
+       * run-keylist.c (main):  Add options --cms and --openpgp.  
+       
        * gpg/pgp-keylist.c: Rename to ...
        * run-keylist.c: ... this.
        * gpg/pgp-import.c: Rename to ...
index 07fc894..8dd28b8 100644 (file)
@@ -43,6 +43,8 @@ show_usage (int ex)
   fputs ("usage: " PGM " [options] [USERID]\n\n"
          "Options:\n"
          "  --verbose        run in verbose mode\n"
+         "  --openpgp        use the OpenPGP protocol (default)\n"
+         "  --cms            use the CMS protocol\n"
          "  --local          use GPGME_KEYLIST_MODE_LOCAL\n"
          "  --extern         use GPGME_KEYLIST_MODE_EXTERN\n"
          "  --sigs           use GPGME_KEYLIST_MODE_SIGS\n"
@@ -54,6 +56,7 @@ show_usage (int ex)
   exit (ex);
 }
 
+
 int 
 main (int argc, char **argv)
 {
@@ -66,6 +69,7 @@ main (int argc, char **argv)
   int import = 0;
   gpgme_key_t keyarray[100];
   int keyidx = 0;
+  gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
 
   if (argc)
     { argc--; argv++; }
@@ -85,6 +89,16 @@ main (int argc, char **argv)
           verbose = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--openpgp"))
+        {
+          protocol = GPGME_PROTOCOL_OpenPGP;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--cms"))
+        {
+          protocol = GPGME_PROTOCOL_CMS;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--local"))
         {
           mode |= GPGME_KEYLIST_MODE_LOCAL;
@@ -128,11 +142,11 @@ main (int argc, char **argv)
   if (argc > 1)
     show_usage (1);
 
-  init_gpgme (GPGME_PROTOCOL_OpenPGP);
+  init_gpgme (protocol);
 
   err = gpgme_new (&ctx);
   fail_if_err (err);
-  gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP);
+  gpgme_set_protocol (ctx, protocol);
 
   gpgme_set_keylist_mode (ctx, mode);