* gpgme.h: Add GPGME_ATTR_SIG_SUMMARY and the GPGME_SIGSUM_

constants.
* verify.c (calc_sig_summary): New.
(gpgme_get_sig_ulong_attr): And use it here.
This commit is contained in:
Werner Koch 2002-06-11 15:33:08 +00:00
parent 8ac95a9772
commit 6b89172051
11 changed files with 187 additions and 27 deletions

1
NEWS
View File

@ -3,6 +3,7 @@ Noteworthy changes in version CVS-HEAD
* Interface changes relative to the 0.3.6 release: * Interface changes relative to the 0.3.6 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GPGME_ATTR_ERRTOK NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.7 (2002-06-04) Noteworthy changes in version 0.3.7 (2002-06-04)

View File

@ -1,3 +1,7 @@
2002-06-10 Werner Koch <wk@gnupg.org>
* gpgme.texi (Verify): Document attribute GPGME_ATTR_ERRTOK.
2002-06-04 Marcus Brinkmann <marcus@g10code.de> 2002-06-04 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Document new autodetection. * gpgme.texi (Multi Threading): Document new autodetection.
@ -183,3 +187,13 @@
* fdl.texi: Likewise. * fdl.texi: Likewise.
* Makefile.am (info_TEXINFOS): New variable. * Makefile.am (info_TEXINFOS): New variable.
(gpgme_TEXINFOS): Likewise. (gpgme_TEXINFOS): Likewise.
Copyright 2002 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
modifications, as long as this notice is preserved.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -2217,16 +2217,17 @@ fingerprint of the key which signed the plaintext, or @code{NULL} if
no verification could be performed. no verification could be performed.
@end deftypefun @end deftypefun
@deftypefun {const char *} gpgme_get_sig_string_attr (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeAttr @var{waht}}, @w{int @var{reserved}}) @deftypefun {const char *} gpgme_get_sig_string_attr (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeAttr @var{what}}, @w{int @var{reserved}})
This function is similar to @code{gpgme_get_sig_status} but may be used This function is similar to @code{gpgme_get_sig_status} but may be used
to retrieve more detailed information. @var{ctx} should be the context to retrieve more detailed information. @var{ctx} should be the context
used for the last signature verification, @var{idx} is used to enumerate used for the last signature verification, @var{idx} is used to enumerate
over all signatures starting with @code{0} and @var{reserved} should be over all signatures starting with @code{0} and @var{reserved} should be
@code{0} for now. @code{0} for now.
The only attribute @var{what} currently supported is The attributes @var{what} currently supports are
@code{GPGME_ATTR_FPR} to return the fingerprint of the key used to @code{GPGME_ATTR_FPR} to return the fingerprint of the key used to
create the signature. create the signature and @code{GPGME_ERRTOK} to return a token
with a more detailed error description.
@end deftypefun @end deftypefun
@deftypefun {const char *} gpgme_get_sig_ulong_attr (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeAttr @var{waht}}, @w{int @var{reserved}}) @deftypefun {const char *} gpgme_get_sig_ulong_attr (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeAttr @var{waht}}, @w{int @var{reserved}})

View File

@ -1,3 +1,21 @@
2002-06-11 Werner Koch <wk@gnupg.org>
* gpgme.h: Add GPGME_ATTR_SIG_SUMMARY and the GPGME_SIGSUM_
constants.
* verify.c (calc_sig_summary): New.
(gpgme_get_sig_ulong_attr): And use it here.
2002-06-10 Werner Koch <wk@gnupg.org>
* rungpg.h: Add new status codes TRUNCATED and ERROR.
* verify.c (is_token, copy_token): New.
(_gpgme_verify_status_handler): Use copy_token, handle the new
ERROR status and store the errorcode used withgpgsm and trust
status codes.
* gpgme.h: New attribute ERRTOK.
* key.c (gpgme_key_get_string_attr): Add dummy case for it.
(gpgme_get_sig_string_attr): Use it here to return the last error.
2002-06-10 Marcus Brinkmann <marcus@g10code.de> 2002-06-10 Marcus Brinkmann <marcus@g10code.de>
* engine-gpgsm.c (_gpgme_gpgsm_start): Move the code that sets the * engine-gpgsm.c (_gpgme_gpgsm_start): Move the code that sets the

View File

@ -137,6 +137,23 @@ typedef enum
} }
GpgmeSigStat; GpgmeSigStat;
/* Flags used with the GPGME_ATTR_SIG_SUMMARY. */
enum
{
GPGME_SIGSUM_VALID = 0x0001, /* The signature is fully valid */
GPGME_SIGSUM_GREEN = 0x0002, /* The signature is good. */
GPGME_SIGSUM_RED = 0x0004, /* The signature is bad. */
GPGME_SIGSUM_KEY_REVOKED = 0x0010, /* One key has been revoked. */
GPGME_SIGSUM_KEY_EXPIRED = 0x0020, /* One key has expired. */
GPGME_SIGSUM_SIG_EXPIRED = 0x0040, /* The signature has expired. */
GPGME_SIGSUM_KEY_MISSING = 0x0080, /* Can't verify: key missing. */
GPGME_SIGSUM_CRL_MISSING = 0x0100, /* CRL not available. */
GPGME_SIGSUM_CRL_TOO_OLD = 0x0200, /* Available CRL is too old. */
GPGME_SIGSUM_BAD_POLICY = 0x0400, /* A policy was not met. */
GPGME_SIGSUM_SYS_ERROR = 0x0800 /* A system error occured. */
};
/* The available signature modes. */ /* The available signature modes. */
typedef enum typedef enum
{ {
@ -177,7 +194,9 @@ typedef enum
GPGME_ATTR_SERIAL = 26, GPGME_ATTR_SERIAL = 26,
GPGME_ATTR_ISSUER = 27, GPGME_ATTR_ISSUER = 27,
GPGME_ATTR_CHAINID = 28, GPGME_ATTR_CHAINID = 28,
GPGME_ATTR_SIG_STATUS = 29 GPGME_ATTR_SIG_STATUS = 29,
GPGME_ATTR_ERRTOK = 30,
GPGME_ATTR_SIG_SUMMARY = 31
} }
GpgmeAttr; GpgmeAttr;

View File

@ -990,6 +990,7 @@ gpgme_key_get_string_attr (GpgmeKey key, GpgmeAttr what,
val = key->chain_id; val = key->chain_id;
break; break;
case GPGME_ATTR_SIG_STATUS: case GPGME_ATTR_SIG_STATUS:
case GPGME_ATTR_ERRTOK:
/* Not of any use here. */ /* Not of any use here. */
break; break;
} }

View File

@ -79,8 +79,3 @@ GpgmeError _gpgme_key_append_name ( GpgmeKey key, const char *s );
#endif /* KEY_H */ #endif /* KEY_H */

View File

@ -102,7 +102,9 @@ typedef enum {
STATUS_ALREADY_SIGNED , STATUS_ALREADY_SIGNED ,
STATUS_SIGEXPIRED , STATUS_SIGEXPIRED ,
STATUS_EXPSIG , STATUS_EXPSIG ,
STATUS_EXPKEYSIG STATUS_EXPKEYSIG ,
STATUS_TRUNCATED ,
STATUS_ERROR ,
} GpgStatusCode; } GpgStatusCode;
typedef void (*GpgStatusHandler)( GpgmeCtx, GpgStatusCode code, char *args ); typedef void (*GpgStatusHandler)( GpgmeCtx, GpgStatusCode code, char *args );

View File

@ -44,6 +44,7 @@ struct verify_result_s
ulong timestamp; /* Signature creation time. */ ulong timestamp; /* Signature creation time. */
ulong exptimestamp; /* signature exipration time or 0 */ ulong exptimestamp; /* signature exipration time or 0 */
GpgmeValidity validity; GpgmeValidity validity;
char trust_errtok[31]; /* error token send with the trust status */
}; };
@ -59,6 +60,44 @@ _gpgme_release_verify_result (VerifyResult result)
} }
} }
/* Check whether STRING starts with TOKEN and return true in this
case. This is case insensitive. If NEXT is not NULL return the
number of bytes to be added to STRING to get to the next token; a
returned value of 0 indicates end of line. */
static int
is_token (const char *string, const char *token, size_t *next)
{
size_t n = 0;
for (;*string && *token && *string == *token; string++, token++, n++)
;
if (*token || (*string != ' ' && !*string))
return 0;
if (next)
{
for (; *string == ' '; string++, n++)
;
*next = n;
}
return 1;
}
static size_t
copy_token (const char *string, char *buffer, size_t length)
{
const char *s = string;
char *p = buffer;
size_t i;
for (i = 1; i < length && *s && *s != ' ' ; i++)
*p++ = *s++;
*p = 0;
/* conmtinue scanning in case the copy was truncated */
while (*s && *s != ' ')
s++;
return s - string;
}
/* FIXME: Check that we are adding this to the correct signature. */ /* FIXME: Check that we are adding this to the correct signature. */
static void static void
@ -147,6 +186,7 @@ void
_gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args) _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{ {
char *p; char *p;
size_t n;
int i; int i;
if (ctx->error) if (ctx->error)
@ -184,11 +224,8 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
case STATUS_VALIDSIG: case STATUS_VALIDSIG:
ctx->result.verify->status = GPGME_SIG_STAT_GOOD; ctx->result.verify->status = GPGME_SIG_STAT_GOOD;
p = ctx->result.verify->fpr; i = copy_token (args, ctx->result.verify->fpr,
for (i = 0; i < DIM(ctx->result.verify->fpr) DIM(ctx->result.verify->fpr));
&& args[i] && args[i] != ' ' ; i++)
*p++ = args[i];
*p = 0;
/* Skip the formatted date. */ /* Skip the formatted date. */
while (args[i] && args[i] == ' ') while (args[i] && args[i] == ' ')
i++; i++;
@ -203,16 +240,13 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
case STATUS_BADSIG: case STATUS_BADSIG:
ctx->result.verify->status = GPGME_SIG_STAT_BAD; ctx->result.verify->status = GPGME_SIG_STAT_BAD;
/* Store the keyID in the fpr field. */ /* Store the keyID in the fpr field. */
p = ctx->result.verify->fpr; copy_token (args, ctx->result.verify->fpr,
for (i = 0; i < DIM(ctx->result.verify->fpr) DIM(ctx->result.verify->fpr));
&& args[i] && args[i] != ' ' ; i++)
*p++ = args[i];
*p = 0;
break; break;
case STATUS_ERRSIG: case STATUS_ERRSIG:
/* The return code is the 6th argument, if it is 9, the problem /* The return code is the 6th argument, if it is 9, the problem
is a missing key. */ is a missing key. Note that this is not emitted by gpgsm */
for (p = args, i = 0; p && *p && i < 5; i++) for (p = args, i = 0; p && *p && i < 5; i++)
{ {
p = strchr (p, ' '); p = strchr (p, ' ');
@ -225,11 +259,8 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
else else
ctx->result.verify->status = GPGME_SIG_STAT_ERROR; ctx->result.verify->status = GPGME_SIG_STAT_ERROR;
/* Store the keyID in the fpr field. */ /* Store the keyID in the fpr field. */
p = ctx->result.verify->fpr; copy_token (args, ctx->result.verify->fpr,
for (i = 0; i < DIM(ctx->result.verify->fpr) DIM(ctx->result.verify->fpr));
&& args[i] && args[i] != ' ' ; i++)
*p++ = args[i];
*p = 0;
break; break;
case STATUS_NOTATION_NAME: case STATUS_NOTATION_NAME:
@ -240,13 +271,19 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
case STATUS_TRUST_UNDEFINED: case STATUS_TRUST_UNDEFINED:
ctx->result.verify->validity = GPGME_VALIDITY_UNKNOWN; ctx->result.verify->validity = GPGME_VALIDITY_UNKNOWN;
copy_token (args, ctx->result.verify->trust_errtok,
DIM(ctx->result.verify->trust_errtok));
break; break;
case STATUS_TRUST_NEVER: case STATUS_TRUST_NEVER:
ctx->result.verify->validity = GPGME_VALIDITY_NEVER; ctx->result.verify->validity = GPGME_VALIDITY_NEVER;
copy_token (args, ctx->result.verify->trust_errtok,
DIM(ctx->result.verify->trust_errtok));
break; break;
case STATUS_TRUST_MARGINAL: case STATUS_TRUST_MARGINAL:
if (ctx->result.verify->status == GPGME_SIG_STAT_GOOD) if (ctx->result.verify->status == GPGME_SIG_STAT_GOOD)
ctx->result.verify->validity = GPGME_VALIDITY_MARGINAL; ctx->result.verify->validity = GPGME_VALIDITY_MARGINAL;
copy_token (args, ctx->result.verify->trust_errtok,
DIM(ctx->result.verify->trust_errtok));
break; break;
case STATUS_TRUST_FULLY: case STATUS_TRUST_FULLY:
case STATUS_TRUST_ULTIMATE: case STATUS_TRUST_ULTIMATE:
@ -257,6 +294,20 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
case STATUS_END_STREAM: case STATUS_END_STREAM:
break; break;
case STATUS_ERROR:
/* Generic error, we need this for gpgsm (and maybe for gpg in future)
to get error descriptions. */
if (is_token (args, "verify.findkey", &n) && n)
{
args += n;
if (is_token (args, "No_Public_Key", NULL))
ctx->result.verify->status = GPGME_SIG_STAT_NOKEY;
else
ctx->result.verify->status = GPGME_SIG_STAT_ERROR;
}
break;
case STATUS_EOF: case STATUS_EOF:
finish_sig (ctx,1); finish_sig (ctx,1);
@ -451,6 +502,55 @@ gpgme_get_sig_status (GpgmeCtx c, int idx,
return result->fpr; return result->fpr;
} }
/* Build a summary vector from RESULT. */
static unsigned long
calc_sig_summary (VerifyResult result)
{
unsigned long sum = 0;
if (result->validity == GPGME_VALIDITY_FULL
|| result->validity == GPGME_VALIDITY_ULTIMATE)
{
if (result->status == GPGME_SIG_STAT_GOOD
|| result->status == GPGME_SIG_STAT_GOOD_EXP
|| result->status == GPGME_SIG_STAT_GOOD_EXPKEY)
sum |= GPGME_SIGSUM_GREEN;
}
else if (result->validity == GPGME_VALIDITY_NEVER)
{
if (result->status == GPGME_SIG_STAT_GOOD
|| result->status == GPGME_SIG_STAT_GOOD_EXP
|| result->status == GPGME_SIG_STAT_GOOD_EXPKEY)
sum |= GPGME_SIGSUM_RED;
}
else if (result->status == GPGME_SIG_STAT_BAD)
sum |= GPGME_SIGSUM_RED;
/* fixme: handle the case when key and message are expired. */
if (result->status == GPGME_SIG_STAT_GOOD_EXP)
sum |= GPGME_SIGSUM_SIG_EXPIRED;
else if (result->status == GPGME_SIG_STAT_GOOD_EXPKEY)
sum |= GPGME_SIGSUM_KEY_EXPIRED;
else if (result->status == GPGME_SIG_STAT_NOKEY)
sum |= GPGME_SIGSUM_KEY_MISSING;
else if (result->status == GPGME_SIG_STAT_ERROR)
sum |= GPGME_SIGSUM_SYS_ERROR;
/* FIXME: Set GPGME_SIGSUM_KEY_REVOKED. */
/* FIXME: Set GPGME_SIGSUM_CRL_MISSING. */
/* FIXME: Set GPGME_SIGSUM_CRL_TOO_OLD. */
/* FIXME: Set GPGME_SIGSUM_BAD_POLICY. */
/* That the valid flag when the signature is unquestionable
valid. */
if ((sum & GPGME_SIGSUM_GREEN) && !(sum & ~GPGME_SIGSUM_GREEN))
sum |= GPGME_SIGSUM_VALID;
return sum;
}
const char * const char *
gpgme_get_sig_string_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved) gpgme_get_sig_string_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved)
{ {
@ -471,6 +571,8 @@ gpgme_get_sig_string_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved)
{ {
case GPGME_ATTR_FPR: case GPGME_ATTR_FPR:
return result->fpr; return result->fpr;
case GPGME_ATTR_ERRTOK:
return result->trust_errtok;
default: default:
break; break;
} }
@ -502,6 +604,8 @@ gpgme_get_sig_ulong_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved)
return (unsigned long)result->validity; return (unsigned long)result->validity;
case GPGME_ATTR_SIG_STATUS: case GPGME_ATTR_SIG_STATUS:
return (unsigned long)result->status; return (unsigned long)result->status;
case GPGME_ATTR_SIG_SUMMARY:
return calc_sig_summary (result);
default: default:
break; break;
} }

View File

@ -1,3 +1,7 @@
2002-06-10 Werner Koch <wk@gnupg.org>
* gpgsm/t-verify.c (print_sig_stat): Print the error token.
2002-06-04 Werner Koch <wk@gnupg.org> 2002-06-04 Werner Koch <wk@gnupg.org>
* gpgsm/t-encrypt.c (main): Add a simple option parser and allow * gpgsm/t-encrypt.c (main): Add a simple option parser and allow

View File

@ -118,8 +118,9 @@ print_sig_stat ( GpgmeCtx ctx, GpgmeSigStat status )
idx, (unsigned long)created, idx, (unsigned long)created,
gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0), gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0),
status_string(status) ); status_string(status) );
printf ("sig %d: fpr/keyid: `%s' validity: %s\n", printf ("sig %d: fpr/keyid: `%s' exterr: `%s' validity: %s\n",
idx, s, idx, s,
gpgme_get_sig_string_attr (ctx, idx, GPGME_ATTR_ERRTOK, 0),
validity_string (gpgme_get_sig_ulong_attr validity_string (gpgme_get_sig_ulong_attr
(ctx, idx, GPGME_ATTR_VALIDITY, 0)) ); (ctx, idx, GPGME_ATTR_VALIDITY, 0)) );
if ( !gpgme_get_sig_key (ctx, idx, &key) ) { if ( !gpgme_get_sig_key (ctx, idx, &key) ) {