From f14bf86feef1b06a34a29e1a96c4cb341e38659c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 3 May 2002 14:06:56 +0000 Subject: [PATCH] * verify.c (_gpgme_verify_status_handler): Handle TRUST_* status lines so that a claim can be made without looking up the key. (gpgme_get_sig_string_attr): New. (gpgme_get_sig_ulong_attr): New. * gpgme.h (GpgmeAttr): Added GPGME_ATTR_SIG_STATUS. * rungpg.h: Add new status codes from gpg 1.0.7 and formatted the list to align with the status.h file from gnupg. * gpgme.h (GpgmeSigStat): Add _GOOD_EXP and _GOOD_EXPKEY. * verify.c (_gpgme_verify_status_handler, finish_sig): Handle these new status codes. Store the expiration time --- NEWS | 12 ++++++ gpgme/ChangeLog | 16 ++++++++ gpgme/gpgme.h | 19 +++++++-- gpgme/key.c | 5 ++- gpgme/rungpg.h | 23 ++++++++--- gpgme/verify.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 166 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 4e37693..b8be7e0 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ + * The signature verfication functions are extended. Instead of + always returning GPGME_SIG_STATUS_GOOD, the functions return more + specific codes for expired signatures. 2 new functions may be used + to retrieve more specific information like the signature expiartion + time and a validut information of the key without looking up the key. + * The current passphrase callback and progress meter callback can be retrieved with the new functions gpgme_get_passphrase_cb and gpgme_get_progress_cb respectively. @@ -9,6 +15,12 @@ gpgme_get_progress_cb NEW GpgmeDataEncoding NEW gpgme_data_set_encoding NEW gpgme_data_get_encoding NEW +GPGME_SIG_STAT_GOOD_EXP NEW +GPGME_SIG_STAT_GOOD_EXPKEY NEW +gpgme_op_verify CHANGED: Returns more status codes. +GPGME_ATTR_SIG_STATUS NEW +gpgme_get_sig_string_attr NEW +gpgme_get_sig_ulong_attr NEW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Noteworthy changes in version 0.3.5 (2002-04-01) diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index ff04df8..d22b361 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,19 @@ +2002-05-03 Werner Koch + + * verify.c (_gpgme_verify_status_handler): Handle TRUST_* status + lines so that a claim can be made without looking up the key. + (gpgme_get_sig_string_attr): New. + (gpgme_get_sig_ulong_attr): New. + + * gpgme.h (GpgmeAttr): Added GPGME_ATTR_SIG_STATUS. + + * rungpg.h: Add new status codes from gpg 1.0.7 and formatted the + list to align with the status.h file from gnupg. + + * gpgme.h (GpgmeSigStat): Add _GOOD_EXP and _GOOD_EXPKEY. + * verify.c (_gpgme_verify_status_handler, finish_sig): Handle + these new status codes. Store the expiration time + 2002-04-27 Werner Koch * gpgme.h (GpgmeData_Encoding): New. diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 079b88a..976eb8b 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -131,7 +131,9 @@ typedef enum GPGME_SIG_STAT_NOKEY = 3, GPGME_SIG_STAT_NOSIG = 4, GPGME_SIG_STAT_ERROR = 5, - GPGME_SIG_STAT_DIFF = 6 + GPGME_SIG_STAT_DIFF = 6, + GPGME_SIG_STAT_GOOD_EXP = 7, + GPGME_SIG_STAT_GOOD_EXPKEY = 8 } GpgmeSigStat; @@ -144,7 +146,7 @@ typedef enum } GpgmeSigMode; -/* The available key attributes. */ +/* The available key and signature attributes. */ typedef enum { GPGME_ATTR_KEYID = 1, @@ -174,7 +176,8 @@ typedef enum GPGME_ATTR_KEY_DISABLED = 25, GPGME_ATTR_SERIAL = 26, GPGME_ATTR_ISSUER = 27, - GPGME_ATTR_CHAINID = 28 + GPGME_ATTR_CHAINID = 28, + GPGME_ATTR_SIG_STATUS = 29 } GpgmeAttr; @@ -289,6 +292,16 @@ GpgmeKey gpgme_signers_enum (const GpgmeCtx ctx, int seq); const char *gpgme_get_sig_status (GpgmeCtx ctx, int idx, GpgmeSigStat *r_stat, time_t *r_created); +/* Retrieve certain attributes of a signature. IDX is the index + number of the signature after a successful verify operation. WHAT + is an attribute where GPGME_ATTR_EXPIRE is probably the most useful + one. RESERVED must be passed as 0. */ +unsigned long gpgme_get_sig_ulong_attr (GpgmeCtx c, int idx, + GpgmeAttr what, int reserved); +const char *gpgme_get_sig_string_attr (GpgmeCtx c, int idx, + GpgmeAttr what, int reserved); + + /* Get the key used to create signature IDX in CTX and return it in R_KEY. */ GpgmeError gpgme_get_sig_key (GpgmeCtx ctx, int idx, GpgmeKey *r_key); diff --git a/gpgme/key.c b/gpgme/key.c index 66482ca..01506de 100644 --- a/gpgme/key.c +++ b/gpgme/key.c @@ -1,6 +1,6 @@ /* key.c - Key and keyList objects * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001 g10 Code GmbH + * Copyright (C) 2001, 2002 g10 Code GmbH * * This file is part of GPGME. * @@ -869,6 +869,9 @@ gpgme_key_get_string_attr ( GpgmeKey key, GpgmeAttr what, case GPGME_ATTR_CHAINID: val = key->chain_id; break; + case GPGME_ATTR_SIG_STATUS: + /* not of any use here */ + break; } return val; } diff --git a/gpgme/rungpg.h b/gpgme/rungpg.h index 58afd8a..3388d06 100644 --- a/gpgme/rungpg.h +++ b/gpgme/rungpg.h @@ -31,24 +31,30 @@ typedef enum { STATUS_ENTER , STATUS_LEAVE , STATUS_ABORT , + STATUS_GOODSIG , STATUS_BADSIG , STATUS_ERRSIG , + + STATUS_BADARMOR , + STATUS_RSA_OR_IDEA , - STATUS_SIGEXPIRED , + STATUS_KEYEXPIRED , STATUS_KEYREVOKED , + STATUS_TRUST_UNDEFINED , STATUS_TRUST_NEVER , STATUS_TRUST_MARGINAL , STATUS_TRUST_FULLY , STATUS_TRUST_ULTIMATE , + STATUS_SHM_INFO , STATUS_SHM_GET , STATUS_SHM_GET_BOOL , STATUS_SHM_GET_HIDDEN , + STATUS_NEED_PASSPHRASE , - STATUS_UNEXPECTED , STATUS_VALIDSIG , STATUS_SIG_ID , STATUS_ENC_TO , @@ -69,10 +75,12 @@ typedef enum { STATUS_FILE_START , STATUS_FILE_DONE , STATUS_FILE_ERROR , + STATUS_BEGIN_DECRYPTION , STATUS_END_DECRYPTION , STATUS_BEGIN_ENCRYPTION , STATUS_END_ENCRYPTION , + STATUS_DELETE_PROBLEM , STATUS_GET_BOOL , STATUS_GET_LINE , @@ -80,16 +88,21 @@ typedef enum { STATUS_GOT_IT , STATUS_PROGRESS , STATUS_SIG_CREATED , - STATUS_KEY_CREATED , STATUS_SESSION_KEY , STATUS_NOTATION_NAME , STATUS_NOTATION_DATA , - STATUS_USERID_HINT , STATUS_POLICY_URL , STATUS_BEGIN_STREAM , STATUS_END_STREAM , + STATUS_KEY_CREATED , + STATUS_USERID_HINT , + STATUS_UNEXPECTED , STATUS_INV_RECP , - STATUS_NO_RECP + STATUS_NO_RECP , + STATUS_ALREADY_SIGNED , + STATUS_SIGEXPIRED , + STATUS_EXPSIG , + STATUS_EXPKEYSIG } GpgStatusCode; typedef void (*GpgStatusHandler)( GpgmeCtx, GpgStatusCode code, char *args ); diff --git a/gpgme/verify.c b/gpgme/verify.c index 13b83c2..5c6a3f7 100644 --- a/gpgme/verify.c +++ b/gpgme/verify.c @@ -35,12 +35,15 @@ struct verify_result_s { struct verify_result_s *next; GpgmeSigStat status; + GpgmeSigStat expstatus; /* only used by finish_sig */ GpgmeData notation; /* We store an XML fragment here. */ int collecting; /* Private to finish_sig(). */ int notation_in_data; /* Private to add_notation(). */ char fpr[41]; /* Fingerprint of a good signature or keyid of a bad one. */ ulong timestamp; /* Signature creation time. */ + ulong exptimestamp; /* signature exipration time or 0 */ + GpgmeValidity validity; }; @@ -113,6 +116,9 @@ add_notation (GpgmeCtx ctx, GpgStatusCode code, const char *data) static void finish_sig (GpgmeCtx ctx, int stop) { + if (ctx->result.verify->status == GPGME_SIG_STAT_GOOD) + ctx->result.verify->status = ctx->result.verify->expstatus; + if (stop) return; /* nothing to do */ @@ -147,7 +153,11 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args) return; test_and_allocate_result (ctx, verify); - if (code == STATUS_GOODSIG || code == STATUS_BADSIG || code == STATUS_ERRSIG) + if (code == STATUS_GOODSIG + || code == STATUS_EXPSIG + || code == STATUS_EXPKEYSIG + || code == STATUS_BADSIG + || code == STATUS_ERRSIG) { finish_sig (ctx,0); if (ctx->error) @@ -161,7 +171,15 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args) break; case STATUS_GOODSIG: - /* We only look at VALIDSIG */ + ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD; + break; + + case STATUS_EXPSIG: + ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD_EXP; + break; + + case STATUS_EXPKEYSIG: + ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD_EXPKEY; break; case STATUS_VALIDSIG: @@ -177,7 +195,9 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args) while (args[i] && args[i] != ' ') i++; /* And get the timestamp. */ - ctx->result.verify->timestamp = strtoul (args+i, NULL, 10); + ctx->result.verify->timestamp = strtoul (args+i, &p, 10); + if (args[i]) + ctx->result.verify->exptimestamp = strtoul (p, NULL, 10); break; case STATUS_BADSIG: @@ -218,6 +238,22 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args) add_notation (ctx, code, args); break; + case STATUS_TRUST_UNDEFINED: + ctx->result.verify->validity = GPGME_VALIDITY_UNKNOWN; + break; + case STATUS_TRUST_NEVER: + ctx->result.verify->validity = GPGME_VALIDITY_NEVER; + break; + case STATUS_TRUST_MARGINAL: + if (ctx->result.verify->status == GPGME_SIG_STAT_GOOD) + ctx->result.verify->validity = GPGME_VALIDITY_MARGINAL; + break; + case STATUS_TRUST_FULLY: + case STATUS_TRUST_ULTIMATE: + if (ctx->result.verify->status == GPGME_SIG_STAT_GOOD) + ctx->result.verify->validity = GPGME_VALIDITY_FULL; + break; + case STATUS_END_STREAM: break; @@ -353,6 +389,8 @@ _gpgme_intersect_stati (VerifyResult result) * GPGME_SIG_STAT_ERROR: Due to some other error the check could not be done. * GPGME_SIG_STAT_DIFF: There is more than 1 signature and they have not * the same status. + * GPGME_SIG_STAT_GOOD_EXP: The signature is good but has expired. + * GPGME_SIG_STAT_GOOD_KEYEXP: The signature is good but the key has expired. * * Return value: 0 on success or an errorcode if something not related to * the signature itself did go wrong. @@ -415,6 +453,64 @@ gpgme_get_sig_status (GpgmeCtx c, int idx, return result->fpr; } +const char * +gpgme_get_sig_string_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved) +{ + VerifyResult result; + + if (!c || c->pending || !c->result.verify) + return NULL; /* No results yet or verification error. */ + if (reserved) + return NULL; /* We might want to use it to enumerate attributes of + one signature */ + for (result = c->result.verify; + result && idx > 0; result = result->next, idx--) + ; + if (!result) + return NULL; /* No more signatures. */ + + switch (what) + { + case GPGME_ATTR_FPR: + return result->fpr; + default: + break; + } + return NULL; +} + +unsigned long +gpgme_get_sig_ulong_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved) +{ + VerifyResult result; + + if (!c || c->pending || !c->result.verify) + return 0; /* No results yet or verification error. */ + if (reserved) + return 0; + for (result = c->result.verify; + result && idx > 0; result = result->next, idx--) + ; + if (!result) + return 0; /* No more signatures. */ + + switch (what) + { + case GPGME_ATTR_CREATED: + return result->timestamp; + case GPGME_ATTR_EXPIRE: + return result->exptimestamp; + case GPGME_ATTR_VALIDITY: + return (unsigned long)result->validity; + case GPGME_ATTR_SIG_STATUS: + return (unsigned long)result->status; + default: + break; + } + return 0; +} + + /** * gpgme_get_sig_key: @@ -465,3 +561,4 @@ gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key) } return err; } + -- 2.26.2