[git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.8-27-g8055f18

by Werner Koch cvs at cvs.gnupg.org
Mon Jul 9 10:45:09 CEST 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, STABLE-BRANCH-2-2 has been updated
       via  8055f186a32e628028de897b7ee4705cd8e999b7 (commit)
       via  046276db3a04f1907ddcf77c3771832613918226 (commit)
       via  40bf383f72b5629de739e30c9c35bbcb628273e8 (commit)
      from  b4599a0449ead7dc5c0d922aa78b6168e625e15e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 8055f186a32e628028de897b7ee4705cd8e999b7
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Jul 9 09:49:09 2018 +0200

    gpg: Let export-clean remove expired subkeys.
    
    * g10/key-clean.h (KEY_CLEAN_NONE, KEY_CLEAN_INVALID)
    (KEY_CLEAN_ENCR, KEY_CLEAN_AUTHENCR, KEY_CLEAN_ALL): New.
    * g10/key-clean.c (clean_one_subkey): New.
    (clean_all_subkeys): Add arg CLEAN_LEVEL.
    * g10/import.c (import_one): Call clean_all_subkeys with
    KEY_CLEAN_NONE.
    * g10/export.c (do_export_stream): Call clean_all_subkeys depedning on
    the export clean options.
    --
    
    GnuPG-bug-id: 3622
    Signed-off-by: Werner Koch <wk at gnupg.org>
    (cherry picked from commit c2fd65ec8498a08ee36ca52d99b6b014f6db8d93)

diff --git a/g10/export.c b/g10/export.c
index 21ff23c..e94e959 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -2003,15 +2003,18 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
         }
 
       /* Always do the cleaning on the public key part if requested.
-       * Note that both export-clean and export-minimal only apply to
-       * UID sigs (0x10, 0x11, 0x12, and 0x13).  A designated
-       * revocation is never stripped, even with export-minimal set.  */
+       * A designated revocation is never stripped, even with
+       * export-minimal set.  */
       if ((options & EXPORT_CLEAN))
         {
           merge_keys_and_selfsig (ctrl, keyblock);
           clean_all_uids (ctrl, keyblock, opt.verbose,
                           (options&EXPORT_MINIMAL), NULL, NULL);
-          clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
+          clean_all_subkeys (ctrl, keyblock, opt.verbose,
+                             (options&EXPORT_MINIMAL)? KEY_CLEAN_ALL
+                             /**/                    : KEY_CLEAN_AUTHENCR,
+                             NULL, NULL);
+          commit_kbnode (&keyblock);
         }
 
       if (export_keep_uid)
diff --git a/g10/import.c b/g10/import.c
index 6b6411c..6dad8ee 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1746,7 +1746,8 @@ import_one (ctrl_t ctrl,
       merge_keys_and_selfsig (ctrl, keyblock);
       clean_all_uids (ctrl, keyblock,
                       opt.verbose, (options&IMPORT_MINIMAL), NULL, NULL);
-      clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
+      clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE,
+                         NULL, NULL);
     }
 
   clear_kbnode_flags( keyblock );
@@ -1892,7 +1893,8 @@ import_one (ctrl_t ctrl,
           merge_keys_and_selfsig (ctrl, keyblock);
           clean_all_uids (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
                           &n_uids_cleaned,&n_sigs_cleaned);
-          clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
+          clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE,
+                             NULL, NULL);
         }
 
       /* Unless we are in restore mode apply meta data to the
@@ -1983,7 +1985,8 @@ import_one (ctrl_t ctrl,
           clean_all_uids (ctrl, keyblock_orig, opt.verbose,
                           (options&IMPORT_MINIMAL),
                           &n_uids_cleaned,&n_sigs_cleaned);
-          clean_all_subkeys (ctrl, keyblock_orig, opt.verbose, NULL, NULL);
+          clean_all_subkeys (ctrl, keyblock_orig, opt.verbose, KEY_CLEAN_NONE,
+                             NULL, NULL);
         }
 
       if (n_uids || n_sigs || n_subk || n_sigs_cleaned || n_uids_cleaned)
diff --git a/g10/key-clean.c b/g10/key-clean.c
index 10478a4..097ca17 100644
--- a/g10/key-clean.c
+++ b/g10/key-clean.c
@@ -408,24 +408,101 @@ clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
 }
 
 
+/* Helper for clean_all_subkeys.  */
+static int
+clean_one_subkey (ctrl_t ctrl, kbnode_t subkeynode, int noisy, int clean_level)
+{
+  kbnode_t node;
+  PKT_public_key *pk = subkeynode->pkt->pkt.public_key;
+  unsigned int use = pk->pubkey_usage;
+  int do_clean = 0;
+
+  (void)ctrl;
+  (void)noisy;
+
+  log_assert (subkeynode->pkt->pkttype == PKT_PUBLIC_SUBKEY
+              || subkeynode->pkt->pkttype == PKT_SECRET_SUBKEY);
+
+  if (DBG_LOOKUP)
+    log_debug ("\tchecking subkey %08lX [%c%c%c%c%c]\n",
+               (ulong) keyid_from_pk (pk, NULL),
+               (use & PUBKEY_USAGE_ENC)? 'e':'-',
+               (use & PUBKEY_USAGE_SIG)? 's':'-',
+               (use & PUBKEY_USAGE_CERT)? 'c':'-',
+               (use & PUBKEY_USAGE_AUTH)? 'a':'-',
+               (use & PUBKEY_USAGE_UNKNOWN)? '?':'-');
+
+  if (!pk->flags.valid)
+    {
+      if (DBG_LOOKUP)
+        log_debug ("\tsubkey not valid\n");
+      if (clean_level == KEY_CLEAN_INVALID)
+        do_clean = 1;
+    }
+  if (pk->has_expired)
+    {
+      if (DBG_LOOKUP)
+        log_debug ("\tsubkey has expired\n");
+      if (clean_level == KEY_CLEAN_ALL)
+        do_clean = 1;
+      else if (clean_level == KEY_CLEAN_AUTHENCR
+               && (use & (PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH))
+               && !(use & (PUBKEY_USAGE_SIG | PUBKEY_USAGE_CERT)))
+        do_clean = 1;
+      else if (clean_level == KEY_CLEAN_ENCR
+               && (use & PUBKEY_USAGE_ENC)
+               && !(use & (PUBKEY_USAGE_SIG | PUBKEY_USAGE_CERT
+                           | PUBKEY_USAGE_AUTH)))
+        do_clean = 1;
+    }
+  if (pk->flags.revoked)
+    {
+      if (DBG_LOOKUP)
+        log_debug ("\tsubkey has been revoked (keeping)\n");
+      /* Avoid any cleaning because revocations are important.  */
+      do_clean = 0;
+    }
+  if (!do_clean)
+    return 0;
+
+  if (DBG_LOOKUP)
+    log_debug ("\t=> removing this subkey\n");
+
+  delete_kbnode (subkeynode);
+  for (node = subkeynode->next;
+       node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                 || node->pkt->pkttype == PKT_SECRET_SUBKEY);
+       node = node->next)
+    delete_kbnode (node);
+
+  return 1;
+}
+
+
 /* This function only marks the deleted nodes and the caller is
  * responsible to skip or remove them.  Needs to be called after a
- * merge_keys_and_selfsig.  */
+ * merge_keys_and_selfsig.  CLEAN_LEVEL is one of the KEY_CLEAN_*
+ * values.   */
 void
-clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy,
+clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy, int clean_level,
                    int *subkeys_cleaned, int *sigs_cleaned)
 {
-  kbnode_t node;
+  kbnode_t first_subkey, node;
+
+  if (DBG_LOOKUP)
+    log_debug ("clean_all_subkeys: checking key %08lX\n",
+	       (ulong) keyid_from_pk (keyblock->pkt->pkt.public_key, NULL));
 
   for (node = keyblock->next; node; node = node->next)
     if (!is_deleted_kbnode (node)
         && (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
             || node->pkt->pkttype == PKT_SECRET_SUBKEY))
       break;
+  first_subkey = node;
 
   /* Remove bogus subkey binding signatures: The only signatures
    * allowed are of class 0x18 and 0x28.  */
-  for (; node; node = node->next)
+  for (node = first_subkey; node; node = node->next)
     {
       if (is_deleted_kbnode (node))
         continue;
@@ -438,4 +515,21 @@ clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy,
             ++*sigs_cleaned;
         }
     }
+
+  /* Do the selected cleaning.  */
+  if (clean_level > KEY_CLEAN_NONE)
+    {
+      for (node = first_subkey; node; node = node->next)
+        {
+          if (is_deleted_kbnode (node))
+            continue;
+          if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+              || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+            if (clean_one_subkey (ctrl, node, noisy, clean_level))
+              {
+                if (subkeys_cleaned)
+                  ++*subkeys_cleaned;
+              }
+        }
+    }
 }
diff --git a/g10/key-clean.h b/g10/key-clean.h
index 6938430..a0fb769 100644
--- a/g10/key-clean.h
+++ b/g10/key-clean.h
@@ -23,6 +23,18 @@
 
 #include "gpg.h"
 
+/* No explict cleaning.  */
+#define KEY_CLEAN_NONE      0
+/* Remove only invalid subkeys (ie. missing key-bindings) */
+#define KEY_CLEAN_INVALID   1
+/* Remove expired encryption keys */
+#define KEY_CLEAN_ENCR      2
+/* Remove expired authentication and encryption keys.  */
+#define KEY_CLEAN_AUTHENCR  3
+/* Remove all expired subkeys.  */
+#define KEY_CLEAN_ALL       4
+
+
 void mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
                             u32 *main_kid, struct key_item *klist,
                             u32 curtime, u32 *next_expire);
@@ -32,7 +44,8 @@ void clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
                     int *uids_cleaned, int *sigs_cleaned);
 void clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
                      int *uids_cleaned,int *sigs_cleaned);
-void clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy,
+void clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock,
+                        int noisy, int clean_level,
                         int *subkeys_cleaned, int *sigs_cleaned);
 
 

commit 046276db3a04f1907ddcf77c3771832613918226
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Jul 6 11:48:38 2018 +0200

    gpg: Split key cleaning function for clarity.
    
    * g10/key-clean.c (clean_key): Rename to clean_all_uids and split
    subkey cleaning into ...
    (clean_all_subkeys): new.  Call that always after the former clean_key
    invocations.
    --
    
    Note that the clean_all_subkeys function will later be extended.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>
    (cherry picked from commit 6c3567196f7e72552f326ce07dccbcce31926e5d)

diff --git a/g10/export.c b/g10/export.c
index 44cf075..21ff23c 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -2007,8 +2007,12 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
        * UID sigs (0x10, 0x11, 0x12, and 0x13).  A designated
        * revocation is never stripped, even with export-minimal set.  */
       if ((options & EXPORT_CLEAN))
-        clean_key (ctrl, keyblock, opt.verbose,
-                   (options&EXPORT_MINIMAL), NULL, NULL);
+        {
+          merge_keys_and_selfsig (ctrl, keyblock);
+          clean_all_uids (ctrl, keyblock, opt.verbose,
+                          (options&EXPORT_MINIMAL), NULL, NULL);
+          clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
+        }
 
       if (export_keep_uid)
         {
diff --git a/g10/import.c b/g10/import.c
index fa7fc1f..6b6411c 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1741,9 +1741,13 @@ import_one (ctrl_t ctrl,
      that we have to clean later.  This has no practical impact on the
      end result, but does result in less logging which might confuse
      the user. */
-  if (options&IMPORT_CLEAN)
-    clean_key (ctrl, keyblock,
-               opt.verbose, (options&IMPORT_MINIMAL), NULL, NULL);
+  if ((options & IMPORT_CLEAN))
+    {
+      merge_keys_and_selfsig (ctrl, keyblock);
+      clean_all_uids (ctrl, keyblock,
+                      opt.verbose, (options&IMPORT_MINIMAL), NULL, NULL);
+      clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
+    }
 
   clear_kbnode_flags( keyblock );
 
@@ -1884,8 +1888,12 @@ import_one (ctrl_t ctrl,
         log_info (_("writing to '%s'\n"), keydb_get_resource_name (hd) );
 
       if ((options & IMPORT_CLEAN))
-        clean_key (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
-                   &n_uids_cleaned,&n_sigs_cleaned);
+        {
+          merge_keys_and_selfsig (ctrl, keyblock);
+          clean_all_uids (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
+                          &n_uids_cleaned,&n_sigs_cleaned);
+          clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
+        }
 
       /* Unless we are in restore mode apply meta data to the
        * keyblock.  Note that this will never change the first packet
@@ -1970,8 +1978,13 @@ import_one (ctrl_t ctrl,
         goto leave;
 
       if ((options & IMPORT_CLEAN))
-        clean_key (ctrl, keyblock_orig, opt.verbose, (options&IMPORT_MINIMAL),
-                   &n_uids_cleaned,&n_sigs_cleaned);
+        {
+          merge_keys_and_selfsig (ctrl, keyblock_orig);
+          clean_all_uids (ctrl, keyblock_orig, opt.verbose,
+                          (options&IMPORT_MINIMAL),
+                          &n_uids_cleaned,&n_sigs_cleaned);
+          clean_all_subkeys (ctrl, keyblock_orig, opt.verbose, NULL, NULL);
+        }
 
       if (n_uids || n_sigs || n_subk || n_sigs_cleaned || n_uids_cleaned)
         {
diff --git a/g10/key-clean.c b/g10/key-clean.c
index d022ff4..10478a4 100644
--- a/g10/key-clean.c
+++ b/g10/key-clean.c
@@ -383,15 +383,14 @@ clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
 
 
 /* NB: This function marks the deleted nodes only and the caller is
- * responsible to skip or remove them.  */
+ * responsible to skip or remove them.  Needs to be called after a
+ * merge_keys_and_selfsig().  */
 void
-clean_key (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
-           int *uids_cleaned, int *sigs_cleaned)
+clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
+                int *uids_cleaned, int *sigs_cleaned)
 {
   kbnode_t node;
 
-  merge_keys_and_selfsig (ctrl, keyblock);
-
   for (node = keyblock->next;
        node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY
                     || node->pkt->pkttype == PKT_SECRET_SUBKEY);
@@ -406,6 +405,26 @@ clean_key (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
    * allowed are of class 0x18 and 0x28.  */
   log_assert (!node || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
                         || node->pkt->pkttype == PKT_SECRET_SUBKEY));
+}
+
+
+/* This function only marks the deleted nodes and the caller is
+ * responsible to skip or remove them.  Needs to be called after a
+ * merge_keys_and_selfsig.  */
+void
+clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy,
+                   int *subkeys_cleaned, int *sigs_cleaned)
+{
+  kbnode_t node;
+
+  for (node = keyblock->next; node; node = node->next)
+    if (!is_deleted_kbnode (node)
+        && (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+            || node->pkt->pkttype == PKT_SECRET_SUBKEY))
+      break;
+
+  /* Remove bogus subkey binding signatures: The only signatures
+   * allowed are of class 0x18 and 0x28.  */
   for (; node; node = node->next)
     {
       if (is_deleted_kbnode (node))
diff --git a/g10/key-clean.h b/g10/key-clean.h
index 4dfd950..6938430 100644
--- a/g10/key-clean.h
+++ b/g10/key-clean.h
@@ -30,8 +30,10 @@ void mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
 void clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
                     int noisy, int self_only,
                     int *uids_cleaned, int *sigs_cleaned);
-void clean_key (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
-                int *uids_cleaned,int *sigs_cleaned);
+void clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
+                     int *uids_cleaned,int *sigs_cleaned);
+void clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy,
+                        int *subkeys_cleaned, int *sigs_cleaned);
 
 
 #endif /*GNUPG_G10_KEY_CLEAN_H*/

commit 40bf383f72b5629de739e30c9c35bbcb628273e8
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Jul 6 11:40:16 2018 +0200

    gpg: Move key cleaning functions to a separate file.
    
    * g10/trust.c (mark_usable_uid_certs, clean_sigs_from_uid)
    (clean_uid_from_key, clean_one_uid, clean_key): Move to ...
    * g10/key-clean.c: new file.
    * g10/key-clean.h: New.
    * g10/Makefile.am (gpg_sources): Add new files.
    * g10/export.c, g10/import.c, g10/keyedit.c, g10/trustdb.c: Include
    new header.
    * g10/trustdb.h (struct key_item, is_in_klist): Move to ...
    * g10/keydb.h: here.
    --
    
    Signed-off-by: Werner Koch <wk at gnupg.org>
    (cherry picked from commit 135e46ea480d749b8a9692f71d4d0bfdadd8ee2f)

diff --git a/g10/Makefile.am b/g10/Makefile.am
index cc4ef5c..1da60ce 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -151,6 +151,7 @@ gpg_sources = server.c          \
 	      trust.c $(trust_source) $(tofu_source) \
 	      $(card_source) \
 	      exec.c exec.h \
+              key-clean.c key-clean.h \
 	      key-check.c key-check.h
 
 gpg_SOURCES  = gpg.c \
diff --git a/g10/export.c b/g10/export.c
index c538dc1..44cf075 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -41,6 +41,8 @@
 #include "../common/init.h"
 #include "trustdb.h"
 #include "call-agent.h"
+#include "key-clean.h"
+
 
 /* An object to keep track of subkeys. */
 struct subkey_list_s
diff --git a/g10/import.c b/g10/import.c
index b43060d..fa7fc1f 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -41,6 +41,7 @@
 #include "../common/init.h"
 #include "../common/mbox-util.h"
 #include "key-check.h"
+#include "key-clean.h"
 
 
 struct import_stats_s
diff --git a/g10/trust.c b/g10/key-clean.c
similarity index 58%
copy from g10/trust.c
copy to g10/key-clean.c
index 6d4f0e7..d022ff4 100644
--- a/g10/trust.c
+++ b/g10/key-clean.c
@@ -1,7 +1,6 @@
-/* trust.c - High level trust functions
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- *               2008, 2012 Free Software Foundation, Inc.
- * Copyright (C) 2014 Werner Koch
+/* key-clean.c - Functions to clean a keyblock
+ * Copyright (C) 1998-2008, 2010-2011 Free Software Foundation, Inc.
+ * Copyright (C) 2014, 2016-2018  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -17,6 +16,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
 #include <config.h>
@@ -27,419 +27,14 @@
 #include "gpg.h"
 #include "keydb.h"
 #include "../common/util.h"
+#include "../common/host2net.h"
+#include "../common/i18n.h"
 #include "options.h"
 #include "packet.h"
 #include "main.h"
-#include "../common/i18n.h"
-#include "trustdb.h"
-#include "../common/host2net.h"
-
-
-/* Return true if key is disabled.  Note that this is usually used via
-   the pk_is_disabled macro.  */
-int
-cache_disabled_value (ctrl_t ctrl, PKT_public_key *pk)
-{
-#ifdef NO_TRUST_MODELS
-  (void)pk;
-  return 0;
-#else
-  return tdb_cache_disabled_value (ctrl, pk);
-#endif
-}
-
-
-void
-register_trusted_keyid (u32 *keyid)
-{
-#ifdef NO_TRUST_MODELS
-  (void)keyid;
-#else
-  tdb_register_trusted_keyid (keyid);
-#endif
-}
-
-
-void
-register_trusted_key (const char *string)
-{
-#ifdef NO_TRUST_MODELS
-  (void)string;
-#else
-
-  /* Some users have conf files with entries like
-   *   trusted-key 0x1234567812345678    # foo
-   * That is obviously wrong.  Before fixing bug#1206 trailing garbage
-   * on a key specification if was ignored.  We detect the above use case
-   * here and  cut off the junk-looking-like-a comment.  */
-  if (strchr (string, '#'))
-    {
-      char *buf;
-
-      buf = xtrystrdup (string);
-      if (buf)
-        {
-          *strchr (buf, '#') = 0;
-          tdb_register_trusted_key (buf);
-          xfree (buf);
-          return;
-        }
-    }
-
-  tdb_register_trusted_key (string);
-#endif
-}
-
-
-

-/*
- * This function returns a letter for a trust value.  Trust flags
- * are ignored.
- */
-static int
-trust_letter (unsigned int value)
-{
-  switch( (value & TRUST_MASK) )
-    {
-    case TRUST_UNKNOWN:   return '-';
-    case TRUST_EXPIRED:   return 'e';
-    case TRUST_UNDEFINED: return 'q';
-    case TRUST_NEVER:     return 'n';
-    case TRUST_MARGINAL:  return 'm';
-    case TRUST_FULLY:     return 'f';
-    case TRUST_ULTIMATE:  return 'u';
-    default:              return '?';
-    }
-}
-
-
-/* The strings here are similar to those in
-   pkclist.c:do_edit_ownertrust() */
-const char *
-trust_value_to_string (unsigned int value)
-{
-  switch ((value & TRUST_MASK))
-    {
-    case TRUST_UNKNOWN:   return _("unknown");
-    case TRUST_EXPIRED:   return _("expired");
-    case TRUST_UNDEFINED: return _("undefined");
-    case TRUST_NEVER:     return _("never");
-    case TRUST_MARGINAL:  return _("marginal");
-    case TRUST_FULLY:     return _("full");
-    case TRUST_ULTIMATE:  return _("ultimate");
-    default:              return "err";
-    }
-}
-
-
-int
-string_to_trust_value (const char *str)
-{
-  if (!ascii_strcasecmp (str, "undefined"))
-    return TRUST_UNDEFINED;
-  else if (!ascii_strcasecmp (str, "never"))
-    return TRUST_NEVER;
-  else if (!ascii_strcasecmp (str, "marginal"))
-    return TRUST_MARGINAL;
-  else if (!ascii_strcasecmp (str, "full"))
-    return TRUST_FULLY;
-  else if (!ascii_strcasecmp(str, "ultimate"))
-    return TRUST_ULTIMATE;
-  else
-    return -1;
-}
-
-
-const char *
-uid_trust_string_fixed (ctrl_t ctrl, PKT_public_key *key, PKT_user_id *uid)
-{
-  if (!key && !uid)
-    {
-      /* TRANSLATORS: these strings are similar to those in
-         trust_value_to_string(), but are a fixed length.  This is needed to
-         make attractive information listings where columns line up
-         properly.  The value "10" should be the length of the strings you
-         choose to translate to.  This is the length in printable columns.
-         It gets passed to atoi() so everything after the number is
-         essentially a comment and need not be translated.  Either key and
-         uid are both NULL, or neither are NULL. */
-      return _("10 translator see trust.c:uid_trust_string_fixed");
-    }
-  else if(uid->flags.revoked || (key && key->flags.revoked))
-    return                         _("[ revoked]");
-  else if(uid->flags.expired)
-    return                         _("[ expired]");
-  else if(key)
-    {
-      switch (get_validity (ctrl, NULL, key, uid, NULL, 0) & TRUST_MASK)
-        {
-        case TRUST_UNKNOWN:   return _("[ unknown]");
-        case TRUST_EXPIRED:   return _("[ expired]");
-        case TRUST_UNDEFINED: return _("[  undef ]");
-        case TRUST_NEVER:     return _("[  never ]");
-        case TRUST_MARGINAL:  return _("[marginal]");
-        case TRUST_FULLY:     return _("[  full  ]");
-        case TRUST_ULTIMATE:  return _("[ultimate]");
-        }
-    }
-
-  return "err";
-}
-
-
-

-/*
- * Return the assigned ownertrust value for the given public key.
- * The key should be the primary key.
- */
-unsigned int
-get_ownertrust (ctrl_t ctrl, PKT_public_key *pk)
-{
-#ifdef NO_TRUST_MODELS
-  (void)pk;
-  return TRUST_UNKNOWN;
-#else
-  return tdb_get_ownertrust (ctrl, pk, 0);
-#endif
-}
-
-
-/*
- * Same as get_ownertrust but this takes the minimum ownertrust value
- * into account, and will bump up the value as needed.  NO_CREATE
- * inhibits creation of a trustdb it that does not yet exists.
- */
-static int
-get_ownertrust_with_min (ctrl_t ctrl, PKT_public_key *pk, int no_create)
-{
-#ifdef NO_TRUST_MODELS
-  (void)pk;
-  return TRUST_UNKNOWN;
-#else
-  unsigned int otrust, otrust_min;
-
-  /* Shortcut instead of doing the same twice in the two tdb_get
-   * functions: If the caller asked not to create a trustdb we call
-   * init_trustdb directly and allow it to fail with an error code for
-   * a non-existing trustdb.  */
-  if (no_create && init_trustdb (ctrl, 1))
-    return TRUST_UNKNOWN;
-
-  otrust = (tdb_get_ownertrust (ctrl, pk, no_create) & TRUST_MASK);
-  otrust_min = tdb_get_min_ownertrust (ctrl, pk, no_create);
-  if (otrust < otrust_min)
-    {
-      /* If the trust that the user has set is less than the trust
-	 that was calculated from a trust signature chain, use the
-	 higher of the two.  We do this here and not in
-	 get_ownertrust since the underlying ownertrust should not
-	 really be set - just the appearance of the ownertrust. */
-
-      otrust = otrust_min;
-    }
-
-  return otrust;
-#endif
-}
-
-
-/*
- * Same as get_ownertrust but return a trust letter instead of an
- * value.  This takes the minimum ownertrust value into account.  If
- * NO_CREATE is set, no efforts for creating a trustdb will be taken.
- */
-int
-get_ownertrust_info (ctrl_t ctrl, PKT_public_key *pk, int no_create)
-{
-  return trust_letter (get_ownertrust_with_min (ctrl, pk, no_create));
-}
-
-
-/*
- * Same as get_ownertrust but return a trust string instead of an
- * value.  This takes the minimum ownertrust value into account.  If
- * NO_CREATE is set, no efforts for creating a trustdb will be taken.
- */
-const char *
-get_ownertrust_string (ctrl_t ctrl, PKT_public_key *pk, int no_create)
-{
-  return trust_value_to_string (get_ownertrust_with_min (ctrl, pk, no_create));
-}
-
-
-/*
- * Set the trust value of the given public key to the new value.
- * The key should be a primary one.
- */
-void
-update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust)
-{
-#ifdef NO_TRUST_MODELS
-  (void)pk;
-  (void)new_trust;
-#else
-  tdb_update_ownertrust (ctrl, pk, new_trust);
-#endif
-}
-
-
-int
-clear_ownertrusts (ctrl_t ctrl, PKT_public_key *pk)
-{
-#ifdef NO_TRUST_MODELS
-  (void)pk;
-  return 0;
-#else
-  return tdb_clear_ownertrusts (ctrl, pk);
-#endif
-}
-
-
-void
-revalidation_mark (ctrl_t ctrl)
-{
-#ifndef NO_TRUST_MODELS
-  tdb_revalidation_mark (ctrl);
-#endif
-}
-
-
-void
-check_trustdb_stale (ctrl_t ctrl)
-{
-#ifndef NO_TRUST_MODELS
-  tdb_check_trustdb_stale (ctrl);
-#else
-  (void)ctrl;
-#endif
-}
-
-
-void
-check_or_update_trustdb (ctrl_t ctrl)
-{
-#ifndef NO_TRUST_MODELS
-  tdb_check_or_update (ctrl);
-#else
-  (void)ctrl;
-#endif
-}
-
-
-/*
- * Return the validity information for KB/PK (at least one must be
- * non-NULL).  If the namehash is not NULL, the validity of the
- * corresponding user ID is returned, otherwise, a reasonable value
- * for the entire key is returned.
- */
-unsigned int
-get_validity (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk, PKT_user_id *uid,
-              PKT_signature *sig, int may_ask)
-{
-  int rc;
-  unsigned int validity;
-  u32 kid[2];
-  PKT_public_key *main_pk;
-
-  if (kb && pk)
-    log_assert (keyid_cmp (pk_main_keyid (pk),
-                           pk_main_keyid (kb->pkt->pkt.public_key)) == 0);
-
-  if (! pk)
-    {
-      log_assert (kb);
-      pk = kb->pkt->pkt.public_key;
-    }
-
-  if (uid)
-    namehash_from_uid (uid);
-
-  keyid_from_pk (pk, kid);
-  if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1])
-    {
-      /* This is a subkey - get the mainkey. */
-      if (kb)
-        main_pk = kb->pkt->pkt.public_key;
-      else
-        {
-          main_pk = xmalloc_clear (sizeof *main_pk);
-          rc = get_pubkey (ctrl, main_pk, pk->main_keyid);
-          if (rc)
-            {
-              char *tempkeystr = xstrdup (keystr (pk->main_keyid));
-              log_error ("error getting main key %s of subkey %s: %s\n",
-                         tempkeystr, keystr (kid), gpg_strerror (rc));
-              xfree (tempkeystr);
-              validity = TRUST_UNKNOWN;
-              goto leave;
-            }
-        }
-    }
-  else
-    main_pk = pk;
-
-#ifdef NO_TRUST_MODELS
-  validity = TRUST_UNKNOWN;
-#else
-  validity = tdb_get_validity_core (ctrl, kb, pk, uid, main_pk, sig, may_ask);
-#endif
-
- leave:
-  /* Set some flags direct from the key */
-  if (main_pk->flags.revoked)
-    validity |= TRUST_FLAG_REVOKED;
-  if (main_pk != pk && pk->flags.revoked)
-    validity |= TRUST_FLAG_SUB_REVOKED;
-  /* Note: expiration is a trust value and not a flag - don't know why
-   * I initially designed it that way.  */
-  if (main_pk->has_expired || pk->has_expired)
-    validity = ((validity & (~TRUST_MASK | TRUST_FLAG_PENDING_CHECK))
-                | TRUST_EXPIRED);
-
-  if (main_pk != pk && !kb)
-    free_public_key (main_pk);
-  return validity;
-}
-
-
-int
-get_validity_info (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk,
-                   PKT_user_id *uid)
-{
-  int trustlevel;
-
-  if (kb && pk)
-    log_assert (keyid_cmp (pk_main_keyid (pk),
-                           pk_main_keyid (kb->pkt->pkt.public_key)) == 0);
-
-  if (! pk && kb)
-    pk = kb->pkt->pkt.public_key;
-  if (!pk)
-    return '?';  /* Just in case a NULL PK is passed.  */
-
-  trustlevel = get_validity (ctrl, kb, pk, uid, NULL, 0);
-  if ((trustlevel & TRUST_FLAG_REVOKED))
-    return 'r';
-  return trust_letter (trustlevel);
-}
-
-
-const char *
-get_validity_string (ctrl_t ctrl, 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 (ctrl, NULL, pk, uid, NULL, 0);
-  if ((trustlevel & TRUST_FLAG_REVOKED))
-    return _("revoked");
-  return trust_value_to_string (trustlevel);
-}
+#include "key-clean.h"
 
 
-

 /*
  * Mark the signature of the given UID which are used to certify it.
  * To do this, we first revmove all signatures which are not valid and
diff --git a/g10/key-clean.h b/g10/key-clean.h
new file mode 100644
index 0000000..4dfd950
--- /dev/null
+++ b/g10/key-clean.h
@@ -0,0 +1,37 @@
+/* key-clean.h - Functions to clean a keyblock
+ * Copyright (C) 2018 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#ifndef GNUPG_G10_KEY_CLEAN_H
+#define GNUPG_G10_KEY_CLEAN_H
+
+#include "gpg.h"
+
+void mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
+                            u32 *main_kid, struct key_item *klist,
+                            u32 curtime, u32 *next_expire);
+
+void clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
+                    int noisy, int self_only,
+                    int *uids_cleaned, int *sigs_cleaned);
+void clean_key (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
+                int *uids_cleaned,int *sigs_cleaned);
+
+
+#endif /*GNUPG_G10_KEY_CLEAN_H*/
diff --git a/g10/keydb.h b/g10/keydb.h
index 70949e4..8e1a724 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -64,6 +64,20 @@ struct kbnode_struct {
 #define is_cloned_kbnode(a)   ((a)->private_flag & 2)
 
 
+/*
+ * A structure to store key identification as well as some stuff
+ * needed for key validation.
+ */
+struct key_item {
+  struct key_item *next;
+  unsigned int ownertrust,min_ownertrust;
+  byte trust_depth;
+  byte trust_value;
+  char *trust_regexp;
+  u32 kid[2];
+};
+
+
 /* Bit flags used with build_pk_list.  */
 enum
   {
@@ -133,6 +147,22 @@ enum
   };
 
 
+/*
+ * Check whether the signature SIG is in the klist K.
+ */
+static inline struct key_item *
+is_in_klist (struct key_item *k, PKT_signature *sig)
+{
+  for (; k; k = k->next)
+    {
+      if (k->kid[0] == sig->keyid[0] && k->kid[1] == sig->keyid[1])
+        return k;
+    }
+  return NULL;
+}
+
+
+
 /*-- keydb.c --*/
 
 #define KEYDB_RESOURCE_FLAG_PRIMARY  2  /* The primary resource.  */
diff --git a/g10/keyedit.c b/g10/keyedit.c
index c3eca93..b717960 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -49,6 +49,7 @@
 #include "../common/host2net.h"
 #include "tofu.h"
 #include "key-check.h"
+#include "key-clean.h"
 #include "keyedit.h"
 
 static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
diff --git a/g10/trust.c b/g10/trust.c
index 6d4f0e7..bd1c894 100644
--- a/g10/trust.c
+++ b/g10/trust.c
@@ -437,391 +437,3 @@ get_validity_string (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
     return _("revoked");
   return trust_value_to_string (trustlevel);
 }
-
-
-

-/*
- * Mark the signature of the given UID which are used to certify it.
- * To do this, we first revmove all signatures which are not valid and
- * from the remain ones we look for the latest one.  If this is not a
- * certification revocation signature we mark the signature by setting
- * node flag bit 8.  Revocations are marked with flag 11, and sigs
- * from unavailable keys are marked with flag 12.  Note that flag bits
- * 9 and 10 are used for internal purposes.
- */
-void
-mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
-                       u32 *main_kid, struct key_item *klist,
-                       u32 curtime, u32 *next_expire)
-{
-  kbnode_t node;
-  PKT_signature *sig;
-
-  /* First check all signatures.  */
-  for (node=uidnode->next; node; node = node->next)
-    {
-      int rc;
-
-      node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
-      if (node->pkt->pkttype == PKT_USER_ID
-          || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-          || node->pkt->pkttype == PKT_SECRET_SUBKEY)
-        break; /* ready */
-      if (node->pkt->pkttype != PKT_SIGNATURE)
-        continue;
-      sig = node->pkt->pkt.signature;
-      if (main_kid
-	  && sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
-        continue; /* ignore self-signatures if we pass in a main_kid */
-      if (!IS_UID_SIG(sig) && !IS_UID_REV(sig))
-        continue; /* we only look at these signature classes */
-      if(sig->sig_class>=0x11 && sig->sig_class<=0x13 &&
-	 sig->sig_class-0x10<opt.min_cert_level)
-	continue; /* treat anything under our min_cert_level as an
-		     invalid signature */
-      if (klist && !is_in_klist (klist, sig))
-        continue;  /* no need to check it then */
-      if ((rc=check_key_signature (ctrl, keyblock, node, NULL)))
-	{
-	  /* we ignore anything that won't verify, but tag the
-	     no_pubkey case */
-	  if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY)
-            node->flag |= 1<<12;
-          continue;
-        }
-      node->flag |= 1<<9;
-    }
-  /* Reset the remaining flags. */
-  for (; node; node = node->next)
-    node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
-
-  /* kbnode flag usage: bit 9 is here set for signatures to consider,
-   * bit 10 will be set by the loop to keep track of keyIDs already
-   * processed, bit 8 will be set for the usable signatures, and bit
-   * 11 will be set for usable revocations. */
-
-  /* For each cert figure out the latest valid one.  */
-  for (node=uidnode->next; node; node = node->next)
-    {
-      KBNODE n, signode;
-      u32 kid[2];
-      u32 sigdate;
-
-      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-          || node->pkt->pkttype == PKT_SECRET_SUBKEY)
-        break;
-      if ( !(node->flag & (1<<9)) )
-        continue; /* not a node to look at */
-      if ( (node->flag & (1<<10)) )
-        continue; /* signature with a keyID already processed */
-      node->flag |= (1<<10); /* mark this node as processed */
-      sig = node->pkt->pkt.signature;
-      signode = node;
-      sigdate = sig->timestamp;
-      kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1];
-
-      /* Now find the latest and greatest signature */
-      for (n=uidnode->next; n; n = n->next)
-        {
-          if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY
-              || n->pkt->pkttype == PKT_SECRET_SUBKEY)
-            break;
-          if ( !(n->flag & (1<<9)) )
-            continue;
-          if ( (n->flag & (1<<10)) )
-            continue; /* shortcut already processed signatures */
-          sig = n->pkt->pkt.signature;
-          if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1])
-            continue;
-          n->flag |= (1<<10); /* mark this node as processed */
-
-	  /* If signode is nonrevocable and unexpired and n isn't,
-             then take signode (skip).  It doesn't matter which is
-             older: if signode was older then we don't want to take n
-             as signode is nonrevocable.  If n was older then we're
-             automatically fine. */
-
-	  if(((IS_UID_SIG(signode->pkt->pkt.signature) &&
-	       !signode->pkt->pkt.signature->flags.revocable &&
-	       (signode->pkt->pkt.signature->expiredate==0 ||
-		signode->pkt->pkt.signature->expiredate>curtime))) &&
-	     (!(IS_UID_SIG(n->pkt->pkt.signature) &&
-		!n->pkt->pkt.signature->flags.revocable &&
-		(n->pkt->pkt.signature->expiredate==0 ||
-		 n->pkt->pkt.signature->expiredate>curtime))))
-	    continue;
-
-	  /* If n is nonrevocable and unexpired and signode isn't,
-             then take n.  Again, it doesn't matter which is older: if
-             n was older then we don't want to take signode as n is
-             nonrevocable.  If signode was older then we're
-             automatically fine. */
-
-	  if((!(IS_UID_SIG(signode->pkt->pkt.signature) &&
-		!signode->pkt->pkt.signature->flags.revocable &&
-		(signode->pkt->pkt.signature->expiredate==0 ||
-		 signode->pkt->pkt.signature->expiredate>curtime))) &&
-	     ((IS_UID_SIG(n->pkt->pkt.signature) &&
-	       !n->pkt->pkt.signature->flags.revocable &&
-	       (n->pkt->pkt.signature->expiredate==0 ||
-		n->pkt->pkt.signature->expiredate>curtime))))
-            {
-              signode = n;
-              sigdate = sig->timestamp;
-	      continue;
-            }
-
-	  /* At this point, if it's newer, it goes in as the only
-             remaining possibilities are signode and n are both either
-             revocable or expired or both nonrevocable and unexpired.
-             If the timestamps are equal take the later ordered
-             packet, presuming that the key packets are hopefully in
-             their original order. */
-
-          if (sig->timestamp >= sigdate)
-            {
-              signode = n;
-              sigdate = sig->timestamp;
-            }
-        }
-
-      sig = signode->pkt->pkt.signature;
-      if (IS_UID_SIG (sig))
-        { /* this seems to be a usable one which is not revoked.
-           * Just need to check whether there is an expiration time,
-           * We do the expired certification after finding a suitable
-           * certification, the assumption is that a signator does not
-           * want that after the expiration of his certificate the
-           * system falls back to an older certification which has a
-           * different expiration time */
-          const byte *p;
-          u32 expire;
-
-          p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL );
-          expire = p? sig->timestamp + buf32_to_u32(p) : 0;
-
-          if (expire==0 || expire > curtime )
-            {
-              signode->flag |= (1<<8); /* yeah, found a good cert */
-              if (next_expire && expire && expire < *next_expire)
-                *next_expire = expire;
-            }
-        }
-      else
-	signode->flag |= (1<<11);
-    }
-}
-
-
-static int
-clean_sigs_from_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
-                     int noisy, int self_only)
-{
-  int deleted = 0;
-  kbnode_t node;
-  u32 keyid[2];
-
-  log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY
-              || keyblock->pkt->pkttype == PKT_SECRET_KEY);
-
-  keyid_from_pk (keyblock->pkt->pkt.public_key, keyid);
-
-  /* Passing in a 0 for current time here means that we'll never weed
-     out an expired sig.  This is correct behavior since we want to
-     keep the most recent expired sig in a series. */
-  mark_usable_uid_certs (ctrl, keyblock, uidnode, NULL, NULL, 0, NULL);
-
-  /* What we want to do here is remove signatures that are not
-     considered as part of the trust calculations.  Thus, all invalid
-     signatures are out, as are any signatures that aren't the last of
-     a series of uid sigs or revocations It breaks down like this:
-     coming out of mark_usable_uid_certs, if a sig is unflagged, it is
-     not even a candidate.  If a sig has flag 9 or 10, that means it
-     was selected as a candidate and vetted.  If a sig has flag 8 it
-     is a usable signature.  If a sig has flag 11 it is a usable
-     revocation.  If a sig has flag 12 it was issued by an unavailable
-     key.  "Usable" here means the most recent valid
-     signature/revocation in a series from a particular signer.
-
-     Delete everything that isn't a usable uid sig (which might be
-     expired), a usable revocation, or a sig from an unavailable
-     key. */
-
-  for (node=uidnode->next;
-       node && node->pkt->pkttype==PKT_SIGNATURE;
-       node=node->next)
-    {
-      int keep;
-
-      keep = self_only? (node->pkt->pkt.signature->keyid[0] == keyid[0]
-                         && node->pkt->pkt.signature->keyid[1] == keyid[1]) : 1;
-
-      /* Keep usable uid sigs ... */
-      if ((node->flag & (1<<8)) && keep)
-	continue;
-
-      /* ... and usable revocations... */
-      if ((node->flag & (1<<11)) && keep)
-	continue;
-
-      /* ... and sigs from unavailable keys. */
-      /* disabled for now since more people seem to want sigs from
-	 unavailable keys removed altogether.  */
-      /*
-	if(node->flag & (1<<12))
-	continue;
-      */
-
-      /* Everything else we delete */
-
-      /* At this point, if 12 is set, the signing key was unavailable.
-	 If 9 or 10 is set, it's superseded.  Otherwise, it's
-	 invalid. */
-
-      if (noisy)
-	log_info ("removing signature from key %s on user ID \"%s\": %s\n",
-                  keystr (node->pkt->pkt.signature->keyid),
-                  uidnode->pkt->pkt.user_id->name,
-                  node->flag&(1<<12)? "key unavailable":
-                  node->flag&(1<<9)?  "signature superseded"
-                  /* */               :"invalid signature"  );
-
-      delete_kbnode (node);
-      deleted++;
-    }
-
-  return deleted;
-}
-
-
-/* This is substantially easier than clean_sigs_from_uid since we just
-   have to establish if the uid has a valid self-sig, is not revoked,
-   and is not expired.  Note that this does not take into account
-   whether the uid has a trust path to it - just whether the keyholder
-   themselves has certified the uid.  Returns true if the uid was
-   compacted.  To "compact" a user ID, we simply remove ALL signatures
-   except the self-sig that caused the user ID to be remove-worthy.
-   We don't actually remove the user ID packet itself since it might
-   be resurrected in a later merge.  Note that this function requires
-   that the caller has already done a merge_keys_and_selfsig().
-
-   TODO: change the import code to allow importing a uid with only a
-   revocation if the uid already exists on the keyring. */
-
-static int
-clean_uid_from_key (kbnode_t keyblock, kbnode_t uidnode, int noisy)
-{
-  kbnode_t node;
-  PKT_user_id *uid = uidnode->pkt->pkt.user_id;
-  int deleted = 0;
-
-  log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY
-              || keyblock->pkt->pkttype == PKT_SECRET_KEY);
-  log_assert (uidnode->pkt->pkttype==PKT_USER_ID);
-
-  /* Skip valid user IDs, compacted user IDs, and non-self-signed user
-     IDs if --allow-non-selfsigned-uid is set. */
-  if (uid->created
-      || uid->flags.compacted
-      || (!uid->flags.expired && !uid->flags.revoked && opt.allow_non_selfsigned_uid))
-    return 0;
-
-  for (node=uidnode->next;
-       node && node->pkt->pkttype == PKT_SIGNATURE;
-      node=node->next)
-    {
-      if (!node->pkt->pkt.signature->flags.chosen_selfsig)
-        {
-          delete_kbnode (node);
-          deleted = 1;
-          uidnode->pkt->pkt.user_id->flags.compacted = 1;
-        }
-    }
-
-  if (noisy)
-    {
-      const char *reason;
-      char *user = utf8_to_native (uid->name, uid->len, 0);
-
-      if (uid->flags.revoked)
-	reason = _("revoked");
-      else if (uid->flags.expired)
-	reason = _("expired");
-      else
-	reason = _("invalid");
-
-      log_info ("compacting user ID \"%s\" on key %s: %s\n",
-                user, keystr_from_pk (keyblock->pkt->pkt.public_key),
-                reason);
-
-      xfree (user);
-    }
-
-  return deleted;
-}
-
-
-/* Needs to be called after a merge_keys_and_selfsig() */
-void
-clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
-               int noisy, int self_only, int *uids_cleaned, int *sigs_cleaned)
-{
-  int dummy = 0;
-
-  log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY
-              || keyblock->pkt->pkttype == PKT_SECRET_KEY);
-  log_assert (uidnode->pkt->pkttype==PKT_USER_ID);
-
-  if (!uids_cleaned)
-    uids_cleaned = &dummy;
-
-  if (!sigs_cleaned)
-    sigs_cleaned = &dummy;
-
-  /* Do clean_uid_from_key first since if it fires off, we don't have
-     to bother with the other.  */
-  *uids_cleaned += clean_uid_from_key (keyblock, uidnode, noisy);
-  if (!uidnode->pkt->pkt.user_id->flags.compacted)
-    *sigs_cleaned += clean_sigs_from_uid (ctrl, keyblock, uidnode,
-                                          noisy, self_only);
-}
-
-
-/* NB: This function marks the deleted nodes only and the caller is
- * responsible to skip or remove them.  */
-void
-clean_key (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
-           int *uids_cleaned, int *sigs_cleaned)
-{
-  kbnode_t node;
-
-  merge_keys_and_selfsig (ctrl, keyblock);
-
-  for (node = keyblock->next;
-       node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-                    || node->pkt->pkttype == PKT_SECRET_SUBKEY);
-       node = node->next)
-    {
-      if (node->pkt->pkttype == PKT_USER_ID)
-        clean_one_uid (ctrl, keyblock, node, noisy, self_only,
-                       uids_cleaned, sigs_cleaned);
-    }
-
-  /* Remove bogus subkey binding signatures: The only signatures
-   * allowed are of class 0x18 and 0x28.  */
-  log_assert (!node || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
-                        || node->pkt->pkttype == PKT_SECRET_SUBKEY));
-  for (; node; node = node->next)
-    {
-      if (is_deleted_kbnode (node))
-        continue;
-      if (node->pkt->pkttype == PKT_SIGNATURE
-          && !(IS_SUBKEY_SIG (node->pkt->pkt.signature)
-                || IS_SUBKEY_REV (node->pkt->pkt.signature)))
-        {
-          delete_kbnode (node);
-          if (sigs_cleaned)
-            ++*sigs_cleaned;
-        }
-    }
-}
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 2c2d239..8ef6db5 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -41,6 +41,7 @@
 #include "tdbio.h"
 #include "trustdb.h"
 #include "tofu.h"
+#include "key-clean.h"
 
 
 typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
diff --git a/g10/trustdb.h b/g10/trustdb.h
index 4bc4ca9..d52fc53 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -46,36 +46,6 @@
 #define NAMEHASH_LEN  20
 
 
-/*
- * A structure to store key identification as well as some stuff needed
- * for validation
- */
-struct key_item {
-  struct key_item *next;
-  unsigned int ownertrust,min_ownertrust;
-  byte trust_depth;
-  byte trust_value;
-  char *trust_regexp;
-  u32 kid[2];
-};
-
-
-/*
- * Check whether the signature SIG is in the klist K.
- */
-static inline struct key_item *
-is_in_klist (struct key_item *k, PKT_signature *sig)
-{
-  for (; k; k = k->next)
-    {
-      if (k->kid[0] == sig->keyid[0] && k->kid[1] == sig->keyid[1])
-        return k;
-    }
-  return NULL;
-}
-
-
-
 /*-- trust.c --*/
 int cache_disabled_value (ctrl_t ctrl, PKT_public_key *pk);
 void register_trusted_keyid (u32 *keyid);
@@ -103,17 +73,6 @@ int get_validity_info (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk,
 const char *get_validity_string (ctrl_t ctrl,
                                  PKT_public_key *pk, PKT_user_id *uid);
 
-void mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
-                            u32 *main_kid, struct key_item *klist,
-                            u32 curtime, u32 *next_expire);
-
-void clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
-                    int noisy, int self_only,
-                    int *uids_cleaned, int *sigs_cleaned);
-void clean_key (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
-                int *uids_cleaned,int *sigs_cleaned);
-
-
 
 /*-- trustdb.c --*/
 void tdb_register_trusted_keyid (u32 *keyid);

-----------------------------------------------------------------------

Summary of changes:
 g10/Makefile.am              |   1 +
 g10/export.c                 |  19 +-
 g10/import.c                 |  31 ++-
 g10/{trust.c => key-clean.c} | 544 ++++++++++---------------------------------
 g10/key-clean.h              |  52 +++++
 g10/keydb.h                  |  30 +++
 g10/keyedit.c                |   1 +
 g10/trust.c                  | 388 ------------------------------
 g10/trustdb.c                |   1 +
 g10/trustdb.h                |  41 ----
 10 files changed, 249 insertions(+), 859 deletions(-)
 copy g10/{trust.c => key-clean.c} (58%)
 create mode 100644 g10/key-clean.h


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list