core: Do not leak the override session key to ps(1).

* src/engine-gpg.c (struct engine_gpg): New field
override_session_key.
(gpg_release): Free that field.
(gpg_decrypt): With gnupg 2.1.16 use --override-session-key-fd.

* tests/run-decrypt.c (main): Fix setting over the override key.
--

Note that this works only with gnupg 2.1.16 and later.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-11-16 10:12:19 +01:00
parent 5730647421
commit 9fc92a15bd
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 34 additions and 5 deletions

View File

@ -2910,7 +2910,9 @@ not exported.
The string given in @var{value} is passed to the GnuPG engine to override The string given in @var{value} is passed to the GnuPG engine to override
the session key for decryption. The format of that session key is the session key for decryption. The format of that session key is
specific to GnuPG and can be retrieved during a decrypt operation when specific to GnuPG and can be retrieved during a decrypt operation when
the context flag "export-session-key" is enabled. the context flag "export-session-key" is enabled. Please be aware that
using this feature with GnuPG < 2.1.16 will leak the session key on
many platforms via ps(1).
@end table @end table

View File

@ -139,6 +139,9 @@ struct engine_gpg
struct gpgme_io_cbs io_cbs; struct gpgme_io_cbs io_cbs;
gpgme_pinentry_mode_t pinentry_mode; gpgme_pinentry_mode_t pinentry_mode;
/* NULL or the data object fed to --override_session_key-fd. */
gpgme_data_t override_session_key;
}; };
typedef struct engine_gpg *engine_gpg_t; typedef struct engine_gpg *engine_gpg_t;
@ -441,6 +444,8 @@ gpg_release (void *engine)
if (gpg->cmd.keyword) if (gpg->cmd.keyword)
free (gpg->cmd.keyword); free (gpg->cmd.keyword);
gpgme_data_release (gpg->override_session_key);
free (gpg); free (gpg);
} }
@ -1563,9 +1568,30 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
if (!err && override_session_key && *override_session_key) if (!err && override_session_key && *override_session_key)
{ {
err = add_arg (gpg, "--override-session-key"); if (have_gpg_version (gpg, "2.1.16"))
if (!err) {
err = add_arg (gpg, override_session_key); gpgme_data_release (gpg->override_session_key);
TRACE2 (DEBUG_ENGINE, "override", gpg, "seskey='%s' len=%zu\n",
override_session_key,
strlen (override_session_key));
err = gpgme_data_new_from_mem (&gpg->override_session_key,
override_session_key,
strlen (override_session_key), 1);
if (!err)
{
err = add_arg (gpg, "--override-session-key-fd");
if (!err)
err = add_data (gpg, gpg->override_session_key, -2, 0);
}
}
else
{
/* Using that option may leak the session key via ps(1). */
err = add_arg (gpg, "--override-session-key");
if (!err)
err = add_arg (gpg, override_session_key);
}
} }
/* Tell the gpg object about the data. */ /* Tell the gpg object about the data. */

View File

@ -185,7 +185,8 @@ main (int argc, char **argv)
} }
if (override_session_key) if (override_session_key)
{ {
err = gpgme_set_ctx_flag (ctx, "overrride-session-key", "1"); err = gpgme_set_ctx_flag (ctx, "override-session-key",
override_session_key);
if (err) if (err)
{ {
fprintf (stderr, PGM ": error overriding session key: %s\n", fprintf (stderr, PGM ": error overriding session key: %s\n",