core: New encryption flag GPGME_ENCRYPT_WANT_ADDRESS.
authorWerner Koch <wk@gnupg.org>
Tue, 17 Apr 2018 07:40:27 +0000 (09:40 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 17 Apr 2018 07:40:27 +0000 (09:40 +0200)
* src/gpgme.h.in (GPGME_ENCRYPT_WANT_ADDRESS): New flag.
* src/engine-gpg.c (add_arg_recipient): New.
(add_arg_recipient_string): New.
(append_args_from_recipients): Call new helper function.
(append_args_from_recipients_string): Ditto.
* src/gpgme-json.c (op_encrypt): Add flag "want-address".
--

Signed-off-by: Werner Koch <wk@gnupg.org>
NEWS
doc/gpgme.texi
src/engine-gpg.c
src/gpgme-json.c
src/gpgme.h.in

diff --git a/NEWS b/NEWS
index 51d7923..162212c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Noteworthy changes in version 1.10.1 (unreleased)
  gpgme_op_encrypt_ext_start       NEW.
  gpgme_op_encrypt_sign_ext        NEW.
  gpgme_op_encrypt_sign_ext_start  NEW.
+ GPGME_ENCRYPT_WANT_ADDRESS       NEW.
  gpgme_import_result_t            EXTENDED: New field 'skipped_v3_keys'.
  cpp: Key::locate                 NEW.
  cpp: Data::toString              NEW.
index 1df9c46..330b167 100644 (file)
@@ -6094,7 +6094,7 @@ also expect a sign command.
 
 The @code{GPGME_ENCRYPT_SYMMETRIC} symbol specifies that the
 output should be additionally encrypted symmetrically even
-if recipients are provided. This feature is only supported for
+if recipients are provided. This feature is only supported
 for the OpenPGP crypto engine.
 
 @item GPGME_ENCRYPT_THROW_KEYIDS
@@ -6113,6 +6113,18 @@ The @code{GPGME_ENCRYPT_WRAP} symbol specifies that the input is an
 OpenPGP message and not a plain data.  This is the counterpart to
 @code{GPGME_DECRYPT_UNWRAP}.
 
+@item GPGME_ENCRYPT_WANT_ADDRESS
+@since{1.11.0}
+
+The @code{GPGME_ENCRYPT_WANT_ADDRESS} symbol requests that all
+supplied keys or key specifications include a syntactically valid mail
+address.  If this is not the case the operation is not even tried and
+the error code @code{GPG_ERR_INV_USER_ID} is returned.  Only the
+address part of the key specification is conveyed to the backend.  As
+of now the key must be specified using the @var{recpstring} argument
+of the extended encrypt functions.  This feature is currently only
+supported for the OpenPGP crypto engine.
+
 @end table
 
 If @code{GPG_ERR_UNUSABLE_PUBKEY} is returned, some recipients in
index 809806c..90e3b89 100644 (file)
@@ -43,6 +43,7 @@
 #include "sema.h"
 #include "debug.h"
 #include "data.h"
+#include "mbox-util.h"
 
 #include "engine-backend.h"
 
@@ -1892,8 +1893,70 @@ gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
 }
 
 
+/* Add a single argument from a key to an -r option.  */
+static gpg_error_t
+add_arg_recipient (engine_gpg_t gpg, gpgme_encrypt_flags_t flags,
+                   gpgme_key_t key)
+{
+  gpg_error_t err;
+
+  if ((flags & GPGME_ENCRYPT_WANT_ADDRESS))
+    {
+      /* We have no way to figure out which mail address was
+       * requested.  FIXME: It would be possible to figure this out by
+       * consulting the SENDER property of the context.  */
+      err = gpg_error (GPG_ERR_INV_USER_ID);
+    }
+  else
+    err = add_arg (gpg, key->subkeys->fpr);
+
+  return err;
+}
+
+
+/* Add a single argument from a USERID string to an -r option.  */
+static gpg_error_t
+add_arg_recipient_string (engine_gpg_t gpg, gpgme_encrypt_flags_t flags,
+                          const char *userid, int useridlen)
+{
+  gpg_error_t err;
+
+  if ((flags & GPGME_ENCRYPT_WANT_ADDRESS))
+    {
+      char *tmpstr, *mbox;
+
+      tmpstr = malloc (useridlen + 1);
+      if (!tmpstr)
+        err = gpg_error_from_syserror ();
+      else
+        {
+          memcpy (tmpstr, userid, useridlen);
+          tmpstr[useridlen] = 0;
+
+          mbox = _gpgme_mailbox_from_userid (tmpstr);
+          if (!mbox)
+            {
+              err = gpg_error_from_syserror ();
+              if (gpg_err_code (err) == GPG_ERR_EINVAL)
+                err = gpg_error (GPG_ERR_INV_USER_ID);
+            }
+          else
+            err = add_arg (gpg, mbox);
+
+          free (mbox);
+          free (tmpstr);
+        }
+    }
+  else
+    err = add_arg_len (gpg, NULL, userid, useridlen);
+
+  return err;
+}
+
+
 static gpgme_error_t
-append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
+append_args_from_recipients (engine_gpg_t gpg, gpgme_encrypt_flags_t flags,
+                             gpgme_key_t recp[])
 {
   gpgme_error_t err = 0;
   int i = 0;
@@ -1905,7 +1968,7 @@ append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
       if (!err)
        err = add_arg (gpg, "-r");
       if (!err)
-       err = add_arg (gpg, recp[i]->subkeys->fpr);
+       err = add_arg_recipient (gpg, flags, recp[i]);
       if (err)
        break;
       i++;
@@ -1916,7 +1979,9 @@ 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)
+append_args_from_recipients_string (engine_gpg_t gpg,
+                                    gpgme_encrypt_flags_t flags,
+                                    const char *string)
 {
   gpg_error_t err = 0;
   int any = 0;
@@ -1945,7 +2010,7 @@ append_args_from_recipients_string (engine_gpg_t gpg, const char *string)
         {
           err = add_arg (gpg, "-r");
           if (!err)
-            err = add_arg_len (gpg, NULL, string, n);
+            err = add_arg_recipient_string (gpg, flags, string, n);
           if (!err)
             any = 1;
         }
@@ -2009,9 +2074,9 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
        err = add_arg (gpg, "--no-encrypt-to");
 
       if (!err && !recp && recpstring)
-       err = append_args_from_recipients_string (gpg, recpstring);
+       err = append_args_from_recipients_string (gpg, flags, recpstring);
       else if (!err)
-       err = append_args_from_recipients (gpg, recp);
+       err = append_args_from_recipients (gpg, flags, recp);
     }
 
   /* Tell the gpg object about the data.  */
@@ -2084,9 +2149,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
        err = add_arg (gpg, "--no-encrypt-to");
 
       if (!err && !recp && recpstring)
-       err = append_args_from_recipients_string (gpg, recpstring);
+       err = append_args_from_recipients_string (gpg, flags, recpstring);
       else if (!err)
-       err = append_args_from_recipients (gpg, recp);
+       err = append_args_from_recipients (gpg, flags, recp);
     }
 
   if (!err)
index 4b1cd5b..c73bebd 100644 (file)
@@ -569,6 +569,7 @@ static const char hlp_encrypt[] =
   "no-encrypt-to: Do not use a default recipient.\n"
   "no-compress:   Do not compress the plaintext first.\n"
   "throw-keyids:  Request the --throw-keyids option.\n"
+  "want-address:  Require that the keys include a mail address.\n"
   "wrap:          Assume the input is an OpenPGP message.\n"
   "\n"
   "Response on success:\n"
@@ -621,6 +622,10 @@ op_encrypt (cjson_t request, cjson_t result)
     goto leave;
   if (abool)
     encrypt_flags |= GPGME_ENCRYPT_WRAP;
+  if ((err = get_boolean_flag (request, "want-address", 0, &abool)))
+    goto leave;
+  if (abool)
+    encrypt_flags |= GPGME_ENCRYPT_WANT_ADDRESS;
 
 
   /* Get the keys.  */
index 8aba5ba..860e093 100644 (file)
@@ -1266,7 +1266,8 @@ typedef enum
     GPGME_ENCRYPT_NO_COMPRESS = 16,
     GPGME_ENCRYPT_SYMMETRIC = 32,
     GPGME_ENCRYPT_THROW_KEYIDS = 64,
-    GPGME_ENCRYPT_WRAP = 128
+    GPGME_ENCRYPT_WRAP = 128,
+    GPGME_ENCRYPT_WANT_ADDRESS = 256
   }
 gpgme_encrypt_flags_t;