gpgme/
authorMarcus Brinkmann <mb@g10code.com>
Fri, 16 Nov 2001 01:37:06 +0000 (01:37 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Fri, 16 Nov 2001 01:37:06 +0000 (01:37 +0000)
2001-11-16  Marcus Brinkmann  <marcus@g10code.de>

* decrypt-verify.c: New file.
* Makefile.am (libgpgme_la_SOURCES): Add decrypt-verify.c.
* types.h: Add decrypt-verify types.
* ops.h: Likewise.
* context.h: Add result type for decrypt-verify.
* gpgme.h: Add decrypt-verify prototypes.

* decrypt.c (decrypt_status_handler): Renamed to ...
(_gpgme_decrypt_status_handler): ... this.  Make non-static.
(_gpgme_decrypt_start): New function, derived from
gpgme_op_decrypt_start.
(gpgme_op_decrypt_start): Reimplement in terms of
_gpgme_decrypt_start.
(_gpgme_decrypt_result): New function to retrieve error value.
(gpgme_op_decrypt): Use _gpgme_decrypt_result.
* ops.h: Add prototypes for new functions.

* verify.c (verify_status_handler): Renamed to ...
(_gpgme_verify_status_handler): ... this.  Make non-static.
(gpgme_op_verify_start): Use new function name.
(intersect_stati): Renamed to ...
(_gpgme_intersect_stati): ... this.  Make non-static.
(gpgme_op_verify): Use new name.
* ops.h: Add prototypes for new functions.

tests/
2001-11-16  Marcus Brinkmann  <marcus@g10code.de>

* Makefile.am (TESTS): Add t-decrypt-verify.
* t-decrypt-verify.c: New file.
* cipher-2.asc: Likewise.

gpgme/ChangeLog
gpgme/Makefile.am
gpgme/decrypt-verify.c [new file with mode: 0644]
gpgme/decrypt.c
gpgme/gpgme.h
gpgme/ops.h
gpgme/verify.c
tests/ChangeLog
tests/Makefile.am
tests/cipher-2.asc [new file with mode: 0644]
tests/t-decrypt-verify.c [new file with mode: 0644]

index 253d8c369194545fbdaed3ed1d7ba3e7f96f458b..d7cf910140b0bd21b3cd611767cd640c574b382e 100644 (file)
@@ -1,3 +1,30 @@
+2001-11-16  Marcus Brinkmann  <marcus@g10code.de>
+
+       * decrypt-verify.c: New file.
+       * Makefile.am (libgpgme_la_SOURCES): Add decrypt-verify.c.
+       * types.h: Add decrypt-verify types.
+       * ops.h: Likewise.
+       * context.h: Add result type for decrypt-verify.
+       * gpgme.h: Add decrypt-verify prototypes.
+
+       * decrypt.c (decrypt_status_handler): Renamed to ...
+       (_gpgme_decrypt_status_handler): ... this.  Make non-static.
+       (_gpgme_decrypt_start): New function, derived from
+       gpgme_op_decrypt_start.
+       (gpgme_op_decrypt_start): Reimplement in terms of
+       _gpgme_decrypt_start.
+       (_gpgme_decrypt_result): New function to retrieve error value.
+       (gpgme_op_decrypt): Use _gpgme_decrypt_result.
+       * ops.h: Add prototypes for new functions.
+
+       * verify.c (verify_status_handler): Renamed to ...
+       (_gpgme_verify_status_handler): ... this.  Make non-static.
+       (gpgme_op_verify_start): Use new function name.
+       (intersect_stati): Renamed to ...
+       (_gpgme_intersect_stati): ... this.  Make non-static.
+       (gpgme_op_verify): Use new name.
+       * ops.h: Add prototypes for new functions.
+
 2001-11-16  Marcus Brinkmann  <marcus@g10code.de>
 
        * passphrase.c: New file.
index 5a7fb4c264458ea974325f071d71fd2544ff86fc..41b513cbe40ac2a23c604e72566df6e7271b352d 100644 (file)
@@ -39,6 +39,7 @@ libgpgme_la_SOURCES = \
         wait.c wait.h \
        encrypt.c \
        decrypt.c \
+       decrypt-verify.c \
        verify.c \
        sign.c \
        passphrase.c \
diff --git a/gpgme/decrypt-verify.c b/gpgme/decrypt-verify.c
new file mode 100644 (file)
index 0000000..e7ec128
--- /dev/null
@@ -0,0 +1,80 @@
+/* decrypt-verify.c -  decrypt and verify functions
+ *     Copyright (C) 2000 Werner Koch (dd9jn)
+ *      Copyright (C) 2001 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
+decrypt_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+{
+  _gpgme_decrypt_status_handler (ctx, code, args);
+  _gpgme_verify_status_handler (ctx, code, args);
+}
+
+GpgmeError
+gpgme_op_decrypt_verify_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
+{
+  return _gpgme_decrypt_start (ctx, ciph, plain,
+                              decrypt_verify_status_handler);
+}
+
+/**
+ * gpgme_op_decrypt_verify:
+ * @ctx: The context
+ * @in: ciphertext input
+ * @out: plaintext output
+ * 
+ * This function decrypts @in to @out and performs a signature check.
+ * Other parameters are take from the context @c.
+ * The function does wait for the result.
+ * 
+ * Return value:  0 on success or an errorcode. 
+ **/
+GpgmeError
+gpgme_op_decrypt_verify (GpgmeCtx ctx,
+                        GpgmeData in, GpgmeData out,
+                        GpgmeSigStat *r_stat)
+{
+  GpgmeError err = gpgme_op_decrypt_verify_start (ctx, in, out);
+  if (!err)
+    {
+      gpgme_wait (ctx, 1);
+      if (!ctx->result.decrypt || !ctx->result.verify)
+       err = mk_error (General_Error);
+      else if (ctx->out_of_core)
+       err = mk_error (Out_Of_Core);
+      else
+       {
+         err = _gpgme_decrypt_result (ctx);
+          if (! err)
+           *r_stat = _gpgme_intersect_stati (ctx->result.verify);
+       }
+      ctx->pending = 0;
+    }
+  return err;
+}
index 4b38cf6001c8ba05328da0879d79c663d5e3c482..fcf440062b725c600630dee62d26734c6f89e150 100644 (file)
@@ -53,8 +53,8 @@ create_result_struct (GpgmeCtx ctx)
   return 0;    
 }
 
-static void
-decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+void
+_gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 {
   _gpgme_passphrase_status_handler (ctx, code, args);
 
@@ -90,7 +90,8 @@ decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 }
 
 GpgmeError
-gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
+_gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
+                     void *status_handler)
 {
   GpgmeError err = 0;
   int i;
@@ -109,7 +110,7 @@ gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
   if (err)
     goto leave;
 
-  _gpgme_gpg_set_status_handler (ctx->gpg, decrypt_status_handler, ctx);
+  _gpgme_gpg_set_status_handler (ctx->gpg, status_handler, ctx);
 
   err = _gpgme_passphrase_start (ctx);
   if (err)
@@ -154,6 +155,36 @@ gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
   return err;
 }
 
+GpgmeError
+gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
+{
+  return _gpgme_decrypt_start (ctx, ciph, plain,
+                              _gpgme_decrypt_status_handler);
+}
+
+GpgmeError
+_gpgme_decrypt_result (GpgmeCtx ctx)
+{
+  GpgmeError err = 0;
+
+  if (!ctx->result.decrypt)
+    err = mk_error (General_Error);
+  else if (ctx->out_of_core)
+    err = mk_error (Out_Of_Core);
+  else
+    {
+      err = _gpgme_passphrase_result (ctx);
+      if (! err)
+       {
+         if (ctx->result.decrypt->failed)
+           err = mk_error (Decryption_Failed);
+         else if (!ctx->result.decrypt->okay)
+           err = mk_error (No_Data);
+       }
+    }
+  return err;
+}
+
 /**
  * gpgme_op_decrypt:
  * @ctx: The context
@@ -173,21 +204,7 @@ gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out)
   if (!err)
     {
       gpgme_wait (ctx, 1);
-      if (!ctx->result.decrypt)
-       err = mk_error (General_Error);
-      else if (ctx->out_of_core)
-       err = mk_error (Out_Of_Core);
-      else
-       {
-         err = _gpgme_passphrase_result (ctx);
-         if (! err)
-           {
-             if (ctx->result.decrypt->failed)
-               err = mk_error (Decryption_Failed);
-             else if (!ctx->result.decrypt->okay)
-               err = mk_error (No_Data);
-           }
-        }
+      err = _gpgme_decrypt_result (ctx);
       ctx->pending = 0;
     }
   return err;
index b48ffc3d90d0adf35a4c72e2311a7a1b029685f9..5ef5aaa38fac0dc2580a019cfd13a97790ae7000 100644 (file)
@@ -257,6 +257,8 @@ GpgmeError gpgme_op_encrypt_start ( GpgmeCtx c,
                                     GpgmeData in, GpgmeData out );
 GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c, 
                                     GpgmeData ciph, GpgmeData plain );
+GpgmeError gpgme_op_decrypt_verify_start (GpgmeCtx c, 
+                                         GpgmeData ciph, GpgmeData plain);
 GpgmeError gpgme_op_sign_start ( GpgmeCtx c,
                                  GpgmeData in, GpgmeData out,
                                  GpgmeSigMode mode );
@@ -288,6 +290,9 @@ GpgmeError gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,
                               GpgmeData in, GpgmeData out );
 GpgmeError gpgme_op_decrypt ( GpgmeCtx c, 
                               GpgmeData in, GpgmeData out );
+GpgmeError gpgme_op_decrypt_verify (GpgmeCtx c, 
+                                   GpgmeData in, GpgmeData out,
+                                   GpgmeSigStat *r_status);
 GpgmeError gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out,
                            GpgmeSigMode mode);
 GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
index 2186d936f67af65502197ece979077ae5f58be3d..2640336271c879867fa44f421eae4fcfdce00c6b 100644 (file)
@@ -69,10 +69,18 @@ GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
 
 
 /*-- verify.c --*/
-void _gpgme_release_verify_result ( VerifyResult res );
+void _gpgme_release_verify_result (VerifyResult result);
+GpgmeSigStat _gpgme_intersect_stati (VerifyResult result);
+void _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code,
+                                  char *args);
 
 /*-- decrypt.c --*/
-void _gpgme_release_decrypt_result ( DecryptResult res );
+void _gpgme_release_decrypt_result (DecryptResult result);
+void _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
+                                   char *args);
+GpgmeError _gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
+                                void *status_handler);
+GpgmeError _gpgme_decrypt_result (GpgmeCtx ctx);
 
 /*-- sign.c --*/
 void _gpgme_release_sign_result ( SignResult res );
index b7692d10320d8c07ca1e8c0572a19df740d1f869..aa09b9b523b12463043bac64a0e560e95eb12a3d 100644 (file)
@@ -127,9 +127,8 @@ finish_sig (GpgmeCtx ctx, int stop)
     ctx->result.verify->collecting = 1;
 }
 
-
-static void
-verify_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
+void
+_gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 {
     char *p;
     int i;
@@ -246,7 +245,7 @@ gpgme_op_verify_start ( GpgmeCtx c,  GpgmeData sig, GpgmeData text )
 
     if (pipemode)
         _gpgme_gpg_enable_pipemode ( c->gpg ); 
-    _gpgme_gpg_set_status_handler ( c->gpg, verify_status_handler, c );
+    _gpgme_gpg_set_status_handler (c->gpg, _gpgme_verify_status_handler, c);
 
     /* build the commandline */
     _gpgme_gpg_add_arg ( c->gpg, pipemode?"--pipemode" : "--verify" );
@@ -294,8 +293,8 @@ gpgme_op_verify_start ( GpgmeCtx c,  GpgmeData sig, GpgmeData text )
 /* 
  * Figure out a common status value for all signatures 
  */
-static GpgmeSigStat
-intersect_stati (VerifyResult result)
+GpgmeSigStat
+_gpgme_intersect_stati (VerifyResult result)
 {
   GpgmeSigStat status = result->status;
 
@@ -364,7 +363,7 @@ gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
                 c->notation = dh;
                 c->result.verify->notation = NULL;
             }
-            *r_stat = intersect_stati (c->result.verify);
+            *r_stat = _gpgme_intersect_stati (c->result.verify);
         }
         c->pending = 0;
     }
index 87ca830a8edcbfc956694033366c97261d7565a9..a57f6625edec712b43dd749aa3f70d3cbda27884 100644 (file)
@@ -1,3 +1,9 @@
+2001-11-16  Marcus Brinkmann  <marcus@g10code.de>
+
+       * Makefile.am (TESTS): Add t-decrypt-verify.
+       * t-decrypt-verify.c: New file.
+       * cipher-2.asc: Likewise.
+
 2001-11-02  Marcus Brinkmann  <marcus@g10code.de>
 
        * t-data.c: Include stddef.h.
index 13cc1ad9fda62ad1520570a2e5851efb5b157b2e..64906988139565efd7c5d551a11ea8e38f18fb40 100644 (file)
@@ -23,7 +23,7 @@
 TESTS_ENVIRONMENT = GNUPGHOME=.
 
 TESTS = t-version t-data t-encrypt t-sign t-signers t-decrypt t-verify \
-       t-keylist t-export t-import t-trustlist
+       t-decrypt-verify t-keylist t-export t-import t-trustlist
 
 
 EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc geheim.txt \
diff --git a/tests/cipher-2.asc b/tests/cipher-2.asc
new file mode 100644 (file)
index 0000000..210f3e9
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.0.6 (GNU/Linux)
+Comment: Weitere Infos: siehe http://www.gnupg.org
+
+hQEOA++dwnahcsiBEAP9HgkC1ElQwZRX1X/MBF54Q28dpXKr84IviO4QcbnnhmYk
+2IlaNe6mr8R7kNM1aqJFK3fnobqnSWwM/VBObMqqYnzZSfclCNsy66sojQJxwXcz
+DKQKi69BLaC6aTMnX048tOl8pJpR72fkffUOUa5ywDHVVVUClDG3XkIrfM1du3YD
+/A6vFSrRylupKhQBxdtSUx5IDmpDYwG2vqqbYKoMaQ4pPSKLYV2zskU+pQWRlk6y
+nwPGY5h9eGz0xYHMPxhe9VnwljeTEDwz5U4CHF3wQ8h5WBxOVx5QN/H/UyjpmoJT
+ddrIu+8GgajhBVKVYAOqr577exkiSDA60/JrYbKZBvzL0sAJAUu+HoeMPJ+5/RYF
+pLSdz/3MbVDRJJqzV2TJnEBvFtPa6urzx99P0u4xr+RJMFmR9/99YXhYz7+Y6d/B
+44F6B3YouYxiK39IoOUcYPZTwb5kaudD5a3mU3XxEhSDUpnyvowPiKQO1T8CPd2u
+2HsD3KeaOc2VFE0gnvqECvUTQfSCZCk/kil8XVAMHZrEA0bWAYiaHfHEOB8SRCy8
+rW0wsON4uDXmZpUkfOjFoYZdpJI7fDKkb5uYUzFZDasharEaXb1X/5xSAclx
+=+eYk
+-----END PGP MESSAGE-----
diff --git a/tests/t-decrypt-verify.c b/tests/t-decrypt-verify.c
new file mode 100644 (file)
index 0000000..1c1f143
--- /dev/null
@@ -0,0 +1,147 @@
+/* t-decrypt-verify.c  - regression test
+ *     Copyright (C) 2000 Werner Koch (dd9jn)
+ *      Copyright (C) 2001 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 <errno.h>
+#include <mcheck.h>
+
+#include "../gpgme/gpgme.h"
+
+struct passphrase_cb_info_s
+{
+  GpgmeCtx c;
+  int did_it;
+};
+
+
+#define fail_if_err(a) do { if(a) { int my_errno = errno;      \
+            fprintf (stderr, "%s:%d: GpgmeError %s\n",         \
+                 __FILE__, __LINE__, gpgme_strerror(a));       \
+            if ((a) == GPGME_File_Error)                       \
+                   fprintf (stderr, "\terrno=`%s'\n", strerror (my_errno)); \
+                   exit (1); }                                 \
+                             } while(0)
+
+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;
+}
+
+static char *
+mk_fname (const char *fname)
+{
+  const char *srcdir = getenv ("srcdir");
+  char *buf;
+
+  if (!srcdir)
+    srcdir = ".";
+  buf = malloc (strlen(srcdir) + strlen(fname) + 2);
+  if (!buf)
+    exit (8);
+  strcpy (buf, srcdir);
+  strcat (buf, "/");
+  strcat (buf, fname);
+  return buf;
+}
+
+int 
+main (int argc, char **argv)
+{
+  GpgmeCtx ctx;
+  GpgmeError err;
+  GpgmeData in, out, pwdata = NULL;
+  struct passphrase_cb_info_s info;
+  const char *cipher_2_asc = mk_fname ("cipher-2.asc");
+  GpgmeSigStat stat;
+
+  do
+    {
+      err = gpgme_new (&ctx);
+      fail_if_err (err);
+      if (!getenv("GPG_AGENT_INFO"))
+       {
+         memset (&info, 0, sizeof info);
+         info.c = ctx;
+         gpgme_set_passphrase_cb (ctx, passphrase_cb, &info);
+       } 
+
+      err = gpgme_data_new_from_file (&in, cipher_2_asc, 1);
+      fail_if_err (err);
+
+      err = gpgme_data_new (&out);
+      fail_if_err (err);
+
+      err = gpgme_op_decrypt_verify (ctx, in, out, &stat);
+      fail_if_err (err);
+    
+      fflush (NULL);
+      fputs ("Begin Result:\n", stdout);
+      print_data (out);
+      fputs ("End Result.\n", stdout);
+   
+      if (stat != GPGME_SIG_STAT_GOOD)
+       {
+         fprintf (stderr, "Signature check failed unexpectedly.\n");
+         exit (1);
+       }
+
+      gpgme_data_release (in);
+      gpgme_data_release (out);
+      gpgme_data_release (pwdata);
+      gpgme_release (ctx);
+    }
+  while (argc > 1 && !strcmp (argv[1], "--loop"));
+
+  return 0;
+}
+
+