core: Add new context flag "no-symkey-cache".
authorWerner Koch <wk@gnupg.org>
Thu, 12 Apr 2018 07:17:27 +0000 (09:17 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 12 Apr 2018 07:17:27 +0000 (09:17 +0200)
* src/gpgme.c (gpgme_set_ctx_flag): Set flag.
(gpgme_get_ctx_flag): Get flag.
* src/context.h (struct gpgme_context): Add field no_symkey_cache.
* src/engine-gpg.c (struct engine_gpg): Ditto.
(gpg_set_engine_flags): Set flag.
(build_argv): Pass option --no-symkey-cache to gpg.

* tests/run-decrypt.c (print_result): Fix segv for symmetric messages.
(main): New option --no-symkey-cache.
* tests/run-encrypt.c (main): New option --no-symkey-cache.

Signed-off-by: Werner Koch <wk@gnupg.org>
NEWS
doc/gpgme.texi
src/context.h
src/engine-gpg.c
src/gpgme.c
tests/run-decrypt.c
tests/run-encrypt.c

diff --git a/NEWS b/NEWS
index 7b6fdd9..a8d73a5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 Noteworthy changes in version 1.10.1 (unreleased)
 -------------------------------------------------
 
 Noteworthy changes in version 1.10.1 (unreleased)
 -------------------------------------------------
 
+ * New context flag "no-symkey-cache".
+
  * Interface changes relative to the 1.10.0 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpgme_import_result_t       EXTENDED: New field 'skipped_v3_keys'
  * Interface changes relative to the 1.10.0 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpgme_import_result_t       EXTENDED: New field 'skipped_v3_keys'
index ab554d8..cbb0e64 100644 (file)
@@ -3069,7 +3069,13 @@ the time when you verified the signature.
 The string given in @var{value} is passed to the GnuPG engines to
 request restrictions based on the origin of the request.  Valid values
 are documented in the GnuPG manual and the gpg man page under the
 The string given in @var{value} is passed to the GnuPG engines to
 request restrictions based on the origin of the request.  Valid values
 are documented in the GnuPG manual and the gpg man page under the
-option ``--request-origin''.
+option ``--request-origin''.  Requires at least GnuPG 2.2.6 to have an
+effect.
+
+@item "no-symkey-cache"
+For OpenPGP disable the passphrase cache used for symmetrical en- and
+decryption.  This cache is based on the message specific salt value.
+Requires at least GnuPG 2.2.7 to have an effect.
 
 @end table
 
 
 @end table
 
index 202cf16..c8e75ba 100644 (file)
@@ -121,6 +121,9 @@ struct gpgme_context
   /* True if the option --auto-key-retrieve shall be passed to gpg.  */
   unsigned int auto_key_retrieve : 1;
 
   /* True if the option --auto-key-retrieve shall be passed to gpg.  */
   unsigned int auto_key_retrieve : 1;
 
+  /* Do not use the symmtric encryption passphrase cache.  */
+  unsigned int no_symkey_cache : 1;
+
   /* Flags for keylist mode.  */
   gpgme_keylist_mode_t keylist_mode;
 
   /* Flags for keylist mode.  */
   gpgme_keylist_mode_t keylist_mode;
 
index 3b9a6ff..a37d1f7 100644 (file)
@@ -145,6 +145,10 @@ struct engine_gpg
   gpgme_pinentry_mode_t pinentry_mode;
   char request_origin[10];
 
   gpgme_pinentry_mode_t pinentry_mode;
   char request_origin[10];
 
+  struct {
+    unsigned int no_symkey_cache : 1;
+  } flags;
+
   /* NULL or the data object fed to --override_session_key-fd.  */
   gpgme_data_t override_session_key;
 };
   /* NULL or the data object fed to --override_session_key-fd.  */
   gpgme_data_t override_session_key;
 };
@@ -642,6 +646,10 @@ gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
       else
         strcpy (gpg->request_origin, ctx->request_origin);
     }
       else
         strcpy (gpg->request_origin, ctx->request_origin);
     }
+  else if (ctx->no_symkey_cache && have_gpg_version (gpg, "2.2.7"))
+    {
+      gpg->flags.no_symkey_cache = 1;
+    }
   else
     *gpg->request_origin = 0;
 }
   else
     *gpg->request_origin = 0;
 }
@@ -875,7 +883,7 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
     argc++;
   if (!gpg->cmd.used)
     argc++;    /* --batch */
     argc++;
   if (!gpg->cmd.used)
     argc++;    /* --batch */
-  argc += 2;   /* --no-sk-comments, --request-origin */
+  argc += 3;   /* --no-sk-comments, --request-origin, --no-symkey-cache */
 
   argv = calloc (argc + 1, sizeof *argv);
   if (!argv)
 
   argv = calloc (argc + 1, sizeof *argv);
   if (!argv)
@@ -937,6 +945,19 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
       argc++;
     }
 
       argc++;
     }
 
+  if (gpg->flags.no_symkey_cache)
+    {
+      argv[argc] = strdup ("--no-symkey-cache");
+      if (!argv[argc])
+       {
+          int saved_err = gpg_error_from_syserror ();
+         free (fd_data_map);
+         free_argv (argv);
+         return saved_err;
+        }
+      argc++;
+    }
+
   if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
     {
       const char *s = NULL;
   if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
     {
       const char *s = NULL;
index 9e65c50..82d6747 100644 (file)
@@ -538,6 +538,10 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
       if (!ctx->request_origin)
         err = gpg_error_from_syserror ();
     }
       if (!ctx->request_origin)
         err = gpg_error_from_syserror ();
     }
+  else if (!strcmp (name, "no-symkey-cache"))
+    {
+      ctx->no_symkey_cache = abool;
+    }
   else
     err = gpg_error (GPG_ERR_UNKNOWN_NAME);
 
   else
     err = gpg_error (GPG_ERR_UNKNOWN_NAME);
 
@@ -583,6 +587,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
     {
       return ctx->request_origin? ctx->request_origin : "";
     }
     {
       return ctx->request_origin? ctx->request_origin : "";
     }
+  else if (!strcmp (name, "no-symkey-cache"))
+    {
+      return ctx->no_symkey_cache? "1":"";
+    }
   else
     return NULL;
 }
   else
     return NULL;
 }
index f4c4754..a2e82a0 100644 (file)
@@ -60,7 +60,7 @@ print_result (gpgme_decrypt_result_t result)
   if (result->session_key)
     printf ("Session key: %s\n", result->session_key);
 
   if (result->session_key)
     printf ("Session key: %s\n", result->session_key);
 
-  for (recp = result->recipients; recp->next; recp = recp->next)
+  for (recp = result->recipients; recp && recp->next; recp = recp->next)
     {
       printf ("recipient %d\n", count++);
       printf ("  status ....: %s\n", gpgme_strerror (recp->status));
     {
       printf ("recipient %d\n", count++);
       printf ("  status ....: %s\n", gpgme_strerror (recp->status));
@@ -82,6 +82,7 @@ show_usage (int ex)
          "  --export-session-key            show the session key\n"
          "  --override-session-key STRING   use STRING as session key\n"
          "  --request-origin STRING         use STRING as request origin\n"
          "  --export-session-key            show the session key\n"
          "  --override-session-key STRING   use STRING as session key\n"
          "  --request-origin STRING         use STRING as request origin\n"
+         "  --no-symkey-cache               disable the use of that cache\n"
          "  --unwrap         remove only the encryption layer\n"
          , stderr);
   exit (ex);
          "  --unwrap         remove only the encryption layer\n"
          , stderr);
   exit (ex);
@@ -104,6 +105,7 @@ main (int argc, char **argv)
   int export_session_key = 0;
   const char *override_session_key = NULL;
   const char *request_origin = NULL;
   int export_session_key = 0;
   const char *override_session_key = NULL;
   const char *request_origin = NULL;
+  int no_symkey_cache = 0;
   int raw_output = 0;
 
   if (argc)
   int raw_output = 0;
 
   if (argc)
@@ -160,6 +162,11 @@ main (int argc, char **argv)
           request_origin = *argv;
           argc--; argv++;
         }
           request_origin = *argv;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--no-symkey-cache"))
+        {
+          no_symkey_cache = 1;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--unwrap"))
         {
           flags |= GPGME_DECRYPT_UNWRAP;
       else if (!strcmp (*argv, "--unwrap"))
         {
           flags |= GPGME_DECRYPT_UNWRAP;
@@ -226,6 +233,17 @@ main (int argc, char **argv)
         }
     }
 
         }
     }
 
+  if (no_symkey_cache)
+    {
+      err = gpgme_set_ctx_flag (ctx, "no-symkey-cache", "1");
+      if (err)
+        {
+          fprintf (stderr, PGM ": error setting no-symkey-cache:  %s\n",
+                   gpgme_strerror (err));
+          exit (1);
+        }
+    }
+
   err = gpgme_data_new_from_stream (&in, fp_in);
   if (err)
     {
   err = gpgme_data_new_from_stream (&in, fp_in);
   if (err)
     {
index e949d76..51e2d60 100644 (file)
@@ -80,17 +80,18 @@ show_usage (int ex)
 {
   fputs ("usage: " PGM " [options] FILE\n\n"
          "Options:\n"
 {
   fputs ("usage: " PGM " [options] FILE\n\n"
          "Options:\n"
-         "  --verbose        run in verbose mode\n"
-         "  --status         print status lines from the backend\n"
-         "  --progress       print progress info\n"
-         "  --openpgp        use the OpenPGP protocol (default)\n"
-         "  --cms            use the CMS protocol\n"
-         "  --uiserver       use the UI server\n"
-         "  --loopback       use a loopback pinentry\n"
-         "  --key NAME       encrypt to key NAME\n"
-         "  --throw-keyids   use this option\n"
-         "  --wrap           assume input is valid OpenPGP message\n"
-         "  --symmetric      encrypt symmetric (OpenPGP only)\n"
+         "  --verbose          run in verbose mode\n"
+         "  --status           print status lines from the backend\n"
+         "  --progress         print progress info\n"
+         "  --openpgp          use the OpenPGP protocol (default)\n"
+         "  --cms              use the CMS protocol\n"
+         "  --uiserver         use the UI server\n"
+         "  --loopback         use a loopback pinentry\n"
+         "  --key NAME         encrypt to key NAME\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"
+         "  --symmetric        encrypt symmetric (OpenPGP only)\n"
          , stderr);
   exit (ex);
 }
          , stderr);
   exit (ex);
 }
@@ -115,6 +116,7 @@ main (int argc, char **argv)
   int i;
   gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
   gpgme_off_t offset;
   int i;
   gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
   gpgme_off_t offset;
+  int no_symkey_cache = 0;
 
   if (argc)
     { argc--; argv++; }
 
   if (argc)
     { argc--; argv++; }
@@ -192,6 +194,11 @@ main (int argc, char **argv)
           flags |= GPGME_ENCRYPT_SYMMETRIC;
           argc--; argv++;
         }
           flags |= GPGME_ENCRYPT_SYMMETRIC;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--no-symkey-cache"))
+        {
+          no_symkey_cache = 1;
+          argc--; argv++;
+        }
       else if (!strncmp (*argv, "--", 2))
         show_usage (1);
 
       else if (!strncmp (*argv, "--", 2))
         show_usage (1);
 
@@ -227,6 +234,16 @@ main (int argc, char **argv)
       gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
       gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
     }
       gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
       gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
     }
+  if (no_symkey_cache)
+    {
+      err = gpgme_set_ctx_flag (ctx, "no-symkey-cache", "1");
+      if (err)
+        {
+          fprintf (stderr, PGM ": error setting no-symkey-cache:  %s\n",
+                   gpgme_strerror (err));
+          exit (1);
+        }
+    }
 
   for (i=0; i < keycount; i++)
     {
 
   for (i=0; i < keycount; i++)
     {