[git] GnuPG - branch, master, updated. gnupg-2.1.16-17-g44c17bc

by Neal H. Walfield cvs at cvs.gnupg.org
Tue Nov 22 15:26:42 CET 2016


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, master has been updated
       via  44c17bcb003a3330f595a6ab144e8439b7b630cb (commit)
      from  5c2db9dedfe9dbb14ffec24751ca23a69cead94e (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 44c17bcb003a3330f595a6ab144e8439b7b630cb
Author: Neal H. Walfield <neal at g10code.com>
Date:   Tue Nov 22 15:05:59 2016 +0100

    g10: If the set of UTKs changes, invalidate any changed policies.
    
    * g10/trustdb.c (tdb_utks): New function.
    * g10/tofu.c (check_utks): New function.
    (initdb): Call it.
    * tests/openpgp/tofu.scm: Modify test to check the effective policy of
    keys whose effective policy changes when we change the set of UTKs.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>
    
    If the set of ultimately trusted keys changes, then it is possible
    that a binding's effective policy changes.  To deal with this, we
    detect when the set of ultimately trusted keys changes and invalidate
    all cached policies.

diff --git a/g10/tofu.c b/g10/tofu.c
index 6eb7f5e..d7730a3 100644
--- a/g10/tofu.c
+++ b/g10/tofu.c
@@ -506,6 +506,152 @@ version_check_cb (void *cookie, int argc, char **argv, char **azColName)
   return 1;
 }
 
+static int
+check_utks (sqlite3 *db)
+{
+  int rc;
+  char *err = NULL;
+  struct key_item *utks;
+  struct key_item *ki;
+  int utk_count;
+  char *utks_string = NULL;
+  char keyid_str[16+1];
+  long utks_unchanged = 0;
+
+  /* An early version of the v1 format did not include the list of
+   * known ultimately trusted keys.
+   *
+   * This list is used to detect when the set of ultimately trusted
+   * keys changes.  We need to detect this to invalidate the effective
+   * policy, which can change if an ultimately trusted key is added or
+   * removed.  */
+  rc = sqlite3_exec (db,
+                     "create table if not exists ultimately_trusted_keys"
+                     " (keyid);\n",
+                     NULL, NULL, &err);
+  if (rc)
+    {
+      log_error (_("error creating 'ultimately_trusted_keys' TOFU table: %s\n"),
+                 err);
+      sqlite3_free (err);
+      goto out;
+    }
+
+
+  utks = tdb_utks ();
+  for (ki = utks, utk_count = 0; ki; ki = ki->next, utk_count ++)
+    ;
+
+  if (utk_count)
+    {
+      /* Build a list of keyids of the form "XXX","YYY","ZZZ".  */
+      int len = (1 + 16 + 1 + 1) * utk_count;
+      int o = 0;
+
+      utks_string = xmalloc (len);
+      *utks_string = 0;
+      for (ki = utks, utk_count = 0; ki; ki = ki->next, utk_count ++)
+        {
+          utks_string[o ++] = '\'';
+          format_keyid (ki->kid, KF_LONG,
+                        keyid_str, sizeof (keyid_str));
+          memcpy (&utks_string[o], keyid_str, 16);
+          o += 16;
+          utks_string[o ++] = '\'';
+          utks_string[o ++] = ',';
+        }
+      utks_string[o - 1] = 0;
+      log_assert (o == len);
+    }
+
+  rc = gpgsql_exec_printf
+    (db, get_single_unsigned_long_cb, &utks_unchanged, &err,
+     "select"
+     /* Removed UTKs?  (Known UTKs in current UTKs.)  */
+     "  ((select count(*) from ultimately_trusted_keys"
+     "     where (keyid in (%s))) == %d)"
+     " and"
+     /* New UTKs?  */
+     "  ((select count(*) from ultimately_trusted_keys"
+     "     where keyid not in (%s)) == 0);",
+     utks_string ? utks_string : "",
+     utk_count,
+     utks_string ? utks_string : "");
+  xfree (utks_string);
+  if (rc)
+    {
+      log_error (_("TOFU DB error"));
+      print_further_info ("checking if ultimately trusted keys changed: %s",
+                         err);
+      sqlite3_free (err);
+      goto out;
+    }
+
+  if (utks_unchanged)
+    goto out;
+
+  if (DBG_TRUST)
+    log_debug ("TOFU: ultimately trusted keys changed.\n");
+
+  /* Given that the set of ultimately trusted keys
+   * changed, clear any cached policies.  */
+  rc = gpgsql_exec_printf
+    (db, NULL, NULL, &err,
+     "update bindings set effective_policy = %d;",
+     TOFU_POLICY_NONE);
+  if (rc)
+    {
+      log_error (_("TOFU DB error"));
+      print_further_info ("clearing cached policies: %s", err);
+      sqlite3_free (err);
+      goto out;
+    }
+
+  /* Now, update the UTK table.  */
+  rc = sqlite3_exec (db,
+                     "drop table ultimately_trusted_keys;",
+                     NULL, NULL, &err);
+  if (rc)
+    {
+      log_error (_("TOFU DB error"));
+      print_further_info ("dropping ultimately_trusted_keys: %s", err);
+      sqlite3_free (err);
+      goto out;
+    }
+
+  rc = sqlite3_exec (db,
+                     "create table if not exists"
+                     " ultimately_trusted_keys (keyid);\n",
+                     NULL, NULL, &err);
+  if (rc)
+    {
+      log_error (_("TOFU DB error"));
+      print_further_info ("creating ultimately_trusted_keys: %s", err);
+      sqlite3_free (err);
+      goto out;
+    }
+
+  for (ki = utks; ki; ki = ki->next)
+    {
+      format_keyid (ki->kid, KF_LONG,
+                    keyid_str, sizeof (keyid_str));
+      rc = gpgsql_exec_printf
+        (db, NULL, NULL, &err,
+         "insert into ultimately_trusted_keys values ('%s');",
+         keyid_str);
+      if (rc)
+        {
+          log_error (_("TOFU DB error"));
+          print_further_info ("updating ultimately_trusted_keys: %s",
+                              err);
+          sqlite3_free (err);
+          goto out;
+        }
+    }
+
+ out:
+  return rc;
+}
 
 /* If the DB is new, initialize it.  Otherwise, check the DB's
    version.
@@ -727,6 +873,9 @@ initdb (sqlite3 *db)
 	}
     }
 
+  if (! rc)
+    rc = check_utks (db);
+
   if (rc)
     {
       rc = sqlite3_exec (db, "rollback;", NULL, NULL, &err);
diff --git a/g10/trustdb.c b/g10/trustdb.c
index edae6ef..51a8f22 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -324,6 +324,13 @@ tdb_keyid_is_utk (u32 *kid)
 
   return 0;
 }
+
+/* Return the list of ultimately trusted keys.  */
+struct key_item *
+tdb_utks (void)
+{
+  return utk_list;
+}
 

 /*********************************************
  *********** TrustDB stuff *******************
diff --git a/g10/trustdb.h b/g10/trustdb.h
index 77aa79d..45ecc56 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -117,6 +117,9 @@ void tdb_register_trusted_keyid (u32 *keyid);
 void tdb_register_trusted_key (const char *string);
 /* Returns whether KID is on the list of ultimately trusted keys.  */
 int tdb_keyid_is_utk (u32 *kid);
+/* Return the list of ultimately trusted keys.  The caller must not
+ * modify this list nor must it free the list.  */
+struct key_item *tdb_utks (void);
 void check_trustdb (ctrl_t ctrl);
 void update_trustdb (ctrl_t ctrl);
 int setup_trustdb( int level, const char *dbname );
diff --git a/tests/openpgp/tofu.scm b/tests/openpgp/tofu.scm
index 2a04d13..e1fa001 100755
--- a/tests/openpgp/tofu.scm
+++ b/tests/openpgp/tofu.scm
@@ -248,6 +248,21 @@
 ;; Alice has an ultimately trusted key and she signs Bob's key.  Then
 ;; Bob adds a new user id, "Alice".  TOFU should now detect a
 ;; conflict, because Alice only signed Bob's "Bob" user id.
+;;
+;;
+;; The Alice key:
+;;   pub   rsa2048 2016-10-11 [SC]
+;;         1938C3A0E4674B6C217AC0B987DB2814EC38277E
+;;   uid           [ultimate] Spy Cow <spy at cow.com>
+;;   sub   rsa2048 2016-10-11 [E]
+;;
+;; The Bob key:
+;;
+;;   pub   rsa2048 2016-10-11 [SC]
+;;         DC463A16E42F03240D76E8BA8B48C6BD871C2247
+;;   uid           [  full  ] Spy R. Cow <spy at cow.com>
+;;   uid           [  full  ] Spy R. Cow <spy at cow.de>
+;;   sub   rsa2048 2016-10-11 [E]
 
 (display "Checking UTK sigs...\n")
 (define GPG `(,(tool 'gpg) --no-permission-warning
@@ -279,12 +294,18 @@
 (call-check `(, at GPG --import ,(in-srcdir DIR (string-append KEYIDB "-1.gpg"))))
 (display "<\n")
 
+(checkpolicy KEYA "auto")
+(checkpolicy KEYB "auto")
+
 ;; Import the cross sigs.
 (display "    > Adding cross signatures. ")
 (call-check `(, at GPG --import ,(in-srcdir DIR (string-append KEYIDA "-2.gpg"))))
 (call-check `(, at GPG --import ,(in-srcdir DIR (string-append KEYIDB "-2.gpg"))))
 (display "<\n")
 
+(checkpolicy KEYA "auto")
+(checkpolicy KEYB "auto")
+
 ;; Make KEYA ultimately trusted.
 (display (string-append "    > Marking " KEYA " as ultimately trusted. "))
 (pipe:do

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

Summary of changes:
 g10/tofu.c             | 149 +++++++++++++++++++++++++++++++++++++++++++++++++
 g10/trustdb.c          |   7 +++
 g10/trustdb.h          |   3 +
 tests/openpgp/tofu.scm |  21 +++++++
 4 files changed, 180 insertions(+)


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




More information about the Gnupg-commits mailing list