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:
Marcus Brinkmann 2003-04-29 20:51:25 +00:00
parent 85425c74ad
commit 26ec59fdbd
4 changed files with 342 additions and 501 deletions

View File

@ -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.

View File

@ -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) \
{ \
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
#define fail_if_err(a) do { if(a) { int my_errno = errno; \ __FILE__, __LINE__, gpgme_strerror (err)); \
fprintf (stderr, "%s:%d: GpgmeError %s\n", \ exit (1); \
__FILE__, __LINE__, gpgme_strerror(a)); \ } \
if ((a) == GPGME_File_Error) \ } \
fprintf (stderr, "\terrno=`%s'\n", strerror (my_errno)); \ while (0)
exit (1); } \
} 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);
fail_if_err (err);
agent_info = getenv("GPG_AGENT_INFO");
if (!(agent_info && strchr (agent_info, ':')))
gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
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);
fail_if_err (err);
decrypt_result = gpgme_op_decrypt_result (ctx);
if (decrypt_result->unsupported_algorithm)
{ {
err = gpgme_new (&ctx); fprintf (stderr, "%s:%i: unsupported algorithm: %s\n",
fail_if_err (err); __FILE__, __LINE__, decrypt_result->unsupported_algorithm);
exit (1);
p = getenv("GPG_AGENT_INFO");
if (!(p && strchr (p, ':')))
{
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);
fail_if_err (err);
fflush (NULL);
fputs ("Begin Result:\n", stdout);
print_data (out);
fputs ("End Result.\n", stdout);
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
{
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 (out);
gpgme_data_release (pwdata);
gpgme_release (ctx);
} }
while (argc > 1 && !strcmp (argv[1], "--loop")); print_data (out);
verify_result = gpgme_op_verify_result (ctx);
check_verify_result (verify_result, 0,
"A0FF4590BB6122EDEF6E3C542D727CC768697734",
GPGME_No_Error);
gpgme_data_release (in);
gpgme_data_release (out);
gpgme_release (ctx);
return 0; return 0;
} }

View File

@ -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,246 +81,127 @@ 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", if (sig->summary != summary)
idx, s, {
validity_string (gpgme_get_sig_ulong_attr fprintf (stderr, "%s:%i: Unexpected signature summary: 0x%x\n",
(ctx, idx, GPGME_ATTR_VALIDITY, 0))); __FILE__, __LINE__, sig->summary);
if (!gpgme_get_sig_key (ctx, idx, &key)) 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)
{ {
char *p = gpgme_key_get_as_xml (key); fprintf (stderr, "%s:%i: Unexpected notation data\n",
printf ("sig %d: key object:\n%s\n", idx, p); __FILE__, __LINE__);
free (p); exit (1);
gpgme_key_release (key); }
} }
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, fail_if_err (err);
test_text1, strlen (test_text1), 0); err = gpgme_data_new_from_mem (&sig, test_sig1, strlen (test_sig1), 0);
fail_if_err (err); fail_if_err (err);
#if 1 err = gpgme_op_verify (ctx, sig, text, NULL);
err = gpgme_data_new_from_mem (&sig, fail_if_err (err);
test_sig1, strlen (test_sig1), 0); result = gpgme_op_verify_result (ctx);
#else check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
err = gpgme_data_new_from_file (&sig, "xx1", 1); GPGME_No_Error, 1);
#endif
fail_if_err (err);
puts ("checking a valid message:\n"); /* Checking a manipulated message. */
err = gpgme_op_verify (ctx, sig, text, NULL); gpgme_data_release (text);
fail_if_err (err); err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0);
if (!gpgme_get_sig_status (ctx, 0, &status, NULL)) fail_if_err (err);
{ gpgme_data_rewind (sig);
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__); err = gpgme_op_verify (ctx, sig, text, NULL);
exit (1); fail_if_err (err);
} result = gpgme_op_verify_result (ctx);
print_sig_stat (ctx, status); check_result (result, GPGME_SIGSUM_RED, "2D727CC768697734",
if (status != GPGME_SIG_STAT_GOOD) GPGME_Bad_Signature, 0);
{
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
exit (1);
}
result = gpgme_op_verify_result (ctx); /* Checking a normal signature. */
notation = result->signatures->notations; gpgme_data_release (sig);
if (notation) gpgme_data_release (text);
{ err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0);
printf ("---Begin Notation---\n"); fail_if_err (err);
while (notation) err = gpgme_data_new (&text);
{ fail_if_err (err);
if (notation->name) err = gpgme_op_verify (ctx, sig, NULL, text);
printf ("%s: %s\n", notation->name, notation->value); fail_if_err (err);
else result = gpgme_op_verify_result (ctx);
printf ("Policy URL: %s\n", notation->value); check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
notation = notation->next; GPGME_No_Error, 0);
}
printf ("---End Notation---\n");
}
puts ("checking a manipulated message:\n");
gpgme_data_release (text);
err = gpgme_data_new_from_mem (&text,
test_text1f, strlen (test_text1f), 0);
fail_if_err (err);
gpgme_data_rewind (sig);
err = gpgme_op_verify (ctx, sig, text, NULL);
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);
notation = result->signatures->notations;
if (notation)
{
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:");
gpgme_data_release (sig);
gpgme_data_release (text);
err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0);
fail_if_err (err);
err = gpgme_data_new (&text);
fail_if_err (err);
err = gpgme_op_verify (ctx, sig, NULL, text);
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);
notation = result->signatures->notations;
if (notation)
{
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);
}
while (argc > 1 && !strcmp (argv[1], "--loop") && ++n < 20);
gpgme_data_release (sig);
gpgme_data_release (text);
gpgme_release (ctx); gpgme_release (ctx);
return 0; return 0;
} }

View File

@ -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,217 +52,103 @@ 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), if (sig->summary != summary)
status_string(status) ); {
printf ("sig %d: fpr/keyid: `%s' exterr: `%s' validity: %s\n", fprintf (stderr, "%s:%i: Unexpected signature summary: 0x%x\n",
idx, s, __FILE__, __LINE__, sig->summary);
gpgme_get_sig_string_attr (ctx, idx, GPGME_ATTR_ERRTOK, 0), exit (1);
validity_string (gpgme_get_sig_ulong_attr }
(ctx, idx, GPGME_ATTR_VALIDITY, 0)) ); if (strcmp (sig->fpr, fpr))
{
sum = gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_SIG_SUMMARY, 0); fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\n",
fputs ("summary:", stdout); __FILE__, __LINE__, sig->fpr);
if ((sum & GPGME_SIGSUM_VALID)) exit (1);
fputs (" valid", stdout); }
if ((sum & GPGME_SIGSUM_GREEN)) if (sig->status != status)
fputs (" green", stdout); {
if ((sum & GPGME_SIGSUM_RED)) fprintf (stderr, "%s:%i: Unexpected signature status: %s\n",
fputs (" red", stdout); __FILE__, __LINE__, gpgme_strerror (sig->status));
if ((sum & GPGME_SIGSUM_KEY_REVOKED)) exit (1);
fputs (" keyRevoked", stdout); }
if ((sum & GPGME_SIGSUM_KEY_EXPIRED)) if (sig->notations)
fputs (" keyExpired", stdout); {
if ((sum & GPGME_SIGSUM_SIG_EXPIRED)) fprintf (stderr, "%s:%i: Unexpected notation data\n",
fputs (" sigExpired", stdout); __FILE__, __LINE__);
if ((sum & GPGME_SIGSUM_KEY_MISSING)) exit (1);
fputs (" keyMissing", stdout); }
if ((sum & GPGME_SIGSUM_CRL_MISSING)) if (sig->wrong_key_usage)
fputs (" crlMissing", stdout); {
if ((sum & GPGME_SIGSUM_CRL_TOO_OLD)) fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\n",
fputs (" crlTooOld", stdout); __FILE__, __LINE__);
if ((sum & GPGME_SIGSUM_BAD_POLICY)) exit (1);
fputs (" badPolicy", stdout); }
if ((sum & GPGME_SIGSUM_SYS_ERROR)) if (sig->validity != validity)
fputs (" sysError", stdout); {
putchar ('\n'); fprintf (stderr, "%s:%i: Unexpected validity: %i\n",
__FILE__, __LINE__, sig->validity);
if ( !gpgme_get_sig_key (ctx, idx, &key) ) exit (1);
{ }
char *p = gpgme_key_get_as_xml ( key ); if (sig->validity_reason != GPGME_No_Error)
printf ("sig %d: key object:\n%s\n", idx, p ); {
free (p); fprintf (stderr, "%s:%i: Unexpected validity reason: %s\n",
gpgme_key_release (key); __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, test_sig1, strlen (test_sig1), 0);
err = gpgme_data_new_from_mem ( &sig, fail_if_err (err);
test_sig1, strlen (test_sig1), 0 ); err = gpgme_op_verify (ctx, sig, text, NULL);
fail_if_err (err); fail_if_err (err);
result = gpgme_op_verify_result (ctx);
check_result (result, GPGME_SIGSUM_VALID | GPGME_SIGSUM_GREEN,
"3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E",
GPGME_No_Error, GPGME_VALIDITY_FULL);
puts ("checking a valid message:\n"); /* Checking a manipulated message. */
err = gpgme_op_verify (ctx, sig, text, NULL); gpgme_data_release (text);
fail_if_err (err); err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0);
if (!gpgme_get_sig_status (ctx, 0, &status, NULL)) fail_if_err (err);
{ gpgme_data_rewind (sig);
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__); err = gpgme_op_verify (ctx, sig, text, NULL);
exit (1); fail_if_err (err);
} result = gpgme_op_verify_result (ctx);
print_sig_stat (ctx, status); check_result (result, GPGME_SIGSUM_RED,
"3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E",
GPGME_Bad_Signature, GPGME_VALIDITY_UNKNOWN);
result = gpgme_op_verify_result (ctx); gpgme_release (ctx);
notation = result->signatures->notations; return 0;
if (notation)
{
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");
gpgme_data_release (text);
err = gpgme_data_new_from_mem ( &text,
test_text1f, strlen (test_text1f), 0);
fail_if_err (err);
gpgme_data_rewind ( sig );
err = gpgme_op_verify (ctx, sig, text, NULL);
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);
notation = result->signatures->notations;
if (notation)
{
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);
return 0;
} }