core: New flags GPGME_DECRYPT_UNWRAP and GPGME_ENCRYPT_WRAP.

* src/gpgme.h.in (GPGME_ENCRYPT_WRAP): New const.
(gpgme_decrypt_flags_t): New enum.
(GPGME_DECRYPT_VERIFY): New const
(GPGME_DECRYPT_UNWRAP): New const
(gpgme_op_decrypt_ext_start): New func.
(gpgme_op_decrypt_ext): New func.
* src/decrypt-verify.c (gpgme_op_decrypt_ext_start): New.
(gpgme_op_decrypt_ext): New.
(decrypt_verify_start): Add arg FLAGS.  Replace call to
engine_op_decrypt_verify by the plain decrypt with the flag set.
(gpgme_op_decrypt_verify_start): Pass the flag.
(gpgme_op_decrypt_verify): Pass the flag.
* src/decrypt.c (decrypt_start): Rename to ...
(_gpgme_decrypt_start): this.  Add arg FLAGS.  Pass FLAGS to
engine_op_decrypt.
(gpgme_op_decrypt_start): Adjust for chnage pass 0 for FLAG.
(gpgme_op_decrypt_start): Ditto.
* src/engine.c (_gpgme_engine_op_decrypt_verify): Remove.
(_gpgme_engine_op_decrypt): Add arg FLAGS.
* src/gpgme.def, src/libgpgme.vers: Add new functions.
* src/engine-backend.h (struct engine_ops): Remove member
'decrypt_verify'.  Add FLAGS to 'decrypt'.  Adjust all initialization.
* src/engine-uiserver.c (uiserver_decrypt): Remove.
(uiserver_decrypt_verify): Remove.
(_uiserver_decrypt): Rename to ...
(uiserver_decrypt): this.  Replace arg VERIFY by new arg FLAGS.
* src/engine-gpg.c (gpg_decrypt): Support GPGME_DECRYPT_UNWRAP.
(gpg_encrypt): Support GPGME_ENCRYPT_WRAP.

* tests/run-decrypt.c (main): New option --unwrap.
* tests/run-encrypt.c (main): New option --wrap.
--

Manual testing of that wrap/unwrap feature can be done this way:

 ./run-encrypt --verbose --key Alice /etc/motd > x
 ./run-decrypt --verbose --unwrap x > y
 ./run-encrypt --verbose --key Bob --wrap y > z

1. The message was first encrypted to Alice.
2. Alice decrypts the message receiving a valid OpenPGP message.
3. Alice encrypt that message to Bob

This will also work with encrypted and signed messages; the signature
will be kept intact during re-encryption.  Requires GnuPG 2.1.12.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2017-03-24 14:36:54 +01:00
parent 66c334650b
commit 6ac1f2cded
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
20 changed files with 227 additions and 75 deletions

5
NEWS
View File

@ -14,7 +14,12 @@ Noteworthy changes in version 1.8.1 (unreleased)
gpgme_op_keylist_from_data_start NEW. gpgme_op_keylist_from_data_start NEW.
gpgme_op_set_uid_flag_start NEW. gpgme_op_set_uid_flag_start NEW.
gpgme_op_set_uid_flag NEW. gpgme_op_set_uid_flag NEW.
gpgme_op_decrypt_ext_start NEW.
gpgme_op_decrypt_ext NEW.
GPGME_ENCRYPT_THROW_KEYIDS NEW. GPGME_ENCRYPT_THROW_KEYIDS NEW.
GPGME_ENCRYPT_WRAP NEW.
GPGME_DECRYPT_VERIFY NEW.
GPGME_DECRYPT_UNWRAP NEW.
gpgme_data_rewind UN-DEPRECATE. gpgme_data_rewind UN-DEPRECATE.
cpp: Context::revUid(const Key&, const char*) NEW. cpp: Context::revUid(const Key&, const char*) NEW.
cpp: Context::startRevUid(const Key&, const char*) NEW. cpp: Context::startRevUid(const Key&, const char*) NEW.

View File

@ -4890,6 +4890,53 @@ operation could be started successfully, and @code{GPG_ERR_INV_VALUE}
if @var{cipher} or @var{plain} is not a valid pointer. if @var{cipher} or @var{plain} is not a valid pointer.
@end deftypefun @end deftypefun
@deftypefun gpgme_error_t gpgme_op_decrypt_ext ( @
@w{gpgme_ctx_t @var{ctx}}, @
@w{gpgme_decrypt_flags_t @var{flags}}, @
@w{gpgme_data_t @var{cipher}}, @
@w{gpgme_data_t @var{plain}})
The function @code{gpgme_op_decrypt_ext} is the same as
@code{gpgme_op_decrypt_ext} but has an additional argument
@var{flags}. If @var{flags} is 0 both function behave identically.
The value in @var{flags} is a bitwise-or combination of one or
multiple of the following bit values:
@table @code
@item GPGME_DECRYPT_VERIFY
The @code{GPGME_DECRYPT_VERIFY} symbol specifies that this function
shall exacty act as @code{gpgme_op_decrypt_verify}.
@item GPGME_DECRYPT_UNWRAP
The @code{GPGME_DECRYPT_UNWRAP} symbol specifies that the output shall
be an OpenPGP message with only the encryption layer removed. This
requires GnuPG 2.1.12 and works only for OpenPGP. This is the
counterpart to @code{GPGME_ENCRYPT_WRAP}.
@end table
The function returns the error codes as descriped for
@code{gpgme_op_decrypt} respective @code{gpgme_op_encrypt}.
@end deftypefun
@deftypefun gpgme_error_t gpgme_op_decrypt_ext_start ( @
@w{gpgme_ctx_t @var{ctx}}, @
@w{gpgme_decrypt_flags_t @var{flags}}, @
@w{gpgme_data_t @var{cipher}}, @
@w{gpgme_data_t @var{plain}})
The function @code{gpgme_op_decrypt_ext_start} initiates a
@code{gpgme_op_decrypt_ext} operation. It can be completed by calling
@code{gpgme_wait} on the context. @xref{Waiting For Completion}.
The function returns the error code @code{GPG_ERR_NO_ERROR} if the
operation could be started successfully, and @code{GPG_ERR_INV_VALUE}
if @var{cipher} or @var{plain} is not a valid pointer.
@end deftypefun
@deftp {Data type} {gpgme_recipient_t} @deftp {Data type} {gpgme_recipient_t}
This is a pointer to a structure used to store information about the This is a pointer to a structure used to store information about the
recipient of an encrypted text which is decrypted in a recipient of an encrypted text which is decrypted in a
@ -5634,6 +5681,11 @@ On the receiving side, the use of this flag may slow down the
decryption process because all available secret keys must be tried. decryption process because all available secret keys must be tried.
This flag is only honored for OpenPGP encryption. This flag is only honored for OpenPGP encryption.
@item GPGME_ENCRYPT_WRAP
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}.
@end table @end table
If @code{GPG_ERR_UNUSABLE_PUBKEY} is returned, some recipients in If @code{GPG_ERR_UNUSABLE_PUBKEY} is returned, some recipients in

View File

@ -23,6 +23,8 @@
#include <config.h> #include <config.h>
#endif #endif
#include <assert.h>
#include "debug.h" #include "debug.h"
#include "gpgme.h" #include "gpgme.h"
#include "ops.h" #include "ops.h"
@ -45,10 +47,13 @@ decrypt_verify_status_handler (void *priv, gpgme_status_code_t code,
static gpgme_error_t static gpgme_error_t
decrypt_verify_start (gpgme_ctx_t ctx, int synchronous, decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
gpgme_decrypt_flags_t flags,
gpgme_data_t cipher, gpgme_data_t plain) gpgme_data_t cipher, gpgme_data_t plain)
{ {
gpgme_error_t err; gpgme_error_t err;
assert ((flags & GPGME_DECRYPT_VERIFY));
err = _gpgme_op_reset (ctx, synchronous); err = _gpgme_op_reset (ctx, synchronous);
if (err) if (err)
return err; return err;
@ -77,7 +82,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, return _gpgme_engine_op_decrypt (ctx->engine,
flags,
cipher, plain,
ctx->export_session_keys, ctx->export_session_keys,
ctx->override_session_key); ctx->override_session_key);
} }
@ -97,7 +104,7 @@ gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx) if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
err = decrypt_verify_start (ctx, 0, cipher, plain); err = decrypt_verify_start (ctx, 0, GPGME_DECRYPT_VERIFY, cipher, plain);
return TRACE_ERR (err); return TRACE_ERR (err);
} }
@ -116,7 +123,57 @@ gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx) if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
err = decrypt_verify_start (ctx, 1, cipher, plain); err = decrypt_verify_start (ctx, 1, GPGME_DECRYPT_VERIFY, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
}
/* Decrypt ciphertext CIPHER within CTX and store the resulting
plaintext in PLAIN. */
gpgme_error_t
gpgme_op_decrypt_ext_start (gpgme_ctx_t ctx,
gpgme_decrypt_flags_t flags,
gpgme_data_t cipher,
gpgme_data_t plain)
{
gpgme_error_t err;
TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_ext_start", ctx,
"cipher=%p, plain=%p", cipher, plain);
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
if ((flags & GPGME_DECRYPT_VERIFY))
err = decrypt_verify_start (ctx, 0, flags, cipher, plain);
else
err = _gpgme_decrypt_start (ctx, 0, flags, cipher, plain);
return TRACE_ERR (err);
}
/* Decrypt ciphertext CIPHER within CTX and store the resulting
plaintext in PLAIN. */
gpgme_error_t
gpgme_op_decrypt_ext (gpgme_ctx_t ctx,
gpgme_decrypt_flags_t flags,
gpgme_data_t cipher,
gpgme_data_t plain)
{
gpgme_error_t err;
TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_ext", ctx,
"cipher=%p, plain=%p", cipher, plain);
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
if ((flags & GPGME_DECRYPT_VERIFY))
err = decrypt_verify_start (ctx, 1, flags, cipher, plain);
else
err = _gpgme_decrypt_start (ctx, 1, flags, cipher, plain);
if (!err) if (!err)
err = _gpgme_wait_one (ctx); err = _gpgme_wait_one (ctx);
return TRACE_ERR (err); return TRACE_ERR (err);

View File

@ -25,6 +25,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#include "debug.h" #include "debug.h"
#include "gpgme.h" #include "gpgme.h"
@ -358,12 +359,15 @@ _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
} }
static gpgme_error_t gpgme_error_t
decrypt_start (gpgme_ctx_t ctx, int synchronous, _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
gpgme_decrypt_flags_t flags,
gpgme_data_t cipher, gpgme_data_t plain) gpgme_data_t cipher, gpgme_data_t plain)
{ {
gpgme_error_t err; gpgme_error_t err;
assert (!(flags & GPGME_DECRYPT_VERIFY));
err = _gpgme_op_reset (ctx, synchronous); err = _gpgme_op_reset (ctx, synchronous);
if (err) if (err)
return err; return err;
@ -390,7 +394,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, return _gpgme_engine_op_decrypt (ctx->engine,
flags,
cipher, plain,
ctx->export_session_keys, ctx->export_session_keys,
ctx->override_session_key); ctx->override_session_key);
} }
@ -408,7 +414,7 @@ gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx) if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
err = decrypt_start (ctx, 0, cipher, plain); err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
return TRACE_ERR (err); return TRACE_ERR (err);
} }
@ -426,7 +432,7 @@ gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
if (!ctx) if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
err = decrypt_start (ctx, 1, cipher, plain); err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
if (!err) if (!err)
err = _gpgme_wait_one (ctx); err = _gpgme_wait_one (ctx);
return TRACE_ERR (err); return TRACE_ERR (err);

View File

@ -776,7 +776,6 @@ struct engine_ops _gpgme_engine_ops_assuan =
llass_set_locale, llass_set_locale,
NULL, /* set_protocol */ NULL, /* set_protocol */
NULL, /* decrypt */ NULL, /* decrypt */
NULL, /* decrypt_verify */
NULL, /* delete */ NULL, /* delete */
NULL, /* edit */ NULL, /* edit */
NULL, /* encrypt */ NULL, /* encrypt */

View File

@ -61,10 +61,9 @@ struct engine_ops
void *fnc_value); void *fnc_value);
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 plain, int export_session_key, gpgme_decrypt_flags_t flags,
const char *override_session_key); 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); 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);

View File

@ -791,7 +791,6 @@ struct engine_ops _gpgme_engine_ops_g13 =
g13_set_locale, g13_set_locale,
NULL, /* set_protocol */ NULL, /* set_protocol */
NULL, /* decrypt */ NULL, /* decrypt */
NULL, /* decrypt_verify */
NULL, /* delete */ NULL, /* delete */
NULL, /* edit */ NULL, /* edit */
NULL, /* encrypt */ NULL, /* encrypt */

View File

@ -1559,7 +1559,9 @@ 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, gpg_decrypt (void *engine,
gpgme_decrypt_flags_t flags,
gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key) int export_session_key, const char *override_session_key)
{ {
engine_gpg_t gpg = engine; engine_gpg_t gpg = engine;
@ -1567,6 +1569,14 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
err = add_arg (gpg, "--decrypt"); err = add_arg (gpg, "--decrypt");
if (!err && (flags & GPGME_DECRYPT_UNWRAP))
{
if (!have_gpg_version (gpg, "2.1.12"))
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
else
err = add_arg (gpg, "--unwrap");
}
if (!err && export_session_key) if (!err && export_session_key)
err = add_arg (gpg, "--show-session-key"); err = add_arg (gpg, "--show-session-key");
@ -1857,6 +1867,17 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!err && use_armor) if (!err && use_armor)
err = add_arg (gpg, "--armor"); err = add_arg (gpg, "--armor");
if (!err && (flags & GPGME_ENCRYPT_WRAP))
{
/* gpg is current not abale to detect already compressed
* packets. Thus when using
* gpg --unwrap -d | gpg --no-literal -e
* the encryption would add an additional compression layer.
* We better suppress that. */
flags |= GPGME_ENCRYPT_NO_COMPRESS;
err = add_arg (gpg, "--no-literal");
}
if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS)) if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
err = add_arg (gpg, "--compress-algo=none"); err = add_arg (gpg, "--compress-algo=none");
@ -3047,7 +3068,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_set_locale, gpg_set_locale,
NULL, /* set_protocol */ NULL, /* set_protocol */
gpg_decrypt, gpg_decrypt,
gpg_decrypt, /* decrypt_verify */
gpg_delete, gpg_delete,
gpg_edit, gpg_edit,
gpg_encrypt, gpg_encrypt,

View File

@ -1233,7 +1233,6 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
NULL, /* set_locale */ NULL, /* set_locale */
NULL, /* set_protocol */ NULL, /* set_protocol */
NULL, /* decrypt */ NULL, /* decrypt */
NULL, /* decrypt_verify */
NULL, /* delete */ NULL, /* delete */
NULL, /* edit */ NULL, /* edit */
NULL, /* encrypt */ NULL, /* encrypt */

View File

@ -1127,12 +1127,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, gpgsm_decrypt (void *engine,
gpgme_decrypt_flags_t flags,
gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key) 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;
(void)flags;
/* 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;
@ -2095,7 +2099,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
gpgsm_set_locale, gpgsm_set_locale,
NULL, /* set_protocol */ NULL, /* set_protocol */
gpgsm_decrypt, gpgsm_decrypt,
gpgsm_decrypt,
gpgsm_delete, /* decrypt_verify */ gpgsm_delete, /* decrypt_verify */
NULL, /* edit */ NULL, /* edit */
gpgsm_encrypt, gpgsm_encrypt,

View File

@ -449,7 +449,6 @@ struct engine_ops _gpgme_engine_ops_spawn =
NULL, /* set_locale */ NULL, /* set_locale */
NULL, /* set_protocol */ NULL, /* set_protocol */
NULL, /* decrypt */ NULL, /* decrypt */
NULL, /* decrypt_verify */
NULL, /* delete */ NULL, /* delete */
NULL, /* edit */ NULL, /* edit */
NULL, /* encrypt */ NULL, /* encrypt */

View File

@ -959,7 +959,8 @@ uiserver_reset (void *engine)
static gpgme_error_t static gpgme_error_t
_uiserver_decrypt (void *engine, int verify, uiserver_decrypt (void *engine,
gpgme_decrypt_flags_t flags,
gpgme_data_t ciph, gpgme_data_t plain, gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key) int export_session_key, const char *override_session_key)
{ {
@ -967,6 +968,7 @@ _uiserver_decrypt (void *engine, int verify,
gpgme_error_t err; gpgme_error_t err;
const char *protocol; const char *protocol;
char *cmd; char *cmd;
int verify = !!(flags & GPGME_DECRYPT_VERIFY);
(void)override_session_key; /* Fixme: We need to see now to add this (void)override_session_key; /* Fixme: We need to see now to add this
* to the UI server protocol */ * to the UI server protocol */
@ -1010,25 +1012,6 @@ _uiserver_decrypt (void *engine, int verify,
} }
static gpgme_error_t
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, override_session_key);
}
static gpgme_error_t
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, override_session_key);
}
static gpgme_error_t static gpgme_error_t
set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[]) set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[])
{ {
@ -1383,7 +1366,6 @@ struct engine_ops _gpgme_engine_ops_uiserver =
uiserver_set_locale, uiserver_set_locale,
uiserver_set_protocol, uiserver_set_protocol,
uiserver_decrypt, uiserver_decrypt,
uiserver_decrypt_verify,
NULL, /* delete */ NULL, /* delete */
NULL, /* edit */ NULL, /* edit */
uiserver_encrypt, uiserver_encrypt,

View File

@ -652,7 +652,9 @@ _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_decrypt_flags_t flags,
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) const char *override_session_key)
{ {
@ -662,28 +664,11 @@ _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, return (*engine->ops->decrypt) (engine->engine, flags, ciph, plain,
export_session_key, override_session_key); export_session_key, override_session_key);
} }
gpgme_error_t
_gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key,
const char *override_session_key)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->decrypt_verify)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain,
export_session_key,
override_session_key);
}
gpgme_error_t gpgme_error_t
_gpgme_engine_op_delete (engine_t engine, gpgme_key_t key, _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret) int allow_secret)

View File

@ -83,16 +83,12 @@ gpgme_error_t
_gpgme_engine_set_colon_line_handler (engine_t engine, _gpgme_engine_set_colon_line_handler (engine_t engine,
engine_colon_line_handler_t fnc, engine_colon_line_handler_t fnc,
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 plain, gpgme_decrypt_flags_t flags,
int export_session_key,
const char *override_session_key);
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 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

@ -259,5 +259,8 @@ EXPORTS
gpgme_op_set_uid_flag_start @193 gpgme_op_set_uid_flag_start @193
gpgme_op_set_uid_flag @194 gpgme_op_set_uid_flag @194
gpgme_op_decrypt_ext @195
gpgme_op_decrypt_ext_start @196
; END ; END

View File

@ -1238,7 +1238,8 @@ typedef enum
GPGME_ENCRYPT_EXPECT_SIGN = 8, GPGME_ENCRYPT_EXPECT_SIGN = 8,
GPGME_ENCRYPT_NO_COMPRESS = 16, GPGME_ENCRYPT_NO_COMPRESS = 16,
GPGME_ENCRYPT_SYMMETRIC = 32, GPGME_ENCRYPT_SYMMETRIC = 32,
GPGME_ENCRYPT_THROW_KEYIDS = 64 GPGME_ENCRYPT_THROW_KEYIDS = 64,
GPGME_ENCRYPT_WRAP = 128
} }
gpgme_encrypt_flags_t; gpgme_encrypt_flags_t;
@ -1317,6 +1318,14 @@ typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t;
/* Retrieve a pointer to the result of the decrypt operation. */ /* Retrieve a pointer to the result of the decrypt operation. */
gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx); gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx);
/* The valid decryption flags. */
typedef enum
{
GPGME_DECRYPT_VERIFY = 1,
GPGME_DECRYPT_UNWRAP = 128
}
gpgme_decrypt_flags_t;
/* Decrypt ciphertext CIPHER within CTX and store the resulting /* Decrypt ciphertext CIPHER within CTX and store the resulting
plaintext in PLAIN. */ plaintext in PLAIN. */
gpgme_error_t gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_error_t gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
@ -1332,6 +1341,19 @@ gpgme_error_t gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx,
gpgme_error_t gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_error_t gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
gpgme_data_t plain); gpgme_data_t plain);
/* Decrypt ciphertext CIPHER within CTX and store the resulting
* plaintext in PLAIN. With the flag GPGME_DECRYPT_VERIFY also do a
* signature verification pn the plaintext. */
gpgme_error_t gpgme_op_decrypt_ext_start (gpgme_ctx_t ctx,
gpgme_decrypt_flags_t flags,
gpgme_data_t cipher,
gpgme_data_t plain);
gpgme_error_t gpgme_op_decrypt_ext (gpgme_ctx_t ctx,
gpgme_decrypt_flags_t flags,
gpgme_data_t cipher,
gpgme_data_t plain);
/* /*
* Signing. * Signing.

View File

@ -129,6 +129,9 @@ GPGME_1.1 {
gpgme_op_set_uid_flag_start; gpgme_op_set_uid_flag_start;
gpgme_op_set_uid_flag; gpgme_op_set_uid_flag;
gpgme_op_decrypt_ext;
gpgme_op_decrypt_ext_start;
}; };

View File

@ -89,6 +89,9 @@ gpgme_error_t _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx);
gpgme_error_t _gpgme_decrypt_status_handler (void *priv, gpgme_error_t _gpgme_decrypt_status_handler (void *priv,
gpgme_status_code_t code, gpgme_status_code_t code,
char *args); char *args);
gpgme_error_t _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
gpgme_decrypt_flags_t flags,
gpgme_data_t cipher, gpgme_data_t plain);
/* From signers.c. */ /* From signers.c. */

View File

@ -80,6 +80,7 @@ show_usage (int ex)
" --cms use the CMS protocol\n" " --cms use the CMS protocol\n"
" --export-session-key show the session key\n" " --export-session-key show the session key\n"
" --override-session-key STRING use STRING as session key\n" " --override-session-key STRING use STRING as session key\n"
" --unwrap remove only the encryption layer\n"
, stderr); , stderr);
exit (ex); exit (ex);
} }
@ -92,6 +93,7 @@ main (int argc, char **argv)
gpgme_error_t err; gpgme_error_t err;
gpgme_ctx_t ctx; gpgme_ctx_t ctx;
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
gpgme_decrypt_flags_t flags = 0;
FILE *fp_in = NULL; FILE *fp_in = NULL;
gpgme_data_t in = NULL; gpgme_data_t in = NULL;
gpgme_data_t out = NULL; gpgme_data_t out = NULL;
@ -99,6 +101,7 @@ main (int argc, char **argv)
int print_status = 0; int print_status = 0;
int export_session_key = 0; int export_session_key = 0;
const char *override_session_key = NULL; const char *override_session_key = NULL;
int raw_output = 0;
if (argc) if (argc)
{ argc--; argv++; } { argc--; argv++; }
@ -146,6 +149,12 @@ main (int argc, char **argv)
override_session_key = *argv; override_session_key = *argv;
argc--; argv++; argc--; argv++;
} }
else if (!strcmp (*argv, "--unwrap"))
{
flags |= GPGME_DECRYPT_UNWRAP;
raw_output = 1;
argc--; argv++;
}
else if (!strncmp (*argv, "--", 2)) else if (!strncmp (*argv, "--", 2))
show_usage (1); show_usage (1);
@ -211,7 +220,7 @@ main (int argc, char **argv)
exit (1); exit (1);
} }
err = gpgme_op_decrypt (ctx, in, out); err = gpgme_op_decrypt_ext (ctx, flags, in, out);
result = gpgme_op_decrypt_result (ctx); result = gpgme_op_decrypt_result (ctx);
if (err) if (err)
{ {
@ -220,8 +229,13 @@ main (int argc, char **argv)
} }
if (result) if (result)
{ {
if (!raw_output)
print_result (result); print_result (result);
if (!raw_output)
fputs ("Begin Output:\n", stdout);
print_data (out); print_data (out);
if (!raw_output)
fputs ("End Output.\n", stdout);
} }
gpgme_data_release (out); gpgme_data_release (out);

View File

@ -89,6 +89,7 @@ show_usage (int ex)
" --loopback use a loopback pinentry\n" " --loopback use a loopback pinentry\n"
" --key NAME encrypt to key NAME\n" " --key NAME encrypt to key NAME\n"
" --throw-keyids use this option\n" " --throw-keyids use this option\n"
" --wrap assume input is valid OpenPGP message\n"
" --symmetric encrypt symmetric (OpenPGP only)\n" " --symmetric encrypt symmetric (OpenPGP only)\n"
, stderr); , stderr);
exit (ex); exit (ex);
@ -176,6 +177,11 @@ main (int argc, char **argv)
flags |= GPGME_ENCRYPT_THROW_KEYIDS; flags |= GPGME_ENCRYPT_THROW_KEYIDS;
argc--; argv++; argc--; argv++;
} }
else if (!strcmp (*argv, "--wrap"))
{
flags |= GPGME_ENCRYPT_WRAP;
argc--; argv++;
}
else if (!strcmp (*argv, "--loopback")) else if (!strcmp (*argv, "--loopback"))
{ {
use_loopback = 1; use_loopback = 1;