From 6ac1f2cdedb085b4ac9372c1e591497e2e618de4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 24 Mar 2017 14:36:54 +0100 Subject: [PATCH] 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 --- NEWS | 5 ++++ doc/gpgme.texi | 52 +++++++++++++++++++++++++++++++++ src/decrypt-verify.c | 67 +++++++++++++++++++++++++++++++++++++++---- src/decrypt.c | 18 ++++++++---- src/engine-assuan.c | 1 - src/engine-backend.h | 7 ++--- src/engine-g13.c | 1 - src/engine-gpg.c | 24 ++++++++++++++-- src/engine-gpgconf.c | 1 - src/engine-gpgsm.c | 7 +++-- src/engine-spawn.c | 1 - src/engine-uiserver.c | 28 ++++-------------- src/engine.c | 23 +++------------ src/engine.h | 10 ++----- src/gpgme.def | 3 ++ src/gpgme.h.in | 24 +++++++++++++++- src/libgpgme.vers | 3 ++ src/ops.h | 3 ++ tests/run-decrypt.c | 18 ++++++++++-- tests/run-encrypt.c | 6 ++++ 20 files changed, 227 insertions(+), 75 deletions(-) diff --git a/NEWS b/NEWS index d03fe80b..104d2b1a 100644 --- a/NEWS +++ b/NEWS @@ -14,7 +14,12 @@ Noteworthy changes in version 1.8.1 (unreleased) gpgme_op_keylist_from_data_start NEW. gpgme_op_set_uid_flag_start 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_WRAP NEW. + GPGME_DECRYPT_VERIFY NEW. + GPGME_DECRYPT_UNWRAP NEW. gpgme_data_rewind UN-DEPRECATE. cpp: Context::revUid(const Key&, const char*) NEW. cpp: Context::startRevUid(const Key&, const char*) NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index fd1f9bc7..d5969b71 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -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. @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} This is a pointer to a structure used to store information about the 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. 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 If @code{GPG_ERR_UNUSABLE_PUBKEY} is returned, some recipients in diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c index e0aa8ea9..66cfe94f 100644 --- a/src/decrypt-verify.c +++ b/src/decrypt-verify.c @@ -23,6 +23,8 @@ #include #endif +#include + #include "debug.h" #include "gpgme.h" #include "ops.h" @@ -45,10 +47,13 @@ decrypt_verify_status_handler (void *priv, gpgme_status_code_t code, static gpgme_error_t decrypt_verify_start (gpgme_ctx_t ctx, int synchronous, + gpgme_decrypt_flags_t flags, gpgme_data_t cipher, gpgme_data_t plain) { gpgme_error_t err; + assert ((flags & GPGME_DECRYPT_VERIFY)); + err = _gpgme_op_reset (ctx, synchronous); if (err) return err; @@ -77,9 +82,11 @@ 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, - ctx->export_session_keys, - ctx->override_session_key); + return _gpgme_engine_op_decrypt (ctx->engine, + flags, + cipher, plain, + ctx->export_session_keys, + ctx->override_session_key); } @@ -97,7 +104,7 @@ gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx, gpgme_data_t cipher, if (!ctx) 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); } @@ -116,7 +123,57 @@ gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher, if (!ctx) 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) err = _gpgme_wait_one (ctx); return TRACE_ERR (err); diff --git a/src/decrypt.c b/src/decrypt.c index 43717c0d..f30f80f6 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "debug.h" #include "gpgme.h" @@ -358,12 +359,15 @@ _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx) } -static gpgme_error_t -decrypt_start (gpgme_ctx_t ctx, int synchronous, - gpgme_data_t cipher, gpgme_data_t plain) +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) { gpgme_error_t err; + assert (!(flags & GPGME_DECRYPT_VERIFY)); + err = _gpgme_op_reset (ctx, synchronous); if (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); - return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain, + return _gpgme_engine_op_decrypt (ctx->engine, + flags, + cipher, plain, ctx->export_session_keys, ctx->override_session_key); } @@ -408,7 +414,7 @@ gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher, if (!ctx) 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); } @@ -426,7 +432,7 @@ gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain) if (!ctx) 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) err = _gpgme_wait_one (ctx); return TRACE_ERR (err); diff --git a/src/engine-assuan.c b/src/engine-assuan.c index 4beb41d7..68bdaa6a 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -776,7 +776,6 @@ struct engine_ops _gpgme_engine_ops_assuan = llass_set_locale, NULL, /* set_protocol */ NULL, /* decrypt */ - NULL, /* decrypt_verify */ NULL, /* delete */ NULL, /* edit */ NULL, /* encrypt */ diff --git a/src/engine-backend.h b/src/engine-backend.h index 635acb06..53af6622 100644 --- a/src/engine-backend.h +++ b/src/engine-backend.h @@ -61,12 +61,11 @@ struct engine_ops void *fnc_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 (*decrypt) (void *engine, gpgme_data_t ciph, + gpgme_error_t (*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); - gpgme_error_t (*decrypt_verify) (void *engine, gpgme_data_t ciph, - 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 (*edit) (void *engine, int type, gpgme_key_t key, gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */); diff --git a/src/engine-g13.c b/src/engine-g13.c index 593177c2..02951e83 100644 --- a/src/engine-g13.c +++ b/src/engine-g13.c @@ -791,7 +791,6 @@ struct engine_ops _gpgme_engine_ops_g13 = g13_set_locale, NULL, /* set_protocol */ NULL, /* decrypt */ - NULL, /* decrypt_verify */ NULL, /* delete */ NULL, /* edit */ NULL, /* encrypt */ diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 6e4b8339..0c3a63ee 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1559,7 +1559,9 @@ 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_decrypt_flags_t flags, + gpgme_data_t ciph, gpgme_data_t plain, int export_session_key, const char *override_session_key) { 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"); + 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) 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) 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)) err = add_arg (gpg, "--compress-algo=none"); @@ -3047,7 +3068,6 @@ struct engine_ops _gpgme_engine_ops_gpg = gpg_set_locale, NULL, /* set_protocol */ gpg_decrypt, - gpg_decrypt, /* decrypt_verify */ gpg_delete, gpg_edit, gpg_encrypt, diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c index 48919775..6f7c8ac0 100644 --- a/src/engine-gpgconf.c +++ b/src/engine-gpgconf.c @@ -1233,7 +1233,6 @@ struct engine_ops _gpgme_engine_ops_gpgconf = NULL, /* set_locale */ NULL, /* set_protocol */ NULL, /* decrypt */ - NULL, /* decrypt_verify */ NULL, /* delete */ NULL, /* edit */ NULL, /* encrypt */ diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index 7652363a..c3d5427f 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -1127,12 +1127,16 @@ 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_decrypt_flags_t flags, + gpgme_data_t ciph, gpgme_data_t plain, int export_session_key, const char *override_session_key) { engine_gpgsm_t gpgsm = engine; gpgme_error_t err; + (void)flags; + /* gpgsm is not capable of exporting session keys right now, so we * will ignore this if requested. */ (void)export_session_key; @@ -2095,7 +2099,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm = gpgsm_set_locale, NULL, /* set_protocol */ gpgsm_decrypt, - gpgsm_decrypt, gpgsm_delete, /* decrypt_verify */ NULL, /* edit */ gpgsm_encrypt, diff --git a/src/engine-spawn.c b/src/engine-spawn.c index fa406d4c..9d587cc5 100644 --- a/src/engine-spawn.c +++ b/src/engine-spawn.c @@ -449,7 +449,6 @@ struct engine_ops _gpgme_engine_ops_spawn = NULL, /* set_locale */ NULL, /* set_protocol */ NULL, /* decrypt */ - NULL, /* decrypt_verify */ NULL, /* delete */ NULL, /* edit */ NULL, /* encrypt */ diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index 12efd270..20a8abf2 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -959,14 +959,16 @@ uiserver_reset (void *engine) static gpgme_error_t -_uiserver_decrypt (void *engine, int verify, - gpgme_data_t ciph, gpgme_data_t plain, - int export_session_key, const char *override_session_key) +uiserver_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) { engine_uiserver_t uiserver = engine; gpgme_error_t err; const char *protocol; char *cmd; + int verify = !!(flags & GPGME_DECRYPT_VERIFY); (void)override_session_key; /* Fixme: We need to see now to add this * 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 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_protocol, uiserver_decrypt, - uiserver_decrypt_verify, NULL, /* delete */ NULL, /* edit */ uiserver_encrypt, diff --git a/src/engine.c b/src/engine.c index a918a50d..278916d4 100644 --- a/src/engine.c +++ b/src/engine.c @@ -652,7 +652,9 @@ _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_engine_op_decrypt (engine_t engine, + gpgme_decrypt_flags_t flags, + gpgme_data_t ciph, gpgme_data_t plain, int export_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) 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); } -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_engine_op_delete (engine_t engine, gpgme_key_t key, int allow_secret) diff --git a/src/engine.h b/src/engine.h index 1064f5ed..dd0ef9c2 100644 --- a/src/engine.h +++ b/src/engine.h @@ -83,16 +83,12 @@ gpgme_error_t _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_error_t _gpgme_engine_op_decrypt (engine_t engine, + gpgme_decrypt_flags_t flags, + gpgme_data_t ciph, gpgme_data_t plain, 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 plain, - int export_session_key, - const char *override_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.def b/src/gpgme.def index 9faffb85..51053cd9 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -259,5 +259,8 @@ EXPORTS gpgme_op_set_uid_flag_start @193 gpgme_op_set_uid_flag @194 + gpgme_op_decrypt_ext @195 + gpgme_op_decrypt_ext_start @196 + ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index e9ee6e2f..b6c14064 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1238,7 +1238,8 @@ typedef enum GPGME_ENCRYPT_EXPECT_SIGN = 8, GPGME_ENCRYPT_NO_COMPRESS = 16, GPGME_ENCRYPT_SYMMETRIC = 32, - GPGME_ENCRYPT_THROW_KEYIDS = 64 + GPGME_ENCRYPT_THROW_KEYIDS = 64, + GPGME_ENCRYPT_WRAP = 128 } 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. */ 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 plaintext in PLAIN. */ 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_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. diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 037a6ae2..adc8d7d4 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -129,6 +129,9 @@ GPGME_1.1 { gpgme_op_set_uid_flag_start; gpgme_op_set_uid_flag; + + gpgme_op_decrypt_ext; + gpgme_op_decrypt_ext_start; }; diff --git a/src/ops.h b/src/ops.h index 97b1019f..cc61dc4f 100644 --- a/src/ops.h +++ b/src/ops.h @@ -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_status_code_t code, 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. */ diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c index 8bcca0e5..0fcacf88 100644 --- a/tests/run-decrypt.c +++ b/tests/run-decrypt.c @@ -80,6 +80,7 @@ show_usage (int ex) " --cms use the CMS protocol\n" " --export-session-key show the session key\n" " --override-session-key STRING use STRING as session key\n" + " --unwrap remove only the encryption layer\n" , stderr); exit (ex); } @@ -92,6 +93,7 @@ main (int argc, char **argv) gpgme_error_t err; gpgme_ctx_t ctx; gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; + gpgme_decrypt_flags_t flags = 0; FILE *fp_in = NULL; gpgme_data_t in = NULL; gpgme_data_t out = NULL; @@ -99,6 +101,7 @@ main (int argc, char **argv) int print_status = 0; int export_session_key = 0; const char *override_session_key = NULL; + int raw_output = 0; if (argc) { argc--; argv++; } @@ -146,6 +149,12 @@ main (int argc, char **argv) override_session_key = *argv; argc--; argv++; } + else if (!strcmp (*argv, "--unwrap")) + { + flags |= GPGME_DECRYPT_UNWRAP; + raw_output = 1; + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) show_usage (1); @@ -211,7 +220,7 @@ main (int argc, char **argv) exit (1); } - err = gpgme_op_decrypt (ctx, in, out); + err = gpgme_op_decrypt_ext (ctx, flags, in, out); result = gpgme_op_decrypt_result (ctx); if (err) { @@ -220,8 +229,13 @@ main (int argc, char **argv) } if (result) { - print_result (result); + if (!raw_output) + print_result (result); + if (!raw_output) + fputs ("Begin Output:\n", stdout); print_data (out); + if (!raw_output) + fputs ("End Output.\n", stdout); } gpgme_data_release (out); diff --git a/tests/run-encrypt.c b/tests/run-encrypt.c index c148e931..e949d760 100644 --- a/tests/run-encrypt.c +++ b/tests/run-encrypt.c @@ -89,6 +89,7 @@ show_usage (int ex) " --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" , stderr); exit (ex); @@ -176,6 +177,11 @@ main (int argc, char **argv) flags |= GPGME_ENCRYPT_THROW_KEYIDS; argc--; argv++; } + else if (!strcmp (*argv, "--wrap")) + { + flags |= GPGME_ENCRYPT_WRAP; + argc--; argv++; + } else if (!strcmp (*argv, "--loopback")) { use_loopback = 1;