gpg: Set the node flags while retrieving a keyblock.
authorWerner Koch <wk@gnupg.org>
Mon, 7 Jan 2013 20:14:52 +0000 (21:14 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 7 Jan 2013 20:14:52 +0000 (21:14 +0100)
* g10/keydb.c (parse_keyblock_image): Add args PK_NO and UID_NO and
set the note flags accordingly.
(keydb_get_keyblock): Transfer PK_NO and UID_NO to parse_keyblock_image.
* kbx/keybox-search.c (blob_cmp_fpr, blob_cmp_fpr_part)
(blob_cmp_name, blob_cmp_mail): Return the key/user number.
(keybox_search): Set the key and user number into the found struct.
(keybox_get_keyblock): Add args R_PK_NO and R_UID_NO and set them from
the found struct.
--

getkey.c needs to know whether the correct subkey was found.  Thus we
need to set the node flags the same way we did it with the keyring
storage.

g10/keydb.c
kbx/keybox-search.c
kbx/keybox.h

index d293948..186f017 100644 (file)
@@ -1,6 +1,6 @@
 /* keydb.c - key database dispatcher
  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
- *               2008, 2009, 2011 Free Software Foundation, Inc.
+ *               2008, 2009, 2011, 2013 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -617,7 +617,8 @@ unlock_all (KEYDB_HANDLE hd)
 
 
 static gpg_error_t
-parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
+parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
+                      const u32 *sigstatus, kbnode_t *r_keyblock)
 {
   gpg_error_t err;
   PACKET *pkt;
@@ -625,6 +626,7 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
   kbnode_t node, *tail;
   int in_cert, save_mode;
   u32 n_sigs;
+  int pk_count, uid_count;
 
   *r_keyblock = NULL;
 
@@ -636,6 +638,7 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
   in_cert = 0;
   n_sigs = 0;
   tail = NULL;
+  pk_count = uid_count = 0;
   while ((err = parse_packet (iobuf, pkt)) != -1)
     {
       if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET)
@@ -714,6 +717,26 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
         }
 
       node = new_kbnode (pkt);
+
+      switch (pkt->pkttype)
+        {
+        case PKT_PUBLIC_KEY:
+        case PKT_PUBLIC_SUBKEY:
+        case PKT_SECRET_KEY:
+        case PKT_SECRET_SUBKEY:
+          if (++pk_count == pk_no)
+            node->flag |= 1;
+          break;
+
+        case PKT_USER_ID:
+          if (++uid_count == uid_no)
+            node->flag |= 2;
+          break;
+
+        default:
+          break;
+        }
+
       if (!keyblock)
         keyblock = node;
       else
@@ -779,12 +802,14 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
       {
         iobuf_t iobuf;
         u32 *sigstatus;
+        int pk_no, uid_no;
 
         err = keybox_get_keyblock (hd->active[hd->found].u.kb,
-                                   &iobuf, &sigstatus);
+                                   &iobuf, &pk_no, &uid_no, &sigstatus);
         if (!err)
           {
-            err = parse_keyblock_image (iobuf, sigstatus, ret_kb);
+            err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
+                                        ret_kb);
             xfree (sigstatus);
             iobuf_close (iobuf);
           }
index a12216b..5e6432f 100644 (file)
@@ -1,5 +1,6 @@
 /* keybox-search.c - Search operations
- * Copyright (C) 2001, 2002, 2003, 2004, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2004, 2012,
+ *               2013 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -233,6 +234,9 @@ blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
 }
 
 
+/* Returns 0 if not found or the number of the key which was found.
+   For X.509 this is always 1, for OpenPGP this is 1 for the primary
+   key and 2 and more for the subkeys.  */
 static int
 blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
 {
@@ -259,7 +263,7 @@ blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
     {
       off = pos + idx*keyinfolen;
       if (!memcmp (buffer + off, fpr, 20))
-        return 1; /* found */
+        return idx+1; /* found */
     }
   return 0; /* not found */
 }
@@ -291,7 +295,7 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
     {
       off = pos + idx*keyinfolen;
       if (!memcmp (buffer + off + fproff, fpr, fprlen))
-        return 1; /* found */
+        return idx+1; /* found */
     }
   return 0; /* not found */
 }
@@ -352,15 +356,14 @@ blob_cmp_name (KEYBOXBLOB blob, int idx,
           if (substr)
             {
               if (ascii_memcasemem (buffer+off, len, name, namelen))
-                return 1; /* found */
+                return idx+1; /* found */
             }
           else
             {
               if (len == namelen && !memcmp (buffer+off, name, len))
-                return 1; /* found */
+                return idx+1; /* found */
             }
         }
-      return 0; /* not found */
     }
   else
     {
@@ -376,13 +379,16 @@ blob_cmp_name (KEYBOXBLOB blob, int idx,
 
       if (substr)
         {
-          return !!ascii_memcasemem (buffer+off, len, name, namelen);
+          if (ascii_memcasemem (buffer+off, len, name, namelen))
+            return idx+1; /* found */
         }
       else
         {
-          return len == namelen && !memcmp (buffer+off, name, len);
+          if (len == namelen && !memcmp (buffer+off, name, len))
+            return idx+1; /* found */
         }
     }
+  return 0; /* not found */
 }
 
 
@@ -458,12 +464,12 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr,
       if (substr)
         {
           if (ascii_memcasemem (buffer+off+1, len, name, namelen))
-            return 1; /* found */
+            return idx+1; /* found */
         }
       else
         {
           if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len))
-            return 1; /* found */
+            return idx+1; /* found */
         }
     }
   return 0; /* not found */
@@ -734,6 +740,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
   int need_words, any_skip;
   KEYBOXBLOB blob = NULL;
   struct sn_array_s *sn_array = NULL;
+  int pk_no, uid_no;
 
   if (!hd)
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -850,6 +857,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
     }
 
 
+  pk_no = uid_no = 0;
   for (;;)
     {
       unsigned int blobflags;
@@ -875,19 +883,23 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
               never_reached ();
               break;
             case KEYDB_SEARCH_MODE_EXACT:
-              if (has_username (blob, desc[n].u.name, 0))
+              uid_no = has_username (blob, desc[n].u.name, 0);
+              if (uid_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_MAIL:
-              if (has_mail (blob, desc[n].u.name, 0))
+              uid_no = has_mail (blob, desc[n].u.name, 0);
+              if (uid_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_MAILSUB:
-              if (has_mail (blob, desc[n].u.name, 1))
+              uid_no = has_mail (blob, desc[n].u.name, 1);
+              if (uid_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_SUBSTR:
-              if (has_username (blob, desc[n].u.name, 1))
+              uid_no =  has_username (blob, desc[n].u.name, 1);
+              if (uid_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_MAILEND:
@@ -914,16 +926,19 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_SHORT_KID:
-              if (has_short_kid (blob, desc[n].u.kid[1]))
+              pk_no = has_short_kid (blob, desc[n].u.kid[1]);
+              if (pk_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_LONG_KID:
-              if (has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]))
+              pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]);
+              if (pk_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_FPR:
             case KEYDB_SEARCH_MODE_FPR20:
-              if (has_fingerprint (blob, desc[n].u.fpr))
+              pk_no = has_fingerprint (blob, desc[n].u.fpr);
+              if (pk_no)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_KEYGRIP:
@@ -956,6 +971,8 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
   if (!rc)
     {
       hd->found.blob = blob;
+      hd->found.pk_no = pk_no;
+      hd->found.uid_no = uid_no;
     }
   else if (rc == -1)
     {
@@ -985,9 +1002,12 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
 
 /* Return the last found keyblock.  Returns 0 on success and stores a
    new iobuf at R_IOBUF and a signature status vector at R_SIGSTATUS
-   in that case.  */
+   in that case.  R_UID_NO and R_PK_NO are used to retun the number of
+   the key or user id which was matched the search criteria; if not
+   known they are set to 0. */
 gpg_error_t
-keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, u32 **r_sigstatus)
+keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
+                     int *r_pk_no, int *r_uid_no, u32 **r_sigstatus)
 {
   gpg_error_t err;
   const unsigned char *buffer, *p;
@@ -1029,6 +1049,8 @@ keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, u32 **r_sigstatus)
   for (n=1; n <= n_sigs; n++, p += sigilen)
     sigstatus[n] = get32 (p);
 
+  *r_pk_no  = hd->found.pk_no;
+  *r_uid_no = hd->found.uid_no;
   *r_sigstatus = sigstatus;
   *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len);
   return 0;
index 03a9245..4f7e23d 100644 (file)
@@ -81,8 +81,8 @@ int keybox_lock (KEYBOX_HANDLE hd, int yes);
 int _keybox_write_header_blob (FILE *fp);
 
 /*-- keybox-search.c --*/
-gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd,
-                                 iobuf_t *r_iobuf, u32 **sigstatus);
+gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
+                                 int *r_uid_no, int *r_pk_no, u32 **sigstatus);
 #ifdef KEYBOX_WITH_X509
 int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert);
 #endif /*KEYBOX_WITH_X509*/
@@ -114,7 +114,6 @@ int keybox_compress (KEYBOX_HANDLE hd);
 /*--  --*/
 
 #if 0
-int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb);
 int keybox_locate_writable (KEYBOX_HANDLE hd);
 int keybox_search_reset (KEYBOX_HANDLE hd);
 int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc);