From 529b82f63861ed82630ab5253ee892c2c32d944d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 15 Nov 2000 21:36:48 +0000 Subject: [PATCH] Notation stuff added --- gpgme/context.h | 2 + gpgme/data.c | 164 +++++++++++++++++++++++++++++++++++++++++++++- gpgme/gpgme.c | 13 ++++ gpgme/gpgme.h | 20 +++++- gpgme/key.c | 152 ++++++++++++++++++++++++++++++++++++++++++ gpgme/keylist.c | 10 +-- gpgme/ops.h | 11 ++++ gpgme/rungpg.h | 5 +- gpgme/verify.c | 117 +++++++++++++++++++++++---------- tests/t-keylist.c | 9 ++- tests/t-verify.c | 60 ++++++++++++++++- 11 files changed, 512 insertions(+), 51 deletions(-) diff --git a/gpgme/context.h b/gpgme/context.h index 417c3c1..c0eec45 100644 --- a/gpgme/context.h +++ b/gpgme/context.h @@ -60,6 +60,8 @@ struct gpgme_context_s { VerifyResult verify; } result; + GpgmeData notation; /* last signature notation */ + GpgmeKey tmp_key; /* used by keylist.c */ volatile int key_cond; /* something new is available */ struct key_queue_item_s *key_queue; diff --git a/gpgme/data.c b/gpgme/data.c index 4bf1ed6..de9c632 100644 --- a/gpgme/data.c +++ b/gpgme/data.c @@ -25,9 +25,14 @@ #include "util.h" #include "context.h" - +#include "ops.h" #define ALLOC_CHUNK 1024 +#define my_isdigit(a) ( (a) >='0' && (a) <= '9' ) +#define my_isxdigit(a) ( my_isdigit((a)) \ + || ((a) >= 'A' && (a) <= 'F') \ + || ((a) >= 'f' && (a) <= 'f') ) + /** @@ -93,6 +98,27 @@ gpgme_data_release ( GpgmeData dh ) } } +char * +_gpgme_data_release_and_return_string ( GpgmeData dh ) +{ + char *val = NULL; + + if (dh) { + if ( _gpgme_data_append ( dh, "", 0 ) ) /* append EOS */ + xfree (dh->private_buffer ); + else { + val = dh->private_buffer; + if ( !val && dh->data ) { + val = xtrymalloc ( dh->len ); + if ( val ) + memcpy ( val, dh->data, dh->len ); + } + } + xfree (dh); + } + return val; +} + GpgmeDataType gpgme_data_get_type ( GpgmeData dh ) @@ -149,6 +175,25 @@ gpgme_data_read ( GpgmeData dh, char *buffer, size_t length, size_t *nread ) return 0; } +/* + * This function does make sense when we know that it contains no nil chars. + */ +char * +_gpgme_data_get_as_string ( GpgmeData dh ) +{ + char *val = NULL; + + if (dh) { + val = xtrymalloc ( dh->len+1 ); + if ( val ) { + memcpy ( val, dh->data, dh->len ); + val[dh->len] = 0; + } + } + return val; +} + + GpgmeError _gpgme_data_append ( GpgmeData dh, const char *buffer, size_t length ) @@ -186,7 +231,8 @@ _gpgme_data_append ( GpgmeData dh, const char *buffer, size_t length ) dh->private_len = 0; return mk_error (Out_Of_Core); } - dh->writepos = 0; + memcpy ( dh->private_buffer, dh->data, dh->len ); + dh->writepos = dh->len; dh->data = dh->private_buffer; } @@ -211,5 +257,119 @@ _gpgme_data_append ( GpgmeData dh, const char *buffer, size_t length ) return 0; } +GpgmeError +_gpgme_data_append_string ( GpgmeData dh, const char *s ) +{ + return _gpgme_data_append ( dh, s, s? strlen(s):0 ); +} + + +GpgmeError +_gpgme_data_append_for_xml ( GpgmeData dh, + const char *buffer, size_t len ) +{ + const char *text, *s; + size_t n; + int rc = 0; + + if ( !dh || !buffer ) + return mk_error (Invalid_Value); + + do { + for (text=NULL, s=buffer, n=len; n && !text; s++, n-- ) { + if ( *s == '<' ) + text = "<"; + else if ( *s == '>' ) + text = ">"; /* not sure whether this is really needed */ + else if ( *s == '&' ) + text = "&"; + else if ( !*s ) + text = "�"; + } + if (text) { + s--; n++; + } + if (s != buffer) + rc = _gpgme_data_append ( dh, buffer, s-buffer ); + if ( !rc && text) { + rc = _gpgme_data_append_string ( dh, text ); + s++; n--; + } + buffer = s; + len = n; + } while ( !rc && len ); + return rc; +} + + +/* + * Append a string to DATA and convert it so that the result will be + * valid XML. + */ +GpgmeError +_gpgme_data_append_string_for_xml ( GpgmeData dh, const char *string ) +{ + return _gpgme_data_append_for_xml ( dh, string, strlen (string) ); +} + + +static int +hextobyte( const byte *s ) +{ + int c; + + if( *s >= '0' && *s <= '9' ) + c = 16 * (*s - '0'); + else if( *s >= 'A' && *s <= 'F' ) + c = 16 * (10 + *s - 'A'); + else if( *s >= 'a' && *s <= 'f' ) + c = 16 * (10 + *s - 'a'); + else + return -1; + s++; + if( *s >= '0' && *s <= '9' ) + c += *s - '0'; + else if( *s >= 'A' && *s <= 'F' ) + c += 10 + *s - 'A'; + else if( *s >= 'a' && *s <= 'f' ) + c += 10 + *s - 'a'; + else + return -1; + return c; +} + + + + +/* + * Append a string with percent style (%XX) escape characters as XML + */ +GpgmeError +_gpgme_data_append_percentstring_for_xml ( GpgmeData dh, const char *string ) +{ + const byte *s; + byte *buf, *d; + int val; + GpgmeError err; + + d = buf = xtrymalloc ( strlen (string) ); + for (s=string; *s; s++ ) { + if ( *s == '%' && (val=hextobyte (s+1)) != -1 ) { + *d++ = val; + s += 2; + } + else + *d++ = *s; + } + + err = _gpgme_data_append_for_xml ( dh, buf, d - buf ); + xfree (buf); + return err; +} + + + + + diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index 6c9a52f..4c1daa3 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -26,6 +26,11 @@ #include "context.h" #include "ops.h" +#define my_isdigit(a) ( (a) >='0' && (a) <= '9' ) +#define my_isxdigit(a) ( my_isdigit((a)) \ + || ((a) >= 'A' && (a) <= 'F') \ + || ((a) >= 'f' && (a) <= 'f') ) + /** * gpgme_new: * @r_ctx: Returns the new context @@ -62,6 +67,7 @@ gpgme_release ( GpgmeCtx c ) _gpgme_gpg_release ( c->gpg ); _gpgme_release_result ( c ); _gpgme_key_release ( c->tmp_key ); + gpgme_data_release ( c->notation ); /* fixme: release the key_queue */ xfree ( c ); } @@ -83,6 +89,13 @@ _gpgme_release_result ( GpgmeCtx c ) } +char * +gpgme_op_get_notation ( GpgmeCtx c ) +{ + if ( !c->notation ) + return NULL; + return _gpgme_data_get_as_string ( c->notation ); +} diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 5bd0d91..2464282 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -68,12 +68,25 @@ typedef enum { GPGME_DATA_TYPE_FILE = 3 } GpgmeDataType; +typedef enum { + GPGME_SIG_STAT_NONE = 0, + GPGME_SIG_STAT_GOOD = 1, + GPGME_SIG_STAT_BAD = 2, + GPGME_SIG_STAT_NOKEY = 3, + GPGME_SIG_STAT_NOSIG = 4, + GPGME_SIG_STAT_ERROR = 5 +} GpgmeSigStat; + + /* Context management */ GpgmeError gpgme_new (GpgmeCtx *r_ctx); void gpgme_release ( GpgmeCtx c ); GpgmeCtx gpgme_wait ( GpgmeCtx c, int hang ); +char *gpgme_op_get_notation ( GpgmeCtx c ); + + /* Functions to handle recipients */ GpgmeError gpgme_recipients_new (GpgmeRecipients *r_rset); void gpgme_recipients_release ( GpgmeRecipients rset); @@ -90,6 +103,8 @@ GpgmeError gpgme_data_rewind ( GpgmeData dh ); GpgmeError gpgme_data_read ( GpgmeData dh, char *buffer, size_t length, size_t *nread ); +/* Key functions */ +char *gpgme_key_get_as_xml ( GpgmeKey key ); /* Basic GnuPG functions */ @@ -105,10 +120,11 @@ GpgmeError gpgme_op_keylist_start ( GpgmeCtx c, GpgmeError gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key ); -/* Convenience functions for syncronous usage */ +/* Convenience functions for normal usage */ GpgmeError gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp, GpgmeData in, GpgmeData out ); -GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text ); +GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text, + GpgmeSigStat *r_status ); /* miscellaneous functions */ diff --git a/gpgme/key.c b/gpgme/key.c index 92bb597..2f3971c 100644 --- a/gpgme/key.c +++ b/gpgme/key.c @@ -132,4 +132,156 @@ _gpgme_key_append_name ( GpgmeKey key, const char *s ) } +static void +add_otag ( GpgmeData d, const char *tag ) +{ + _gpgme_data_append_string ( d, " <" ); + _gpgme_data_append_string ( d, tag ); + _gpgme_data_append_string ( d, ">" ); +} + +static void +add_ctag ( GpgmeData d, const char *tag ) +{ + _gpgme_data_append_string ( d, "\n" ); +} + +static void +add_tag_and_string ( GpgmeData d, const char *tag, const char *string ) +{ + add_otag (d, tag); + _gpgme_data_append_string_for_xml ( d, string ); + add_ctag (d, tag); +} + +static void +add_user_id_name ( GpgmeData d, const char *buf, size_t len ) +{ + while ( len && (buf[len-1] == ' ' || buf[len-1] == '\t') ) + len--; + if (len) { + add_otag (d, "name" ); + _gpgme_data_append_for_xml ( d, buf, len ); + add_ctag (d, "name"); + } +} + + +static void +add_user_id ( GpgmeData d, const char *string ) +{ + const char *s, *start=NULL; + int in_name = 0; + int in_email = 0; + int in_comment = 0; + + for (s=string; *s; s++ ) { + if ( in_email ) { + if ( *s == '<' ) + in_email++; /* not legal but anyway */ + else if (*s== '>') { + if ( !--in_email ) { + _gpgme_data_append_for_xml ( d, start, s-start ); + add_ctag (d, "email"); + } + } + } + else if ( in_comment ) { + if ( *s == '(' ) + in_comment++; + else if (*s== ')') { + if ( !--in_comment ) { + _gpgme_data_append_for_xml ( d, start, s-start ); + add_ctag (d, "comment"); + } + } + } + else if ( *s == '<' ) { + if ( in_name ) { + add_user_id_name (d, start, s-start ); + in_name = 0; + } + in_email = 1; + add_otag ( d, "email" ); + start = s+1; + } + else if ( *s == '(' ) { + if ( in_name ) { + add_user_id_name (d, start, s-start ); + in_name = 0; + } + in_comment = 1; + add_otag ( d, "comment" ); + start = s+1; + } + else if ( !in_name && *s != ' ' && *s != '\t' ) { + in_name = 1; + start = s; + } + } + + if ( in_name ) + add_user_id_name (d, start, s-start ); +} + +static void +add_tag_and_uint ( GpgmeData d, const char *tag, unsigned int val ) +{ + char buf[30]; + sprintf (buf, "%u", val ); + add_tag_and_string ( d, tag, buf ); +} + +static void +add_tag_and_time ( GpgmeData d, const char *tag, time_t val ) +{ + char buf[30]; + + if (!val || val == (time_t)-1 ) + return; + sprintf (buf, "%lu", (unsigned long)val ); + add_tag_and_string ( d, tag, buf ); +} + +char * +gpgme_key_get_as_xml ( GpgmeKey key ) +{ + GpgmeData d; + struct user_id_s *u; + + if ( !key ) + return NULL; + + if ( gpgme_data_new ( &d, NULL, 0, 0 ) ) + return NULL; + + _gpgme_data_append_string ( d, "\n" + " \n" ); + add_tag_and_string (d, "keyid", key->keyid ); + if (key) + add_tag_and_string (d, "fpr", key->fingerprint ); + add_tag_and_uint (d, "algo", key->key_algo ); + add_tag_and_uint (d, "len", key->key_len ); + add_tag_and_time (d, "created", key->timestamp ); + /*add_tag_and_time (d, "expires", key->expires );*/ + _gpgme_data_append_string (d, " \n"); + + /* No the user IDs */ + for ( u = key->uids; u; u = u->next ) { + _gpgme_data_append_string (d, " \n"); + add_tag_and_string ( d, "raw", u->name ); + add_user_id ( d, u->name ); + _gpgme_data_append_string (d, " \n"); + } + _gpgme_data_append_string (d, " \n"); + _gpgme_data_append_string (d, " \n"); + + _gpgme_data_append_string ( d, "\n" ); + + return _gpgme_data_release_and_return_string (d); +} + + diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 315469b..cbd7cb4 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -127,6 +127,8 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line ) if (!line) return; /* EOF */ + /*fprintf (stderr, "line=`%s'\n", line );*/ + for (p = line; p; p = pend) { field++; pend = strchr (p, ':'); @@ -251,18 +253,11 @@ static void finish_key ( GpgmeCtx ctx ) { GpgmeKey key = ctx->tmp_key; - struct user_id_s *u; struct key_queue_item_s *q, *q2; assert (key); ctx->tmp_key = NULL; - fprintf (stdout, "finish_key: keyid=`%s'\n", key->keyid ); - if ( key->fingerprint ) - fprintf (stdout, "finish_key: fpr=`%s'\n", key->fingerprint ); - for (u=key->uids; u; u = u->next ) - fprintf (stdout, "finish_key: uid=`%s'\n", u->name ); - q = xtrymalloc ( sizeof *q ); if ( !q ) { _gpgme_key_release (key); @@ -322,6 +317,7 @@ gpgme_op_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only ) _gpgme_gpg_add_arg ( c->gpg, "--verbose" ); _gpgme_gpg_add_arg ( c->gpg, "--with-colons" ); _gpgme_gpg_add_arg ( c->gpg, "--with-fingerprint" ); + /*_gpgme_gpg_add_arg ( c->gpg, "--fast-list-mode" );*/ _gpgme_gpg_add_arg ( c->gpg, secret_only? "--list-secret-keys":"--list-keys" ); diff --git a/gpgme/ops.h b/gpgme/ops.h index 6b7f7c2..1e67fc5 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -38,10 +38,21 @@ void _gpgme_append_gpg_args_from_recipients ( /*-- data.c --*/ +char * _gpgme_data_release_and_return_string ( GpgmeData dh ); GpgmeDataMode _gpgme_data_get_mode ( GpgmeData dh ); void _gpgme_data_set_mode ( GpgmeData dh, GpgmeDataMode mode ); +char * _gpgme_data_get_as_string ( GpgmeData dh ); GpgmeError _gpgme_data_append ( GpgmeData dh, const char *buffer, size_t length ); +GpgmeError _gpgme_data_append_string ( GpgmeData dh, const char *s ); +GpgmeError _gpgme_data_append_string_for_xml ( GpgmeData dh, + const char *s); +GpgmeError _gpgme_data_append_for_xml ( GpgmeData dh, + const char *buffer, + size_t len ); +GpgmeError _gpgme_data_append_percentstring_for_xml ( GpgmeData dh, + const char *string ); + /*-- key.c --*/ GpgmeError _gpgme_key_new( GpgmeKey *r_key ); diff --git a/gpgme/rungpg.h b/gpgme/rungpg.h index 010ec32..3ab0904 100644 --- a/gpgme/rungpg.h +++ b/gpgme/rungpg.h @@ -78,7 +78,10 @@ typedef enum { STATUS_GOT_IT , STATUS_PROGRESS , STATUS_SIG_CREATED , - STATUS_SESSION_KEY + STATUS_SESSION_KEY , + STATUS_NOTATION_NAME , + STATUS_NOTATION_DATA , + STATUS_POLICY_URL } GpgStatusCode; typedef void (*GpgStatusHandler)( GpgmeCtx, GpgStatusCode code, char *args ); diff --git a/gpgme/verify.c b/gpgme/verify.c index b98fdeb..8ead4b3 100644 --- a/gpgme/verify.c +++ b/gpgme/verify.c @@ -28,28 +28,64 @@ #include "context.h" #include "ops.h" -typedef enum { - VERIFY_STATUS_NONE = 0, - VERIFY_STATUS_NOSIG, - VERIFY_STATUS_NOKEY, - VERIFY_STATUS_ERROR, - VERIFY_STATUS_BAD, - VERIFY_STATUS_GOOD -} VerifyStatus; - struct verify_result_s { - VerifyStatus status; + GpgmeSigStat status; + GpgmeData notation; /* we store an XML fragment here */ + int notation_in_data; /* private to add_notation() */ }; void _gpgme_release_verify_result ( VerifyResult res ) { + gpgme_data_release ( res->notation ); xfree (res); } +static void +add_notation ( GpgmeCtx ctx, GpgStatusCode code, const char *data ) +{ + GpgmeData dh = ctx->result.verify->notation; + + if ( !dh ) { + if ( gpgme_data_new ( &dh, NULL, 0,0) ) { + ctx->out_of_core = 1; + return; + } + ctx->result.verify->notation = dh; + _gpgme_data_append_string (dh, " \n"); + } + + if ( code == STATUS_NOTATION_DATA ) { + if ( !ctx->result.verify->notation_in_data ) + _gpgme_data_append_string (dh, " "); + _gpgme_data_append_percentstring_for_xml (dh, data); + ctx->result.verify->notation_in_data = 1; + return; + } + + if ( ctx->result.verify->notation_in_data ) { + _gpgme_data_append_string (dh, "\n"); + ctx->result.verify->notation_in_data = 0; + } + + if ( code == STATUS_NOTATION_NAME ) { + _gpgme_data_append_string (dh, " "); + _gpgme_data_append_percentstring_for_xml (dh, data); + _gpgme_data_append_string (dh, "\n"); + } + else if ( code == STATUS_POLICY_URL ) { + _gpgme_data_append_string (dh, " "); + _gpgme_data_append_percentstring_for_xml (dh, data); + _gpgme_data_append_string (dh, "\n"); + } + else { + assert (0); + } +} + static void verify_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args ) { @@ -67,19 +103,27 @@ verify_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args ) assert ( ctx->result_type == RESULT_TYPE_VERIFY ); /* FIXME: For now we handle only one signature */ - /* FIXME: Collect useful information */ + /* FIXME: Collect useful information + and return them as XML */ switch (code) { case STATUS_GOODSIG: - ctx->result.verify->status = VERIFY_STATUS_GOOD; + ctx->result.verify->status = GPGME_SIG_STAT_GOOD; break; case STATUS_BADSIG: - ctx->result.verify->status = VERIFY_STATUS_BAD; + ctx->result.verify->status = GPGME_SIG_STAT_BAD; break; case STATUS_ERRSIG: - ctx->result.verify->status = VERIFY_STATUS_ERROR; + ctx->result.verify->status = GPGME_SIG_STAT_ERROR; /* FIXME: distinguish between a regular error and a missing key. * this is encoded in the args. */ break; + + case STATUS_NOTATION_NAME: + case STATUS_NOTATION_DATA: + case STATUS_POLICY_URL: + add_notation ( ctx, code, args ); + break; + default: /* ignore all other codes */ fprintf (stderr, "verify_status: code=%d not handled\n", code ); @@ -151,11 +195,20 @@ gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text ) } - GpgmeError -gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text ) +gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text, + GpgmeSigStat *r_stat ) { - int rc = gpgme_op_verify_start ( c, sig, text ); + int rc; + + if ( !r_stat ) + return mk_error (Invalid_Value); + + gpgme_data_release (c->notation); + c->notation = NULL; + + *r_stat = GPGME_SIG_STAT_NONE; + rc = gpgme_op_verify_start ( c, sig, text ); if ( !rc ) { gpgme_wait (c, 1); if ( c->result_type != RESULT_TYPE_VERIFY ) @@ -164,26 +217,18 @@ gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text ) rc = mk_error (Out_Of_Core); else { assert ( c->result.verify ); - switch ( c->result.verify->status ) { - case VERIFY_STATUS_NONE: - fputs ("Verification Status: None\n", stdout); - break; - case VERIFY_STATUS_NOSIG: - fputs ("Verification Status: No Signature\n", stdout); - break; - case VERIFY_STATUS_GOOD: - fputs ("Verification Status: Good\n", stdout); - break; - case VERIFY_STATUS_BAD: - fputs ("Verification Status: Bad\n", stdout); - break; - case VERIFY_STATUS_NOKEY: - fputs ("Verification Status: No Key\n", stdout); - break; - case VERIFY_STATUS_ERROR: - fputs ("Verification Status: Error\n", stdout); - break; + if ( c->result.verify->notation ) { + GpgmeData dh = c->result.verify->notation; + + if ( c->result.verify->notation_in_data ) { + _gpgme_data_append_string (dh, "\n"); + c->result.verify->notation_in_data = 0; + } + _gpgme_data_append_string (dh, "\n"); + c->notation = dh; + c->result.verify->notation = NULL; } + *r_stat = c->result.verify->status; } c->pending = 0; } diff --git a/tests/t-keylist.c b/tests/t-keylist.c index 249c21d..a67d1ee 100644 --- a/tests/t-keylist.c +++ b/tests/t-keylist.c @@ -41,7 +41,14 @@ doit ( GpgmeCtx ctx, const char *pattern ) fail_if_err (err); while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) { - printf ("Got key object (%p)\n", key ); + char *p; + printf ("\n", key ); + p = gpgme_key_get_as_xml ( key ); + if ( p ) + fputs ( p, stdout ); + else + fputs("\n", stdout ); + printf ("\n", key ); } if ( err != GPGME_EOF ) fail_if_err (err); diff --git a/tests/t-verify.c b/tests/t-verify.c index 779d560..5ab6bbc 100644 --- a/tests/t-verify.c +++ b/tests/t-verify.c @@ -28,21 +28,69 @@ static const char test_text1[] = "Just GNU it!\n"; static const char test_text1f[]= "Just GNU it?\n"; static const char test_sig1[] = +#if 0 "-----BEGIN PGP SIGNATURE-----\n" "\n" "iEYEABECAAYFAjoKgjIACgkQLXJ8x2hpdzQMSwCeO/xUrhysZ7zJKPf/FyXA//u1\n" "ZgIAn0204PBR7yxSdQx6CFxugstNqmRv\n" "=yku6\n" "-----END PGP SIGNATURE-----\n" +#elif 0 +"-----BEGIN PGP SIGNATURE-----\n" +"Version: GnuPG v1.0.4-2 (GNU/Linux)\n" +"Comment: For info see http://www.gnupg.org\n" +"\n" +"iJcEABECAFcFAjoS8/E1FIAAAAAACAAkZm9vYmFyLjF0aGlzIGlzIGEgbm90YXRp\n" +"b24gZGF0YSB3aXRoIDIgbGluZXMaGmh0dHA6Ly93d3cuZ3Uub3JnL3BvbGljeS8A\n" +"CgkQLXJ8x2hpdzQLyQCbBW/fgU8ZeWSlWPM1F8umHX17bAAAoIfSNDSp5zM85XcG\n" +"iwxMrf+u8v4r\n" +"=88Zo\n" +"-----END PGP SIGNATURE-----\n" +#elif 1 +"-----BEGIN PGP SIGNATURE-----\n" +"\n" +"iN0EABECAJ0FAjoS+i9FFIAAAAAAAwA5YmFyw7bDpMO8w58gZGFzIHdhcmVuIFVt\n" +"bGF1dGUgdW5kIGpldHp0IGVpbiBwcm96ZW50JS1aZWljaGVuNRSAAAAAAAgAJGZv\n" +"b2Jhci4xdGhpcyBpcyBhIG5vdGF0aW9uIGRhdGEgd2l0aCAyIGxpbmVzGhpodHRw\n" +"Oi8vd3d3Lmd1Lm9yZy9wb2xpY3kvAAoJEC1yfMdoaXc0JBIAoIiLlUsvpMDOyGEc\n" +"dADGKXF/Hcb+AKCJWPphZCphduxSvrzH0hgzHdeQaA==\n" +"=nts1\n" +"-----END PGP SIGNATURE-----\n" +#endif ; + #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_sig_stat ( GpgmeSigStat status ) +{ + switch ( status ) { + case GPGME_SIG_STAT_NONE: + fputs ("Verification Status: None\n", stdout); + break; + case GPGME_SIG_STAT_NOSIG: + fputs ("Verification Status: No Signature\n", stdout); + break; + case GPGME_SIG_STAT_GOOD: + fputs ("Verification Status: Good\n", stdout); + break; + case GPGME_SIG_STAT_BAD: + fputs ("Verification Status: Bad\n", stdout); + break; + case GPGME_SIG_STAT_NOKEY: + fputs ("Verification Status: No Key\n", stdout); + break; + case GPGME_SIG_STAT_ERROR: + fputs ("Verification Status: Error\n", stdout); + break; + } +} int main (int argc, char **argv ) @@ -50,6 +98,8 @@ main (int argc, char **argv ) GpgmeCtx ctx; GpgmeError err; GpgmeData sig, text; + GpgmeSigStat status; + char *nota; err = gpgme_new (&ctx); fail_if_err (err); @@ -61,16 +111,22 @@ main (int argc, char **argv ) fail_if_err (err); puts ("checking a valid message:\n"); - err = gpgme_op_verify (ctx, sig, text ); + err = gpgme_op_verify (ctx, sig, text, &status ); + print_sig_stat ( status ); fail_if_err (err); + if ( (nota=gpgme_op_get_notation (ctx)) ) + printf ("---Begin Notation---\n%s---End Notation---\n", nota ); puts ("checking a manipulated message:\n"); gpgme_data_release (text); err = gpgme_data_new ( &text, test_text1f, strlen (test_text1f), 0 ); fail_if_err (err); gpgme_data_rewind ( sig ); - err = gpgme_op_verify (ctx, sig, text ); + err = gpgme_op_verify (ctx, sig, text, &status ); + print_sig_stat ( status ); fail_if_err (err); + if ( (nota=gpgme_op_get_notation (ctx)) ) + printf ("---Begin Notation---\n%s---End Notation---\n", nota ); gpgme_data_release (sig); gpgme_data_release (text); -- 2.26.2