* verify.c (_gpgme_verify_status_handler): Handle TRUST_* status
authorWerner Koch <wk@gnupg.org>
Fri, 3 May 2002 14:06:56 +0000 (14:06 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 3 May 2002 14:06:56 +0000 (14:06 +0000)
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
gpgme/ChangeLog
gpgme/gpgme.h
gpgme/key.c
gpgme/rungpg.h
gpgme/verify.c

diff --git a/NEWS b/NEWS
index 4e37693c6057eb098430e67f8e1cfe8428007eef..b8be7e0662c272cdc28195e22f2b7b3ea6e2c14a 100644 (file)
--- 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)
index ff04df80d9d373d52c250df5e925ee2dfb5ea52a..d22b36177b47b3a6695373dd04a953d88e19040b 100644 (file)
@@ -1,3 +1,19 @@
+2002-05-03  Werner Koch  <wk@gnupg.org>
+
+       * 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  <wk@gnupg.org>
 
        * gpgme.h (GpgmeData_Encoding): New.
index 079b88ab38db68f300777d667421278b74dcf657..976eb8ba0e0a3642927130bf027205600f04d4fc 100644 (file)
@@ -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);
index 66482caafe5d0afbbdd20c285401533a526b700a..01506de300f15e9fa8d6640eb26766d5f880e4b4 100644 (file)
@@ -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;
 }
index 58afd8a8017ef1f71a1c70cef6b3cbbdd5c8a78b..3388d060e0665a57ae2f0ad9ba6f315898b6caaf 100644 (file)
@@ -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 ); 
index 13b83c28a2aa2236bd93157f5fa390931bf9dd63..5c6a3f728305cf64e8b70dfc1d982293ea0fbbd4 100644 (file)
@@ -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;
 }
+