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.
This commit is contained in:
Marcus Brinkmann 2001-10-29 00:08:14 +00:00
parent 4a8042beae
commit c3e7053489
6 changed files with 250 additions and 53 deletions

View 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> 2001-10-22 Marcus Brinkmann <marcus@g10code.de>
* data.c (_gpgme_data_append): Check if LENGTH is smaller than * data.c (_gpgme_data_append): Check if LENGTH is smaller than

View File

@ -67,6 +67,7 @@ struct gpgme_context_s {
int use_textmode; int use_textmode;
int keylist_mode; int keylist_mode;
int signers_len; /* The number of keys in signers. */
int signers_size; /* size of the following array */ int signers_size; /* size of the following array */
GpgmeKey *signers; GpgmeKey *signers;

View File

@ -33,6 +33,15 @@
*/ */
/**
* 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 void
gpgme_signers_clear (GpgmeCtx c) gpgme_signers_clear (GpgmeCtx c)
{ {
@ -42,67 +51,70 @@ gpgme_signers_clear (GpgmeCtx c)
if (!c->signers) if (!c->signers)
return; return;
for (i=0; i < c->signers_size; i++ ) { for (i = 0; i < c->signers_len; i++)
if (!c->signers[i]) {
break; assert (c->signers[i]);
gpgme_key_unref (c->signers[i]); gpgme_key_unref (c->signers[i]);
c->signers[i] = NULL; 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 GpgmeError
gpgme_signers_add (GpgmeCtx c, const GpgmeKey key) gpgme_signers_add (GpgmeCtx c, const GpgmeKey key)
{ {
int i = 0;
if (!c || !key) if (!c || !key)
return mk_error (Invalid_Value); return mk_error (Invalid_Value);
if (!c->signers) if (c->signers_len == c->signers_size)
c->signers_size = 0; {
for (i=0; i < c->signers_size && c->signers[i]; i++ )
;
if ( !(i < c->signers_size) ) {
GpgmeKey *newarr; GpgmeKey *newarr;
int j;
int n = c->signers_size + 5; int n = c->signers_size + 5;
int j;
newarr = xtrycalloc ( n, sizeof *newarr ); newarr = xtryrealloc (c->signers, n * sizeof (*newarr));
if ( !newarr ) if (!newarr)
return mk_error (Out_Of_Core); return mk_error (Out_Of_Core);
for (j=0; j < c->signers_size; j++ ) for (j = c->signers_size; j < n; j++)
newarr[j] = c->signers[j]; newarr[j] = NULL;
c->signers_size = n;
xfree (c->signers);
c->signers = newarr; c->signers = newarr;
c->signers_size = n;
} }
gpgme_key_ref (key); gpgme_key_ref (key);
c->signers[i] = key; c->signers[c->signers_len++] = key;
return 0; 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 GpgmeKey
gpgme_signers_enum (const GpgmeCtx c, int seq ) gpgme_signers_enum (const GpgmeCtx c, int seq )
{ {
int i;
return_null_if_fail (c); return_null_if_fail (c);
return_null_if_fail (seq>=0); return_null_if_fail (seq >= 0);
if (!c->signers) if (seq >= c->signers_len)
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];
}
}
return NULL; return NULL;
gpgme_key_ref (c->signers[seq]);
return c->signers[seq];
} }

View 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> 2001-10-22 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (TEST_ENVIRONMENT): Revert last change. * Makefile.am (TEST_ENVIRONMENT): Revert last change.

View File

@ -22,8 +22,8 @@
TESTS_ENVIRONMENT = GNUPGHOME=. TESTS_ENVIRONMENT = GNUPGHOME=.
TESTS = t-version t-data t-encrypt t-sign t-decrypt t-verify t-keylist \ TESTS = t-version t-data t-encrypt t-sign t-signers t-decrypt t-verify \
t-export t-import t-trustlist t-keylist t-export t-import t-trustlist
EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc geheim.txt \ EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc geheim.txt \

167
tests/t-signers.c Normal file
View File

@ -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;
}