[git] GPGME - branch, master, updated. gpgme-1.10.0-189-ga1f76b3

by Werner Koch cvs at cvs.gnupg.org
Tue Apr 17 08:52:29 CEST 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".

The branch, master has been updated
       via  a1f76b3b54b75a150fe272b804d85ffd40a507a6 (commit)
      from  b99502274ae5efdf6df0d967900ec3d1e64373d7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a1f76b3b54b75a150fe272b804d85ffd40a507a6
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Apr 17 08:33:44 2018 +0200

    core: Add extended versions of the encrypt functions.
    
    * src/gpgme.h.in (gpgme_op_encrypt_ext_start) New.
    (gpgme_op_encrypt_ext): New.
    (gpgme_op_encrypt_sign_ext_start): New.
    (gpgme_op_encrypt_sign_ext): New.
    * src/libgpgme.vers, tests/run-encrypt.c: Add them.
    
    * src/encrypt.c (encrypt_start): Add arg recpstring.
    (gpgme_op_encrypt): Factor code out to ...
    (gpgme_op_encrypt_ext): new function with new arg recpstring.
    (gpgme_op_encrypt_start): Factor code out to ...
    (gpgme_op_encrypt_ext_start): new function with new arg recpstring.
    * src/encrypt-sign.c (encrypt_sign_start): Add arg recpstring.
    (gpgme_op_encrypt_sign): Factor code out to ...
    (gpgme_op_encrypt_sign_ext): new function with new arg recpstring.
    (gpgme_op_encrypt_sign_start): Factor code out to ...
    (gpgme_op_encrypt_sign_ext_start): new function with new arg
    recpstring.
    
    * src/engine-backend.h (struct engine_ops): Change fields encrypt and
    encrypt_sign.
    * src/engine.c (_gpgme_engine_op_encrypt): Add arg recpstring and pass
    to engine.
    (_gpgme_engine_op_encrypt_sign): Ditto.
    * src/engine-gpg.c (append_args_from_recipients_string): New.
    (gpg_encrypt): Add arg recpstring and call new function as needed.
    (gpg_encrypt_sign): Ditto.
    * src/engine-gpgsm.c (set_recipients_from_string): New.
    (gpgsm_encrypt): Add arg recpstring and call new function as needed.
    * src/engine-uiserver.c (set_recipients_from_string): New.
    (uiserver_encrypt): Add arg recpstring and call new function as
    needed.
    
    * tests/run-encrypt.c (xstrdup): New.
    (main): Add option --keystring.
    
    * src/gpgme-json.c (get_keys): Simplify.
    (op_encrypt): Modify to make use of the extended encrypt function.
    
    --
    
    This new feature can be used to avoid the need for a key lookup and
    thus several extra calls to the backend.
    
    Note that run-test uses a semicolon as delimiter because that make
    testing the feature on the command line much easier.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index a8d73a5..51d7923 100644
--- a/NEWS
+++ b/NEWS
@@ -5,11 +5,16 @@ Noteworthy changes in version 1.10.1 (unreleased)
 
  * Interface changes relative to the 1.10.0 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- gpgme_import_result_t       EXTENDED: New field 'skipped_v3_keys'
- cpp: Key::locate                     NEW.
- cpp: Data::toString                  NEW.
+ gpgme_op_encrypt_ext             NEW.
+ gpgme_op_encrypt_ext_start       NEW.
+ gpgme_op_encrypt_sign_ext        NEW.
+ gpgme_op_encrypt_sign_ext_start  NEW.
+ gpgme_import_result_t            EXTENDED: New field 'skipped_v3_keys'.
+ cpp: Key::locate                 NEW.
+ cpp: Data::toString              NEW.
  cpp: ImportResult::numV3KeysSkipped  NEW.
 
+
 Noteworthy changes in version 1.10.0 (2017-12-12)
 -------------------------------------------------
 
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index cbb0e64..1df9c46 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -6154,6 +6154,45 @@ pointer, and @code{GPG_ERR_UNUSABLE_PUBKEY} if @var{rset} does not
 contain any valid recipients.
 @end deftypefun
 
+ at deftypefun gpgme_error_t gpgme_op_encrypt_ext @
+            (@w{gpgme_ctx_t @var{ctx}}, @
+             @w{gpgme_key_t @var{recp}[]}, @
+             @w{const char *@var{recpstring}}, @
+             @w{gpgme_encrypt_flags_t @var{flags}}, @
+             @w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
+
+ at since{1.11.0}
+
+This is an extended version of @code{gpgme_op_encrypt} with
+ at var{recpstring} as additional parameter.  If @var{recp} is NULL and
+ at var{recpstring} is not NULL, the latter is expected to be a linefeed
+delimited string with the set of key specifications.  In contrast to
+ at var{recp} the keys are given directly as strings and there is no need
+to first create key objects.  The keys are passed verbatim to the
+backend engine.
+
+ at end deftypefun
+
+
+ at deftypefun gpgme_error_t gpgme_op_encrypt_ext_start @
+            (@w{gpgme_ctx_t @var{ctx}}, @
+             @w{gpgme_key_t @var{recp}[]}, @
+             @w{const char *@var{recpstring}}, @
+             @w{gpgme_encrypt_flags_t @var{flags}}, @
+             @w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
+
+ at since{1.11.0}
+
+This is an extended version of @code{gpgme_op_encrypt_start} with
+ at var{recpstring} as additional parameter.  If @var{recp} is NULL and
+ at var{recpstring} is not NULL, the latter is expected to be a linefeed
+delimited string with the set of key specifications.  In contrast to
+ at var{recp} the keys are given directly as strings and there is no need
+to first create key objects.  The keys are passed verbatim to the
+backend engine.
+
+ at end deftypefun
+
 @deftp {Data type} {gpgme_encrypt_result_t}
 This is a pointer to a structure used to store the result of a
 @code{gpgme_op_encrypt} operation.  After successfully encrypting
@@ -6203,6 +6242,44 @@ if @var{ctx}, @var{rset}, @var{plain} or @var{cipher} is not a valid
 pointer.
 @end deftypefun
 
+ at deftypefun gpgme_error_t gpgme_op_encrypt_sign_ext @
+            (@w{gpgme_ctx_t @var{ctx}}, @
+             @w{gpgme_key_t @var{recp}[]}, @
+             @w{const char *@var{recpstring}}, @
+             @w{gpgme_encrypt_flags_t @var{flags}}, @
+             @w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
+
+ at since{1.11.0}
+
+This is an extended version of @code{gpgme_op_encrypt_sign} with
+ at var{recpstring} as additional parameter.  If @var{recp} is NULL and
+ at var{recpstring} is not NULL, the latter is expected to be a linefeed
+delimited string with the set of key specifications.  In contrast to
+ at var{recp} the keys are given directly as strings and there is no need
+to first create the key objects.  The keys are passed verbatim to the
+backend engine.
+
+ at end deftypefun
+
+ at deftypefun gpgme_error_t gpgme_op_encrypt_sign_ext_start @
+            (@w{gpgme_ctx_t @var{ctx}}, @
+             @w{gpgme_key_t @var{recp}[]}, @
+             @w{const char *@var{recpstring}}, @
+             @w{gpgme_encrypt_flags_t @var{flags}}, @
+             @w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
+
+ at since{1.11.0}
+
+This is an extended version of @code{gpgme_op_encrypt_sign_start} with
+ at var{recpstring} as additional parameter.  If @var{recp} is NULL and
+ at var{recpstring} is not NULL, the latter is expected to be a linefeed
+delimited string with the set of key specifications.  In contrast to
+ at var{recp} the keys are given directly as strings and there is no need
+to first create the key objects.  The keys are passed verbatim to the
+backend engine.
+
+ at end deftypefun
+
 
 @node Miscellaneous
 @section Miscellaneous operations
diff --git a/src/encrypt-sign.c b/src/encrypt-sign.c
index af6de63..4db46e2 100644
--- a/src/encrypt-sign.c
+++ b/src/encrypt-sign.c
@@ -62,6 +62,7 @@ encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args)
 
 static gpgme_error_t
 encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
+                    const char *recpstring,
 		    gpgme_encrypt_flags_t flags,
 		    gpgme_data_t plain, gpgme_data_t cipher)
 {
@@ -72,7 +73,7 @@ encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
   if (err)
     return err;
 
-  symmetric = !recp || (flags & GPGME_ENCRYPT_SYMMETRIC);
+  symmetric = (!recp && !recpstring) || (flags & GPGME_ENCRYPT_SYMMETRIC);
 
   if (!plain)
     return gpg_error (GPG_ERR_NO_DATA);
@@ -103,43 +104,75 @@ encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
                                     : encrypt_sign_status_handler,
 				    ctx);
 
-  return _gpgme_engine_op_encrypt_sign (ctx->engine, recp, flags, plain,
+  return _gpgme_engine_op_encrypt_sign (ctx->engine, recp, recpstring,
+                                        flags, plain,
 					cipher, ctx->use_armor,
 					ctx /* FIXME */);
 }
 
 
-/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
-   store the resulting ciphertext in CIPHER.  Also sign the ciphertext
-   with the signers in CTX.  */
+/* Old version of gpgme_op_encrypt_sign_ext_start w/o RECPSTRING.  */
 gpgme_error_t
 gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
 			     gpgme_encrypt_flags_t flags,
 			     gpgme_data_t plain, gpgme_data_t cipher)
 {
+  return gpgme_op_encrypt_sign_ext_start (ctx, recp, NULL,
+                                          flags, plain, cipher);
+}
+
+
+/* Old version of gpgme_op_encrypt_sign_ext w/o RECPSTRING.  */
+gpgme_error_t
+gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
+		       gpgme_encrypt_flags_t flags,
+		       gpgme_data_t plain, gpgme_data_t cipher)
+{
+  return gpgme_op_encrypt_sign_ext (ctx, recp, NULL, flags, plain, cipher);
+}
+
+
+/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
+ * store the resulting ciphertext in CIPHER.  Also sign the ciphertext
+ * with the signers in CTX.  */
+gpgme_error_t
+gpgme_op_encrypt_sign_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
+                           const char *recpstring,
+                           gpgme_encrypt_flags_t flags,
+                           gpgme_data_t plain, gpgme_data_t cipher)
+{
   gpgme_error_t err;
 
-  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign_start", ctx,
+  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign", ctx,
 	      "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
 
   if (!ctx)
     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
 
-  if (_gpgme_debug_trace () && recp)
+  if (_gpgme_debug_trace () && (recp || recpstring))
     {
-      int i = 0;
-
-      while (recp[i])
-	{
-	  TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
-		      (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
-		      recp[i]->subkeys->fpr : "invalid");
-	  i++;
-	}
+      if (recp)
+        {
+          int i = 0;
+
+          while (recp[i])
+            {
+              TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
+                          (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
+                          recp[i]->subkeys->fpr : "invalid");
+              i++;
+            }
+        }
+      else
+        {
+          TRACE_LOG1 ("recipients = '%s'", recpstring);
+        }
     }
 
-  err = encrypt_sign_start (ctx, 0, recp, flags, plain, cipher);
-  return err;
+  err = encrypt_sign_start (ctx, 1, recp, recpstring, flags, plain, cipher);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return TRACE_ERR (err);
 }
 
 
@@ -147,33 +180,39 @@ gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
    store the resulting ciphertext in CIPHER.  Also sign the ciphertext
    with the signers in CTX.  */
 gpgme_error_t
-gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
-		       gpgme_encrypt_flags_t flags,
-		       gpgme_data_t plain, gpgme_data_t cipher)
+gpgme_op_encrypt_sign_ext_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
+                                 const char *recpstring,
+                                 gpgme_encrypt_flags_t flags,
+                                 gpgme_data_t plain, gpgme_data_t cipher)
 {
   gpgme_error_t err;
 
-  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign", ctx,
+  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign_start", ctx,
 	      "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
 
   if (!ctx)
     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
 
-  if (_gpgme_debug_trace () && recp)
+  if (_gpgme_debug_trace () && (recp || recpstring))
     {
-      int i = 0;
-
-      while (recp[i])
-	{
-	  TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
-		      (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
-		      recp[i]->subkeys->fpr : "invalid");
-	  i++;
-	}
+      if (recp)
+        {
+          int i = 0;
+
+          while (recp[i])
+            {
+              TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
+                          (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
+                          recp[i]->subkeys->fpr : "invalid");
+              i++;
+            }
+        }
+      else
+        {
+          TRACE_LOG1 ("recipients = '%s'", recpstring);
+        }
     }
 
-  err = encrypt_sign_start (ctx, 1, recp, flags, plain, cipher);
-  if (!err)
-    err = _gpgme_wait_one (ctx);
-  return TRACE_ERR (err);
+  err = encrypt_sign_start (ctx, 0, recp, recpstring, flags, plain, cipher);
+  return err;
 }
diff --git a/src/encrypt.c b/src/encrypt.c
index 4023654..2318497 100644
--- a/src/encrypt.c
+++ b/src/encrypt.c
@@ -214,6 +214,7 @@ _gpgme_op_encrypt_init_result (gpgme_ctx_t ctx)
 
 static gpgme_error_t
 encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
+               const char *recpstring,
 	       gpgme_encrypt_flags_t flags,
 	       gpgme_data_t plain, gpgme_data_t cipher)
 {
@@ -228,13 +229,13 @@ encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
   if (err)
     return err;
 
-  symmetric = !recp || (flags & GPGME_ENCRYPT_SYMMETRIC);
+  symmetric = (!recp && !recpstring) || (flags & GPGME_ENCRYPT_SYMMETRIC);
 
   if (!plain)
     return gpg_error (GPG_ERR_NO_DATA);
   if (!cipher)
     return gpg_error (GPG_ERR_INV_VALUE);
-  if (recp && ! *recp)
+  if (recp && !*recp)
     return gpg_error (GPG_ERR_INV_VALUE);
 
   if (symmetric && ctx->passphrase_cb)
@@ -252,72 +253,111 @@ encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
 				    : encrypt_status_handler,
 				    ctx);
 
-  return _gpgme_engine_op_encrypt (ctx->engine, recp, flags, plain, cipher,
-				   ctx->use_armor);
+  return _gpgme_engine_op_encrypt (ctx->engine, recp, recpstring,
+                                   flags, plain, cipher, ctx->use_armor);
 }
 
 
+/* Old version of gpgme_op_encrypt_ext without RECPSTRING.  */
+gpgme_error_t
+gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
+		  gpgme_encrypt_flags_t flags,
+		  gpgme_data_t plain, gpgme_data_t cipher)
+{
+  return gpgme_op_encrypt_ext (ctx, recp, NULL, flags, plain, cipher);
+}
+
+
+/* Old version of gpgme_op_encrypt_ext_start without RECPSTRING.  */
 gpgme_error_t
 gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
 			gpgme_encrypt_flags_t flags,
 			gpgme_data_t plain, gpgme_data_t cipher)
 {
+  return gpgme_op_encrypt_ext_start (ctx, recp, NULL, flags, plain, cipher);
+}
+
+
+/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
+ * store the resulting ciphertext in CIPHER.  RECPSTRING can be used
+ * instead of the RECP array to directly specify recipients as LF
+ * delimited strings; these may be any kind of recipient specification
+ * patterns as supported by the backend.  */
+gpgme_error_t
+gpgme_op_encrypt_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
+                      const char *recpstring,
+                      gpgme_encrypt_flags_t flags,
+                      gpgme_data_t plain, gpgme_data_t cipher)
+{
   gpgme_error_t err;
 
-  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_start", ctx,
+  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt", ctx,
 	      "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
 
   if (!ctx)
     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
 
-  if (_gpgme_debug_trace () && recp)
+  if (_gpgme_debug_trace () && (recp || recpstring))
     {
-      int i = 0;
+      if (recp)
+        {
+          int i = 0;
 
-      while (recp[i])
-	{
-	  TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
+          while (recp[i])
+            {
+              TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
 		      (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
-		      recp[i]->subkeys->fpr : "invalid");
-	  i++;
-	}
+                          recp[i]->subkeys->fpr : "invalid");
+              i++;
+            }
+        }
+      else
+        {
+          TRACE_LOG1 ("recipients = '%s'", recpstring);
+        }
     }
 
-  err = encrypt_start (ctx, 0, recp, flags, plain, cipher);
+  err = encrypt_start (ctx, 1, recp, recpstring, flags, plain, cipher);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
   return TRACE_ERR (err);
 }
 
 
-/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
-   store the resulting ciphertext in CIPHER.  */
 gpgme_error_t
-gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
-		  gpgme_encrypt_flags_t flags,
-		  gpgme_data_t plain, gpgme_data_t cipher)
+gpgme_op_encrypt_ext_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
+                            const char *recpstring,
+                            gpgme_encrypt_flags_t flags,
+                            gpgme_data_t plain, gpgme_data_t cipher)
 {
   gpgme_error_t err;
 
-  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt", ctx,
+  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_start", ctx,
 	      "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
 
   if (!ctx)
     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
 
-  if (_gpgme_debug_trace () && recp)
+  if (_gpgme_debug_trace () && (recp || recpstring))
     {
-      int i = 0;
-
-      while (recp[i])
-	{
-	  TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
-		      (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
-		      recp[i]->subkeys->fpr : "invalid");
-	  i++;
-	}
+      if (recp)
+        {
+          int i = 0;
+
+          while (recp[i])
+            {
+              TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
+                          (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
+                          recp[i]->subkeys->fpr : "invalid");
+              i++;
+            }
+        }
+      else
+        {
+          TRACE_LOG1 ("recipients = '%s'", recpstring);
+        }
     }
 
-  err = encrypt_start (ctx, 1, recp, flags, plain, cipher);
-  if (!err)
-    err = _gpgme_wait_one (ctx);
+  err = encrypt_start (ctx, 0, recp, recpstring, flags, plain, cipher);
   return TRACE_ERR (err);
 }
diff --git a/src/engine-backend.h b/src/engine-backend.h
index 97cf6a1..f692666 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -72,10 +72,12 @@ struct engine_ops
   gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
 			 gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
   gpgme_error_t (*encrypt) (void *engine, gpgme_key_t recp[],
+                            const char *recpstring,
 			    gpgme_encrypt_flags_t flags,
 			    gpgme_data_t plain, gpgme_data_t ciph,
 			    int use_armor);
   gpgme_error_t (*encrypt_sign) (void *engine, gpgme_key_t recp[],
+                                 const char *recpstring,
 				 gpgme_encrypt_flags_t flags,
 				 gpgme_data_t plain, gpgme_data_t ciph,
 				 int use_armor, gpgme_ctx_t ctx /* FIXME */);
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index a37d1f7..809806c 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -1914,17 +1914,64 @@ append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
 }
 
 
+/* Take recipients from the LF delimited STRING and add -r args.  */
+static gpg_error_t
+append_args_from_recipients_string (engine_gpg_t gpg, const char *string)
+{
+  gpg_error_t err = 0;
+  int any = 0;
+  const char *s;
+  int n;
+
+  do
+    {
+      /* Skip leading white space */
+      while (*string == ' ' || *string == '\t')
+        string++;
+      if (!*string)
+        break;
+
+      /* Look for the LF. */
+      s = strchr (string, '\n');
+      if (s)
+        n = s - string;
+      else
+        n = strlen (string);
+      while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
+        n--;
+
+      /* Add arg if it is not empty.  */
+      if (n)
+        {
+          err = add_arg (gpg, "-r");
+          if (!err)
+            err = add_arg_len (gpg, NULL, string, n);
+          if (!err)
+            any = 1;
+        }
+
+      string += n + !!s;
+    }
+  while (!err);
+
+  if (!err && !any)
+    err = gpg_error (GPG_ERR_MISSING_KEY);
+  return err;
+}
+
+
 static gpgme_error_t
-gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
+gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
+             gpgme_encrypt_flags_t flags,
 	     gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
 {
   engine_gpg_t gpg = engine;
   gpgme_error_t err = 0;
 
-  if (recp)
+  if (recp || recpstring)
     err = add_arg (gpg, "--encrypt");
 
-  if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
+  if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || (!recp && !recpstring)))
     err = add_arg (gpg, "--symmetric");
 
   if (!err && use_armor)
@@ -1951,7 +1998,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
       && have_gpg_version (gpg, "2.1.14"))
     err = add_arg (gpg, "--mimemode");
 
-  if (recp)
+  if (recp || recpstring)
     {
       /* If we know that all recipients are valid (full or ultimate trust)
 	 we can suppress further checks.  */
@@ -1961,7 +2008,9 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
 	err = add_arg (gpg, "--no-encrypt-to");
 
-      if (!err)
+      if (!err && !recp && recpstring)
+	err = append_args_from_recipients_string (gpg, recpstring);
+      else if (!err)
 	err = append_args_from_recipients (gpg, recp);
     }
 
@@ -1995,6 +2044,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
 
 static gpgme_error_t
 gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
+                  const char *recpstring,
 		  gpgme_encrypt_flags_t flags, gpgme_data_t plain,
 		  gpgme_data_t ciph, int use_armor,
 		  gpgme_ctx_t ctx /* FIXME */)
@@ -2002,10 +2052,10 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
   engine_gpg_t gpg = engine;
   gpgme_error_t err = 0;
 
-  if (recp)
+  if (recp || recpstring)
     err = add_arg (gpg, "--encrypt");
 
-  if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
+  if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || (!recp && !recpstring)))
     err = add_arg (gpg, "--symmetric");
 
   if (!err)
@@ -2023,7 +2073,7 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
       && have_gpg_version (gpg, "2.1.14"))
     err = add_arg (gpg, "--mimemode");
 
-  if (recp)
+  if (recp || recpstring)
     {
       /* If we know that all recipients are valid (full or ultimate trust)
 	 we can suppress further checks.  */
@@ -2033,7 +2083,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
 	err = add_arg (gpg, "--no-encrypt-to");
 
-      if (!err)
+      if (!err && !recp && recpstring)
+	err = append_args_from_recipients_string (gpg, recpstring);
+      else if (!err)
 	err = append_args_from_recipients (gpg, recp);
     }
 
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index b8e44e7..da7e524 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -1327,8 +1327,57 @@ set_recipients (engine_gpgsm_t gpgsm, gpgme_key_t recp[])
 }
 
 
+/* Take recipients from the LF delimited STRING and send RECIPIENT
+ * commands to gpgsm.  */
 static gpgme_error_t
-gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
+set_recipients_from_string (engine_gpgsm_t gpgsm, const char *string)
+{
+  gpg_error_t err = 0;
+  char *line = NULL;
+  int no_pubkey = 0;
+  const char *s;
+  int n;
+
+  for (;;)
+    {
+      while (*string == ' ' || *string == '\t')
+        string++;
+      if (!*string)
+        break;
+
+      s = strchr (string, '\n');
+      if (s)
+        n = s - string;
+      else
+        n = strlen (string);
+      while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
+        n--;
+
+      gpgrt_free (line);
+      if (gpgrt_asprintf (&line, "RECIPIENT %.*s", n, string) < 0)
+        {
+          err = gpg_error_from_syserror ();
+          break;
+        }
+      string += n + !!s;
+
+      err = gpgsm_assuan_simple_command (gpgsm, line, gpgsm->status.fnc,
+					 gpgsm->status.fnc_value);
+
+      /* Fixme: Improve error reporting.  */
+      if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
+	no_pubkey++;
+      else if (err)
+        break;
+    }
+  gpgrt_free (line);
+  return err? err : no_pubkey? gpg_error (GPG_ERR_NO_PUBKEY) : 0;
+}
+
+
+static gpgme_error_t
+gpgsm_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
+               gpgme_encrypt_flags_t flags,
 	       gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
 {
   engine_gpgsm_t gpgsm = engine;
@@ -1339,7 +1388,7 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
   if (!recp)
     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
 
-  if (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO)
+  if ((flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
     {
       err = gpgsm_assuan_simple_command (gpgsm,
 					 "OPTION no-encrypt-to", NULL, NULL);
@@ -1359,7 +1408,10 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
   gpgsm_clear_fd (gpgsm, MESSAGE_FD);
   gpgsm->inline_data = NULL;
 
-  err = set_recipients (gpgsm, recp);
+  if (!recp && recpstring)
+    err = set_recipients_from_string (gpgsm, recpstring);
+  else
+    err = set_recipients (gpgsm, recp);
 
   if (!err)
     err = start (gpgsm, "ENCRYPT");
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index fd5ac17..d8f4fce 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -1075,8 +1075,58 @@ set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[])
 }
 
 
+/* Take recipients from the LF delimited STRING and send RECIPIENT
+ * commands to gpgsm.  */
 static gpgme_error_t
-uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
+set_recipients_from_string (engine_uiserver_t uiserver, const char *string)
+{
+  gpg_error_t err = 0;
+  char *line = NULL;
+  int no_pubkey = 0;
+  const char *s;
+  int n;
+
+  for (;;)
+    {
+      while (*string == ' ' || *string == '\t')
+        string++;
+      if (!*string)
+        break;
+
+      s = strchr (string, '\n');
+      if (s)
+        n = s - string;
+      else
+        n = strlen (string);
+      while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
+        n--;
+
+      gpgrt_free (line);
+      if (gpgrt_asprintf (&line, "RECIPIENT %.*s", n, string) < 0)
+        {
+          err = gpg_error_from_syserror ();
+          break;
+        }
+      string += n + !!s;
+
+      err = uiserver_assuan_simple_command (uiserver, line,
+                                            uiserver->status.fnc,
+                                            uiserver->status.fnc_value);
+
+      /* Fixme: Improve error reporting.  */
+      if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
+	no_pubkey++;
+      else if (err)
+        break;
+    }
+  gpgrt_free (line);
+  return err? err : no_pubkey? gpg_error (GPG_ERR_NO_PUBKEY) : 0;
+}
+
+
+static gpgme_error_t
+uiserver_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
+                  gpgme_encrypt_flags_t flags,
 		  gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
 {
   engine_uiserver_t uiserver = engine;
@@ -1140,9 +1190,12 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
 
   uiserver->inline_data = NULL;
 
-  if (recp)
+  if (recp || recpstring)
     {
-      err = set_recipients (uiserver, recp);
+      if (recp)
+        err = set_recipients (uiserver, recp);
+      else
+        err = set_recipients_from_string (uiserver, recpstring);
       if (err)
 	{
 	  gpgrt_free (cmd);
diff --git a/src/engine.c b/src/engine.c
index e51384f..b716ca2 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -721,6 +721,7 @@ _gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
 
 gpgme_error_t
 _gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
+                          const char *recpstring,
 			  gpgme_encrypt_flags_t flags,
 			  gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
 {
@@ -730,13 +731,14 @@ _gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
   if (!engine->ops->encrypt)
     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
 
-  return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
-				  use_armor);
+  return (*engine->ops->encrypt) (engine->engine, recp, recpstring,
+                                  flags, plain, ciph, use_armor);
 }
 
 
 gpgme_error_t
 _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
+                               const char *recpstring,
 			       gpgme_encrypt_flags_t flags,
 			       gpgme_data_t plain, gpgme_data_t ciph,
 			       int use_armor, gpgme_ctx_t ctx /* FIXME */)
@@ -747,8 +749,8 @@ _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
   if (!engine->ops->encrypt_sign)
     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
 
-  return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
-				       plain, ciph, use_armor, ctx);
+  return (*engine->ops->encrypt_sign) (engine->engine, recp, recpstring,
+                                       flags, plain, ciph, use_armor, ctx);
 }
 
 
diff --git a/src/engine.h b/src/engine.h
index 34bf8e9..8b692f2 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -98,11 +98,13 @@ gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,
 				     gpgme_ctx_t ctx /* FIXME */);
 gpgme_error_t _gpgme_engine_op_encrypt (engine_t engine,
 					gpgme_key_t recp[],
+                                        const char *recpstring,
 					gpgme_encrypt_flags_t flags,
 					gpgme_data_t plain, gpgme_data_t ciph,
 					int use_armor);
 gpgme_error_t _gpgme_engine_op_encrypt_sign (engine_t engine,
 					     gpgme_key_t recp[],
+                                             const char *recpstring,
 					     gpgme_encrypt_flags_t flags,
 					     gpgme_data_t plain,
 					     gpgme_data_t ciph,
diff --git a/src/gpgme-json.c b/src/gpgme-json.c
index b54d9a8..4b1cd5b 100644
--- a/src/gpgme-json.c
+++ b/src/gpgme-json.c
@@ -354,18 +354,19 @@ get_protocol (cjson_t json, gpgme_protocol_t *r_protocol)
 }
 
 
-/* Extract the keys from the KEYS array in the JSON object.  CTX is a
- * GPGME context object.  On success an array with the keys is stored
- * at R_KEYS.  In failure an error code is returned.  */
+/* Extract the keys from the "keys" array in the JSON object.  On
+ * success a string with the keys identifiers is stored at R_KEYS.
+ * The keys in that string are LF delimited.  On failure an error code
+ * is returned.  */
 static gpg_error_t
-get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
+get_keys (cjson_t json, char **r_keystring)
 {
-  gpg_error_t err;
   cjson_t j_keys, j_item;
   int i, nkeys;
-  gpgme_key_t *keys;
+  char *p;
+  size_t length;
 
-  *r_keys = NULL;
+  *r_keystring = NULL;
 
   j_keys = cJSON_GetObjectItem (json, "keys");
   if (!j_keys)
@@ -373,8 +374,15 @@ get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
   if (!cjson_is_array (j_keys) && !cjson_is_string (j_keys))
     return gpg_error (GPG_ERR_INV_VALUE);
 
+  /* Fixme: We should better use a membuf like thing.  */
+  length = 1; /* For the EOS.  */
   if (cjson_is_string (j_keys))
-    nkeys = 1;
+    {
+      nkeys = 1;
+      length += strlen (j_keys->valuestring);
+      if (strchr (j_keys->valuestring, '\n'))
+        return gpg_error (GPG_ERR_INV_USER_ID);
+    }
   else
     {
       nkeys = cJSON_GetArraySize (j_keys);
@@ -385,43 +393,37 @@ get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
           j_item = cJSON_GetArrayItem (j_keys, i);
           if (!j_item || !cjson_is_string (j_item))
             return gpg_error (GPG_ERR_INV_VALUE);
+          if (i)
+            length++; /* Space for delimiter. */
+          length += strlen (j_item->valuestring);
+          if (strchr (j_item->valuestring, '\n'))
+            return gpg_error (GPG_ERR_INV_USER_ID);
         }
     }
 
-  /* Now allocate an array to store the gpgme key objects.  */
-  keys = xcalloc (nkeys + 1, sizeof *keys);
+  p = *r_keystring = xtrymalloc (length);
+  if (!p)
+    return gpg_error_from_syserror ();
 
   if (cjson_is_string (j_keys))
     {
-      err = gpgme_get_key (ctx, j_keys->valuestring, &keys[0], 0);
-      if (err)
-        goto leave;
+      strcpy (p, j_keys->valuestring);
     }
   else
     {
       for (i=0; i < nkeys; i++)
         {
           j_item = cJSON_GetArrayItem (j_keys, i);
-          err = gpgme_get_key (ctx, j_item->valuestring, &keys[i], 0);
-          if (err)
-            goto leave;
+          if (i)
+            *p++ = '\n'; /* Add delimiter.  */
+          p = stpcpy (p, j_item->valuestring);
         }
     }
-  err = 0;
-  *r_keys = keys;
-  keys = NULL;
-
- leave:
-  if (keys)
-    {
-      for (i=0; keys[i]; i++)
-        gpgme_key_unref (keys[i]);
-      xfree (keys);
-    }
-  return err;
+  return 0;
 }
 
 
+
 

 /*
  *  GPGME support functions.
@@ -582,11 +584,11 @@ op_encrypt (cjson_t request, cjson_t result)
   gpgme_ctx_t ctx = NULL;
   gpgme_protocol_t protocol;
   int opt_base64;
-  gpgme_key_t *keys = NULL;
+  char *keystring = NULL;
   cjson_t j_input;
   gpgme_data_t input = NULL;
   gpgme_data_t output = NULL;
-  int abool, i;
+  int abool;
   gpgme_encrypt_flags_t encrypt_flags = 0;
 
   if ((err = get_protocol (request, &protocol)))
@@ -622,7 +624,7 @@ op_encrypt (cjson_t request, cjson_t result)
 
 
   /* Get the keys.  */
-  err = get_keys (ctx, request, &keys);
+  err = get_keys (request, &keystring);
   if (err)
     {
       /* Provide a custom error response.  */
@@ -674,7 +676,8 @@ op_encrypt (cjson_t request, cjson_t result)
     }
 
   /* Encrypt.  */
-  err = gpgme_op_encrypt (ctx, keys, encrypt_flags, input, output);
+  err = gpgme_op_encrypt_ext (ctx, NULL, keystring, encrypt_flags,
+                              input, output);
   /* encrypt_result = gpgme_op_encrypt_result (ctx); */
   if (err)
     {
@@ -713,12 +716,7 @@ op_encrypt (cjson_t request, cjson_t result)
     }
 
  leave:
-  if (keys)
-    {
-      for (i=0; keys[i]; i++)
-        gpgme_key_unref (keys[i]);
-      xfree (keys);
-    }
+  xfree (keystring);
   release_context (ctx);
   gpgme_data_release (input);
   return err;
diff --git a/src/gpgme.def b/src/gpgme.def
index cad30f6..a01d89a 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -267,5 +267,10 @@ EXPORTS
 
     gpgme_op_conf_dir			  @199
 
+    gpgme_op_encrypt_ext                  @200
+    gpgme_op_encrypt_ext_start            @201
+    gpgme_op_encrypt_sign_ext             @202
+    gpgme_op_encrypt_sign_ext_start       @203
+
 ; END
 
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index e319879..8aba5ba 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1274,10 +1274,22 @@ gpgme_encrypt_flags_t;
    store the resulting ciphertext in CIPHER.  */
 gpgme_error_t gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
 				      gpgme_encrypt_flags_t flags,
-				      gpgme_data_t plain, gpgme_data_t cipher);
+				      gpgme_data_t plain,
+                                      gpgme_data_t cipher);
 gpgme_error_t gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
 				gpgme_encrypt_flags_t flags,
-				gpgme_data_t plain, gpgme_data_t cipher);
+				gpgme_data_t plain,
+                                gpgme_data_t cipher);
+gpgme_error_t gpgme_op_encrypt_ext_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
+                                          const char *recpstring,
+                                          gpgme_encrypt_flags_t flags,
+                                          gpgme_data_t plain,
+                                          gpgme_data_t cipher);
+gpgme_error_t gpgme_op_encrypt_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
+                                    const char *recpstring,
+                                    gpgme_encrypt_flags_t flags,
+                                    gpgme_data_t plain,
+                                    gpgme_data_t cipher);
 
 /* Encrypt plaintext PLAIN within CTX for the recipients RECP and
    store the resulting ciphertext in CIPHER.  Also sign the ciphertext
@@ -1289,7 +1301,19 @@ gpgme_error_t gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx,
 					   gpgme_data_t cipher);
 gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
 				     gpgme_encrypt_flags_t flags,
-				     gpgme_data_t plain, gpgme_data_t cipher);
+				     gpgme_data_t plain,
+                                     gpgme_data_t cipher);
+gpgme_error_t gpgme_op_encrypt_sign_ext_start (gpgme_ctx_t ctx,
+                                               gpgme_key_t recp[],
+                                               const char *recpstring,
+                                               gpgme_encrypt_flags_t flags,
+                                               gpgme_data_t plain,
+                                               gpgme_data_t cipher);
+gpgme_error_t gpgme_op_encrypt_sign_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
+                                         const char *recpstring,
+                                         gpgme_encrypt_flags_t flags,
+                                         gpgme_data_t plain,
+                                         gpgme_data_t cipher);
 
 

 /*
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index a95befb..b49c86d 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -215,10 +215,15 @@ GPGME_1.0 {
     gpgme_op_edit;
     gpgme_op_edit_start;
     gpgme_op_encrypt;
-    gpgme_op_encrypt_result;
+    gpgme_op_encrypt_start;
+    gpgme_op_encrypt_ext;
+    gpgme_op_encrypt_ext_start;
     gpgme_op_encrypt_sign;
+    gpgme_op_encrypt_sign_ext;
     gpgme_op_encrypt_sign_start;
-    gpgme_op_encrypt_start;
+    gpgme_op_encrypt_sign_ext_start;
+    gpgme_op_encrypt_result;
+
     gpgme_op_export;
     gpgme_op_export_ext;
     gpgme_op_export_ext_start;
diff --git a/tests/run-encrypt.c b/tests/run-encrypt.c
index 51e2d60..9408469 100644
--- a/tests/run-encrypt.c
+++ b/tests/run-encrypt.c
@@ -37,6 +37,19 @@
 static int verbose;
 
 
+static char *
+xstrdup (const char *string)
+{
+  char *p = strdup (string);
+  if (!p)
+    {
+      fprintf (stderr, "strdup failed\n");
+      exit (2);
+    }
+  return p;
+}
+
+
 static gpg_error_t
 status_cb (void *opaque, const char *keyword, const char *value)
 {
@@ -88,6 +101,7 @@ show_usage (int ex)
          "  --uiserver         use the UI server\n"
          "  --loopback         use a loopback pinentry\n"
          "  --key NAME         encrypt to key NAME\n"
+         "  --keystring NAMES  encrypt to ';' delimited NAMES\n"
          "  --throw-keyids     use this option\n"
          "  --no-symkey-cache  disable the use of that cache\n"
          "  --wrap             assume input is valid OpenPGP message\n"
@@ -103,7 +117,6 @@ main (int argc, char **argv)
   int last_argc = -1;
   gpgme_error_t err;
   gpgme_ctx_t ctx;
-  const char *key_string = NULL;
   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
   gpgme_data_t in, out;
   gpgme_encrypt_result_t result;
@@ -113,6 +126,7 @@ main (int argc, char **argv)
   char *keyargs[10];
   gpgme_key_t keys[10+1];
   int keycount = 0;
+  char *keystring = NULL;
   int i;
   gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
   gpgme_off_t offset;
@@ -174,6 +188,17 @@ main (int argc, char **argv)
           keyargs[keycount++] = *argv;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--keystring"))
+        {
+          argc--; argv++;
+          if (!argc)
+            show_usage (1);
+          keystring = xstrdup (*argv);
+          for (i=0; keystring[i]; i++)
+            if (keystring[i] == ';')
+              keystring[i] = '\n';
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--throw-keyids"))
         {
           flags |= GPGME_ENCRYPT_THROW_KEYIDS;
@@ -207,15 +232,6 @@ main (int argc, char **argv)
   if (argc != 1)
     show_usage (1);
 
-  if (key_string && protocol == GPGME_PROTOCOL_UISERVER)
-    {
-      fprintf (stderr, PGM ": ignoring --key in UI-server mode\n");
-      key_string = NULL;
-    }
-
-  if (!key_string)
-    key_string = "test";
-
   init_gpgme (protocol);
 
   err = gpgme_new (&ctx);
@@ -298,7 +314,8 @@ main (int argc, char **argv)
   err = gpgme_data_new (&out);
   fail_if_err (err);
 
-  err = gpgme_op_encrypt (ctx, keycount ? keys : NULL, flags, in, out);
+  err = gpgme_op_encrypt_ext (ctx, keycount ? keys : NULL, keystring,
+                              flags, in, out);
   result = gpgme_op_encrypt_result (ctx);
   if (result)
     print_result (result);
@@ -318,5 +335,6 @@ main (int argc, char **argv)
   for (i=0; i < keycount; i++)
     gpgme_key_unref (keys[i]);
   gpgme_release (ctx);
+  free (keystring);
   return 0;
 }

-----------------------------------------------------------------------

Summary of changes:
 NEWS                  |  11 +++--
 doc/gpgme.texi        |  77 ++++++++++++++++++++++++++++++++++
 src/encrypt-sign.c    | 111 ++++++++++++++++++++++++++++++++++----------------
 src/encrypt.c         | 106 ++++++++++++++++++++++++++++++++---------------
 src/engine-backend.h  |   2 +
 src/engine-gpg.c      |  70 +++++++++++++++++++++++++++----
 src/engine-gpgsm.c    |  58 ++++++++++++++++++++++++--
 src/engine-uiserver.c |  59 +++++++++++++++++++++++++--
 src/engine.c          |  10 +++--
 src/engine.h          |   2 +
 src/gpgme-json.c      |  74 ++++++++++++++++-----------------
 src/gpgme.def         |   5 +++
 src/gpgme.h.in        |  30 ++++++++++++--
 src/libgpgme.vers     |   9 +++-
 tests/run-encrypt.c   |  40 +++++++++++++-----
 15 files changed, 519 insertions(+), 145 deletions(-)


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list