[git] GnuPG - branch, master, updated. gnupg-2.1.15-317-gab89164

by Justus Winter cvs at cvs.gnupg.org
Thu Nov 3 15:08:27 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  ab89164be02012f1bf159c971853b8610e966301 (commit)
       via  1ec07cbc209f247fd85704f5701564e31aa56d0b (commit)
      from  d10b67b9bc32e8feff1be86e6646fc23e58fe45d (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 ab89164be02012f1bf159c971853b8610e966301
Author: Justus Winter <justus at g10code.com>
Date:   Thu Oct 27 18:48:51 2016 +0200

    g10: Improve and unify key selection for -r and --locate-keys.
    
    * g10/getkey.c (struct pubkey_cmp_cookie): New type.
    (key_is_ok, uid_is_ok, subkey_is_ok): New functions.
    (pubkey_cmp): Likewise.
    (get_best_pubkey_byname): Likewise.
    * g10/keydb.h (get_best_pubkey_byname): New prototype.
    * g10/keylist.c (locate_one): Use the new function.
    * g10/pkclist.c (find_and_check_key): Likewise.
    * tests/openpgp/Makefile.am (XTESTS): Add new test.
    (TEST_FILES): Add new files.
    * tests/openpgp/key-selection.scm: New file.
    * tests/openpgp/key-selection/0.asc: Likewise.
    * tests/openpgp/key-selection/1.asc: Likewise.
    * tests/openpgp/key-selection/2.asc: Likewise.
    * tests/openpgp/key-selection/3.asc: Likewise.
    * tests/openpgp/key-selection/4.asc: Likewise.
    --
    
    When a name resembling a mail address is given to either --locate-keys
    or --recipient, rank the search results and use only the most relevant
    key.
    
    This also lets us query which key will be used for encryption using
    --locate-keys.  However, note that --locate-keys may also return keys
    incapable of encryption, though it will prefer keys that have an
    encryption subkey.
    
    GnuPG-bug-id: 2359
    Signed-off-by: Justus Winter <justus at g10code.com>

diff --git a/g10/getkey.c b/g10/getkey.c
index 5ef5fc3..926575d 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -1461,6 +1461,211 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
   return rc;
 }
 
+

+
+/* Comparison machinery for get_best_pubkey_byname.  */
+
+/* First we have a struct to cache computed information about the key
+ * in question.  */
+struct pubkey_cmp_cookie
+{
+  int valid;			/* Is this cookie valid?  */
+  PKT_public_key key;		/* The key.  */
+  PKT_user_id *uid;		/* The matching UID packet.  */
+  unsigned int validity;	/* Computed validity of (KEY, UID).  */
+  u32 creation_time;		/* Creation time of the newest subkey
+                                   capable of encryption.  */
+};
+
+/* Then we have a series of helper functions.  */
+static int
+key_is_ok (const PKT_public_key *key)
+{
+  return ! key->has_expired && ! key->flags.revoked
+    && key->flags.valid && ! key->flags.disabled;
+}
+
+static int
+uid_is_ok (const PKT_public_key *key, const PKT_user_id *uid)
+{
+  return key_is_ok (key) && ! uid->is_revoked;
+}
+
+static int
+subkey_is_ok (const PKT_public_key *sub)
+{
+  return ! sub->flags.revoked && sub->flags.valid && ! sub->flags.disabled;
+}
+
+/* Finally this function compares a NEW key to the former candidate
+ * OLD.  Returns < 0 if the old key is worse, > 0 if the old key is
+ * better, == 0 if it is a tie.  */
+static int
+pubkey_cmp (ctrl_t ctrl, const char *name, struct pubkey_cmp_cookie *old,
+            struct pubkey_cmp_cookie *new, KBNODE new_keyblock)
+{
+  KBNODE n;
+
+  new->creation_time = 0;
+  for (n = find_next_kbnode (new_keyblock, PKT_PUBLIC_SUBKEY);
+       n; n = find_next_kbnode (n, PKT_PUBLIC_SUBKEY))
+    {
+      PKT_public_key *sub = n->pkt->pkt.public_key;
+
+      if ((sub->pubkey_usage & PUBKEY_USAGE_ENC) == 0)
+        continue;
+
+      if (! subkey_is_ok (sub))
+        continue;
+
+      if (sub->timestamp > new->creation_time)
+        new->creation_time = sub->timestamp;
+    }
+
+  for (n = find_next_kbnode (new_keyblock, PKT_USER_ID);
+       n; n = find_next_kbnode (n, PKT_USER_ID))
+    {
+      PKT_user_id *uid = n->pkt->pkt.user_id;
+      char *mbox = mailbox_from_userid (uid->name);
+      int match = mbox ? strcasecmp (name, mbox) == 0 : 0;
+
+      xfree (mbox);
+      if (! match)
+        continue;
+
+      new->uid = uid;
+      new->validity =
+        get_validity (ctrl, &new->key, uid, NULL, 0) & TRUST_MASK;
+      new->valid = 1;
+
+      if (! old->valid)
+        return -1;	/* No OLD key.  */
+
+      if (! uid_is_ok (&old->key, old->uid) && uid_is_ok (&new->key, uid))
+        return -1;	/* Validity of the NEW key is better.  */
+
+      if (old->validity < new->validity)
+        return -1;	/* Validity of the NEW key is better.  */
+
+      if (old->validity == new->validity && uid_is_ok (&new->key, uid)
+          && old->creation_time < new->creation_time)
+        return -1;	/* Both keys are of the same validity, but the
+                           NEW key is newer.  */
+    }
+
+  /* Stick with the OLD key.  */
+  return 1;
+}
+
+
+/* This function works like get_pubkey_byname, but if the name
+ * resembles a mail address, the results are ranked and only the best
+ * result is returned.  */
+int
+get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+                        const char *name, KBNODE *ret_keyblock,
+                        int include_unusable, int no_akl)
+{
+  int rc;
+  struct getkey_ctx_s *ctx = NULL;
+
+  rc = get_pubkey_byname (ctrl, &ctx, pk, name, ret_keyblock,
+                          NULL, include_unusable, no_akl);
+  if (rc)
+    {
+      if (ctx)
+        getkey_end (ctx);
+      if (retctx)
+        *retctx = NULL;
+      return rc;
+    }
+
+  if (is_valid_mailbox (name))
+    {
+      /* Rank results and return only the most relevant key.  */
+      struct pubkey_cmp_cookie best = { 0 }, new;
+      while (getkey_next (ctx, &new.key, NULL) == 0)
+        {
+          KBNODE new_keyblock = get_pubkeyblock (pk_keyid (&new.key));
+          int diff = pubkey_cmp (ctrl, name, &best, &new, new_keyblock);
+          release_kbnode (new_keyblock);
+          if (diff < 0)
+            {
+              /* New key is better.  */
+              release_public_key_parts (&best.key);
+              best = new;
+            }
+          else if (diff > 0)
+            {
+              /* Old key is better.  */
+              release_public_key_parts (&new.key);
+            }
+          else
+            {
+              /* A tie.  Keep the old key.  */
+              release_public_key_parts (&new.key);
+            }
+        }
+      getkey_end (ctx);
+      ctx = NULL;
+
+      if (best.valid)
+        {
+          if (retctx || ret_keyblock)
+            {
+              ctx = xtrycalloc (1, sizeof **retctx);
+              if (! ctx)
+                rc = gpg_error_from_syserror ();
+              else
+                {
+                  ctx->kr_handle = keydb_new ();
+                  if (! ctx->kr_handle)
+                    {
+                      xfree (ctx);
+                      *retctx = NULL;
+                      rc = gpg_error_from_syserror ();
+                    }
+                  else
+                    {
+                      u32 *keyid = pk_keyid (&best.key);
+                      ctx->exact = 1;
+                      ctx->nitems = 1;
+                      ctx->items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
+                      ctx->items[0].u.kid[0] = keyid[0];
+                      ctx->items[0].u.kid[1] = keyid[1];
+
+                      if (ret_keyblock)
+                        {
+                          release_kbnode (*ret_keyblock);
+                          *ret_keyblock = NULL;
+                          rc = getkey_next (ctx, NULL, ret_keyblock);
+                        }
+                    }
+                }
+            }
+
+          if (pk)
+            *pk = best.key;
+          else
+            release_public_key_parts (&best.key);
+        }
+    }
+
+  if (rc && ctx)
+    {
+      getkey_end (ctx);
+      ctx = NULL;
+    }
+
+  if (retctx && ctx)
+    *retctx = ctx;
+  else
+    getkey_end (ctx);
+
+  return rc;
+}
+
+

 
 /* Get a public key from a file.
  *
diff --git a/g10/keydb.h b/g10/keydb.h
index 35512bb..6133202 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -324,6 +324,13 @@ int get_pubkey_byname (ctrl_t ctrl,
                        KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
 		       int include_unusable, int no_akl );
 
+/* Likewise, but only return the best match if NAME resembles a mail
+ * address.  */
+int get_best_pubkey_byname (ctrl_t ctrl,
+			    GETKEY_CTX *retctx, PKT_public_key *pk,
+			    const char *name, KBNODE *ret_keyblock,
+			    int include_unusable, int no_akl);
+
 /* Get a public key directly from file FNAME.  */
 gpg_error_t get_pubkey_fromfile (ctrl_t ctrl,
                                  PKT_public_key *pk, const char *fname);
diff --git a/g10/keylist.c b/g10/keylist.c
index 212d77e..51dc409 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -650,7 +650,7 @@ locate_one (ctrl_t ctrl, strlist_t names)
 
   for (sl = names; sl; sl = sl->next)
     {
-      rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
+      rc = get_best_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, 1, 0);
       if (rc)
 	{
 	  if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
diff --git a/g10/pkclist.c b/g10/pkclist.c
index da4cc06..eef3437 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -838,7 +838,7 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
   if (from_file)
     rc = get_pubkey_fromfile (ctrl, pk, name);
   else
-    rc = get_pubkey_byname (ctrl, NULL, pk, name, NULL, NULL, 0, 0);
+    rc = get_best_pubkey_byname (ctrl, NULL, pk, name, NULL, 0, 0);
   if (rc)
     {
       int code;
diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
index 5725e11..75e2fd4 100644
--- a/tests/openpgp/Makefile.am
+++ b/tests/openpgp/Makefile.am
@@ -83,6 +83,7 @@ XTESTS = \
 	export.scm \
 	ssh.scm \
 	quick-key-manipulation.scm \
+	key-selection.scm \
 	issue2015.scm \
 	issue2346.scm \
 	issue2417.scm \
@@ -124,7 +125,12 @@ TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \
 	     tofu/cross-sigs/871C2247-3.gpg \
 	     tofu/cross-sigs/871C2247-3.txt \
 	     tofu/cross-sigs/871C2247-4.gpg \
-	     tofu/cross-sigs/README
+	     tofu/cross-sigs/README \
+	     key-selection/0.asc \
+	     key-selection/1.asc \
+	     key-selection/2.asc \
+	     key-selection/3.asc \
+	     key-selection/4.asc
 
 data_files = data-500 data-9000 data-32000 data-80000 plain-large
 
diff --git a/tests/openpgp/key-selection.scm b/tests/openpgp/key-selection.scm
new file mode 100644
index 0000000..536f607
--- /dev/null
+++ b/tests/openpgp/key-selection.scm
@@ -0,0 +1,82 @@
+#!/usr/bin/env gpgscm
+
+;; Copyright (C) 2016 g10 Code GmbH
+;;
+;; 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 <http://www.gnu.org/licenses/>.
+
+(load (with-path "defs.scm"))
+
+;; This test assumes a fixed time of 2004-01-01.
+
+ ;; Redefine gpg with a fixed time.
+(define gpg `(, at gpg --faked-system-time=1072911600))
+
+;; We have a number of keys for Mr. Acejlnu Acdipr <acdipr at example.org>.
+(define mailbox "acdipr at example.org")
+
+;; The keys are sorted, from the least relevant to the most relevant
+;; key.
+(define keys
+  '(("ED087E9D3394340738E20A244892A3CF8F65EBAC"
+     "no encryption-capable subkey, created: 2003-11-30, expires: 2006-11-29"
+     4)
+    ("D7388651A1B7466D03B538428178E04B0BAA385B"
+     "encryption-capable subkey, created: 2000-12-31, expired: 2001-12-31"
+     0)
+    ("DDEF1BEC66C8BAC8D69CED2AEABED840EC98B024"
+     "encryption-capable subkey, created: 2001-12-31, expires: 2006-12-30"
+     1)
+    ("03FCFEDE014027DD897AD2F23D32670A96A9C2BF"
+     "encryption-capable subkey, created: 2002-12-31, expires: 2005-12-30"
+     2)
+    ("B95BD6175CB6339244355BA160B8117E6119CED6"
+     "encryption-capable subkeys, last created: 2003-05-31, expires: 2005-05-30"
+     3)))
+
+;; Accessors for the elements of KEYS.
+(define :fpr car)
+(define :comment cadr)
+(define :number caddr)
+(define (:filename key)
+  (in-srcdir "key-selection"
+	     (string-append (number->string (:number key)) ".asc")))
+
+(define (delete-keys which)
+  (call-check `(, at gpg --delete-keys ,@(map :fpr which))))
+
+(define (import-keys which)
+  (call-check `(, at gpg --import ,@(map :filename which))))
+
+(for-each-p'
+ "Checking key selection"
+ (lambda (set)
+   (import-keys set)
+   (let ((fpr (list-ref (assoc "fpr"
+			       (gpg-with-colons `(--locate-key ,mailbox)))
+			9))
+	 (expected (:fpr (last set))))
+     (unless (equal? fpr expected)
+	     (display "Given keys ")
+	     (apply echo (map :fpr set))
+	     (echo "This is what --locate-key says:")
+	     (display (call-popen `(, at gpg --locate-key ,mailbox) ""))
+	     (echo "This is the key we expected:")
+	     (display (call-popen `(, at gpg --list-keys ,expected) ""))
+	     (error "Expected" expected "but got" fpr)))
+   (delete-keys set))
+ (lambda (set)
+   (length set))
+ (filter (lambda (x) (not (null? x))) (powerset keys)))
diff --git a/tests/openpgp/key-selection/0.asc b/tests/openpgp/key-selection/0.asc
new file mode 100644
index 0000000..d40a98b
--- /dev/null
+++ b/tests/openpgp/key-selection/0.asc
@@ -0,0 +1,30 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBDpPvC8BCACqDbU+2znCURAocNMmcwCSYVl5l4Zbx6jcy9ON7y12Ai7CRSbX
+8Nb8kggit02pNFtb1l2NKad7DqR1f/WPqkQjZ6rvFHKEOsupqrUhpQ6dU3H94wuO
+g4M2PGsaxKAcw24qIoKkTotecLgUFMhduIq7u8kTnalTOW1o/18moVuoVNkDdO4Y
+I7n/dloVNv5Xkm5bS4VBdvUzJ9gvbqkynud/L6pSFeng0vVJQMN3tVbApcNzhLBs
+G5Fvf9Rve4V8xTeBYQ+VRO7H9nvaS8YFf07kTwUDS69Vs8qIaLKOQJL3F75CileN
+K7fb9OC3J4PNF0CDz+e2KkRRF6Q/xS8KXF9rABEBAAG0I0FjZWpsbnUgQWNkaXBy
+IDxhY2RpcHJAZXhhbXBsZS5vcmc+iQFUBBMBCAA+FiEE1ziGUaG3Rm0DtThCgXjg
+SwuqOFsFAjpPvC8CGwMFCQHhM4AFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQ
+gXjgSwuqOFt7Lgf8DFDVQ4JykT8njX0+JkemSL2UUDH2iVRWkU6tKZPGneEnQGMm
+iRfSX0im0pFHWxJ0vZsmUNq33Vr2sbvppT8Ti1rBx4TrdZ7PSEIEi1KTVSx6GKjr
+2ObCax2u1p+u+tC35GfhV1Y1pUcSZXc45C1o259ivekRJY/fw9DrvR7154S3ygjp
+lkEM4PC33216XMTqUG1sAWw40aDtKaiyp5J8zqLKXXjCnZsTWdj4uxB7E5WPjaEF
+ylON/h+Hfw2RMzlYRGTbUu2G/Ma0TiycGJvT78myCpnc5akcKVZu1Wu4VDBqBC1N
+dVcTzhJ5T4gwFCWHif3/MYqTVBnZSAVURtI3V7kBDQQ6T7wvAQgAuF5JaVAE9/Vv
+K1U+VSAAhWMGSp6fwezgWdj0rn1GBx3DtqQkYXoLRjTrlBf1qOO6NPbBUi1gz8R+
+IQTHsesIXiUSlMige3/HxdSOsbzKipm1SGJedqUz3H03+yfr82NT+QvQmlEGX9k6
+goPY9t3r+O3F6ab4mc5NxFKhj2XvbRyf8I9J+3w6zXBWwsgLHacTCa13zGz6B0NH
+dCk/2B6HTJeIJWpHdALQXp0/JcKWksw0Hsihpdu0QploUSPihZostRUKszOkugeu
+W0t3fmt6on4fIFWveh9NSVDYIHKVMRU8cl5vRXNNRTsYQOarIvjmoUHv5u+UpZcc
+iE/7wILNhQARAQABiQE8BBgBCAAmFiEE1ziGUaG3Rm0DtThCgXjgSwuqOFsFAjpP
+vC8CGwwFCQHhM4AACgkQgXjgSwuqOFv9GAgAkACyK3Km4jFBqw7ah2xMxWCkdpgu
+DdTi64ra6GyMQk/Lem8DzBO/ER/cavV9lg61qCOy7ecCNs7MhPiWZIod2bcV3JDZ
+AglnGgTQ+lSpPXFCk3eoRktRsXesgQ1dE30uR9pypEqZ0BYNZZ2G2hRqAnRgUOOI
+7THmf/X5w5KPKLlm3zOlGQomFy6lfOR9Zd5/QoKRNmuD9gNfSE+3vBvr+ISQPIev
+Ch2qeC/N0BP5EoVE4SXp8l2oaaVJLi/Yx2J6vfximeeaBPxsKjuA+GJu6IIhegnY
+X4kCxWStla+KuN0p0iNUh002pKybISuqyI9vgImH9Nh22Nf7mcRQWflR6A==
+=nyjX
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/key-selection/1.asc b/tests/openpgp/key-selection/1.asc
new file mode 100644
index 0000000..fea379c
--- /dev/null
+++ b/tests/openpgp/key-selection/1.asc
@@ -0,0 +1,30 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBDww7w4BCADCvhkDDCAAtDpLCUa2ryPqWxlSSVKdyY9ecqjgEswijsZ+2T6O
+Xr/50POpLbW9IWvHdvcifXUk1YZg8wLcnVIMwiZsdNSDM3MycoPoNc7pL5MaPGL6
+e9u+8HWX6aowOo5st6Y57HUeaKReH1Peb0avoEUIE9l4xqVx41AYrKViS7Zp5p9A
+67thNKMisZ8aYutlhmVQB/uDO7XiKal07vjftf6aZazNBC5ZBOj4G+/TLcKMox8h
+AaUJTkqsJcSCZTc7cMVjikmWItgKm6wIceGTpUGSvvZ3TnWUtgq3ivaMQrpyN3RT
+tVM5uO2Mh8Uzkq9YWh2V7IT+jGKztrpdPKu3ABEBAAG0I0FjZWpsbnUgQWNkaXBy
+IDxhY2RpcHJAZXhhbXBsZS5vcmc+iQFUBBMBCAA+FiEE3e8b7GbIusjWnO0q6r7Y
+QOyYsCQFAjww7w4CGwMFCQlmAYAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQ
+6r7YQOyYsCT0awf+NENO1grzmRfsyl8ODREmUlnnUAaRiZGQ0h+JkooXiwcm/p5O
+DupjRc5OLluDtnjTLMBwNk5ysX6yqSNTni9qCCpm62PaIopG+r8RyFPp4aRjR1Q3
+mbwHkKifLRBxDxeCDKdrqFs7hkVCYOxjyiaEZ2BYogqFDwHFoiE6UwQvwZfpNWex
+4Zx8nhoGpcegMMEiGREWCTi0H+zJrYOiVzV2jPQF5lkFkwYMQKNaNQv3L5v2/5AC
+Nu6Kej+oYcw/EA+o3OXYLxwa+tijfKqUxtndFsQS/lYSUNszxrcm7dOAx52DCMpC
+8MNHmwe3qmofO6G9svqG02bIZTdyJBob5nNBD7kBDQQ8MO8OAQgAttn9ru3Ou6+A
+lAqbV7fAbpdeIF5bHy/QZtLxa2dpG8BTOXDcoMp9MUyKjafHbNr+z5unqqTfduXy
+oRdJ1D/iXbSpcRkMKRJz4fa+uPNN5SiGzrjxHTcALPG8ctTUvdNrV+Z5VkssU+FW
+LQD+s5SQWn848kYTacrDL22JshIpekmz3ztDoNGOZxVj2DwF/QXDeaRhXT9ngB3c
+PY8x7e8yIvmAcg8olt9rKTpkGXZHWAyBpyGzBJkxM+wfiNreGMNUkv41G/R4d1Lv
+xMlGF05xrBJX9YrV1pRM+EdS4WOs2gvFT3qnBzFAQBZ9nqaLAFVxw0Sl7C+wSQPk
+7ZPIKYANFwARAQABiQE8BBgBCAAmFiEE3e8b7GbIusjWnO0q6r7YQOyYsCQFAjww
+7w4CGwwFCQlmAYAACgkQ6r7YQOyYsCSDdwf/an06WTTAIwHj8PfXIkywnq3SWfSZ
+yuRaFaDan9en8xAfyw2smNnrHnTk86CZWL6yPTij6JZYynv4OxtSafIoT9LxT7uX
+VpEtSBpTnnojlHFivfRYMGJ9k/EXGgb941W2DTbvQqzafc2u4K3u8KnFOgzfEj5B
+qjYzbt/L2uR2PLOAfYIUYzqTKjdzvSIX2DRvkepHhTwRbCjJrkF/zx0IXFoJeU/k
+6tYK6cNNCFTWT0uLJCflAZMtGpf4KDvjlccNts3mZQbEov+Dymj/nZ9JRgjc2heH
+Pxi5muPMQ8jAc2i4V8vTybozlZ5O/+JkOOOH0ciLpD3buhgYBY309DIVmA==
+=zVE+
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/key-selection/2.asc b/tests/openpgp/key-selection/2.asc
new file mode 100644
index 0000000..4b697f7
--- /dev/null
+++ b/tests/openpgp/key-selection/2.asc
@@ -0,0 +1,30 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBD4SIdsBCACqRRWUd9mwgRzVzaDbVLRdNOdyswPYuBKWlHI6Yx0lpfiQK6/X
+rnRoR18lYJ0wBqImd/BJbjNE4bYaMUd+p7HzYIKzv8/DuvZQgovt9VIBn+a3YyCa
+hdAaWEz994fjl8U5IGbrrGuV4XXlFATA6S7KX7CgxgiK/jVnRl1NVcTjOSnasU2J
+LIbh0lawUe0b3HlwT8uFGg/MK3vHGGIalOJRlgeTBAF7zcaTfqoDiAXbbsfaxT4a
+zB1OTRut1VOGBLWCsr09VCAMyz8awQqF81uG6cuv9swo76SuTiMcMMBfdNw3etVa
+kLgL4JnsnMGM7c1fx/mfMUIUHYndDVT5LzQjABEBAAG0I0FjZWpsbnUgQWNkaXBy
+IDxhY2RpcHJAZXhhbXBsZS5vcmc+iQFUBBMBCAA+FiEEA/z+3gFAJ92JetLyPTJn
+Cpapwr8FAj4SIdsCGwMFCQWjmoAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQ
+PTJnCpapwr/bGAgAjGWQ3F9RUpeI3ogLLhGMsXmsOxZX1ptNtjL9HiDsrUY5XCS1
+7vZUpRz0/2nscbu7or6Xy8yZtG0vLXwfzeOvHQz/F8tnzruIWBFSAU8WBidxKxmC
+AUlQWg6bAp0aTxyyVi/r719J6k/G/ZOhjgXM243Ck9HNnY2a0h0ArKzPo56N8Cks
+caXshdWxIh3M9uJKSxBCxfDTtqPcU7LjNApaUOFphpAPT9ypE/Zw9BZNTVN6vILr
+I7upnG5PNXybMCDh2XhpXS2E5/rY9Y3/aFKthBws16JMAzBRKMQqWTTC9a8X+4pa
+KcNtQih3X9eRzj4JBAh6cl5qXIbz+32EzXA8drkBDQQ+EiHbAQgAz017pYsm9Sf0
+z5HqOQLx1dwCclzVE5RhvI+qplPT5e9sLG+trbOVpGM6fjWAK/yuxaUJibm/44UX
+cxsTuR7gpAwc+gvwrF3cG6kmT+g4kZ7/I4EyBMZjM9lhlIk77MCTLXcT9ONr7Pm4
+flQO+vM6ZYRFm7DtSHzP2z2Uu9USqgLJumn+V61xQXYj3E2ORczOV3blPVUoI7gl
+aRnVdveEqrucw+miRWq3clykTdbuP39H2nRgY0KXGbOefWh5dRe2okxL5nlhINGL
+lOyj9n4jM6fNp9K8jWeg8YJ7tKRsffrrNnIovslNlkXucYAzM2OveP+JxDdtosSK
+fzWtUSzrmQARAQABiQE8BBgBCAAmFiEEA/z+3gFAJ92JetLyPTJnCpapwr8FAj4S
+IdsCGwwFCQWjmoAACgkQPTJnCpapwr+p6wf/cO8apRVlpRrI2q92j5DJ0IQsBdUv
+Srvp3w8UHZad0VkhgT+edbYHN8VS245ckyWoUBB78XEvxayMF1/Mx0N+u1MOM1dY
+MrAiwbaQnE99yjifwVzZz6wJuJ94MMzWw38j22ZTbIBHPh/4nzSl84sN+KuEcP4f
+C2h7mat4NDO/VRTf7xWuLInS5yGdDOACwROd85ua4YNxo54s5mcd6BVr4upHd1Hj
+0TULgmWvqz49N40VY4GF+38OAC7+DSsdamHVNdTb0fT+KaxTQ0K5BCl+7Oe66CqH
+RWxaXRUD4YMRh1jdgc+j4D3Sj4xhevu0Kd6+7BWxmxWZKdOCiu9TEDBjrg==
+=YqE5
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/key-selection/3.asc b/tests/openpgp/key-selection/3.asc
new file mode 100644
index 0000000..ab2ff73
--- /dev/null
+++ b/tests/openpgp/key-selection/3.asc
@@ -0,0 +1,43 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+vlWlPNIJSTq1Bg==
+=rf5l
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/openpgp/key-selection/4.asc b/tests/openpgp/key-selection/4.asc
new file mode 100644
index 0000000..6a0ab9b
--- /dev/null
+++ b/tests/openpgp/key-selection/4.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBD/KdpABCAD2wlP1kYHldknjyGTnMOUq9r+3/fJR8n4qVt5TRRlDdyfK3ZxM
+KWStsmkZuK9dMxo4VSOjVeiXdZlHeQU7RlzVPsCNiJ1Qc2HDgHFdmT7eUgOILA12
+36bueRUwVPGmrBEecs0TpNRQ5CVFbO7mC6cTLhT9nRMd+W+BSuuZ8Zm98ebaVh3I
+ml3nPEVhs1UFmIop48RGCt45MZ2mYp77kuAmk8NBJjHy9J4H5UK19r0hla2WY4a3
+Z59hh7kFnNFCM/MhPxd6GwkeXzUF7WSnhzRVIkdv81u2AnIHbo1zD0BUp8Rf64Ns
+3iFAeB1VuR6ZJpEypHiHUJtYPmr9okEmg8EDABEBAAG0I0FjZWpsbnUgQWNkaXBy
+IDxhY2RpcHJAZXhhbXBsZS5vcmc+iQFUBBMBCAA+FiEE7Qh+nTOUNAc44gokSJKj
+z49l66wFAj/KdpACGwMFCQWjmoAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQ
+SJKjz49l66xZ7QgA7dBJsQP09LhkYDIu8cJzRU6tqa2Y8dx0iFaCU8nqD/0q6xJf
+fs2euwMEPsHWmA1WwGwxZpE/NGEksMSQ8TZSQUwCsURxBIiGww5MBtIGeO3ZzreR
+Dn0Qhivbiup8ZPtPfFFomoK7ZtWjtGjZ8I5zyYbjT0eEB7P348dkpOtReWDiqGVd
+taMnVau4OTDqTRo6fvAiVb37zoaWETsPWtq/TymgkqO/LEhzClzG8xJgpSl98cQW
+BoHz5GDVYeVxPEKAN4DdS7gt0KTUC9ZQUcZP+1wTzFohDd/CeUAl4kTeP0QSJVJ3
+QC/WnHk4Y56q8/nngIY6w/wID/R/Cp+plw6F5w==
+=BA1F
+-----END PGP PUBLIC KEY BLOCK-----

commit 1ec07cbc209f247fd85704f5701564e31aa56d0b
Author: Justus Winter <justus at g10code.com>
Date:   Thu Nov 3 14:37:15 2016 +0100

    gpgscm,tests: Add new functions to the test environment.
    
    * tests/gpgscm/lib.scm (first, last, powerset): New functions.
    * tests/gpgscm/tests.scm (interactive-shell): New function.
    * tests/openpgp/Makefile.am (EXTRA_DIST): Add new file.
    * tests/openpgp/README: Document 'interactive-shell'.
    * tests/openpgp/shell.scm: New file.
    
    Signed-off-by: Justus Winter <justus at g10code.com>

diff --git a/tests/gpgscm/lib.scm b/tests/gpgscm/lib.scm
index e4ab483..316eacf 100644
--- a/tests/gpgscm/lib.scm
+++ b/tests/gpgscm/lib.scm
@@ -42,6 +42,24 @@
         ((not (p (car l))) #f)
         (else (all p (cdr l)))))
 
+;; Return the first element of a list.
+(define first car)
+
+;; Return the last element of a list.
+(define (last lst)
+  (if (null? (cdr lst))
+      (car lst)
+      (last (cdr lst))))
+
+;; Compute the powerset of a list.
+(define (powerset set)
+  (if (null? set)
+      '(())
+      (let ((rst (powerset (cdr set))))
+        (append (map (lambda (x) (cons (car set) x))
+                     rst)
+                rst))))
+
 ;; Is PREFIX a prefix of S?
 (define (string-prefix? s prefix)
   (and (>= (string-length s) (string-length prefix))
diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm
index 8986a70..d89a96f 100644
--- a/tests/gpgscm/tests.scm
+++ b/tests/gpgscm/tests.scm
@@ -481,3 +481,11 @@
     (catch (list tmpfiles source *error*)
 	   (apply function `(,(call-with-input-file source read-all) , at args)))
     (list tmpfiles source #f)))
+
+;;
+;; Developing and debugging tests.
+;;
+
+;; Spawn an os shell.
+(define (interactive-shell)
+  (call-with-fds `(,(getenv "SHELL")) 0 1 2))
diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
index bb9b2f4..5725e11 100644
--- a/tests/openpgp/Makefile.am
+++ b/tests/openpgp/Makefile.am
@@ -188,7 +188,7 @@ sample_msgs = samplemsgs/issue2419.asc
 EXTRA_DIST = defs.scm $(XTESTS) $(TEST_FILES) \
 	     mkdemodirs signdemokey $(priv_keys) $(sample_keys)   \
 	     $(sample_msgs) ChangeLog-2011 run-tests.scm \
-	     setup.scm finish.scm
+	     setup.scm finish.scm shell.scm
 
 CLEANFILES = prepared.stamp x y yy z out err  $(data_files) \
 	     plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \
diff --git a/tests/openpgp/README b/tests/openpgp/README
index 8845afd..75d818e 100644
--- a/tests/openpgp/README
+++ b/tests/openpgp/README
@@ -110,7 +110,10 @@ You can also get an interactive repl by dropping
 
   (interactive-repl (current-environment))
 
-anywhere you like.
+anywhere you like.  Or, if you want to examine the environment from an
+operating system shell, use
+
+  (interactive-shell)
 
 ** Interfacing with gpg
 
diff --git a/tests/openpgp/shell.scm b/tests/openpgp/shell.scm
new file mode 100644
index 0000000..dadafff
--- /dev/null
+++ b/tests/openpgp/shell.scm
@@ -0,0 +1,32 @@
+#!/usr/bin/env gpgscm
+
+;; Copyright (C) 2016 g10 Code GmbH
+;;
+;; 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 <http://www.gnu.org/licenses/>.
+
+(load (with-path "defs.scm"))
+
+;; This is not a test, but can be used to inspect the test
+;; environment.  Simply execute
+;;
+;;   make -Ctests/openpgp check XTESTS=shell.scm
+;;
+;; to run it.
+
+(echo "Note that gpg.conf includes 'batch'.  If you want to use gpg")
+(echo "interactively you should drop that.")
+(echo)
+(interactive-shell)

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

Summary of changes:
 g10/getkey.c                                | 205 ++++++++++++++++++++++++++++
 g10/keydb.h                                 |   7 +
 g10/keylist.c                               |   2 +-
 g10/pkclist.c                               |   2 +-
 tests/gpgscm/lib.scm                        |  18 +++
 tests/gpgscm/tests.scm                      |   8 ++
 tests/openpgp/Makefile.am                   |  10 +-
 tests/openpgp/README                        |   5 +-
 tests/openpgp/key-selection.scm             |  82 +++++++++++
 tests/openpgp/key-selection/0.asc           |  30 ++++
 tests/openpgp/key-selection/1.asc           |  30 ++++
 tests/openpgp/key-selection/2.asc           |  30 ++++
 tests/openpgp/key-selection/3.asc           |  43 ++++++
 tests/openpgp/key-selection/4.asc           |  18 +++
 tests/openpgp/{4gb-packet.scm => shell.scm} |  17 ++-
 15 files changed, 496 insertions(+), 11 deletions(-)
 create mode 100644 tests/openpgp/key-selection.scm
 create mode 100644 tests/openpgp/key-selection/0.asc
 create mode 100644 tests/openpgp/key-selection/1.asc
 create mode 100644 tests/openpgp/key-selection/2.asc
 create mode 100644 tests/openpgp/key-selection/3.asc
 create mode 100644 tests/openpgp/key-selection/4.asc
 copy tests/openpgp/{4gb-packet.scm => shell.scm} (71%)
 mode change 100755 => 100644


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




More information about the Gnupg-commits mailing list