Take care of already existing bogus 0x1f signatures.
[gnupg.git] / g10 / trustdb.c
index 265b883..c83e169 100644 (file)
@@ -1,6 +1,6 @@
 /* trustdb.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ *               2008 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -408,6 +408,27 @@ setup_trustdb( int level, const char *dbname )
 }
 
 void
+how_to_fix_the_trustdb ()
+{
+  const char *name = trustdb_args.dbname;
+
+  if (!name)
+    name = "trustdb.gpg";
+
+  log_info (_("You may try to re-create the trustdb using the commands:\n"));
+  log_info ("  cd %s\n", default_homedir ());
+  log_info ("  gpg2 --export-ownertrust > otrust.tmp\n");
+#ifdef HAVE_W32_SYSTEM
+  log_info ("  del %s\n", name);
+#else
+  log_info ("  rm %s\n", name);
+#endif
+  log_info ("  gpg2 --import-ownertrust < otrust.tmp\n");
+  log_info (_("If that does not work, please consult the manual\n"));
+}
+
+
+void
 init_trustdb()
 {
   int level = trustdb_args.level;
@@ -1155,12 +1176,15 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid)
 int
 get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
 {
-    int trustlevel;
-
-    trustlevel = get_validity (pk, uid);
-    if( trustlevel & TRUST_FLAG_REVOKED )
-       return 'r';
-    return trust_letter ( trustlevel );
+  int trustlevel;
+  
+  if (!pk)
+    return '?';  /* Just in case a NULL PK is passed.  */
+  
+  trustlevel = get_validity (pk, uid);
+  if ( (trustlevel & TRUST_FLAG_REVOKED) )
+    return 'r';
+  return trust_letter (trustlevel);
 }
 
 const char *
@@ -1168,6 +1192,9 @@ get_validity_string (PKT_public_key *pk, PKT_user_id *uid)
 {
   int trustlevel;
 
+  if (!pk)
+    return "err";  /* Just in case a NULL PK is passed.  */
+
   trustlevel = get_validity (pk, uid);
   if( trustlevel & TRUST_FLAG_REVOKED )
     return _("revoked");
@@ -1634,7 +1661,7 @@ clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy,int self_only)
       /* Everything else we delete */
 
       /* At this point, if 12 is set, the signing key was unavailable.
-        If 9 or 10 is set, it's superceded.  Otherwise, it's
+        If 9 or 10 is set, it's superseded.  Otherwise, it's
         invalid. */
 
       if(noisy)
@@ -1642,7 +1669,7 @@ clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy,int self_only)
                 keystr(node->pkt->pkt.signature->keyid),
                 uidnode->pkt->pkt.user_id->name,
                 node->flag&(1<<12)?"key unavailable":
-                node->flag&(1<<9)?"signature superceded":"invalid signature");
+                node->flag&(1<<9)?"signature superseded":"invalid signature");
 
       delete_kbnode(node);
       deleted++;
@@ -1935,54 +1962,78 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
              did not exist.  This is safe for non-trust sigs as well
              since we don't accept a regexp on the sig unless it's a
              trust sig. */
-          if (kr && (kr->trust_regexp==NULL || opt.trust_model!=TM_PGP ||
-                    (uidnode && check_regexp(kr->trust_regexp,
-                                           uidnode->pkt->pkt.user_id->name))))
+          if (kr && (!kr->trust_regexp 
+                     || opt.trust_model != TM_PGP 
+                     || (uidnode 
+                         && check_regexp(kr->trust_regexp,
+                                         uidnode->pkt->pkt.user_id->name))))
             {
-             if(DBG_TRUST && opt.trust_model==TM_PGP && sig->trust_depth)
-               log_debug("trust sig on %s, sig depth is %d, kr depth is %d\n",
-                         uidnode->pkt->pkt.user_id->name,sig->trust_depth,
-                         kr->trust_depth);
-
              /* Are we part of a trust sig chain?  We always favor
                  the latest trust sig, rather than the greater or
                  lesser trust sig or value.  I could make a decent
                  argument for any of these cases, but this seems to be
                  what PGP does, and I'd like to be compatible. -dms */
-             if(opt.trust_model==TM_PGP && sig->trust_depth
-                && pk->trust_timestamp<=sig->timestamp
-                && (sig->trust_depth<=kr->trust_depth
-                    || kr->ownertrust==TRUST_ULTIMATE))
+              if (opt.trust_model == TM_PGP
+                  && sig->trust_depth
+                  && pk->trust_timestamp <= sig->timestamp)
                {
-                 /* If we got here, we know that:
-
-                    this is a trust sig.
-
-                    it's a newer trust sig than any previous trust
-                    sig on this key (not uid).
-
-                    it is legal in that it was either generated by an
-                    ultimate key, or a key that was part of a trust
-                    chain, and the depth does not violate the
-                    original trust sig.
-
-                    if there is a regexp attached, it matched
-                    successfully.
-                 */
-
-                 if(DBG_TRUST)
-                   log_debug("replacing trust value %d with %d and "
-                             "depth %d with %d\n",
-                             pk->trust_value,sig->trust_value,
-                             pk->trust_depth,sig->trust_depth);
-
-                 pk->trust_value=sig->trust_value;
-                 pk->trust_depth=sig->trust_depth-1;
-
-                 /* If the trust sig contains a regexp, record it
-                    on the pk for the next round. */
-                 if(sig->trust_regexp)
-                   pk->trust_regexp=sig->trust_regexp;
+                 unsigned char depth;
+
+                 /* If the depth on the signature is less than the
+                    chain currently has, then use the signature depth
+                    so we don't increase the depth beyond what the
+                    signer wanted.  If the depth on the signature is
+                    more than the chain currently has, then use the
+                    chain depth so we use as much of the signature
+                    depth as the chain will permit.  An ultimately
+                    trusted signature can restart the depth to
+                    whatever level it likes. */
+
+                 if (sig->trust_depth < kr->trust_depth
+                      || kr->ownertrust == TRUST_ULTIMATE)
+                   depth = sig->trust_depth;
+                 else
+                   depth = kr->trust_depth;
+
+                 if (depth)
+                   {
+                     if(DBG_TRUST)
+                       log_debug ("trust sig on %s, sig depth is %d,"
+                                   " kr depth is %d\n",
+                                   uidnode->pkt->pkt.user_id->name,
+                                   sig->trust_depth,
+                                   kr->trust_depth);
+
+                     /* If we got here, we know that:
+
+                        this is a trust sig.
+
+                        it's a newer trust sig than any previous trust
+                        sig on this key (not uid).
+
+                        it is legal in that it was either generated by an
+                        ultimate key, or a key that was part of a trust
+                        chain, and the depth does not violate the
+                        original trust sig.
+
+                        if there is a regexp attached, it matched
+                        successfully.
+                     */
+
+                     if (DBG_TRUST)
+                       log_debug ("replacing trust value %d with %d and "
+                                   "depth %d with %d\n",
+                                   pk->trust_value,sig->trust_value,
+                                   pk->trust_depth,depth);
+
+                     pk->trust_value = sig->trust_value;
+                     pk->trust_depth = depth-1;
+                      
+                     /* If the trust sig contains a regexp, record it
+                        on the pk for the next round. */
+                     if (sig->trust_regexp)
+                       pk->trust_regexp = sig->trust_regexp;
+                   }
                }
 
               if (kr->ownertrust == TRUST_ULTIMATE)