gpgme/
authorMarcus Brinkmann <mb@g10code.com>
Mon, 29 Oct 2001 00:08:14 +0000 (00:08 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Mon, 29 Oct 2001 00:08:14 +0000 (00:08 +0000)
2001-10-29  Marcus Brinkmann  <marcus@g10code.de>

* context.h: New member signers_len.  * signers.c
(gpgme_signers_clear): Require that signers are non-NULL with
assertion.  Use signers_len to determine how much keys to release.
Add documentation.
(gpgme_signers_add): Use signers_len to determine if the buffer is
large enough.  Use xtryrealloc rather than xtrymalloc and copying.
Add documentation.
(gpgme_signers_enum): Use signers_len to determine if key is
available.  Add documentation.

tests/
2001-10-29  Marcus Brinkmann  <marcus@g10code.de>

* t-signers.c: New file.
* Makefile.am (TESTS): Add t-signers.

gpgme/ChangeLog
gpgme/context.h
gpgme/signers.c
tests/ChangeLog
tests/Makefile.am
tests/t-signers.c [new file with mode: 0644]

index db7ce50..2406759 100644 (file)
@@ -1,3 +1,15 @@
+2001-10-29  Marcus Brinkmann  <marcus@g10code.de>
+
+       * context.h: New member signers_len.  * signers.c
+       (gpgme_signers_clear): Require that signers are non-NULL with
+       assertion.  Use signers_len to determine how much keys to release.
+       Add documentation.
+       (gpgme_signers_add): Use signers_len to determine if the buffer is
+       large enough.  Use xtryrealloc rather than xtrymalloc and copying.
+       Add documentation.
+       (gpgme_signers_enum): Use signers_len to determine if key is
+       available.  Add documentation.
+
 2001-10-22  Marcus Brinkmann  <marcus@g10code.de>
 
        * data.c (_gpgme_data_append): Check if LENGTH is smaller than
index ee3f224..0f2de34 100644 (file)
@@ -67,6 +67,7 @@ struct gpgme_context_s {
     int use_textmode;
     int keylist_mode;
 
+    int signers_len;   /* The number of keys in signers.  */
     int signers_size;  /* size of the following array */
     GpgmeKey *signers;
 
index 95d8a22..73f1caa 100644 (file)
  */
 
 
+/**
+ * gpgme_signers_clear:
+ * @c: context to clear from signers
+ *
+ * Remove the list of signers from the context and release the
+ * references to the signers keys.
+ *
+ * Return value: The version string or NULL
+ **/
 void
 gpgme_signers_clear (GpgmeCtx c)
 {
-    int i;
+  int i;
 
-    return_if_fail (c);
+  return_if_fail (c);
 
-    if (!c->signers)
-        return;
-    for (i=0; i < c->signers_size; i++ ) {
-        if (!c->signers[i])
-            break;
-        gpgme_key_unref (c->signers[i]);
-        c->signers[i] = NULL;
+  if (!c->signers)
+    return;
+  for (i = 0; i < c->signers_len; i++)
+    {
+      assert (c->signers[i]);
+      gpgme_key_unref (c->signers[i]);
+      c->signers[i] = NULL;
     }
+  c->signers_len = 0;
 }
 
-
+/**
+ * gpgme_signers_add:
+ * @c: context to add signer to
+ * @key: key to add
+ *
+ * Add the key as a signer to the context.  Acquires a reference to
+ * the key.
+ *
+ * Return value: NULL on success, or an error code.
+ **/
 GpgmeError
 gpgme_signers_add (GpgmeCtx c, const GpgmeKey key)
 {
-    int i = 0;
-
-    if (!c || !key)
-        return mk_error (Invalid_Value);
-
-    if (!c->signers)
-        c->signers_size = 0;
-
-    for (i=0; i < c->signers_size && c->signers[i]; i++ )
-        ;
-    if ( !(i < c->signers_size) ) {
-        GpgmeKey *newarr;
-        int j;
-        int n = c->signers_size + 5;
-
-        newarr = xtrycalloc ( n, sizeof *newarr );
-        if ( !newarr )
-            return mk_error (Out_Of_Core);
-        for (j=0; j < c->signers_size; j++ )
-            newarr[j] = c->signers[j];
-        c->signers_size = n;
-        xfree (c->signers);
-        c->signers = newarr;
+  if (!c || !key)
+    return mk_error (Invalid_Value);
+
+  if (c->signers_len == c->signers_size)
+    {
+      GpgmeKey *newarr;
+      int n = c->signers_size + 5;
+      int j;
+
+      newarr = xtryrealloc (c->signers, n * sizeof (*newarr));
+      if (!newarr)
+       return mk_error (Out_Of_Core);
+      for (j = c->signers_size; j < n; j++)
+       newarr[j] = NULL;
+      c->signers = newarr;
+      c->signers_size = n;
     }
-    gpgme_key_ref (key);
-    c->signers[i] = key;
-    return 0;
-}
 
+  gpgme_key_ref (key);
+  c->signers[c->signers_len++] = key;
+  return 0;
+}
 
+/**
+ * gpgme_signers_enum:
+ * @c: context to retrieve signer from
+ * @seq: index of key to retrieve
+ *
+ * Acquire a reference to the signers key with the specified index
+ * number in the context and return it to the caller.
+ *
+ * Return value: A GpgmeKey or NULL on failure.
+ **/
 GpgmeKey
 gpgme_signers_enum (const GpgmeCtx c, int seq )
 {
-    int i;
+  return_null_if_fail (c);
+  return_null_if_fail (seq >= 0);
 
-    return_null_if_fail (c);
-    return_null_if_fail (seq>=0);
-
-    if (!c->signers)
-        c->signers_size = 0;
-    for (i=0; i < c->signers_size && c->signers[i]; i++ ) {
-        if (i==seq) {
-            gpgme_key_ref (c->signers[i]);
-            return c->signers[i];
-        }
-    }
+  if (seq >= c->signers_len)
     return NULL;
-}
-
-
-
 
+  gpgme_key_ref (c->signers[seq]);
+  return c->signers[seq];
+}
index fba4de2..153bd15 100644 (file)
@@ -1,3 +1,8 @@
+2001-10-29  Marcus Brinkmann  <marcus@g10code.de>
+
+       * t-signers.c: New file.
+       * Makefile.am (TESTS): Add t-signers.
+
 2001-10-22  Marcus Brinkmann  <marcus@g10code.de>
 
        * Makefile.am (TEST_ENVIRONMENT): Revert last change.
index cb453a3..13cc1ad 100644 (file)
@@ -22,8 +22,8 @@
 
 TESTS_ENVIRONMENT = GNUPGHOME=.
 
-TESTS = t-version t-data t-encrypt t-sign t-decrypt t-verify t-keylist \
-       t-export t-import t-trustlist
+TESTS = t-version t-data t-encrypt t-sign t-signers t-decrypt t-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/t-signers.c b/tests/t-signers.c
new file mode 100644 (file)
index 0000000..bdda2bc
--- /dev/null
@@ -0,0 +1,167 @@
+/* t-signers.c  - Regression tests for the Gpgme multiple signers interface.
+ *     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 "../gpgme/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;
+  GpgmeKey key[2];  /* There are two secret keys in the test area.  */
+
+  err = gpgme_new (&ctx);
+  fail_if_err (err);
+  err = gpgme_op_keylist_start (ctx, NULL, 1);
+  fail_if_err (err);
+  err = gpgme_op_keylist_next (ctx, &key[0]);
+  fail_if_err (err);
+  err = gpgme_op_keylist_next (ctx, &key[1]);
+  fail_if_err (err);
+  gpgme_release (ctx);
+  
+  do
+    {
+      err = gpgme_new (&ctx);
+      fail_if_err (err);
+      if (!getenv ("GPG_AGENT_INFO"))
+       gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
+      err = gpgme_signers_add (ctx, key[0]);
+      fail_if_err (err);
+      err = gpgme_signers_add (ctx, key[1]);
+      fail_if_err (err);
+
+      gpgme_set_textmode (ctx, 1);
+      gpgme_set_armor (ctx, 1);
+
+      err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0);
+      fail_if_err (err);
+
+
+      /* First a normal signature.  */
+      err = gpgme_data_new (&out);
+      fail_if_err (err);
+      err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_NORMAL);
+      fail_if_err (err);
+      fflush (NULL);
+      fputs ("Begin Result:\n", stdout);
+      print_op_info (ctx);
+      print_data (out);
+      fputs ("End Result.\n", stdout);
+      gpgme_data_release (out);
+      gpgme_data_rewind (in);
+    
+      /* Now a detached signature.  */
+      err = gpgme_data_new (&out);
+      fail_if_err (err);
+      err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_DETACH);
+      fail_if_err (err);
+      fflush (NULL);
+      print_op_info (ctx);
+      fputs ("Begin Result:\n", stdout);
+      print_data (out);
+      fputs ("End Result.\n", stdout);
+      gpgme_data_release (out);
+      gpgme_data_rewind (in);
+    
+      /* And finally a cleartext signature.  */
+      err = gpgme_data_new (&out);
+      fail_if_err (err);
+      err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_CLEAR);
+      fail_if_err (err);
+      fflush (NULL);
+      print_op_info (ctx);
+      fputs ("Begin Result:\n", stdout);
+      print_data (out);
+      fputs ("End Result.\n", stdout);
+      gpgme_data_release (out);
+      gpgme_data_rewind (in);
+    
+      /* Ready.  */
+      gpgme_data_release (in);
+      gpgme_release (ctx);
+    }
+  while (argc > 1 && !strcmp (argv[1], "--loop"));
+
+  gpgme_key_release (key[0]);
+  gpgme_key_release (key[1]);
+
+  return 0;
+}