2003-04-29 Marcus Brinkmann <marcus@g10code.de>
* gpg/t-verify.c (main): Rewritten. * gpg/t-decrypt-verify.c: Rewritten. * gpgsm/t-verify.c (main): Rewritten.
This commit is contained in:
parent
85425c74ad
commit
26ec59fdbd
@ -1,3 +1,9 @@
|
|||||||
|
2003-04-29 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* gpg/t-verify.c (main): Rewritten.
|
||||||
|
* gpg/t-decrypt-verify.c: Rewritten.
|
||||||
|
* gpgsm/t-verify.c (main): Rewritten.
|
||||||
|
|
||||||
2003-04-28 Marcus Brinkmann <marcus@g10code.de>
|
2003-04-28 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* gpgsm/t-decrypt.c (main): Rewritten.
|
* gpgsm/t-decrypt.c (main): Rewritten.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* t-decrypt-verify.c - regression test
|
/* t-decrypt-verify.c - Regression test.
|
||||||
Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
|
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
|
||||||
|
|
||||||
@ -18,40 +18,38 @@
|
|||||||
along with GPGME; if not, write to the Free Software Foundation,
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <gpgme.h>
|
#include <gpgme.h>
|
||||||
|
|
||||||
struct passphrase_cb_info_s
|
|
||||||
{
|
#define fail_if_err(err) \
|
||||||
GpgmeCtx c;
|
do \
|
||||||
int did_it;
|
{ \
|
||||||
};
|
if (err) \
|
||||||
|
{ \
|
||||||
|
|
||||||
#define fail_if_err(a) do { if(a) { int my_errno = errno; \
|
|
||||||
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
||||||
__FILE__, __LINE__, gpgme_strerror(a)); \
|
__FILE__, __LINE__, gpgme_strerror (err)); \
|
||||||
if ((a) == GPGME_File_Error) \
|
exit (1); \
|
||||||
fprintf (stderr, "\terrno=`%s'\n", strerror (my_errno)); \
|
} \
|
||||||
exit (1); } \
|
} \
|
||||||
} while(0)
|
while (0)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_data (GpgmeData dh)
|
print_data (GpgmeData dh)
|
||||||
{
|
{
|
||||||
char buf[100];
|
#define BUF_SIZE 512
|
||||||
|
char buf[BUF_SIZE + 1];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = gpgme_data_seek (dh, 0, SEEK_SET);
|
ret = gpgme_data_seek (dh, 0, SEEK_SET);
|
||||||
if (ret)
|
if (ret)
|
||||||
fail_if_err (GPGME_File_Error);
|
fail_if_err (GPGME_File_Error);
|
||||||
while ((ret = gpgme_data_read (dh, buf, 100)) > 0)
|
while ((ret = gpgme_data_read (dh, buf, BUF_SIZE)) > 0)
|
||||||
fwrite (buf, ret, 1, stdout);
|
fwrite (buf, ret, 1, stdout);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
fail_if_err (GPGME_File_Error);
|
fail_if_err (GPGME_File_Error);
|
||||||
@ -59,23 +57,19 @@ print_data (GpgmeData dh)
|
|||||||
|
|
||||||
|
|
||||||
static GpgmeError
|
static GpgmeError
|
||||||
passphrase_cb (void *opaque, const char *desc,
|
passphrase_cb (void *opaque, const char *desc, void **hd, const char **result)
|
||||||
void **r_hd, const char **result)
|
|
||||||
{
|
{
|
||||||
|
/* Cleanup by looking at *hd. */
|
||||||
if (!desc)
|
if (!desc)
|
||||||
/* Cleanup by looking at *r_hd. */
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*result = "abc";
|
*result = "abc";
|
||||||
fprintf (stderr, "%% requesting passphrase for `%s': ", desc);
|
|
||||||
fprintf (stderr, "sending `%s'\n", *result);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
mk_fname (const char *fname)
|
make_filename (const char *fname)
|
||||||
{
|
{
|
||||||
const char *srcdir = getenv ("srcdir");
|
const char *srcdir = getenv ("srcdir");
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -84,69 +78,117 @@ mk_fname (const char *fname)
|
|||||||
srcdir = ".";
|
srcdir = ".";
|
||||||
buf = malloc (strlen(srcdir) + strlen(fname) + 2);
|
buf = malloc (strlen(srcdir) + strlen(fname) + 2);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
exit (8);
|
{
|
||||||
|
fprintf (stderr, "%s:%d: could not allocate string: %s\n",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
strcpy (buf, srcdir);
|
strcpy (buf, srcdir);
|
||||||
strcat (buf, "/");
|
strcat (buf, "/");
|
||||||
strcat (buf, fname);
|
strcat (buf, fname);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_verify_result (GpgmeVerifyResult result, int summary, char *fpr,
|
||||||
|
GpgmeError status)
|
||||||
|
{
|
||||||
|
GpgmeSignature sig;
|
||||||
|
|
||||||
|
sig = result->signatures;
|
||||||
|
if (!sig || sig->next)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected number of signatures\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->summary != summary)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected signature summary: 0x%x\n",
|
||||||
|
__FILE__, __LINE__, sig->summary);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (sig->fpr, fpr))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\n",
|
||||||
|
__FILE__, __LINE__, sig->fpr);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->status != status)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected signature status: %s\n",
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (sig->status));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->notations)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected notation data\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->wrong_key_usage)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->validity != GPGME_VALIDITY_UNKNOWN)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected validity: %i\n",
|
||||||
|
__FILE__, __LINE__, sig->validity);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->validity_reason != GPGME_No_Error)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected validity reason: %s\n",
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (sig->validity_reason));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
GpgmeCtx ctx;
|
GpgmeCtx ctx;
|
||||||
GpgmeError err;
|
GpgmeError err;
|
||||||
GpgmeData in, out, pwdata = NULL;
|
GpgmeData in, out;
|
||||||
struct passphrase_cb_info_s info;
|
GpgmeDecryptResult decrypt_result;
|
||||||
const char *cipher_2_asc = mk_fname ("cipher-2.asc");
|
GpgmeVerifyResult verify_result;
|
||||||
GpgmeSigStat status;
|
const char *cipher_2_asc = make_filename ("cipher-2.asc");
|
||||||
char *p;
|
char *agent_info;
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
err = gpgme_new (&ctx);
|
err = gpgme_new (&ctx);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
p = getenv("GPG_AGENT_INFO");
|
agent_info = getenv("GPG_AGENT_INFO");
|
||||||
if (!(p && strchr (p, ':')))
|
if (!(agent_info && strchr (agent_info, ':')))
|
||||||
{
|
gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
|
||||||
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);
|
err = gpgme_data_new_from_file (&in, cipher_2_asc, 1);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
err = gpgme_data_new (&out);
|
err = gpgme_data_new (&out);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
err = gpgme_op_decrypt_verify (ctx, in, out);
|
err = gpgme_op_decrypt_verify (ctx, in, out);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
decrypt_result = gpgme_op_decrypt_result (ctx);
|
||||||
fflush (NULL);
|
if (decrypt_result->unsupported_algorithm)
|
||||||
fputs ("Begin Result:\n", stdout);
|
{
|
||||||
|
fprintf (stderr, "%s:%i: unsupported algorithm: %s\n",
|
||||||
|
__FILE__, __LINE__, decrypt_result->unsupported_algorithm);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
print_data (out);
|
print_data (out);
|
||||||
fputs ("End Result.\n", stdout);
|
verify_result = gpgme_op_verify_result (ctx);
|
||||||
|
check_verify_result (verify_result, 0,
|
||||||
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
|
"A0FF4590BB6122EDEF6E3C542D727CC768697734",
|
||||||
{
|
GPGME_No_Error);
|
||||||
fprintf (stderr, "Signature check failed unexpectedly.\n");
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
if (status != GPGME_SIG_STAT_GOOD)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Signature check failed unexpectedly.\n");
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
gpgme_data_release (in);
|
gpgme_data_release (in);
|
||||||
gpgme_data_release (out);
|
gpgme_data_release (out);
|
||||||
gpgme_data_release (pwdata);
|
|
||||||
gpgme_release (ctx);
|
gpgme_release (ctx);
|
||||||
}
|
|
||||||
while (argc > 1 && !strcmp (argv[1], "--loop"));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* t-verify.c - regression test
|
/* t-verify.c - Regression test.
|
||||||
Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
Copyright (C) 2001, 2002 g10 Code GmbH
|
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
|
||||||
|
|
||||||
This file is part of GPGME.
|
This file is part of GPGME.
|
||||||
|
|
||||||
@ -18,13 +18,26 @@
|
|||||||
along with GPGME; if not, write to the Free Software Foundation,
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <gpgme.h>
|
#include <gpgme.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define fail_if_err(err) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (err) \
|
||||||
|
{ \
|
||||||
|
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (err)); \
|
||||||
|
exit (1); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
|
||||||
static const char test_text1[] = "Just GNU it!\n";
|
static const char test_text1[] = "Just GNU it!\n";
|
||||||
static const char test_text1f[]= "Just GNU it?\n";
|
static const char test_text1f[]= "Just GNU it?\n";
|
||||||
static const char test_sig1[] =
|
static const char test_sig1[] =
|
||||||
@ -68,197 +81,113 @@ static const char test_sig2[] =
|
|||||||
"-----END PGP MESSAGE-----\n";
|
"-----END PGP MESSAGE-----\n";
|
||||||
|
|
||||||
|
|
||||||
#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 const char *
|
|
||||||
status_string (GpgmeSigStat status)
|
|
||||||
{
|
|
||||||
const char *s = "?";
|
|
||||||
|
|
||||||
switch ( status ) {
|
|
||||||
case GPGME_SIG_STAT_NONE:
|
|
||||||
s = "None";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_NOSIG:
|
|
||||||
s = "No Signature";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_GOOD:
|
|
||||||
s = "Good";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_GOOD_EXP:
|
|
||||||
s = "Good but expired";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_GOOD_EXPKEY:
|
|
||||||
s = "Good but key exipired";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_BAD:
|
|
||||||
s = "Bad";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_NOKEY:
|
|
||||||
s = "No Key";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_ERROR:
|
|
||||||
s = "Error";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_DIFF:
|
|
||||||
s = "More than one signature";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
validity_string (GpgmeValidity val)
|
|
||||||
{
|
|
||||||
const char *s = "?";
|
|
||||||
|
|
||||||
switch (val)
|
|
||||||
{
|
|
||||||
case GPGME_VALIDITY_UNKNOWN: s = "unknown"; break;
|
|
||||||
case GPGME_VALIDITY_NEVER: s = "not trusted"; break;
|
|
||||||
case GPGME_VALIDITY_MARGINAL:s = "marginal trusted"; break;
|
|
||||||
case GPGME_VALIDITY_FULL: s = "fully trusted"; break;
|
|
||||||
case GPGME_VALIDITY_UNDEFINED:
|
|
||||||
case GPGME_VALIDITY_ULTIMATE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_sig_stat (GpgmeCtx ctx, GpgmeSigStat status)
|
check_result (GpgmeVerifyResult result, int summary, char *fpr,
|
||||||
|
GpgmeError status, int notation)
|
||||||
{
|
{
|
||||||
const char *s;
|
GpgmeSignature sig;
|
||||||
time_t created;
|
|
||||||
int idx;
|
|
||||||
GpgmeKey key;
|
|
||||||
|
|
||||||
printf ("Verification Status: %s\n", status_string (status));
|
sig = result->signatures;
|
||||||
|
if (!sig || sig->next)
|
||||||
for (idx = 0; (s = gpgme_get_sig_status (ctx, idx, &status, &created)); idx++)
|
|
||||||
{
|
{
|
||||||
printf ("sig %d: created: %lu expires: %lu status: %s\n",
|
fprintf (stderr, "%s:%i: Unexpected number of signatures\n",
|
||||||
idx, (unsigned long) created,
|
__FILE__, __LINE__);
|
||||||
gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0),
|
exit (1);
|
||||||
status_string (status));
|
|
||||||
printf ("sig %d: fpr/keyid: `%s' validity: %s\n",
|
|
||||||
idx, s,
|
|
||||||
validity_string (gpgme_get_sig_ulong_attr
|
|
||||||
(ctx, idx, GPGME_ATTR_VALIDITY, 0)));
|
|
||||||
if (!gpgme_get_sig_key (ctx, idx, &key))
|
|
||||||
{
|
|
||||||
char *p = gpgme_key_get_as_xml (key);
|
|
||||||
printf ("sig %d: key object:\n%s\n", idx, p);
|
|
||||||
free (p);
|
|
||||||
gpgme_key_release (key);
|
|
||||||
}
|
}
|
||||||
|
if (sig->summary != summary)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected signature summary: 0x%x\n",
|
||||||
|
__FILE__, __LINE__, sig->summary);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (sig->fpr, fpr))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\n",
|
||||||
|
__FILE__, __LINE__, sig->fpr);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->status != status)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected signature status: %s\n",
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (sig->status));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (notation)
|
||||||
|
{
|
||||||
|
if (!sig->notations
|
||||||
|
|| strcmp (sig->notations->name, "bar")
|
||||||
|
|| strcmp (sig->notations->value, "\xc3\xb6\xc3\xa4\xc3\xbc\xc3\x9f"
|
||||||
|
" das waren Umlaute und jetzt ein prozent%-Zeichen")
|
||||||
|
|| !sig->notations->next
|
||||||
|
|| strcmp (sig->notations->next->name, "foobar.1")
|
||||||
|
|| strcmp (sig->notations->next->value,
|
||||||
|
"this is a notation data with 2 lines")
|
||||||
|
|| !sig->notations->next->next
|
||||||
|
|| sig->notations->next->next->name != NULL
|
||||||
|
|| strcmp (sig->notations->next->next->value,
|
||||||
|
"http://www.gu.org/policy/")
|
||||||
|
|| sig->notations->next->next->next)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected notation data\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sig->wrong_key_usage)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->validity != GPGME_VALIDITY_UNKNOWN)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected validity: %i\n",
|
||||||
|
__FILE__, __LINE__, sig->validity);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->validity_reason != GPGME_No_Error)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected validity reason: %s\n",
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (sig->validity_reason));
|
||||||
|
exit (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
GpgmeCtx ctx;
|
GpgmeCtx ctx;
|
||||||
GpgmeError err;
|
GpgmeError err;
|
||||||
GpgmeData sig, text;
|
GpgmeData sig, text;
|
||||||
GpgmeSigStat status;
|
|
||||||
GpgmeVerifyResult result;
|
GpgmeVerifyResult result;
|
||||||
GpgmeSigNotation notation;
|
|
||||||
char *nota;
|
|
||||||
int n = 0;
|
|
||||||
size_t len;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
err = gpgme_new (&ctx);
|
err = gpgme_new (&ctx);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
do
|
/* Checking a valid message. */
|
||||||
{
|
err = gpgme_data_new_from_mem (&text, test_text1, strlen (test_text1), 0);
|
||||||
err = gpgme_data_new_from_mem (&text,
|
|
||||||
test_text1, strlen (test_text1), 0);
|
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
#if 1
|
err = gpgme_data_new_from_mem (&sig, test_sig1, strlen (test_sig1), 0);
|
||||||
err = gpgme_data_new_from_mem (&sig,
|
|
||||||
test_sig1, strlen (test_sig1), 0);
|
|
||||||
#else
|
|
||||||
err = gpgme_data_new_from_file (&sig, "xx1", 1);
|
|
||||||
#endif
|
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
puts ("checking a valid message:\n");
|
|
||||||
err = gpgme_op_verify (ctx, sig, text, NULL);
|
err = gpgme_op_verify (ctx, sig, text, NULL);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
print_sig_stat (ctx, status);
|
|
||||||
if (status != GPGME_SIG_STAT_GOOD)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = gpgme_op_verify_result (ctx);
|
result = gpgme_op_verify_result (ctx);
|
||||||
notation = result->signatures->notations;
|
check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
|
||||||
if (notation)
|
GPGME_No_Error, 1);
|
||||||
{
|
|
||||||
printf ("---Begin Notation---\n");
|
|
||||||
while (notation)
|
|
||||||
{
|
|
||||||
if (notation->name)
|
|
||||||
printf ("%s: %s\n", notation->name, notation->value);
|
|
||||||
else
|
|
||||||
printf ("Policy URL: %s\n", notation->value);
|
|
||||||
notation = notation->next;
|
|
||||||
}
|
|
||||||
printf ("---End Notation---\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
puts ("checking a manipulated message:\n");
|
/* Checking a manipulated message. */
|
||||||
gpgme_data_release (text);
|
gpgme_data_release (text);
|
||||||
err = gpgme_data_new_from_mem (&text,
|
err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0);
|
||||||
test_text1f, strlen (test_text1f), 0);
|
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
gpgme_data_rewind (sig);
|
gpgme_data_rewind (sig);
|
||||||
err = gpgme_op_verify (ctx, sig, text, NULL);
|
err = gpgme_op_verify (ctx, sig, text, NULL);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
print_sig_stat (ctx, status);
|
|
||||||
if (status != GPGME_SIG_STAT_BAD)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
result = gpgme_op_verify_result (ctx);
|
result = gpgme_op_verify_result (ctx);
|
||||||
notation = result->signatures->notations;
|
check_result (result, GPGME_SIGSUM_RED, "2D727CC768697734",
|
||||||
if (notation)
|
GPGME_Bad_Signature, 0);
|
||||||
{
|
|
||||||
printf ("---Begin Notation---\n");
|
|
||||||
while (notation)
|
|
||||||
{
|
|
||||||
if (notation->name)
|
|
||||||
printf ("%s: %s\n", notation->name, notation->value);
|
|
||||||
else
|
|
||||||
printf ("Policy URL: %s\n", notation->value);
|
|
||||||
notation = notation->next;
|
|
||||||
}
|
|
||||||
printf ("---End Notation---\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
puts ("checking a normal signature:");
|
/* Checking a normal signature. */
|
||||||
gpgme_data_release (sig);
|
gpgme_data_release (sig);
|
||||||
gpgme_data_release (text);
|
gpgme_data_release (text);
|
||||||
err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0);
|
err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0);
|
||||||
@ -267,47 +196,12 @@ main (int argc, char *argv[])
|
|||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
err = gpgme_op_verify (ctx, sig, NULL, text);
|
err = gpgme_op_verify (ctx, sig, NULL, text);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
nota = gpgme_data_release_and_get_mem (text, &len);
|
|
||||||
for (j = 0; j < len; j++)
|
|
||||||
putchar (nota[j]);
|
|
||||||
if (strncmp (nota, test_text1, strlen (test_text1)))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: Wrong plaintext\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_sig_stat (ctx, status);
|
|
||||||
if (status != GPGME_SIG_STAT_GOOD)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
result = gpgme_op_verify_result (ctx);
|
result = gpgme_op_verify_result (ctx);
|
||||||
notation = result->signatures->notations;
|
check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
|
||||||
if (notation)
|
GPGME_No_Error, 0);
|
||||||
{
|
|
||||||
printf ("---Begin Notation---\n");
|
|
||||||
while (notation)
|
|
||||||
{
|
|
||||||
if (notation->name)
|
|
||||||
printf ("%s: %s\n", notation->name, notation->value);
|
|
||||||
else
|
|
||||||
printf ("Policy URL: %s\n", notation->value);
|
|
||||||
notation = notation->next;
|
|
||||||
}
|
|
||||||
printf ("---End Notation---\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
gpgme_data_release (sig);
|
gpgme_data_release (sig);
|
||||||
}
|
gpgme_data_release (text);
|
||||||
while (argc > 1 && !strcmp (argv[1], "--loop") && ++n < 20);
|
|
||||||
|
|
||||||
gpgme_release (ctx);
|
gpgme_release (ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* t-verify.c - regression test
|
/* t-verify.c - Regression test.
|
||||||
Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
Copyright (C) 2001, 2002 g10 Code GmbH
|
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
|
||||||
|
|
||||||
This file is part of GPGME.
|
This file is part of GPGME.
|
||||||
|
|
||||||
@ -18,13 +18,26 @@
|
|||||||
along with GPGME; if not, write to the Free Software Foundation,
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <gpgme.h>
|
#include <gpgme.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define fail_if_err(err) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (err) \
|
||||||
|
{ \
|
||||||
|
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (err)); \
|
||||||
|
exit (1); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
|
||||||
static const char test_text1[] = "Hallo Leute!\n";
|
static const char test_text1[] = "Hallo Leute!\n";
|
||||||
static const char test_text1f[]= "Hallo Leute?\n";
|
static const char test_text1f[]= "Hallo Leute?\n";
|
||||||
static const char test_sig1[] =
|
static const char test_sig1[] =
|
||||||
@ -39,216 +52,102 @@ static const char test_sig1[] =
|
|||||||
"MYdRclgjObCcoilA8fZ13VR4DiMJVFCxJL4qVWI=\n"
|
"MYdRclgjObCcoilA8fZ13VR4DiMJVFCxJL4qVWI=\n"
|
||||||
"-----END CMS OBJECT-----\n";
|
"-----END CMS OBJECT-----\n";
|
||||||
|
|
||||||
#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 const char *
|
|
||||||
status_string (GpgmeSigStat status)
|
|
||||||
{
|
|
||||||
const char *s = "?";
|
|
||||||
|
|
||||||
switch ( status ) {
|
|
||||||
case GPGME_SIG_STAT_NONE:
|
|
||||||
s = "None";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_NOSIG:
|
|
||||||
s = "No Signature";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_GOOD:
|
|
||||||
s = "Good";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_GOOD_EXP:
|
|
||||||
s = "Good but expired";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_GOOD_EXPKEY:
|
|
||||||
s = "Good but key exipired";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_BAD:
|
|
||||||
s = "Bad";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_NOKEY:
|
|
||||||
s = "No Key";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_ERROR:
|
|
||||||
s = "Error";
|
|
||||||
break;
|
|
||||||
case GPGME_SIG_STAT_DIFF:
|
|
||||||
s = "More than one signature";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
validity_string (GpgmeValidity val)
|
|
||||||
{
|
|
||||||
const char *s = "?";
|
|
||||||
|
|
||||||
switch (val)
|
|
||||||
{
|
|
||||||
case GPGME_VALIDITY_UNKNOWN: s = "unknown"; break;
|
|
||||||
case GPGME_VALIDITY_NEVER: s = "not trusted"; break;
|
|
||||||
case GPGME_VALIDITY_MARGINAL:s = "marginal trusted"; break;
|
|
||||||
case GPGME_VALIDITY_FULL: s = "fully trusted"; break;
|
|
||||||
case GPGME_VALIDITY_UNDEFINED:
|
|
||||||
case GPGME_VALIDITY_ULTIMATE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_sig_stat ( GpgmeCtx ctx, GpgmeSigStat status )
|
check_result (GpgmeVerifyResult result, int summary, char *fpr,
|
||||||
|
GpgmeError status, GpgmeValidity validity)
|
||||||
{
|
{
|
||||||
const char *s;
|
GpgmeSignature sig;
|
||||||
time_t created;
|
|
||||||
int idx;
|
|
||||||
GpgmeKey key;
|
|
||||||
|
|
||||||
printf ("Verification Status: %s\n", status_string (status));
|
sig = result->signatures;
|
||||||
|
if (!sig || sig->next)
|
||||||
for (idx=0; (s=gpgme_get_sig_status (ctx, idx, &status, &created)); idx++ )
|
|
||||||
{
|
{
|
||||||
unsigned long sum;
|
fprintf (stderr, "%s:%i: Unexpected number of signatures\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
printf ("sig %d: created: %lu expires: %lu status: %s\n",
|
exit (1);
|
||||||
idx, (unsigned long)created,
|
|
||||||
gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0),
|
|
||||||
status_string(status) );
|
|
||||||
printf ("sig %d: fpr/keyid: `%s' exterr: `%s' validity: %s\n",
|
|
||||||
idx, s,
|
|
||||||
gpgme_get_sig_string_attr (ctx, idx, GPGME_ATTR_ERRTOK, 0),
|
|
||||||
validity_string (gpgme_get_sig_ulong_attr
|
|
||||||
(ctx, idx, GPGME_ATTR_VALIDITY, 0)) );
|
|
||||||
|
|
||||||
sum = gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_SIG_SUMMARY, 0);
|
|
||||||
fputs ("summary:", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_VALID))
|
|
||||||
fputs (" valid", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_GREEN))
|
|
||||||
fputs (" green", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_RED))
|
|
||||||
fputs (" red", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_KEY_REVOKED))
|
|
||||||
fputs (" keyRevoked", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_KEY_EXPIRED))
|
|
||||||
fputs (" keyExpired", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_SIG_EXPIRED))
|
|
||||||
fputs (" sigExpired", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_KEY_MISSING))
|
|
||||||
fputs (" keyMissing", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_CRL_MISSING))
|
|
||||||
fputs (" crlMissing", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_CRL_TOO_OLD))
|
|
||||||
fputs (" crlTooOld", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_BAD_POLICY))
|
|
||||||
fputs (" badPolicy", stdout);
|
|
||||||
if ((sum & GPGME_SIGSUM_SYS_ERROR))
|
|
||||||
fputs (" sysError", stdout);
|
|
||||||
putchar ('\n');
|
|
||||||
|
|
||||||
if ( !gpgme_get_sig_key (ctx, idx, &key) )
|
|
||||||
{
|
|
||||||
char *p = gpgme_key_get_as_xml ( key );
|
|
||||||
printf ("sig %d: key object:\n%s\n", idx, p );
|
|
||||||
free (p);
|
|
||||||
gpgme_key_release (key);
|
|
||||||
}
|
}
|
||||||
|
if (sig->summary != summary)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected signature summary: 0x%x\n",
|
||||||
|
__FILE__, __LINE__, sig->summary);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (sig->fpr, fpr))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\n",
|
||||||
|
__FILE__, __LINE__, sig->fpr);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->status != status)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected signature status: %s\n",
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (sig->status));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->notations)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected notation data\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->wrong_key_usage)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->validity != validity)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected validity: %i\n",
|
||||||
|
__FILE__, __LINE__, sig->validity);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (sig->validity_reason != GPGME_No_Error)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s:%i: Unexpected validity reason: %s\n",
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (sig->validity_reason));
|
||||||
|
exit (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv )
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
GpgmeCtx ctx;
|
GpgmeCtx ctx;
|
||||||
GpgmeError err;
|
GpgmeError err;
|
||||||
GpgmeData sig, text;
|
GpgmeData sig, text;
|
||||||
GpgmeSigStat status;
|
|
||||||
GpgmeVerifyResult result;
|
GpgmeVerifyResult result;
|
||||||
GpgmeSigNotation notation;
|
|
||||||
char *nota;
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
err = gpgme_new (&ctx);
|
err = gpgme_new (&ctx);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
|
gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
|
||||||
|
|
||||||
do {
|
/* Checking a valid message. */
|
||||||
err = gpgme_data_new_from_mem ( &text,
|
err = gpgme_data_new_from_mem (&text, test_text1, strlen (test_text1), 0);
|
||||||
test_text1, strlen (test_text1), 0 );
|
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
err = gpgme_data_new_from_mem ( &sig,
|
err = gpgme_data_new_from_mem (&sig, test_sig1, strlen (test_sig1), 0);
|
||||||
test_sig1, strlen (test_sig1), 0 );
|
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
puts ("checking a valid message:\n");
|
|
||||||
err = gpgme_op_verify (ctx, sig, text, NULL);
|
err = gpgme_op_verify (ctx, sig, text, NULL);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
print_sig_stat (ctx, status);
|
|
||||||
|
|
||||||
result = gpgme_op_verify_result (ctx);
|
result = gpgme_op_verify_result (ctx);
|
||||||
notation = result->signatures->notations;
|
check_result (result, GPGME_SIGSUM_VALID | GPGME_SIGSUM_GREEN,
|
||||||
if (notation)
|
"3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E",
|
||||||
{
|
GPGME_No_Error, GPGME_VALIDITY_FULL);
|
||||||
printf ("---Begin Notation---\n");
|
|
||||||
while (notation)
|
|
||||||
{
|
|
||||||
if (notation->name)
|
|
||||||
printf ("%s: %s\n", notation->name, notation->value);
|
|
||||||
else
|
|
||||||
printf ("Policy URL: %s\n", notation->value);
|
|
||||||
notation = notation->next;
|
|
||||||
}
|
|
||||||
printf ("---End Notation---\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
puts ("checking a manipulated message:\n");
|
/* Checking a manipulated message. */
|
||||||
gpgme_data_release (text);
|
gpgme_data_release (text);
|
||||||
err = gpgme_data_new_from_mem ( &text,
|
err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0);
|
||||||
test_text1f, strlen (test_text1f), 0);
|
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
gpgme_data_rewind ( sig );
|
gpgme_data_rewind (sig);
|
||||||
err = gpgme_op_verify (ctx, sig, text, NULL);
|
err = gpgme_op_verify (ctx, sig, text, NULL);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
print_sig_stat (ctx, status);
|
|
||||||
|
|
||||||
result = gpgme_op_verify_result (ctx);
|
result = gpgme_op_verify_result (ctx);
|
||||||
notation = result->signatures->notations;
|
check_result (result, GPGME_SIGSUM_RED,
|
||||||
if (notation)
|
"3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E",
|
||||||
{
|
GPGME_Bad_Signature, GPGME_VALIDITY_UNKNOWN);
|
||||||
printf ("---Begin Notation---\n");
|
|
||||||
while (notation)
|
|
||||||
{
|
|
||||||
if (notation->name)
|
|
||||||
printf ("%s: %s\n", notation->name, notation->value);
|
|
||||||
else
|
|
||||||
printf ("Policy URL: %s\n", notation->value);
|
|
||||||
notation = notation->next;
|
|
||||||
}
|
|
||||||
printf ("---End Notation---\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
gpgme_data_release (sig);
|
|
||||||
gpgme_data_release (text);
|
|
||||||
|
|
||||||
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) && ++n < 20 );
|
|
||||||
gpgme_release (ctx);
|
gpgme_release (ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user