g10: Enumerated keys for decryption should be unique.
authorNIIBE Yutaka <gniibe@fsij.org>
Mon, 11 Jun 2018 02:48:14 +0000 (11:48 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Mon, 27 Aug 2018 07:24:00 +0000 (16:24 +0900)
* g10/getkey.c (enum_secret_keys): Collecting keys in the context,
check duplicate to make sure returning only unique keys.
* g10/pubkey-enc.c (get_session_key): Now, it's the responsibility of
enum_secret_keys to free keys.

--

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
g10/getkey.c
g10/pubkey-enc.c

index 08e17e9..5e4ca54 100644 (file)
@@ -3993,6 +3993,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
     kbnode_t keyblock;
     kbnode_t node;
     getkey_ctx_t ctx;
+    pubkey_t results;
   } *c = *context;
 
   if (!c)
@@ -4007,6 +4008,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
   if (!sk)
     {
       /* Free the context.  */
+      pubkeys_free (c->results);
       release_kbnode (c->keyblock);
       getkey_end (ctrl, c->ctx);
       xfree (c);
@@ -4109,8 +4111,31 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
          if (c->node->pkt->pkttype == PKT_PUBLIC_KEY
               || c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
            {
+              pubkey_t r;
+
+              /* Skip this candidate if it's already enumerated.  */
+              for (r = c->results; r; r = r->next)
+                if (!cmp_public_keys (r->pk, c->node->pkt->pkt.public_key))
+                  break;
+              if (r)
+                continue;
+
              copy_public_key (sk, c->node->pkt->pkt.public_key);
              c->node = c->node->next;
+
+              r = xtrycalloc (1, sizeof (*r));
+              if (!r)
+                {
+                  err = gpg_error_from_syserror ();
+                  free_public_key (sk);
+                  return err;
+                }
+
+              r->pk = sk;
+              r->keyblock = NULL;
+              r->next = c->results;
+              c->results = r;
+
              return 0; /* Found.  */
            }
         }
index 8540e03..32b1ed0 100644 (file)
@@ -87,7 +87,6 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
     {
       struct pubkey_enc_list *k;
 
-      free_public_key (sk);
       sk = xmalloc_clear (sizeof *sk);
       rc = enum_secret_keys (ctrl, &enum_context, sk);
       if (rc)
@@ -156,7 +155,6 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
         }
     }
   enum_secret_keys (ctrl, &enum_context, NULL);  /* free context */
-  free_public_key (sk);
 
   if (DBG_CLOCK)
     log_clock ("get_session_key leave");