aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/gpgme.texi38
-rw-r--r--doc/uiserver.texi10
-rw-r--r--src/context.h3
-rw-r--r--src/decrypt-verify.c2
-rw-r--r--src/decrypt.c11
-rw-r--r--src/engine-backend.h4
-rw-r--r--src/engine-gpg.c5
-rw-r--r--src/engine-gpgsm.c5
-rw-r--r--src/engine-uiserver.c16
-rw-r--r--src/engine.c8
-rw-r--r--src/engine.h6
-rw-r--r--src/gpgme.c24
-rw-r--r--src/gpgme.def2
-rw-r--r--src/gpgme.h.in11
-rw-r--r--src/libgpgme.vers3
15 files changed, 125 insertions, 23 deletions
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 801a53f3..7eabab48 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -191,6 +191,7 @@ Context Attributes
* Text Mode:: Choosing canonical text mode.
* Offline Mode:: Choosing offline mode.
* Included Certificates:: Including a number of certificates.
+* Exporting Session Keys:: Requesting session keys upon decryption.
* Key Listing Mode:: Selecting key listing mode.
* Passphrase Callback:: Getting the passphrase from the user.
* Progress Meter Callback:: Being informed about the progress.
@@ -2351,6 +2352,7 @@ started. In fact, these references are accessed through the
* Offline Mode:: Choosing offline mode.
* Pinentry Mode:: Choosing the pinentry mode.
* Included Certificates:: Including a number of certificates.
+* Exporting Session Keys:: Requesting session keys upon decryption.
* Key Listing Mode:: Selecting key listing mode.
* Passphrase Callback:: Getting the passphrase from the user.
* Progress Meter Callback:: Being informed about the progress.
@@ -2641,6 +2643,29 @@ certificates to include into an S/MIME signed message.
@end deftypefun
+@node Exporting Session Keys
+@subsection Exporting Session Keys
+@cindex context, exporting session keys
+@cindex Exporting Session Keys
+@cindex exporting session keys
+
+@deftypefun void gpgme_set_export_session_keys (@w{gpgme_ctx_t @var{ctx}}, @w{int @var{yes}})
+The function @code{gpgme_set_export_session_keys} specifies whether
+the context should try to export the symmetric session key when
+decrypting data. By default, session keys are not exported.
+
+Session keys are not exported if @var{yes} is zero, and
+enabled otherwise.
+@end deftypefun
+
+@deftypefun int gpgme_get_export_session_keys (@w{gpgme_ctx_t @var{ctx}})
+The function @code{gpgme_get_export_session_keys} returns @code{1} if
+the context will try to export the symmetric session key when
+decrypting, and @code{0} if not, or if @var{ctx} is not a valid
+pointer.
+@end deftypefun
+
+
@node Key Listing Mode
@subsection Key Listing Mode
@cindex key listing mode
@@ -4777,6 +4802,19 @@ This is a linked list of recipients to which this message was encrypted.
@item char *file_name
This is the filename of the original plaintext message file if it is
known, otherwise this is a null pointer.
+
+@item char *session_key
+A textual representation (null-terminated string) of the session key
+used in symmetric encryption of the message, if the context has been
+set to export session keys (see @code{gpgme_get_export_session_keys}
+and @code{gpgme_set_export_session_keys}), and a session key was
+available for the most recent decryption operation. Otherwise, this
+is a null pointer.
+
+You should never access this member of a
+@code{gpgme_op_decrypt_result_t} without first ensuring that
+@code{gpgme_get_export_session_keys} returns non-zero for the
+reporting context.
@end table
@end deftp
diff --git a/doc/uiserver.texi b/doc/uiserver.texi
index aae3b606..f10db01a 100644
--- a/doc/uiserver.texi
+++ b/doc/uiserver.texi
@@ -260,12 +260,14 @@ encoded. For details on the file descriptor, see the description of
@noindent
The decryption is started with the command:
-@deffn Command DECRYPT -@w{}-protocol=@var{name} [-@w{}-no-verify]
+@deffn Command DECRYPT -@w{}-protocol=@var{name} [-@w{}-no-verify] [-@w{}-export-session-key]
@var{name} is the encryption protocol used for the message. For a
description of the allowed protocols see the @code{ENCRYPT} command.
-This argument is mandatory. If the option @option{--no-verify} is given,
-the server should not try to verify a signature, in case the input data
-is an OpenPGP combined message.
+This argument is mandatory. If the option @option{--no-verify} is
+given, the server should not try to verify a signature, in case the
+input data is an OpenPGP combined message. If the option
+@option{--export-session-key} is given and the underlying engine knows
+how to export the session key, it will appear on a status line
@end deffn
diff --git a/src/context.h b/src/context.h
index 00e2e779..94935c80 100644
--- a/src/context.h
+++ b/src/context.h
@@ -111,6 +111,9 @@ struct gpgme_context
* unmodified string, as received form gpg, will be returned. */
unsigned int raw_description : 1;
+ /* True if session keys should be exported upon decryption. */
+ unsigned int export_session_keys : 1;
+
/* Flags for keylist mode. */
gpgme_keylist_mode_t keylist_mode;
diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c
index a334f86f..00d256a9 100644
--- a/src/decrypt-verify.c
+++ b/src/decrypt-verify.c
@@ -77,7 +77,7 @@ decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine,
decrypt_verify_status_handler, ctx);
- return _gpgme_engine_op_decrypt_verify (ctx->engine, cipher, plain);
+ return _gpgme_engine_op_decrypt_verify (ctx->engine, cipher, plain, ctx->export_session_keys);
}
diff --git a/src/decrypt.c b/src/decrypt.c
index 51e42920..49c735ca 100644
--- a/src/decrypt.c
+++ b/src/decrypt.c
@@ -63,6 +63,9 @@ release_op_data (void *hook)
if (opd->result.file_name)
free (opd->result.file_name);
+ if (opd->result.session_key)
+ free (opd->result.session_key);
+
while (recipient)
{
gpgme_recipient_t next = recipient->next;
@@ -277,6 +280,12 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
opd->last_recipient_p = &(*opd->last_recipient_p)->next;
break;
+ case GPGME_STATUS_SESSION_KEY:
+ if (opd->result.session_key)
+ free (opd->result.session_key);
+ opd->result.session_key = strdup(args);
+ break;
+
case GPGME_STATUS_NO_SECKEY:
{
gpgme_recipient_t rec = opd->result.recipients;
@@ -381,7 +390,7 @@ decrypt_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
- return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain);
+ return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain, ctx->export_session_keys);
}
diff --git a/src/engine-backend.h b/src/engine-backend.h
index a8b1ac60..144b1561 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -62,9 +62,9 @@ struct engine_ops
gpgme_error_t (*set_locale) (void *engine, int category, const char *value);
gpgme_error_t (*set_protocol) (void *engine, gpgme_protocol_t protocol);
gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph,
- gpgme_data_t plain);
+ gpgme_data_t plain, int export_session_key);
gpgme_error_t (*decrypt_verify) (void *engine, gpgme_data_t ciph,
- gpgme_data_t plain);
+ gpgme_data_t plain, int export_session_key);
gpgme_error_t (*delete) (void *engine, gpgme_key_t key, int allow_secret);
gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 7725a001..0e43c248 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -1550,13 +1550,16 @@ add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
static gpgme_error_t
-gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
+gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_session_key)
{
engine_gpg_t gpg = engine;
gpgme_error_t err;
err = add_arg (gpg, "--decrypt");
+ if (!err && export_session_key)
+ err = add_arg (gpg, "--show-session-key");
+
/* Tell the gpg object about the data. */
if (!err)
err = add_arg (gpg, "--output");
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index a815cf00..2ff353b9 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -1120,10 +1120,13 @@ gpgsm_reset (void *engine)
static gpgme_error_t
-gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
+gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_session_key)
{
engine_gpgsm_t gpgsm = engine;
gpgme_error_t err;
+ /* gpgsm is not capable of exporting session keys right now, so we
+ * will ignore this if requested. */
+ (void)export_session_key;
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index 47b7dc33..26f0d18b 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -960,7 +960,8 @@ uiserver_reset (void *engine)
static gpgme_error_t
_uiserver_decrypt (void *engine, int verify,
- gpgme_data_t ciph, gpgme_data_t plain)
+ gpgme_data_t ciph, gpgme_data_t plain,
+ int export_session_key)
{
engine_uiserver_t uiserver = engine;
gpgme_error_t err;
@@ -978,8 +979,9 @@ _uiserver_decrypt (void *engine, int verify,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
- if (asprintf (&cmd, "DECRYPT%s%s", protocol,
- verify ? "" : " --no-verify") < 0)
+ if (asprintf (&cmd, "DECRYPT%s%s%s", protocol,
+ verify ? "" : " --no-verify",
+ export_session_key ? " --export-session-key" : "") < 0)
return gpg_error_from_syserror ();
uiserver->input_cb.data = ciph;
@@ -1006,16 +1008,16 @@ _uiserver_decrypt (void *engine, int verify,
static gpgme_error_t
-uiserver_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
+uiserver_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_session_key)
{
- return _uiserver_decrypt (engine, 0, ciph, plain);
+ return _uiserver_decrypt (engine, 0, ciph, plain, export_session_key);
}
static gpgme_error_t
-uiserver_decrypt_verify (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
+uiserver_decrypt_verify (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_session_key)
{
- return _uiserver_decrypt (engine, 1, ciph, plain);
+ return _uiserver_decrypt (engine, 1, ciph, plain, export_session_key);
}
diff --git a/src/engine.c b/src/engine.c
index 4e513b6d..b43f683e 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -653,7 +653,7 @@ _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
gpgme_error_t
_gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
- gpgme_data_t plain)
+ gpgme_data_t plain, int export_session_key)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -661,13 +661,13 @@ _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
if (!engine->ops->decrypt)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- return (*engine->ops->decrypt) (engine->engine, ciph, plain);
+ return (*engine->ops->decrypt) (engine->engine, ciph, plain, export_session_key);
}
gpgme_error_t
_gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
- gpgme_data_t plain)
+ gpgme_data_t plain, int export_session_key)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -675,7 +675,7 @@ _gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
if (!engine->ops->decrypt_verify)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain);
+ return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain, export_session_key);
}
diff --git a/src/engine.h b/src/engine.h
index 15b0b5d4..512ac19a 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -83,10 +83,12 @@ _gpgme_engine_set_colon_line_handler (engine_t engine,
engine_colon_line_handler_t fnc,
void *fnc_value);
gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
- gpgme_data_t plain);
+ gpgme_data_t plain,
+ int export_session_key);
gpgme_error_t _gpgme_engine_op_decrypt_verify (engine_t engine,
gpgme_data_t ciph,
- gpgme_data_t plain);
+ gpgme_data_t plain,
+ int export_session_key);
gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret);
gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,
diff --git a/src/gpgme.c b/src/gpgme.c
index 443cb768..7b14b5e9 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -518,6 +518,30 @@ gpgme_get_armor (gpgme_ctx_t ctx)
}
+/* Enable or disable the exporting session keys upon decryption. */
+void
+gpgme_set_export_session_keys (gpgme_ctx_t ctx, int export_session_keys)
+{
+ TRACE2 (DEBUG_CTX, "gpgme_set_export_session_keys", ctx, "export_session_keys=%i (%s)",
+ export_session_keys, export_session_keys ? "yes" : "no");
+
+ if (!ctx)
+ return;
+
+ ctx->export_session_keys = !!export_session_keys;
+}
+
+
+/* Return whether this context will export session keys upon decryption. */
+int
+gpgme_get_export_session_keys (gpgme_ctx_t ctx)
+{
+ TRACE2 (DEBUG_CTX, "gpgme_get_export_session_keys", ctx, "ctx->export_session_keys=%i (%s)",
+ ctx->export_session_keys, ctx->export_session_keys ? "yes" : "no");
+ return ctx->export_session_keys;
+}
+
+
/* Enable or disable the use of the special textmode. Textmode is for
example used for the RFC2015 signatures; note that the updated RFC
3156 mandates that the MUA does some preparations so that textmode
diff --git a/src/gpgme.def b/src/gpgme.def
index 2f6837da..35f43411 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -252,5 +252,7 @@ EXPORTS
gpgme_op_query_swdb @189
gpgme_op_query_swdb_result @190
+ gpgme_set_export_session_keys @191
+ gpgme_get_export_session_keys @192
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 4f470a03..2a0e16e3 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1037,6 +1037,13 @@ void gpgme_set_offline (gpgme_ctx_t ctx, int yes);
/* Return non-zero if offline mode is set in CTX. */
int gpgme_get_offline (gpgme_ctx_t ctx);
+/* If YES is non-zero, try to return session keys during decryption,
+ do not otherwise. */
+void gpgme_set_export_session_keys (gpgme_ctx_t ctx, int yes);
+
+/* Return non-zero if export_session_keys is set in CTX. */
+int gpgme_get_export_session_keys (gpgme_ctx_t ctx);
+
/* Use whatever the default of the backend crypto engine is. */
#define GPGME_INCLUDE_CERTS_DEFAULT -256
@@ -1527,6 +1534,10 @@ struct _gpgme_op_decrypt_result
/* The original file name of the plaintext message, if
available. */
char *file_name;
+
+ /* A textual representation of the session key used to decrypt the
+ * message, if available */
+ char *session_key;
};
typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t;
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index 5457daa4..9a3ecb2e 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -125,6 +125,9 @@ GPGME_1.1 {
gpgme_op_query_swdb;
gpgme_op_query_swdb_result;
+
+ gpgme_set_export_session_keys;
+ gpgme_get_export_session_keys;
};