doc/
authorMarcus Brinkmann <mb@g10code.com>
Tue, 26 Feb 2002 00:08:09 +0000 (00:08 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Tue, 26 Feb 2002 00:08:09 +0000 (00:08 +0000)
2002-02-26  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.texi (Encrypting a Plaintext): Document
gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start.

gpgme/
2002-02-25  Marcus Brinkmann  <marcus@g10code.de>

* engine.c (_gpgme_engine_op_encrypt_sign): New function.
* engine.h (_gpgme_engine_op_encrypt_sign): New prototype.
* rungpg.c (_gpgme_append_gpg_args_from_signers): New function.
(_gpgme_gpg_op_sign): Use that new function.
(_gpgme_gpg_op_encrypt_sign): New function.
* rungpg.h (_gpgme_gpg_op_encrypt_sign): New prototype.
* gpgme.h (gpgme_op_encrypt_sign_start): New prototype.
(gpgme_op_encrypt_sign): Likewise.
* Makefile.am (libgpgme_la_SOURCES): Add encrypt-sign.c.
* ops.h (_gpgme_encrypt_status_handler): Add prototype.
(_gpgme_sign_status_handler): Add prototype.
* sign.c (sign_status_handler): Rename to ...
(_gpgme_sign_status_handler): ... this and make non-static.
* encrypt.c (encrypt_status_handler): Rename to ...
(_gpgme_encrypt_status_handler): ... this and make non-static.
* encrypt.c (gpgme_op_encrypt_start): Use new status handler name.
* sign.c (gpgme_op_sign_start): Likewise.

tests/
2002-02-26  Marcus Brinkmann  <marcus@g10code.de>

* gpg/t-encrypt-sign.c: New file.
* gpg/Makefile.am (TESTS): Add t-encrypt-sign.

17 files changed:
NEWS
doc/ChangeLog
doc/gpgme.texi
gpgme/ChangeLog
gpgme/Makefile.am
gpgme/encrypt-sign.c [new file with mode: 0644]
gpgme/encrypt.c
gpgme/engine.c
gpgme/engine.h
gpgme/gpgme.h
gpgme/ops.h
gpgme/rungpg.c
gpgme/rungpg.h
gpgme/sign.c
tests/ChangeLog
tests/gpg/Makefile.am
tests/gpg/t-encrypt-sign.c [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index f01424ca42cfa9410cbf067423c3b9c731c9bbb4..4476d408123dccd07765d44e4bfceca4b5b5617f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,10 +3,15 @@
    to set and get the number of certifications to include in S/MIME
    signed messages.
 
+ * New interfaces gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start
+   to encrypt and sign a message in a combined operation.
+
  * Interface changes relative to the 0.3.3 release:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 gpgme_set_include_certs                NEW
 gpgme_get_include_certs                NEW
+gpgme_op_encrypt_sign          NEW
+gpgme_op_encrypt_sign_start    NEW
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Noteworthy changes in version 0.3.3 (2002-02-12)
index da067da4890b8fcf7995536d5ec916a684595683..fe5eb4e5701a46bcb4a7dc9699b9664a9743d14f 100644 (file)
@@ -1,3 +1,8 @@
+2002-02-26  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.texi (Encrypting a Plaintext): Document
+       gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start.
+
 2002-02-25  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme.texi (Creating a Signature): Add a note about
index 708110c3fab2f6378613d7c10a567556f30467d6..2be6170b8d8014d0f59a7b3025ce0839d809427f 100644 (file)
@@ -2201,7 +2201,7 @@ The function @code{gpgme_recipients_enum_close} releases the iterator
 @subsubsection Encrypting a Plaintext
 
 @deftypefun GpgmeError gpgme_op_encrypt (@w{GpgmeCtx @var{ctx}}, @w{GpgmeRecipients @var{rset}}, @w{GpgmeData @var{plain}}, @w{GpgmeData @var{cipher}})
-The function @code{gpgme_op_crypt} encrypts the plaintext in the data
+The function @code{gpgme_op_encrypt} encrypts the plaintext in the data
 object @var{plain} for the recipients @var{rset} and stores the
 ciphertext in the data object @var{cipher}.  The type of the
 ciphertext created is determined by the @acronym{ASCII} armor and text
@@ -2232,6 +2232,30 @@ recipients.
 @end deftypefun
 
 
+@deftypefun GpgmeError gpgme_op_encrypt_sign (@w{GpgmeCtx @var{ctx}}, @w{GpgmeRecipients @var{rset}}, @w{GpgmeData @var{plain}}, @w{GpgmeData @var{cipher}})
+The function @code{gpgme_op_encrypt_sign} does a combined encrypt and
+sign operation.  It is used like @code{gpgme_op_encrypt}, but the
+ciphertext also contains signatures for the signers listed in
+@var{ctx}.
+
+The combined encrypt and sign operation is currently only available
+for the OpenPGP crypto engine.
+@end deftypefun
+
+@deftypefun GpgmeError gpgme_op_encrypt_sign_start (@w{GpgmeCtx @var{ctx}}, @w{GpgmeRecipients @var{rset}}, @w{GpgmeData @var{plain}}, @w{GpgmeData @var{cipher}})
+The function @code{gpgme_op_encrypt_sign_start} initiates a
+@code{gpgme_op_encrypt_sign} operation.  It can be completed by
+calling @code{gpgme_wait} on the context.  @xref{Waiting For
+Completion}.
+
+The function returns @code{GPGME_No_Error} if the operation could be
+started successfully, @code{GPGME_Invalid_Value} if @var{ctx},
+@var{rset}, @var{plain} or @var{cipher} is not a valid pointer, and
+@code{GPGME_No_Recipient} if @var{rset} does not contain any valid
+recipients.
+@end deftypefun
+
+
 @node Detailed Results
 @subsection Detailed Results
 @cindex cryptographic operation, detailed results
index ebecd26446697901a6e26da91d1917a4e6281ac2..1b7930ff7192853401986c6e534726dcfbbb6eab 100644 (file)
@@ -1,3 +1,23 @@
+2002-02-25  Marcus Brinkmann  <marcus@g10code.de>
+
+       * engine.c (_gpgme_engine_op_encrypt_sign): New function.
+       * engine.h (_gpgme_engine_op_encrypt_sign): New prototype.
+       * rungpg.c (_gpgme_append_gpg_args_from_signers): New function.
+       (_gpgme_gpg_op_sign): Use that new function.
+       (_gpgme_gpg_op_encrypt_sign): New function.
+       * rungpg.h (_gpgme_gpg_op_encrypt_sign): New prototype. 
+       * gpgme.h (gpgme_op_encrypt_sign_start): New prototype.
+       (gpgme_op_encrypt_sign): Likewise.
+       * Makefile.am (libgpgme_la_SOURCES): Add encrypt-sign.c.
+       * ops.h (_gpgme_encrypt_status_handler): Add prototype.
+       (_gpgme_sign_status_handler): Add prototype.
+       * sign.c (sign_status_handler): Rename to ...
+       (_gpgme_sign_status_handler): ... this and make non-static.
+       * encrypt.c (encrypt_status_handler): Rename to ...
+       (_gpgme_encrypt_status_handler): ... this and make non-static.
+       * encrypt.c (gpgme_op_encrypt_start): Use new status handler name.
+       * sign.c (gpgme_op_sign_start): Likewise.
+       
 2002-02-25  Marcus Brinkmann  <marcus@g10code.de>
 
        * verify.c (_gpgme_verify_status_handler): Parse the args line to
index 9bec612d1d8e7007d14915f07dfe0daff23631a8..aa6ef831cd2a63f3e600eb9845416751376669a9 100644 (file)
@@ -42,6 +42,7 @@ libgpgme_la_SOURCES = \
        data.c recipient.c signers.c \
         wait.c wait.h \
        encrypt.c \
+       encrypt-sign.c \
        decrypt.c \
        decrypt-verify.c \
        verify.c \
diff --git a/gpgme/encrypt-sign.c b/gpgme/encrypt-sign.c
new file mode 100644 (file)
index 0000000..1c8e596
--- /dev/null
@@ -0,0 +1,150 @@
+/* encrypt-sign.c -  encrypt and verify functions
+ *     Copyright (C) 2000 Werner Koch (dd9jn)
+ *      Copyright (C) 2001, 2002 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+
+
+static void
+encrypt_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+{
+  char *encrypt_info = 0;
+  int encrypt_info_len;
+
+  _gpgme_encrypt_status_handler (ctx, code, args);
+
+  if (code == STATUS_EOF)
+    {
+      encrypt_info = gpgme_data_release_and_get_mem (ctx->op_info,
+                                                    &encrypt_info_len);
+      ctx->op_info = NULL;
+    }
+  _gpgme_sign_status_handler (ctx, code, args);
+  if (code == STATUS_EOF && encrypt_info)
+    _gpgme_data_append (ctx->op_info, encrypt_info, encrypt_info_len);
+}
+
+
+GpgmeError
+gpgme_op_encrypt_sign_start (GpgmeCtx ctx, GpgmeRecipients recp,
+                            GpgmeData plain, GpgmeData cipher)
+{
+  int err = 0;
+
+  fail_on_pending_request (ctx);
+  ctx->pending = 1;
+
+  _gpgme_release_result (ctx);
+
+  /* Do some checks.  */
+  if (!gpgme_recipients_count (recp))
+    {
+      /* FIXME: In this case we should do symmetric encryption.  */
+      err = mk_error (No_Recipients);
+      goto leave;
+    }
+
+  /* Create an engine object.  */
+  _gpgme_engine_release (ctx->engine);
+  ctx->engine = NULL;
+  err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
+                          : GPGME_PROTOCOL_OpenPGP, &ctx->engine);
+  if (err)
+    goto leave;
+
+  err = _gpgme_passphrase_start (ctx);
+  if (err)
+    goto leave;
+
+  _gpgme_engine_set_status_handler (ctx->engine,
+                                   encrypt_sign_status_handler, ctx);
+  _gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
+
+  /* Check the supplied data */
+  if (gpgme_data_get_type (plain) == GPGME_DATA_TYPE_NONE)
+    {
+      err = mk_error (No_Data);
+      goto leave;
+    }
+  _gpgme_data_set_mode (plain, GPGME_DATA_MODE_OUT);
+  if (!cipher || gpgme_data_get_type (cipher) != GPGME_DATA_TYPE_NONE)
+    {
+      err = mk_error (Invalid_Value);
+      goto leave;
+    }
+  _gpgme_data_set_mode (cipher, GPGME_DATA_MODE_IN);
+
+  err = _gpgme_engine_op_encrypt_sign (ctx->engine, recp, plain, cipher,
+                                      ctx->use_armor, ctx /* FIXME */);
+
+  if (!err)    /* And kick off the process.  */
+    err = _gpgme_engine_start (ctx->engine, ctx);
+
+ leave:
+  if (err)
+    {
+      ctx->pending = 0; 
+      _gpgme_engine_release (ctx->engine);
+      ctx->engine = NULL;
+    }
+  return err;
+}
+
+
+/**
+ * gpgme_op_encrypt_sign:
+ * @ctx: The context
+ * @recp: The set of recipients
+ * @plain: plaintext input
+ * @cipher: signed ciphertext
+ * 
+ * This function encrypts @plain for all recipients in recp, signs it,
+ * and returns the ciphertext in @out.  The function does wait for the
+ * result.
+ * 
+ * Return value:  0 on success or an errorcode. 
+ **/
+GpgmeError
+gpgme_op_encrypt_sign (GpgmeCtx ctx, GpgmeRecipients recp,
+                      GpgmeData plain, GpgmeData cipher)
+{
+  GpgmeError err = gpgme_op_encrypt_sign_start (ctx, recp, plain, cipher);
+
+  if (!err)
+    {
+      gpgme_wait (ctx, &err, 1);
+      /* Old gpg versions don't return status info for invalid
+         recipients, so we simply check whether we got any output at
+         all, and if not we assume that we don't have valid
+         recipients.  */
+      if (!ctx->error && gpgme_data_get_type (cipher) == GPGME_DATA_TYPE_NONE)
+        ctx->error = mk_error (No_Recipients);
+      err = ctx->error;
+    }
+  return err;
+}
index d0b8fc6e235112e3b938307b766d6984653d4ad6..2f6abdae872b070898f0a505e479f9b33074d039 100644 (file)
@@ -97,8 +97,8 @@ append_xml_encinfo (GpgmeData *rdh, char *args)
 }
 
 
-static void
-encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+void
+_gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 {
   if (ctx->error)
     return;
@@ -158,7 +158,8 @@ gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
   if (err)
     goto leave;
 
-  _gpgme_engine_set_status_handler (ctx->engine, encrypt_status_handler, ctx);
+  _gpgme_engine_set_status_handler (ctx->engine, _gpgme_encrypt_status_handler,
+                                   ctx);
   _gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
 
   /* Check the supplied data */
index e53327a3c4dfdeb206fdaf2cdfa43a36cbcefb36..8841b20bdcb24c51759c9b2b34f5d1330630ed66 100644 (file)
@@ -333,6 +333,7 @@ _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key, int allow_secret)
   return 0;
 }
 
+
 GpgmeError
 _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
                          GpgmeData plain, GpgmeData ciph, int use_armor)
@@ -354,6 +355,29 @@ _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
   return 0;
 }
 
+
+GpgmeError
+_gpgme_engine_op_encrypt_sign (EngineObject engine, GpgmeRecipients recp,
+                              GpgmeData plain, GpgmeData ciph, int use_armor,
+                              GpgmeCtx ctx /* FIXME */)
+{
+  if (!engine)
+    return mk_error (Invalid_Value);
+
+  switch (engine->protocol)
+    {
+    case GPGME_PROTOCOL_OpenPGP:
+      return _gpgme_gpg_op_encrypt_sign (engine->engine.gpg, recp, plain, ciph,
+                                        use_armor, ctx);
+    case GPGME_PROTOCOL_CMS:
+      return mk_error (Not_Implemented);
+    default:
+      break;
+    }
+  return 0;
+}
+
+
 GpgmeError
 _gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp,
                         GpgmeData keydata, int use_armor)
index 7e4acd305cecb3d75c14b2b309959b6dbb4d150e..d8881a109594dfbbbed064dae76289a0f990f810 100644 (file)
@@ -46,6 +46,11 @@ GpgmeError _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key,
 GpgmeError _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
                                     GpgmeData plain, GpgmeData ciph,
                                     int use_armor);
+GpgmeError _gpgme_engine_op_encrypt_sign (EngineObject engine,
+                                         GpgmeRecipients recp,
+                                         GpgmeData plain, GpgmeData ciph,
+                                         int use_armor,
+                                         GpgmeCtx ctx /* FIXME */);
 GpgmeError _gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp,
                                    GpgmeData keydata, int use_armor);
 GpgmeError _gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data,
index 5c7ff8783331b08f3d54a9e114c38fb88899471e..713125a5962a45e8115c5fb5e93ae955d1869eac 100644 (file)
@@ -427,6 +427,16 @@ GpgmeError gpgme_op_encrypt (GpgmeCtx ctx,
                             GpgmeRecipients recp,
                             GpgmeData plain, GpgmeData cipher);
 
+/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
+   store the resulting ciphertext in CIPHER.  Also sign the ciphertext
+   with the signers in CTX.  */
+GpgmeError gpgme_op_encrypt_sign_start (GpgmeCtx ctx,
+                                       GpgmeRecipients recp,
+                                       GpgmeData plain, GpgmeData cipher);
+GpgmeError gpgme_op_encrypt_sign (GpgmeCtx ctx,
+                                 GpgmeRecipients recp,
+                                 GpgmeData plain, GpgmeData cipher);
+
 /* Decrypt ciphertext CIPHER within CTX and store the resulting
    plaintext in PLAIN.  */
 GpgmeError gpgme_op_decrypt_start (GpgmeCtx ctx,
index 5b09a9ffe475ea2b6e634e1c0244860984d00d0e..2ff8b5596b8e102a23888e3ab3e18786102e2013 100644 (file)
@@ -101,9 +101,13 @@ GpgmeError _gpgme_decrypt_result (GpgmeCtx ctx);
 
 /*-- sign.c --*/
 void _gpgme_release_sign_result ( SignResult res );
+void _gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code,
+                                char *args);
 
 /*-- encrypt.c --*/
 void _gpgme_release_encrypt_result ( EncryptResult res );
+void _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
+                                   char *args);
 
 /*-- passphrase.c --*/
 void _gpgme_release_passphrase_result (PassphraseResult result);
index b30bb04cbe542ceb94db621d9ed67bd5e93ed238..8738fc38612234cecb49c2c65bf749c9c47fe22f 100644 (file)
@@ -1256,6 +1256,7 @@ _gpgme_gpg_op_delete (GpgObject gpg, GpgmeKey key, int allow_secret)
   return err;
 }
 
+
 static GpgmeError
 _gpgme_append_gpg_args_from_recipients (GpgObject gpg,
                                        const GpgmeRecipients rset)
@@ -1275,6 +1276,33 @@ _gpgme_append_gpg_args_from_recipients (GpgObject gpg,
   return err;
 }
 
+
+static GpgmeError
+_gpgme_append_gpg_args_from_signers (GpgObject gpg,
+                                    GpgmeCtx ctx /* FIXME */)
+{
+  GpgmeError err = 0;
+  int i;
+  GpgmeKey key;
+
+  for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
+    {
+      const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID,
+                                                NULL, 0);
+      if (s)
+       {
+         if (!err)
+           err = _gpgme_gpg_add_arg (gpg, "-u");
+         if (!err)
+           err = _gpgme_gpg_add_arg (gpg, s);
+       }
+      gpgme_key_unref (key);
+      if (err) break;
+    }
+  return err;
+}
+
+
 GpgmeError
 _gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp,
                       GpgmeData plain, GpgmeData ciph, int use_armor)
@@ -1308,6 +1336,45 @@ _gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp,
   return err;
 }
 
+GpgmeError
+_gpgme_gpg_op_encrypt_sign (GpgObject gpg, GpgmeRecipients recp,
+                           GpgmeData plain, GpgmeData ciph, int use_armor,
+                           GpgmeCtx ctx /* FIXME */)
+{
+  GpgmeError err;
+
+  err = _gpgme_gpg_add_arg (gpg, "--encrypt");
+  if (!err)
+    err = _gpgme_gpg_add_arg (gpg, "--sign");
+  if (!err && use_armor)
+    err = _gpgme_gpg_add_arg (gpg, "--armor");
+
+  /* If we know that all recipients are valid (full or ultimate trust)
+   * we can suppress further checks */
+  if (!err && _gpgme_recipients_all_valid (recp))
+    err = _gpgme_gpg_add_arg (gpg, "--always-trust");
+
+  if (!err)
+    err = _gpgme_append_gpg_args_from_recipients (gpg, recp);
+
+  if (!err)
+    err = _gpgme_append_gpg_args_from_signers (gpg, ctx);
+
+  /* Tell the gpg object about the data.  */
+  if (!err)
+    err = _gpgme_gpg_add_arg (gpg, "--output");
+  if (!err)
+    err = _gpgme_gpg_add_arg (gpg, "-");
+  if (!err)
+    err = _gpgme_gpg_add_data (gpg, ciph, 1);
+  if (!err)
+    err = _gpgme_gpg_add_arg (gpg, "--");
+  if (!err)
+    err = _gpgme_gpg_add_data (gpg, plain, 0);
+
+  return err;
+}
+
 GpgmeError
 _gpgme_gpg_op_export (GpgObject gpg, GpgmeRecipients recp,
                      GpgmeData keydata, int use_armor)
@@ -1404,8 +1471,6 @@ _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
                    int use_textmode, GpgmeCtx ctx /* FIXME */)
 {
   GpgmeError err;
-  GpgmeKey key;
-  int i;
 
   if (mode == GPGME_SIG_MODE_CLEAR)
     err = _gpgme_gpg_add_arg (gpg, "--clearsign");
@@ -1419,20 +1484,9 @@ _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
       if (!err && use_textmode)
        _gpgme_gpg_add_arg (gpg, "--textmode");
     }
-  for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
-    {
-      const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID,
-                                                NULL, 0);
-      if (s)
-       {
-         if (!err)
-           err = _gpgme_gpg_add_arg (gpg, "-u");
-         if (!err)
-           err = _gpgme_gpg_add_arg (gpg, s);
-       }
-      gpgme_key_unref (key);
-      if (err) break;
-    }
+
+  if (!err)
+    err = _gpgme_append_gpg_args_from_signers (gpg, ctx);
 
   /* Tell the gpg object about the data.  */
   if (!err)
index 36bd5c4f9b07e3a88552fc9a5e39a66762871660..ed65cf15fd88e3f77d077b0ae519ee9f10fc68dc 100644 (file)
@@ -126,6 +126,9 @@ GpgmeError _gpgme_gpg_op_delete (GpgObject gpg, GpgmeKey key, int allow_secret);
 GpgmeError _gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp,
                                  GpgmeData plain, GpgmeData ciph,
                                  int use_armor);
+GpgmeError _gpgme_gpg_op_encrypt_sign (GpgObject gpg, GpgmeRecipients recp,
+                                      GpgmeData plain, GpgmeData ciph,
+                                      int use_armor, GpgmeCtx ctx);
 GpgmeError _gpgme_gpg_op_export (GpgObject gpg, GpgmeRecipients recp,
                                 GpgmeData keydata, int use_armor);
 GpgmeError _gpgme_gpg_op_genkey (GpgObject gpg, GpgmeData help_data,
index f63974d1661cdaac307a39131bb113aa19f4701f..494eed8144dbd70a0886c23f07417247faac1fb4 100644 (file)
@@ -135,8 +135,8 @@ append_xml_siginfo (GpgmeData *rdh, char *args)
   _gpgme_data_append_string (dh, "</fpr>\n");
 }
 
-static void
-sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+void
+_gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 {
   _gpgme_passphrase_status_handler (ctx, code, args);
 
@@ -210,7 +210,8 @@ gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
   if (err)
     goto leave;
 
-  _gpgme_engine_set_status_handler (ctx->engine, sign_status_handler, ctx);
+  _gpgme_engine_set_status_handler (ctx->engine, _gpgme_sign_status_handler,
+                                   ctx);
   _gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
 
   _gpgme_engine_op_sign (ctx->engine, in, out, mode, ctx->use_armor,
index 3a7ae6b1840551dd39857bf304adffaa6523f10e..5eaf47130fed12e6a2ae7a775a95b491b82aff7f 100644 (file)
@@ -1,3 +1,8 @@
+2002-02-26  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpg/t-encrypt-sign.c: New file.
+       * gpg/Makefile.am (TESTS): Add t-encrypt-sign.
+
 2002-02-13  Werner Koch  <wk@gnupg.org>
 
        * gpgsm/Makefile.am (private-keys-v1.d): Don't
index 7d249bae872a198982f6dcc477eedcfa005d445f..424e9d2ed7f95ae8fd79d15144b1c9ee9ffbdee2 100644 (file)
@@ -23,7 +23,7 @@ GPG = @GPG@
 
 TESTS_ENVIRONMENT = GNUPGHOME=.
 
-TESTS = t-encrypt t-sign t-signers t-decrypt t-verify  \
+TESTS = t-encrypt t-encrypt-sign t-sign t-signers t-decrypt t-verify \
        t-decrypt-verify t-keylist t-export t-import t-trustlist
 
 CLEANFILES = secring.gpg pubring.gpg trustdb.gpg random_seed
diff --git a/tests/gpg/t-encrypt-sign.c b/tests/gpg/t-encrypt-sign.c
new file mode 100644 (file)
index 0000000..a4620d2
--- /dev/null
@@ -0,0 +1,139 @@
+/* t-encrypt-sign.c  - regression test
+ *     Copyright (C) 2000 Werner Koch (dd9jn)
+ *      Copyright (C) 2001, 2002 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <gpgme.h>
+
+#define fail_if_err(a) do { if(a) {                                       \
+                               fprintf (stderr, "%s:%d: GpgmeError %s\n", \
+                                __FILE__, __LINE__, gpgme_strerror(a));   \
+                                exit (1); }                               \
+                             } while(0)
+
+static void
+print_op_info (GpgmeCtx c)
+{
+    char *s = gpgme_get_op_info (c, 0);
+
+    if (!s)
+        puts ("<!-- no operation info available -->");
+    else {
+        puts (s);
+        free (s);
+    }
+}
+
+
+static void
+print_data ( GpgmeData dh )
+{
+    char buf[100];
+    size_t nread;
+    GpgmeError err;
+
+    err = gpgme_data_rewind ( dh );
+    fail_if_err (err);
+    while ( !(err = gpgme_data_read ( dh, buf, 100, &nread )) ) {
+        fwrite ( buf, nread, 1, stdout );
+    }
+    if (err != GPGME_EOF) 
+        fail_if_err (err);
+}
+
+
+static const char *
+passphrase_cb ( void *opaque, const char *desc, void **r_hd )
+{
+    const char *pass;
+
+    if ( !desc ) {
+        /* cleanup by looking at *r_hd */
+
+        
+        return NULL;
+    }
+
+    pass = "abc";
+    fprintf (stderr, "%% requesting passphrase for `%s': ", desc );
+    fprintf (stderr, "sending `%s'\n", pass );
+
+    return pass;
+}
+
+
+int 
+main (int argc, char **argv )
+{
+    GpgmeCtx ctx;
+    GpgmeError err;
+    GpgmeData in, out;
+    GpgmeRecipients rset;
+
+    err = gpgme_check_engine ();
+    fail_if_err (err);
+    puts ( gpgme_get_engine_info() );
+
+  do {
+    err = gpgme_new (&ctx);
+    fail_if_err (err);
+    gpgme_set_armor (ctx, 1);
+    if (!getenv("GPG_AGENT_INFO"))
+      gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
+
+    err = gpgme_data_new_from_mem ( &in, "Hallo Leute\n", 12, 0 );
+    fail_if_err (err);
+
+    err = gpgme_data_new ( &out );
+    fail_if_err (err);
+
+    err = gpgme_recipients_new (&rset);
+    fail_if_err (err);
+    err = gpgme_recipients_add_name_with_validity (rset, "Bob",
+                                                   GPGME_VALIDITY_FULL);
+    fail_if_err (err);
+    err = gpgme_recipients_add_name_with_validity (rset, "Alpha",
+                                                   GPGME_VALIDITY_FULL);
+    fail_if_err (err);
+
+
+    err = gpgme_op_encrypt_sign (ctx, rset, in, out);
+    print_op_info (ctx);
+    fail_if_err (err);
+
+    fflush (NULL);
+    fputs ("Begin Result:\n", stdout );
+    print_data (out);
+    fputs ("End Result.\n", stdout );
+   
+    gpgme_recipients_release (rset);
+    gpgme_data_release (in);
+    gpgme_data_release (out);
+    gpgme_release (ctx);
+  } while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
+   
+    return 0;
+}
+
+