core: New flags GPGME_DECRYPT_UNWRAP and GPGME_ENCRYPT_WRAP.
authorWerner Koch <wk@gnupg.org>
Fri, 24 Mar 2017 13:36:54 +0000 (14:36 +0100)
committerWerner Koch <wk@gnupg.org>
Fri, 24 Mar 2017 14:17:23 +0000 (15:17 +0100)
* 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>
20 files changed:
NEWS
doc/gpgme.texi
src/decrypt-verify.c
src/decrypt.c
src/engine-assuan.c
src/engine-backend.h
src/engine-g13.c
src/engine-gpg.c
src/engine-gpgconf.c
src/engine-gpgsm.c
src/engine-spawn.c
src/engine-uiserver.c
src/engine.c
src/engine.h
src/gpgme.def
src/gpgme.h.in
src/libgpgme.vers
src/ops.h
tests/run-decrypt.c
tests/run-encrypt.c

diff --git a/NEWS b/NEWS
index d03fe80..104d2b1 100644 (file)
--- 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.
index fd1f9bc..d5969b7 100644 (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.
 @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
index e0aa8ea..66cfe94 100644 (file)
@@ -23,6 +23,8 @@
 #include <config.h>
 #endif
 
+#include <assert.h>
+
 #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);
index 43717c0..f30f80f 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <assert.h>
 
 #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);
index 4beb41d..68bdaa6 100644 (file)
@@ -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 */
index 635acb0..53af662 100644 (file)
@@ -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 */);
index 593177c..02951e8 100644 (file)
@@ -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 */
index 6e4b833..0c3a63e 100644 (file)
@@ -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,
index 4891977..6f7c8ac 100644 (file)
@@ -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 */
index 7652363..c3d5427 100644 (file)
@@ -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,
index fa406d4..9d587cc 100644 (file)
@@ -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 */
index 12efd27..20a8abf 100644 (file)
@@ -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  */
@@ -1011,25 +1013,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[])
 {
   gpgme_error_t err = 0;
@@ -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,
index a918a50..278916d 100644 (file)
@@ -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,29 +664,12 @@ _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)
 {
index 1064f5e..dd0ef9c 100644 (file)
@@ -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,
index 9faffb8..51053cd 100644 (file)
@@ -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
 
index e9ee6e2..b6c1406 100644 (file)
@@ -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);
+
+
 \f
 /*
  * Signing.
index 037a6ae..adc8d7d 100644 (file)
@@ -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;
 };
 
 
index 97b1019..cc61dc4 100644 (file)
--- 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);
 
 \f
 /* From signers.c.  */
index 8bcca0e..0fcacf8 100644 (file)
@@ -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);
index c148e93..e949d76 100644 (file)
@@ -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;