core: Implement context flag "override-session-key".

* src/gpgme.c (gpgme_set_ctx_flag): Add flags "export-session-key" and
"override-session-key".
(gpgme_get_ctx_flag): Ditto.
(gpgme_set_export_session_keys): Remove.
(gpgme_get_export_session_keys): Remove.
* src/gpgme.def, src/libgpgme.vers: Remove them.
* src/context.h (struct gpgme_context): Add field
override_session_key.
* src/decrypt-verify.c (decrypt_verify_start): Pass
override_session_key value to the engine.
* src/decrypt.c (decrypt_start): Ditto.
* src/engine.c (_gpgme_engine_op_decrypt): Ditto.
(_gpgme_engine_op_decrypt_verify): Ditto.
* src/engine-backend.h (struct engine_ops): Extend DECRYPT and
DECRYPT_VERIFY_START with override_session_key.
* src/engine-uiserver.c (_uiserver_decrypt): Add stub arg
override_session_key.
(uiserver_decrypt): Ditto.
(uiserver_decrypt_verify): Ditto.
* src/engine-gpgsm.c (gpgsm_decrypt): Ditto.
* src/engine-gpg.c (gpg_decrypt): Add arg override_session_key and set
corresponding gpg option.

* tests/run-decrypt.c (print_result): Print the session key if
available.
(main): Add options --export-session-key and --override-session-key.

--

To keep the number of context manipulation functions at bay, this
patches removes the just added gpgme_set_export_session_keys and
gpgme_get_export_session_keys by flags for the generic context
function.

The patch also implements the --override-session-key feature.

GnuPG-bug-id: 2754
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-11-15 10:29:48 +01:00
parent 3234b1bf1d
commit 7659d42468
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
15 changed files with 128 additions and 97 deletions

View File

@ -191,7 +191,6 @@ Context Attributes
* Text Mode:: Choosing canonical text mode. * Text Mode:: Choosing canonical text mode.
* Offline Mode:: Choosing offline mode. * Offline Mode:: Choosing offline mode.
* Included Certificates:: Including a number of certificates. * Included Certificates:: Including a number of certificates.
* Exporting Session Keys:: Requesting session keys upon decryption.
* Key Listing Mode:: Selecting key listing mode. * Key Listing Mode:: Selecting key listing mode.
* Passphrase Callback:: Getting the passphrase from the user. * Passphrase Callback:: Getting the passphrase from the user.
* Progress Meter Callback:: Being informed about the progress. * Progress Meter Callback:: Being informed about the progress.
@ -2314,10 +2313,12 @@ The function @code{gpgme_release} destroys the context with the handle
The detailed result of an operation is returned in operation-specific The detailed result of an operation is returned in operation-specific
structures such as @code{gpgme_decrypt_result_t}. The corresponding structures such as @code{gpgme_decrypt_result_t}. The corresponding
retrieval functions such as @code{gpgme_op_decrypt_result} provide retrieval functions such as @code{gpgme_op_decrypt_result} provide
static access to the results after an operation completes. The static access to the results after an operation completes. Those
following interfaces make it possible to detach a result structure structures shall be considered read-only and an application must not
from its associated context and give it a lifetime beyond that of the allocated such a strucure on its own. The following interfaces make
current operation or context. it possible to detach a result structure from its associated context
and give it a lifetime beyond that of the current operation or
context.
@deftypefun void gpgme_result_ref (@w{void *@var{result}}) @deftypefun void gpgme_result_ref (@w{void *@var{result}})
The function @code{gpgme_result_ref} acquires an additional reference The function @code{gpgme_result_ref} acquires an additional reference
@ -2352,7 +2353,6 @@ started. In fact, these references are accessed through the
* Offline Mode:: Choosing offline mode. * Offline Mode:: Choosing offline mode.
* Pinentry Mode:: Choosing the pinentry mode. * Pinentry Mode:: Choosing the pinentry mode.
* Included Certificates:: Including a number of certificates. * Included Certificates:: Including a number of certificates.
* Exporting Session Keys:: Requesting session keys upon decryption.
* Key Listing Mode:: Selecting key listing mode. * Key Listing Mode:: Selecting key listing mode.
* Passphrase Callback:: Getting the passphrase from the user. * Passphrase Callback:: Getting the passphrase from the user.
* Progress Meter Callback:: Being informed about the progress. * Progress Meter Callback:: Being informed about the progress.
@ -2643,29 +2643,6 @@ certificates to include into an S/MIME signed message.
@end deftypefun @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 @node Key Listing Mode
@subsection Key Listing Mode @subsection Key Listing Mode
@cindex key listing mode @cindex key listing mode
@ -2923,6 +2900,18 @@ format. For example the non breaking space characters ("~") will not
be removed from the @code{description} field of the be removed from the @code{description} field of the
@code{gpgme_tofu_info_t} object. @code{gpgme_tofu_info_t} object.
@item "export-session-key"
Using a @var{value} of "1" specifies that the context should try to
export the symmetric session key when decrypting data. By default, or
when using an empty string or "0" for @var{value}, session keys are
not exported.
@item "override-session-key"
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
specific to GnuPG and can be retrieved during a decrypt operation when
the context flag "export-session-key" is enabled.
@end table @end table
This function returns @code{0} on success. This function returns @code{0} on success.
@ -4798,8 +4787,10 @@ secret key for this recipient is not available, and 0 otherwise.
This is a pointer to a structure used to store the result of a This is a pointer to a structure used to store the result of a
@code{gpgme_op_decrypt} operation. After successfully decrypting @code{gpgme_op_decrypt} operation. After successfully decrypting
data, you can retrieve the pointer to the result with data, you can retrieve the pointer to the result with
@code{gpgme_op_decrypt_result}. The structure contains the following @code{gpgme_op_decrypt_result}. As with all result structures, it
members: this structure shall be considered read-only and an application must
not allocated such a strucure on its own. The structure contains the
following members:
@table @code @table @code
@item char *unsupported_algorithm @item char *unsupported_algorithm
@ -4817,17 +4808,12 @@ This is the filename of the original plaintext message file if it is
known, otherwise this is a null pointer. known, otherwise this is a null pointer.
@item char *session_key @item char *session_key
A textual representation (null-terminated string) of the session key A textual representation (nul-terminated string) of the session key
used in symmetric encryption of the message, if the context has been used in symmetric encryption of the message, if the context has been
set to export session keys (see @code{gpgme_get_export_session_keys} set to export session keys (see @code{gpgme_set_ctx_flag,
and @code{gpgme_set_export_session_keys}), and a session key was "export-session-key"}), and a session key was available for the most
available for the most recent decryption operation. Otherwise, this recent decryption operation. Otherwise, this is a null pointer.
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 table
@end deftp @end deftp

View File

@ -135,6 +135,9 @@ struct gpgme_context
/* The sender's addr-spec or NULL. */ /* The sender's addr-spec or NULL. */
char *sender; char *sender;
/* The gpg specific override session key or NULL. */
char *override_session_key;
/* The locale for the pinentry. */ /* The locale for the pinentry. */
char *lc_ctype; char *lc_ctype;
char *lc_messages; char *lc_messages;

View File

@ -77,7 +77,9 @@ decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine, _gpgme_engine_set_status_handler (ctx->engine,
decrypt_verify_status_handler, ctx); decrypt_verify_status_handler, ctx);
return _gpgme_engine_op_decrypt_verify (ctx->engine, cipher, plain, ctx->export_session_keys); return _gpgme_engine_op_decrypt_verify (ctx->engine, cipher, plain,
ctx->export_session_keys,
ctx->override_session_key);
} }

View File

@ -360,7 +360,7 @@ _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
static gpgme_error_t static gpgme_error_t
decrypt_start (gpgme_ctx_t ctx, int synchronous, decrypt_start (gpgme_ctx_t ctx, int synchronous,
gpgme_data_t cipher, gpgme_data_t plain) gpgme_data_t cipher, gpgme_data_t plain)
{ {
gpgme_error_t err; gpgme_error_t err;
@ -390,7 +390,9 @@ decrypt_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx); _gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain, ctx->export_session_keys); return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain,
ctx->export_session_keys,
ctx->override_session_key);
} }

View File

@ -62,9 +62,11 @@ struct engine_ops
gpgme_error_t (*set_locale) (void *engine, int category, const char *value); 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 (*set_protocol) (void *engine, gpgme_protocol_t protocol);
gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph, gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key); gpgme_data_t plain, int export_session_key,
const char *override_session_key);
gpgme_error_t (*decrypt_verify) (void *engine, gpgme_data_t ciph, gpgme_error_t (*decrypt_verify) (void *engine, gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key); gpgme_data_t plain, int export_session_key,
const char *override_session_key);
gpgme_error_t (*delete) (void *engine, gpgme_key_t key, int allow_secret); 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_error_t (*edit) (void *engine, int type, gpgme_key_t key,
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */); gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);

View File

@ -1550,7 +1550,8 @@ add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
static gpgme_error_t static gpgme_error_t
gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_session_key) gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key)
{ {
engine_gpg_t gpg = engine; engine_gpg_t gpg = engine;
gpgme_error_t err; gpgme_error_t err;
@ -1560,6 +1561,13 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_ses
if (!err && export_session_key) if (!err && export_session_key)
err = add_arg (gpg, "--show-session-key"); err = add_arg (gpg, "--show-session-key");
if (!err && override_session_key && *override_session_key)
{
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. */
if (!err) if (!err)
err = add_arg (gpg, "--output"); err = add_arg (gpg, "--output");

View File

@ -1120,13 +1120,16 @@ gpgsm_reset (void *engine)
static gpgme_error_t static gpgme_error_t
gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_session_key) gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key)
{ {
engine_gpgsm_t gpgsm = engine; engine_gpgsm_t gpgsm = engine;
gpgme_error_t err; gpgme_error_t err;
/* gpgsm is not capable of exporting session keys right now, so we /* gpgsm is not capable of exporting session keys right now, so we
* will ignore this if requested. */ * will ignore this if requested. */
(void)export_session_key; (void)export_session_key;
(void)override_session_key;
if (!gpgsm) if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);

View File

@ -961,13 +961,16 @@ uiserver_reset (void *engine)
static gpgme_error_t static gpgme_error_t
_uiserver_decrypt (void *engine, int verify, _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) int export_session_key, const char *override_session_key)
{ {
engine_uiserver_t uiserver = engine; engine_uiserver_t uiserver = engine;
gpgme_error_t err; gpgme_error_t err;
const char *protocol; const char *protocol;
char *cmd; char *cmd;
(void)override_session_key; /* Fixme: We need to see now to add this
* to the UI server protocol */
if (!uiserver) if (!uiserver)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT) if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT)
@ -1008,16 +1011,21 @@ _uiserver_decrypt (void *engine, int verify,
static gpgme_error_t static gpgme_error_t
uiserver_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_session_key) uiserver_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key)
{ {
return _uiserver_decrypt (engine, 0, ciph, plain, export_session_key); return _uiserver_decrypt (engine, 0, ciph, plain,
export_session_key, override_session_key);
} }
static gpgme_error_t static gpgme_error_t
uiserver_decrypt_verify (void *engine, gpgme_data_t ciph, gpgme_data_t plain, int export_session_key) uiserver_decrypt_verify (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key,
const char *override_session_key)
{ {
return _uiserver_decrypt (engine, 1, ciph, plain, export_session_key); return _uiserver_decrypt (engine, 1, ciph, plain,
export_session_key, override_session_key);
} }

View File

@ -653,7 +653,8 @@ _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
gpgme_error_t gpgme_error_t
_gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph, _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key) gpgme_data_t plain, int export_session_key,
const char *override_session_key)
{ {
if (!engine) if (!engine)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
@ -661,13 +662,15 @@ _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
if (!engine->ops->decrypt) if (!engine->ops->decrypt)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED); return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->decrypt) (engine->engine, ciph, plain, export_session_key); return (*engine->ops->decrypt) (engine->engine, ciph, plain,
export_session_key, override_session_key);
} }
gpgme_error_t gpgme_error_t
_gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph, _gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key) gpgme_data_t plain, int export_session_key,
const char *override_session_key)
{ {
if (!engine) if (!engine)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
@ -675,7 +678,9 @@ _gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
if (!engine->ops->decrypt_verify) if (!engine->ops->decrypt_verify)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED); return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain, export_session_key); return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain,
export_session_key,
override_session_key);
} }

View File

@ -84,11 +84,14 @@ _gpgme_engine_set_colon_line_handler (engine_t engine,
void *fnc_value); void *fnc_value);
gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph, 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); int export_session_key,
const char *override_session_key);
gpgme_error_t _gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_error_t _gpgme_engine_op_decrypt_verify (engine_t engine,
gpgme_data_t ciph, gpgme_data_t ciph,
gpgme_data_t plain, gpgme_data_t plain,
int export_session_key); int export_session_key,
const char *override_session_key
);
gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key, gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret); int allow_secret);
gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type, gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,

View File

@ -247,6 +247,7 @@ gpgme_release (gpgme_ctx_t ctx)
free (ctx->signers); free (ctx->signers);
free (ctx->lc_ctype); free (ctx->lc_ctype);
free (ctx->lc_messages); free (ctx->lc_messages);
free (ctx->override_session_key);
_gpgme_engine_info_release (ctx->engine_info); _gpgme_engine_info_release (ctx->engine_info);
ctx->engine_info = NULL; ctx->engine_info = NULL;
DESTROY_LOCK (ctx->lock); DESTROY_LOCK (ctx->lock);
@ -515,6 +516,17 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
{ {
ctx->raw_description = abool; ctx->raw_description = abool;
} }
else if (!strcmp (name, "export-session-key"))
{
ctx->export_session_keys = abool;
}
else if (!strcmp (name, "override-session-key"))
{
free (ctx->override_session_key);
ctx->override_session_key = strdup (value);
if (!ctx->override_session_key)
err = gpg_error_from_syserror ();
}
else else
err = gpg_error (GPG_ERR_UNKNOWN_NAME); err = gpg_error (GPG_ERR_UNKNOWN_NAME);
@ -526,7 +538,7 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
* of valid names. If the NAME is unknown NULL is returned. For a * of valid names. If the NAME is unknown NULL is returned. For a
* boolean flag an empty string is returned for False and the string * boolean flag an empty string is returned for False and the string
* "1" for True; thus either atoi or a simple string test can be * "1" for True; thus either atoi or a simple string test can be
* used. */ * used. */
const char * const char *
gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name) gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{ {
@ -540,35 +552,19 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{ {
return ctx->raw_description? "1":""; return ctx->raw_description? "1":"";
} }
else if (!strcmp (name, "export-session-key"))
{
return ctx->export_session_keys? "1":"";
}
else if (!strcmp (name, "override-session-key"))
{
return ctx->override_session_key? ctx->override_session_key : "";
}
else else
return NULL; return NULL;
} }
/* 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 /* Enable or disable the use of the special textmode. Textmode is for
example used for the RFC2015 signatures; note that the updated RFC example used for the RFC2015 signatures; note that the updated RFC
3156 mandates that the MUA does some preparations so that textmode 3156 mandates that the MUA does some preparations so that textmode

View File

@ -252,8 +252,6 @@ EXPORTS
gpgme_op_query_swdb @189 gpgme_op_query_swdb @189
gpgme_op_query_swdb_result @190 gpgme_op_query_swdb_result @190
gpgme_set_export_session_keys @191 gpgme_get_ctx_flag @191
gpgme_get_export_session_keys @192
gpgme_get_ctx_flag @193
; END ; END

View File

@ -1040,13 +1040,6 @@ void gpgme_set_offline (gpgme_ctx_t ctx, int yes);
/* Return non-zero if offline mode is set in CTX. */ /* Return non-zero if offline mode is set in CTX. */
int gpgme_get_offline (gpgme_ctx_t 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. */ /* Use whatever the default of the backend crypto engine is. */
#define GPGME_INCLUDE_CERTS_DEFAULT -256 #define GPGME_INCLUDE_CERTS_DEFAULT -256

View File

@ -126,9 +126,6 @@ GPGME_1.1 {
gpgme_op_query_swdb; gpgme_op_query_swdb;
gpgme_op_query_swdb_result; gpgme_op_query_swdb_result;
gpgme_set_export_session_keys;
gpgme_get_export_session_keys;
}; };

View File

@ -51,9 +51,13 @@ print_result (gpgme_decrypt_result_t result)
{ {
gpgme_recipient_t recp; gpgme_recipient_t recp;
int count = 0; int count = 0;
printf ("Original file name: %s\n", nonnull(result->file_name)); printf ("Original file name: %s\n", nonnull(result->file_name));
printf ("Wrong key usage: %i\n", result->wrong_key_usage); printf ("Wrong key usage: %i\n", result->wrong_key_usage);
printf ("Unsupported algorithm: %s\n ", nonnull(result->unsupported_algorithm)); printf ("Unsupported algorithm: %s\n",
nonnull(result->unsupported_algorithm));
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->next; recp = recp->next)
{ {
@ -74,6 +78,8 @@ show_usage (int ex)
" --status print status lines from the backend\n" " --status print status lines from the backend\n"
" --openpgp use the OpenPGP protocol (default)\n" " --openpgp use the OpenPGP protocol (default)\n"
" --cms use the CMS protocol\n" " --cms use the CMS protocol\n"
" --export-session-key show the session key\n"
" --override-session-key STRING use STRING as session key\n"
, stderr); , stderr);
exit (ex); exit (ex);
} }
@ -91,6 +97,8 @@ main (int argc, char **argv)
gpgme_data_t out = NULL; gpgme_data_t out = NULL;
gpgme_decrypt_result_t result; gpgme_decrypt_result_t result;
int print_status = 0; int print_status = 0;
int export_session_key = 0;
const char *override_session_key = NULL;
if (argc) if (argc)
{ argc--; argv++; } { argc--; argv++; }
@ -125,6 +133,19 @@ main (int argc, char **argv)
protocol = GPGME_PROTOCOL_CMS; protocol = GPGME_PROTOCOL_CMS;
argc--; argv++; argc--; argv++;
} }
else if (!strcmp (*argv, "--export-session-key"))
{
export_session_key = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--override-session-key"))
{
argc--; argv++;
if (!argc)
show_usage (1);
override_session_key = *argv;
argc--; argv++;
}
else if (!strncmp (*argv, "--", 2)) else if (!strncmp (*argv, "--", 2))
show_usage (1); show_usage (1);
@ -152,6 +173,10 @@ main (int argc, char **argv)
gpgme_set_status_cb (ctx, status_cb, NULL); gpgme_set_status_cb (ctx, status_cb, NULL);
gpgme_set_ctx_flag (ctx, "full-status", "1"); gpgme_set_ctx_flag (ctx, "full-status", "1");
} }
if (export_session_key)
gpgme_set_ctx_flag (ctx, "export-session-key", "1");
if (override_session_key)
gpgme_set_ctx_flag (ctx, "override-session-key", override_session_key);
err = gpgme_data_new_from_stream (&in, fp_in); err = gpgme_data_new_from_stream (&in, fp_in);
if (err) if (err)