From c3e7053489df648dfccf9bb4146c374aa229b483 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Mon, 29 Oct 2001 00:08:14 +0000 Subject: [PATCH] gpgme/ 2001-10-29 Marcus Brinkmann * 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 * t-signers.c: New file. * Makefile.am (TESTS): Add t-signers. --- gpgme/ChangeLog | 12 ++++ gpgme/context.h | 1 + gpgme/signers.c | 114 +++++++++++++++++-------------- tests/ChangeLog | 5 ++ tests/Makefile.am | 4 +- tests/t-signers.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 250 insertions(+), 53 deletions(-) create mode 100644 tests/t-signers.c diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index db7ce50e..2406759e 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,15 @@ +2001-10-29 Marcus Brinkmann + + * 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 * data.c (_gpgme_data_append): Check if LENGTH is smaller than diff --git a/gpgme/context.h b/gpgme/context.h index ee3f224a..0f2de347 100644 --- a/gpgme/context.h +++ b/gpgme/context.h @@ -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; diff --git a/gpgme/signers.c b/gpgme/signers.c index 95d8a228..73f1caa5 100644 --- a/gpgme/signers.c +++ b/gpgme/signers.c @@ -33,76 +33,88 @@ */ +/** + * 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 || !key) - return mk_error (Invalid_Value); + if (c->signers_len == c->signers_size) + { + GpgmeKey *newarr; + int n = c->signers_size + 5; + int j; - 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; + 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]; } - - - - diff --git a/tests/ChangeLog b/tests/ChangeLog index fba4de2e..153bd153 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2001-10-29 Marcus Brinkmann + + * t-signers.c: New file. + * Makefile.am (TESTS): Add t-signers. + 2001-10-22 Marcus Brinkmann * Makefile.am (TEST_ENVIRONMENT): Revert last change. diff --git a/tests/Makefile.am b/tests/Makefile.am index cb453a34..13cc1ad9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 00000000..bdda2bce --- /dev/null +++ b/tests/t-signers.c @@ -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 +#include +#include +#include + +#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 (""); + 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; +}