LCOV - code coverage report
Current view: top level - g10 - keydb.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 418 766 54.6 %
Date: 2015-11-05 17:10:59 Functions: 22 32 68.8 %

          Line data    Source code
       1             : /* keydb.c - key database dispatcher
       2             :  * Copyright (C) 2001-2013 Free Software Foundation, Inc.
       3             :  * Coyrright (C) 2001-2015 Werner Koch
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       7             :  * GnuPG is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published by
       9             :  * the Free Software Foundation; either version 3 of the License, or
      10             :  * (at your option) any later version.
      11             :  *
      12             :  * GnuPG is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h>
      25             : #include <errno.h>
      26             : #include <assert.h>
      27             : #include <sys/types.h>
      28             : #include <sys/stat.h>
      29             : #include <unistd.h>
      30             : 
      31             : #include "gpg.h"
      32             : #include "util.h"
      33             : #include "options.h"
      34             : #include "main.h" /*try_make_homedir ()*/
      35             : #include "packet.h"
      36             : #include "keyring.h"
      37             : #include "../kbx/keybox.h"
      38             : #include "keydb.h"
      39             : #include "i18n.h"
      40             : 
      41             : static int active_handles;
      42             : 
      43             : typedef enum
      44             :   {
      45             :     KEYDB_RESOURCE_TYPE_NONE = 0,
      46             :     KEYDB_RESOURCE_TYPE_KEYRING,
      47             :     KEYDB_RESOURCE_TYPE_KEYBOX
      48             :   } KeydbResourceType;
      49             : #define MAX_KEYDB_RESOURCES 40
      50             : 
      51             : struct resource_item
      52             : {
      53             :   KeydbResourceType type;
      54             :   union {
      55             :     KEYRING_HANDLE kr;
      56             :     KEYBOX_HANDLE kb;
      57             :   } u;
      58             :   void *token;
      59             : };
      60             : 
      61             : static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
      62             : static int used_resources;
      63             : static void *primary_keyring=NULL;
      64             : 
      65             : 
      66             : /* This is a simple cache used to return the last result of a
      67             :    successful fingerprint search.  This works only for keybox resources
      68             :    because (due to lack of a copy_keyblock function) we need to store
      69             :    an image of the keyblock which is fortunately instantly available
      70             :    for keyboxes.  */
      71             : enum keyblock_cache_states {
      72             :   KEYBLOCK_CACHE_EMPTY,
      73             :   KEYBLOCK_CACHE_PREPARED,
      74             :   KEYBLOCK_CACHE_FILLED
      75             : };
      76             : 
      77             : struct keyblock_cache {
      78             :   enum keyblock_cache_states state;
      79             :   byte fpr[MAX_FINGERPRINT_LEN];
      80             :   iobuf_t iobuf; /* Image of the keyblock.  */
      81             :   u32 *sigstatus;
      82             :   int pk_no;
      83             :   int uid_no;
      84             : };
      85             : 
      86             : 
      87             : struct keydb_handle
      88             : {
      89             :   /* When we locked all of the resources in ACTIVE (using keyring_lock
      90             :      / keybox_lock, as appropriate).  */
      91             :   int locked;
      92             : 
      93             :   /* The index into ACTIVE of the resources in which the last search
      94             :      result was found.  Initially -1.  */
      95             :   int found;
      96             : 
      97             :   /* Initially -1 (invalid).  This is used to save a search result and
      98             :      later restore it as the selected result.  */
      99             :   int saved_found;
     100             : 
     101             :   /* The number of skipped long blobs since the last search
     102             :      (keydb_search_reset).  */
     103             :   unsigned long skipped_long_blobs;
     104             : 
     105             :   /* If set, this disables the use of the keyblock cache.  */
     106             :   int no_caching;
     107             : 
     108             :   /* Whether the next search will be from the beginning of the
     109             :      database (and thus consider all records).  */
     110             :   int is_reset;
     111             : 
     112             :   /* The "file position."  In our case, this is index of the current
     113             :      resource in ACTIVE.  */
     114             :   int current;
     115             : 
     116             :   /* The number of resources in ACTIVE.  */
     117             :   int used;
     118             : 
     119             :   /* Cache of the last found and parsed key block (only used for
     120             :      keyboxes, not keyrings).  */
     121             :   struct keyblock_cache keyblock_cache;
     122             : 
     123             :   /* Copy of ALL_RESOURCES when keydb_new is called.  */
     124             :   struct resource_item active[MAX_KEYDB_RESOURCES];
     125             : };
     126             : 
     127             : /* Looking up keys is expensive.  To hide the cost, we cache whether
     128             :    keys exist in the key database.  Then, if we know a key does not
     129             :    exist, we don't have to spend time looking it up.  This
     130             :    particularly helps the --list-sigs and --check-sigs commands.
     131             : 
     132             :    The cache stores the results in a hash using separate chaining.
     133             :    Concretely: we use the LSB of the keyid to index the hash table and
     134             :    each bucket consists of a linked list of entries.  An entry
     135             :    consists of the 64-bit key id.  If a key id is not in the cache,
     136             :    then we don't know whether it is in the DB or not.
     137             : 
     138             :    To simplify the cache consistency protocol, we simply flush the
     139             :    whole cache whenever a key is inserted or updated.  */
     140             : 
     141             : #define KID_NOT_FOUND_CACHE_BUCKETS 256
     142             : static struct kid_not_found_cache_bucket *
     143             :   kid_not_found_cache[KID_NOT_FOUND_CACHE_BUCKETS];
     144             : 
     145             : /* The total number of entries in the hash table.  */
     146             : static unsigned int kid_not_found_cache_count;
     147             : 
     148             : struct kid_not_found_cache_bucket
     149             : {
     150             :   struct kid_not_found_cache_bucket *next;
     151             :   u32 kid[2];
     152             : };
     153             : 
     154             : 
     155             : static int lock_all (KEYDB_HANDLE hd);
     156             : static void unlock_all (KEYDB_HANDLE hd);
     157             : 
     158             : 
     159             : /* Check whether the keyid KID is in key id is definately not in the
     160             :    database.
     161             : 
     162             :    Returns:
     163             : 
     164             :      0 - Indeterminate: the key id is not in the cache; we don't know
     165             :          whether the key is in the database or not.  If you want a
     166             :          definitive answer, you'll need to perform a lookup.
     167             : 
     168             :      1 - There is definitely no key with this key id in the database.
     169             :          We searched for a key with this key id previously, but we
     170             :          didn't find it in the database.  */
     171             : static int
     172        1940 : kid_not_found_p (u32 *kid)
     173             : {
     174             :   struct kid_not_found_cache_bucket *k;
     175             : 
     176        1940 :   for (k = kid_not_found_cache[kid[0] % KID_NOT_FOUND_CACHE_BUCKETS]; k; k = k->next)
     177           1 :     if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
     178             :       {
     179           1 :         if (DBG_CACHE)
     180           0 :           log_debug ("keydb: kid_not_found_p (%08lx%08lx) => not in DB\n",
     181           0 :                      (ulong)kid[0], (ulong)kid[1]);
     182           1 :         return 1;
     183             :       }
     184             : 
     185        1939 :   if (DBG_CACHE)
     186           0 :     log_debug ("keydb: kid_not_found_p (%08lx%08lx) => indeterminate\n",
     187           0 :                (ulong)kid[0], (ulong)kid[1]);
     188        1939 :   return 0;
     189             : }
     190             : 
     191             : 
     192             : /* Insert the keyid KID into the kid_not_found_cache.  FOUND is whether
     193             :    the key is in the key database or not.
     194             : 
     195             :    Note this function does not check whether the key id is already in
     196             :    the cache.  As such, kid_not_found_p() should be called first.  */
     197             : static void
     198           3 : kid_not_found_insert (u32 *kid)
     199             : {
     200             :   struct kid_not_found_cache_bucket *k;
     201             : 
     202           3 :   if (DBG_CACHE)
     203           0 :     log_debug ("keydb: kid_not_found_insert (%08lx%08lx)\n",
     204           0 :                (ulong)kid[0], (ulong)kid[1]);
     205           3 :   k = xmalloc (sizeof *k);
     206           3 :   k->kid[0] = kid[0];
     207           3 :   k->kid[1] = kid[1];
     208           3 :   k->next = kid_not_found_cache[kid[0] % KID_NOT_FOUND_CACHE_BUCKETS];
     209           3 :   kid_not_found_cache[kid[0] % KID_NOT_FOUND_CACHE_BUCKETS] = k;
     210           3 :   kid_not_found_cache_count++;
     211           3 : }
     212             : 
     213             : 
     214             : /* Flush the kid not found cache.  */
     215             : static void
     216          64 : kid_not_found_flush (void)
     217             : {
     218             :   struct kid_not_found_cache_bucket *k, *knext;
     219             :   int i;
     220             : 
     221          64 :   if (DBG_CACHE)
     222           0 :     log_debug ("keydb: kid_not_found_flush\n");
     223             : 
     224          64 :   if (!kid_not_found_cache_count)
     225         126 :     return;
     226             : 
     227         514 :   for (i=0; i < DIM(kid_not_found_cache); i++)
     228             :     {
     229         514 :       for (k = kid_not_found_cache[i]; k; k = knext)
     230             :         {
     231           2 :           knext = k->next;
     232           2 :           xfree (k);
     233             :         }
     234         512 :       kid_not_found_cache[i] = NULL;
     235             :     }
     236           2 :   kid_not_found_cache_count = 0;
     237             : }
     238             : 
     239             : 
     240             : static void
     241        5159 : keyblock_cache_clear (struct keydb_handle *hd)
     242             : {
     243        5159 :   hd->keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
     244        5159 :   xfree (hd->keyblock_cache.sigstatus);
     245        5159 :   hd->keyblock_cache.sigstatus = NULL;
     246        5159 :   iobuf_close (hd->keyblock_cache.iobuf);
     247        5159 :   hd->keyblock_cache.iobuf = NULL;
     248        5159 : }
     249             : 
     250             : 
     251             : /* Handle the creation of a keyring or a keybox if it does not yet
     252             :    exist.  Take into account that other processes might have the
     253             :    keyring/keybox already locked.  This lock check does not work if
     254             :    the directory itself is not yet available.  If IS_BOX is true the
     255             :    filename is expected to refer to a keybox.  If FORCE_CREATE is true
     256             :    the keyring or keybox will be created.
     257             : 
     258             :    Return 0 if it is okay to access the specified file.  */
     259             : static int
     260        1257 : maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
     261             : {
     262        1257 :   dotlock_t lockhd = NULL;
     263             :   IOBUF iobuf;
     264             :   int rc;
     265             :   mode_t oldmask;
     266             :   char *last_slash_in_filename;
     267             :   int save_slash;
     268             : 
     269             :   /* A quick test whether the filename already exists. */
     270        1257 :   if (!access (filename, F_OK))
     271        1256 :     return 0;
     272             : 
     273             :   /* If we don't want to create a new file at all, there is no need to
     274             :      go any further - bail out right here.  */
     275           1 :   if (!force_create)
     276           0 :     return gpg_error (GPG_ERR_ENOENT);
     277             : 
     278             :   /* First of all we try to create the home directory.  Note, that we
     279             :      don't do any locking here because any sane application of gpg
     280             :      would create the home directory by itself and not rely on gpg's
     281             :      tricky auto-creation which is anyway only done for certain home
     282             :      directory name pattern. */
     283           1 :   last_slash_in_filename = strrchr (filename, DIRSEP_C);
     284             : #if HAVE_W32_SYSTEM
     285             :   {
     286             :     /* Windows may either have a slash or a backslash.  Take care of it.  */
     287             :     char *p = strrchr (filename, '/');
     288             :     if (!last_slash_in_filename || p > last_slash_in_filename)
     289             :       last_slash_in_filename = p;
     290             :   }
     291             : #endif /*HAVE_W32_SYSTEM*/
     292           1 :   if (!last_slash_in_filename)
     293           0 :     return gpg_error (GPG_ERR_ENOENT);  /* No slash at all - should
     294             :                                            not happen though.  */
     295           1 :   save_slash = *last_slash_in_filename;
     296           1 :   *last_slash_in_filename = 0;
     297           1 :   if (access(filename, F_OK))
     298             :     {
     299             :       static int tried;
     300             : 
     301           0 :       if (!tried)
     302             :         {
     303           0 :           tried = 1;
     304           0 :           try_make_homedir (filename);
     305             :         }
     306           0 :       if (access (filename, F_OK))
     307             :         {
     308           0 :           rc = gpg_error_from_syserror ();
     309           0 :           *last_slash_in_filename = save_slash;
     310           0 :           goto leave;
     311             :         }
     312             :     }
     313           1 :   *last_slash_in_filename = save_slash;
     314             : 
     315             :   /* To avoid races with other instances of gpg trying to create or
     316             :      update the keyring (it is removed during an update for a short
     317             :      time), we do the next stuff in a locked state. */
     318           1 :   lockhd = dotlock_create (filename, 0);
     319           1 :   if (!lockhd)
     320             :     {
     321           0 :       rc = gpg_error_from_syserror ();
     322             :       /* A reason for this to fail is that the directory is not
     323             :          writable. However, this whole locking stuff does not make
     324             :          sense if this is the case. An empty non-writable directory
     325             :          with no keyring is not really useful at all. */
     326           0 :       if (opt.verbose)
     327           0 :         log_info ("can't allocate lock for '%s': %s\n",
     328             :                   filename, gpg_strerror (rc));
     329             : 
     330           0 :       if (!force_create)
     331           0 :         return gpg_error (GPG_ERR_ENOENT);  /* Won't happen.  */
     332             :       else
     333           0 :         return rc;
     334             :     }
     335             : 
     336           1 :   if ( dotlock_take (lockhd, -1) )
     337             :     {
     338           0 :       rc = gpg_error_from_syserror ();
     339             :       /* This is something bad.  Probably a stale lockfile.  */
     340           0 :       log_info ("can't lock '%s': %s\n", filename, gpg_strerror (rc));
     341           0 :       goto leave;
     342             :     }
     343             : 
     344             :   /* Now the real test while we are locked. */
     345           1 :   if (!access (filename, F_OK))
     346             :     {
     347           0 :       rc = 0;  /* Okay, we may access the file now.  */
     348           0 :       goto leave;
     349             :     }
     350             : 
     351             :   /* The file does not yet exist, create it now. */
     352           1 :   oldmask = umask (077);
     353           1 :   if (is_secured_filename (filename))
     354             :     {
     355           0 :       iobuf = NULL;
     356           0 :       gpg_err_set_errno (EPERM);
     357             :     }
     358             :   else
     359           1 :     iobuf = iobuf_create (filename, 0);
     360           1 :   umask (oldmask);
     361           1 :   if (!iobuf)
     362             :     {
     363           0 :       rc = gpg_error_from_syserror ();
     364           0 :       if (is_box)
     365           0 :         log_error (_("error creating keybox '%s': %s\n"),
     366             :                    filename, gpg_strerror (rc));
     367             :       else
     368           0 :         log_error (_("error creating keyring '%s': %s\n"),
     369             :                    filename, gpg_strerror (rc));
     370           0 :       goto leave;
     371             :     }
     372             : 
     373           1 :   iobuf_close (iobuf);
     374             :   /* Must invalidate that ugly cache */
     375           1 :   iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename);
     376             : 
     377             :   /* Make sure that at least one record is in a new keybox file, so
     378             :      that the detection magic will work the next time it is used.  */
     379           1 :   if (is_box)
     380             :     {
     381           1 :       FILE *fp = fopen (filename, "w");
     382           1 :       if (!fp)
     383           0 :         rc = gpg_error_from_syserror ();
     384             :       else
     385             :         {
     386           1 :           rc = _keybox_write_header_blob (fp, 1);
     387           1 :           fclose (fp);
     388             :         }
     389           1 :       if (rc)
     390             :         {
     391           0 :           if (is_box)
     392           0 :             log_error (_("error creating keybox '%s': %s\n"),
     393             :                        filename, gpg_strerror (rc));
     394             :           else
     395           0 :             log_error (_("error creating keyring '%s': %s\n"),
     396             :                        filename, gpg_strerror (rc));
     397           0 :           goto leave;
     398             :         }
     399             :     }
     400             : 
     401           1 :   if (!opt.quiet)
     402             :     {
     403           1 :       if (is_box)
     404           1 :         log_info (_("keybox '%s' created\n"), filename);
     405             :       else
     406           0 :         log_info (_("keyring '%s' created\n"), filename);
     407             :     }
     408             : 
     409           1 :   rc = 0;
     410             : 
     411             :  leave:
     412           1 :   if (lockhd)
     413             :     {
     414           1 :       dotlock_release (lockhd);
     415           1 :       dotlock_destroy (lockhd);
     416             :     }
     417           1 :   return rc;
     418             : }
     419             : 
     420             : 
     421             : /* Helper for keydb_add_resource.  Opens FILENAME to figure out the
     422             :    resource type.
     423             : 
     424             :    Returns the specified file's likely type.  If the file does not
     425             :    exist, returns KEYDB_RESOURCE_TYPE_NONE and sets *R_FOUND to 0.
     426             :    Otherwise, tries to figure out the file's type.  This is either
     427             :    KEYDB_RESOURCE_TYPE_KEYBOX, KEYDB_RESOURCE_TYPE_KEYRING or
     428             :    KEYDB_RESOURCE_TYPE_KEYNONE.  If the file is a keybox and it has
     429             :    the OpenPGP flag set, then R_OPENPGP is also set.  */
     430             : static KeydbResourceType
     431        2513 : rt_from_file (const char *filename, int *r_found, int *r_openpgp)
     432             : {
     433             :   u32 magic;
     434             :   unsigned char verbuf[4];
     435             :   FILE *fp;
     436        2513 :   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
     437             : 
     438        2513 :   *r_found = *r_openpgp = 0;
     439        2513 :   fp = fopen (filename, "rb");
     440        2513 :   if (fp)
     441             :     {
     442        1256 :       *r_found = 1;
     443             : 
     444        1256 :       if (fread (&magic, 4, 1, fp) == 1 )
     445             :         {
     446        1256 :           if (magic == 0x13579ace || magic == 0xce9a5713)
     447             :             ; /* GDBM magic - not anymore supported. */
     448        1256 :           else if (fread (&verbuf, 4, 1, fp) == 1
     449        1256 :                    && verbuf[0] == 1
     450        1256 :                    && fread (&magic, 4, 1, fp) == 1
     451        1256 :                    && !memcmp (&magic, "KBXf", 4))
     452             :             {
     453        1256 :               if ((verbuf[3] & 0x02))
     454        1256 :                 *r_openpgp = 1;
     455        1256 :               rt = KEYDB_RESOURCE_TYPE_KEYBOX;
     456             :             }
     457             :           else
     458           0 :             rt = KEYDB_RESOURCE_TYPE_KEYRING;
     459             :         }
     460             :       else /* Maybe empty: assume keyring. */
     461           0 :         rt = KEYDB_RESOURCE_TYPE_KEYRING;
     462             : 
     463        1256 :       fclose (fp);
     464             :     }
     465             : 
     466        2513 :   return rt;
     467             : }
     468             : 
     469             : 
     470             : gpg_error_t
     471        1257 : keydb_add_resource (const char *url, unsigned int flags)
     472             : {
     473             :   /* Whether we have successfully registered a resource.  */
     474             :   static int any_registered;
     475             :   /* The file named by the URL (i.e., without the prototype).  */
     476        1257 :   const char *resname = url;
     477             : 
     478        1257 :   char *filename = NULL;
     479             :   int create;
     480        1257 :   int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY);
     481        1257 :   int is_default = !!(flags&KEYDB_RESOURCE_FLAG_DEFAULT);
     482        1257 :   int is_gpgvdef = !!(flags&KEYDB_RESOURCE_FLAG_GPGVDEF);
     483        1257 :   int rc = 0;
     484        1257 :   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
     485             :   void *token;
     486             : 
     487             :   /* Create the resource if it is the first registered one.  */
     488        1257 :   create = (!read_only && !any_registered);
     489             : 
     490        1257 :   if (strlen (resname) > 11 && !strncmp( resname, "gnupg-ring:", 11) )
     491             :     {
     492           0 :       rt = KEYDB_RESOURCE_TYPE_KEYRING;
     493           0 :       resname += 11;
     494             :     }
     495        1257 :   else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) )
     496             :     {
     497           0 :       rt = KEYDB_RESOURCE_TYPE_KEYBOX;
     498           0 :       resname += 10;
     499             :     }
     500             : #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
     501        1257 :   else if (strchr (resname, ':'))
     502             :     {
     503           0 :       log_error ("invalid key resource URL '%s'\n", url );
     504           0 :       rc = gpg_error (GPG_ERR_GENERAL);
     505           0 :       goto leave;
     506             :     }
     507             : #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
     508             : 
     509        1257 :   if (*resname != DIRSEP_C
     510             : #ifdef HAVE_W32_SYSTEM
     511             :       && *resname != '/'  /* Fixme: does not handle drive letters.  */
     512             : #endif
     513             :         )
     514             :     {
     515             :       /* Do tilde expansion etc. */
     516        1257 :       if (strchr (resname, DIRSEP_C)
     517             : #ifdef HAVE_W32_SYSTEM
     518             :           || strchr (resname, '/')  /* Windows also accepts this.  */
     519             : #endif
     520             :           )
     521           1 :         filename = make_filename (resname, NULL);
     522             :       else
     523        1256 :         filename = make_filename (opt.homedir, resname, NULL);
     524             :     }
     525             :   else
     526           0 :     filename = xstrdup (resname);
     527             : 
     528             :   /* See whether we can determine the filetype.  */
     529        1257 :   if (rt == KEYDB_RESOURCE_TYPE_NONE)
     530             :     {
     531             :       int found, openpgp_flag;
     532        1257 :       int pass = 0;
     533             :       size_t filenamelen;
     534             : 
     535             :     check_again:
     536        2513 :       filenamelen = strlen (filename);
     537        2513 :       rt = rt_from_file (filename, &found, &openpgp_flag);
     538        2513 :       if (found)
     539             :         {
     540             :           /* The file exists and we have the resource type in RT.
     541             : 
     542             :              Now let us check whether in addition to the "pubring.gpg"
     543             :              a "pubring.kbx with openpgp keys exists.  This is so that
     544             :              GPG 2.1 will use an existing "pubring.kbx" by default iff
     545             :              that file has been created or used by 2.1.  This check is
     546             :              needed because after creation or use of the kbx file with
     547             :              2.1 an older version of gpg may have created a new
     548             :              pubring.gpg for its own use.  */
     549        1256 :           if (!pass && is_default && rt == KEYDB_RESOURCE_TYPE_KEYRING
     550           0 :               && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".gpg"))
     551             :             {
     552           0 :               strcpy (filename+filenamelen-4, ".kbx");
     553           0 :               if ((rt_from_file (filename, &found, &openpgp_flag)
     554           0 :                    == KEYDB_RESOURCE_TYPE_KEYBOX) && found && openpgp_flag)
     555           0 :                 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
     556             :               else /* Restore filename */
     557           0 :                 strcpy (filename+filenamelen-4, ".gpg");
     558             :             }
     559             :         }
     560        1257 :       else if (!pass && is_gpgvdef
     561           0 :                && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".kbx"))
     562           0 :         {
     563             :           /* Not found but gpgv's default "trustedkeys.kbx" file has
     564             :              been requested.  We did not found it so now check whether
     565             :              a "trustedkeys.gpg" file exists and use that instead.  */
     566             :           KeydbResourceType rttmp;
     567             : 
     568           0 :           strcpy (filename+filenamelen-4, ".gpg");
     569           0 :           rttmp = rt_from_file (filename, &found, &openpgp_flag);
     570           0 :           if (found
     571           0 :               && ((rttmp == KEYDB_RESOURCE_TYPE_KEYBOX && openpgp_flag)
     572           0 :                   || (rttmp == KEYDB_RESOURCE_TYPE_KEYRING)))
     573           0 :             rt = rttmp;
     574             :           else /* Restore filename */
     575           0 :             strcpy (filename+filenamelen-4, ".kbx");
     576             :         }
     577        1257 :       else if (!pass
     578        1256 :                && is_default && create
     579        1256 :                && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".gpg"))
     580             :         {
     581             :           /* The file does not exist, the default resource has been
     582             :              requested, the file shall be created, and the file has a
     583             :              ".gpg" suffix.  Change the suffix to ".kbx" and try once
     584             :              more.  This way we achieve that we open an existing
     585             :              ".gpg" keyring, but create a new keybox file with an
     586             :              ".kbx" suffix.  */
     587        1256 :           strcpy (filename+filenamelen-4, ".kbx");
     588        1256 :           pass++;
     589        1256 :           goto check_again;
     590             :         }
     591             :       else /* No file yet: create keybox. */
     592           1 :         rt = KEYDB_RESOURCE_TYPE_KEYBOX;
     593             :     }
     594             : 
     595        1257 :   switch (rt)
     596             :     {
     597             :     case KEYDB_RESOURCE_TYPE_NONE:
     598           0 :       log_error ("unknown type of key resource '%s'\n", url );
     599           0 :       rc = gpg_error (GPG_ERR_GENERAL);
     600           0 :       goto leave;
     601             : 
     602             :     case KEYDB_RESOURCE_TYPE_KEYRING:
     603           0 :       rc = maybe_create_keyring_or_box (filename, 0, create);
     604           0 :       if (rc)
     605           0 :         goto leave;
     606             : 
     607           0 :       if (keyring_register_filename (filename, read_only, &token))
     608             :         {
     609           0 :           if (used_resources >= MAX_KEYDB_RESOURCES)
     610           0 :             rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
     611             :           else
     612             :             {
     613           0 :               if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
     614           0 :                 primary_keyring = token;
     615           0 :               all_resources[used_resources].type = rt;
     616           0 :               all_resources[used_resources].u.kr = NULL; /* Not used here */
     617           0 :               all_resources[used_resources].token = token;
     618           0 :               used_resources++;
     619             :             }
     620             :         }
     621             :       else
     622             :         {
     623             :           /* This keyring was already registered, so ignore it.
     624             :              However, we can still mark it as primary even if it was
     625             :              already registered.  */
     626           0 :           if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
     627           0 :             primary_keyring = token;
     628             :         }
     629           0 :       break;
     630             : 
     631             :     case KEYDB_RESOURCE_TYPE_KEYBOX:
     632             :       {
     633        1257 :         rc = maybe_create_keyring_or_box (filename, 1, create);
     634        1257 :         if (rc)
     635           0 :           goto leave;
     636             : 
     637             :         /* FIXME: How do we register a read-only keybox?  */
     638        1257 :         token = keybox_register_file (filename, 0);
     639        1257 :         if (token)
     640             :           {
     641        1257 :             if (used_resources >= MAX_KEYDB_RESOURCES)
     642           0 :               rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
     643             :             else
     644             :               {
     645             :                 /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
     646             :                 /*   primary_keyring = token; */
     647        1257 :                 all_resources[used_resources].type = rt;
     648        1257 :                 all_resources[used_resources].u.kb = NULL; /* Not used here */
     649        1257 :                 all_resources[used_resources].token = token;
     650             : 
     651             :                 /* FIXME: Do a compress run if needed and no other
     652             :                    user is currently using the keybox. */
     653             : 
     654        1257 :                 used_resources++;
     655             :               }
     656             :           }
     657             :         else
     658             :           {
     659             :             /* Already registered.  We will mark it as the primary key
     660             :                if requested.  */
     661             :             /* FIXME: How to do that?  Change the keybox interface?  */
     662             :             /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
     663             :             /*   primary_keyring = token; */
     664             :           }
     665             :       }
     666        1257 :       break;
     667             : 
     668             :       default:
     669           0 :         log_error ("resource type of '%s' not supported\n", url);
     670           0 :         rc = gpg_error (GPG_ERR_GENERAL);
     671           0 :         goto leave;
     672             :     }
     673             : 
     674             :   /* fixme: check directory permissions and print a warning */
     675             : 
     676             :  leave:
     677        1257 :   if (rc)
     678           0 :     log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc));
     679             :   else
     680        1257 :     any_registered = 1;
     681        1257 :   xfree (filename);
     682        1257 :   return rc;
     683             : }
     684             : 
     685             : 
     686             : void
     687           0 : keydb_dump_stats (void)
     688             : {
     689           0 :   if (kid_not_found_cache_count)
     690           0 :     log_info ("keydb: kid_not_found_cache: total: %u\n",
     691             :               kid_not_found_cache_count);
     692           0 : }
     693             : 
     694             : 
     695             : KEYDB_HANDLE
     696        2582 : keydb_new (void)
     697             : {
     698             :   KEYDB_HANDLE hd;
     699             :   int i, j;
     700        2582 :   int die = 0;
     701             : 
     702        2582 :   if (DBG_CLOCK)
     703           0 :     log_clock ("keydb_new");
     704             : 
     705        2582 :   hd = xmalloc_clear (sizeof *hd);
     706        2582 :   hd->found = -1;
     707        2582 :   hd->saved_found = -1;
     708        2582 :   hd->is_reset = 1;
     709             : 
     710        2582 :   assert (used_resources <= MAX_KEYDB_RESOURCES);
     711        5164 :   for (i=j=0; ! die && i < used_resources; i++)
     712             :     {
     713        2582 :       switch (all_resources[i].type)
     714             :         {
     715             :         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
     716           0 :           break;
     717             :         case KEYDB_RESOURCE_TYPE_KEYRING:
     718           0 :           hd->active[j].type   = all_resources[i].type;
     719           0 :           hd->active[j].token  = all_resources[i].token;
     720           0 :           hd->active[j].u.kr = keyring_new (all_resources[i].token);
     721           0 :           if (!hd->active[j].u.kr)
     722           0 :             die = 1;
     723           0 :           j++;
     724           0 :           break;
     725             :         case KEYDB_RESOURCE_TYPE_KEYBOX:
     726        2582 :           hd->active[j].type   = all_resources[i].type;
     727        2582 :           hd->active[j].token  = all_resources[i].token;
     728        2582 :           hd->active[j].u.kb   = keybox_new_openpgp (all_resources[i].token, 0);
     729        2582 :           if (!hd->active[j].u.kb)
     730           0 :             die = 1;
     731        2582 :           j++;
     732        2582 :           break;
     733             :         }
     734             :     }
     735        2582 :   hd->used = j;
     736             : 
     737        2582 :   active_handles++;
     738             : 
     739        2582 :   if (die)
     740             :     {
     741           0 :       keydb_release (hd);
     742           0 :       hd = NULL;
     743             :     }
     744             : 
     745        2582 :   return hd;
     746             : }
     747             : 
     748             : 
     749             : void
     750        2580 : keydb_release (KEYDB_HANDLE hd)
     751             : {
     752             :   int i;
     753             : 
     754        2580 :   if (!hd)
     755        2580 :     return;
     756        2580 :   assert (active_handles > 0);
     757        2580 :   active_handles--;
     758             : 
     759        2580 :   unlock_all (hd);
     760        5160 :   for (i=0; i < hd->used; i++)
     761             :     {
     762        2580 :       switch (hd->active[i].type)
     763             :         {
     764             :         case KEYDB_RESOURCE_TYPE_NONE:
     765           0 :           break;
     766             :         case KEYDB_RESOURCE_TYPE_KEYRING:
     767           0 :           keyring_release (hd->active[i].u.kr);
     768           0 :           break;
     769             :         case KEYDB_RESOURCE_TYPE_KEYBOX:
     770        2580 :           keybox_release (hd->active[i].u.kb);
     771        2580 :           break;
     772             :         }
     773             :     }
     774             : 
     775        2580 :   xfree (hd);
     776             : }
     777             : 
     778             : 
     779             : void
     780         119 : keydb_disable_caching (KEYDB_HANDLE hd)
     781             : {
     782         119 :   if (hd)
     783         119 :     hd->no_caching = 1;
     784         119 : }
     785             : 
     786             : 
     787             : const char *
     788           0 : keydb_get_resource_name (KEYDB_HANDLE hd)
     789             : {
     790             :   int idx;
     791           0 :   const char *s = NULL;
     792             : 
     793           0 :   if (!hd)
     794           0 :     return NULL;
     795             : 
     796           0 :   if ( hd->found >= 0 && hd->found < hd->used)
     797           0 :     idx = hd->found;
     798           0 :   else if ( hd->current >= 0 && hd->current < hd->used)
     799           0 :     idx = hd->current;
     800             :   else
     801           0 :     idx = 0;
     802             : 
     803           0 :   switch (hd->active[idx].type)
     804             :     {
     805             :     case KEYDB_RESOURCE_TYPE_NONE:
     806           0 :       s = NULL;
     807           0 :       break;
     808             :     case KEYDB_RESOURCE_TYPE_KEYRING:
     809           0 :       s = keyring_get_resource_name (hd->active[idx].u.kr);
     810           0 :       break;
     811             :     case KEYDB_RESOURCE_TYPE_KEYBOX:
     812           0 :       s = keybox_get_resource_name (hd->active[idx].u.kb);
     813           0 :       break;
     814             :     }
     815             : 
     816           0 :   return s? s: "";
     817             : }
     818             : 
     819             : 
     820             : 
     821             : static int
     822          64 : lock_all (KEYDB_HANDLE hd)
     823             : {
     824          64 :   int i, rc = 0;
     825             : 
     826             :   /* Fixme: This locking scheme may lead to a deadlock if the resources
     827             :      are not added in the same order by all processes.  We are
     828             :      currently only allowing one resource so it is not a problem.
     829             :      [Oops: Who claimed the latter]
     830             : 
     831             :      To fix this we need to use a lock file to protect lock_all.  */
     832             : 
     833         128 :   for (i=0; !rc && i < hd->used; i++)
     834             :     {
     835          64 :       switch (hd->active[i].type)
     836             :         {
     837             :         case KEYDB_RESOURCE_TYPE_NONE:
     838           0 :           break;
     839             :         case KEYDB_RESOURCE_TYPE_KEYRING:
     840           0 :           rc = keyring_lock (hd->active[i].u.kr, 1);
     841           0 :           break;
     842             :         case KEYDB_RESOURCE_TYPE_KEYBOX:
     843          64 :           rc = keybox_lock (hd->active[i].u.kb, 1);
     844          64 :           break;
     845             :         }
     846             :     }
     847             : 
     848          64 :   if (rc)
     849             :     {
     850             :       /* Revert the already taken locks.  */
     851           0 :       for (i--; i >= 0; i--)
     852             :         {
     853           0 :           switch (hd->active[i].type)
     854             :             {
     855             :             case KEYDB_RESOURCE_TYPE_NONE:
     856           0 :               break;
     857             :             case KEYDB_RESOURCE_TYPE_KEYRING:
     858           0 :               keyring_lock (hd->active[i].u.kr, 0);
     859           0 :               break;
     860             :             case KEYDB_RESOURCE_TYPE_KEYBOX:
     861           0 :               rc = keybox_lock (hd->active[i].u.kb, 0);
     862           0 :               break;
     863             :             }
     864             :         }
     865             :     }
     866             :   else
     867          64 :     hd->locked = 1;
     868             : 
     869          64 :   return rc;
     870             : }
     871             : 
     872             : 
     873             : static void
     874        2644 : unlock_all (KEYDB_HANDLE hd)
     875             : {
     876             :   int i;
     877             : 
     878        2644 :   if (!hd->locked)
     879        5224 :     return;
     880             : 
     881         128 :   for (i=hd->used-1; i >= 0; i--)
     882             :     {
     883          64 :       switch (hd->active[i].type)
     884             :         {
     885             :         case KEYDB_RESOURCE_TYPE_NONE:
     886           0 :           break;
     887             :         case KEYDB_RESOURCE_TYPE_KEYRING:
     888           0 :           keyring_lock (hd->active[i].u.kr, 0);
     889           0 :           break;
     890             :         case KEYDB_RESOURCE_TYPE_KEYBOX:
     891          64 :           keybox_lock (hd->active[i].u.kb, 0);
     892          64 :           break;
     893             :         }
     894             :     }
     895          64 :   hd->locked = 0;
     896             : }
     897             : 
     898             : 
     899             : 
     900             : void
     901           0 : keydb_push_found_state (KEYDB_HANDLE hd)
     902             : {
     903           0 :   if (!hd)
     904           0 :     return;
     905             : 
     906           0 :   if (hd->found < 0 || hd->found >= hd->used)
     907             :     {
     908           0 :       hd->saved_found = -1;
     909           0 :       return;
     910             :     }
     911             : 
     912           0 :   switch (hd->active[hd->found].type)
     913             :     {
     914             :     case KEYDB_RESOURCE_TYPE_NONE:
     915           0 :       break;
     916             :     case KEYDB_RESOURCE_TYPE_KEYRING:
     917           0 :       keyring_push_found_state (hd->active[hd->found].u.kr);
     918           0 :       break;
     919             :     case KEYDB_RESOURCE_TYPE_KEYBOX:
     920           0 :       keybox_push_found_state (hd->active[hd->found].u.kb);
     921           0 :       break;
     922             :     }
     923             : 
     924           0 :   hd->saved_found = hd->found;
     925           0 :   hd->found = -1;
     926             : }
     927             : 
     928             : 
     929             : void
     930           0 : keydb_pop_found_state (KEYDB_HANDLE hd)
     931             : {
     932           0 :   if (!hd)
     933           0 :     return;
     934             : 
     935           0 :   hd->found = hd->saved_found;
     936           0 :   hd->saved_found = -1;
     937           0 :   if (hd->found < 0 || hd->found >= hd->used)
     938           0 :     return;
     939             : 
     940           0 :   switch (hd->active[hd->found].type)
     941             :     {
     942             :     case KEYDB_RESOURCE_TYPE_NONE:
     943           0 :       break;
     944             :     case KEYDB_RESOURCE_TYPE_KEYRING:
     945           0 :       keyring_pop_found_state (hd->active[hd->found].u.kr);
     946           0 :       break;
     947             :     case KEYDB_RESOURCE_TYPE_KEYBOX:
     948           0 :       keybox_pop_found_state (hd->active[hd->found].u.kb);
     949           0 :       break;
     950             :     }
     951             : }
     952             : 
     953             : 
     954             : 
     955             : static gpg_error_t
     956        2459 : parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
     957             :                       const u32 *sigstatus, kbnode_t *r_keyblock)
     958             : {
     959             :   gpg_error_t err;
     960             :   PACKET *pkt;
     961        2459 :   kbnode_t keyblock = NULL;
     962             :   kbnode_t node, *tail;
     963             :   int in_cert, save_mode;
     964             :   u32 n_sigs;
     965             :   int pk_count, uid_count;
     966             : 
     967        2459 :   *r_keyblock = NULL;
     968             : 
     969        2459 :   pkt = xtrymalloc (sizeof *pkt);
     970        2459 :   if (!pkt)
     971           0 :     return gpg_error_from_syserror ();
     972        2459 :   init_packet (pkt);
     973        2459 :   save_mode = set_packet_list_mode (0);
     974        2459 :   in_cert = 0;
     975        2459 :   n_sigs = 0;
     976        2459 :   tail = NULL;
     977        2459 :   pk_count = uid_count = 0;
     978       18764 :   while ((err = parse_packet (iobuf, pkt)) != -1)
     979             :     {
     980       13846 :       if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET)
     981             :         {
     982           0 :           free_packet (pkt);
     983           0 :           init_packet (pkt);
     984           0 :           continue;
     985             :         }
     986       13846 :       if (err)
     987             :         {
     988           0 :           log_error ("parse_keyblock_image: read error: %s\n",
     989             :                      gpg_strerror (err));
     990           0 :           err = gpg_error (GPG_ERR_INV_KEYRING);
     991           0 :           break;
     992             :         }
     993             : 
     994             :       /* Filter allowed packets.  */
     995       13846 :       switch (pkt->pkttype)
     996             :         {
     997             :         case PKT_PUBLIC_KEY:
     998             :         case PKT_PUBLIC_SUBKEY:
     999             :         case PKT_SECRET_KEY:
    1000             :         case PKT_SECRET_SUBKEY:
    1001             :         case PKT_USER_ID:
    1002             :         case PKT_ATTRIBUTE:
    1003             :         case PKT_SIGNATURE:
    1004       13846 :           break; /* Allowed per RFC.  */
    1005             : 
    1006             :         default:
    1007             :           /* Note that can't allow ring trust packets here and some of
    1008             :              the other GPG specific packets don't make sense either.  */
    1009           0 :           log_error ("skipped packet of type %d in keybox\n",
    1010           0 :                      (int)pkt->pkttype);
    1011           0 :           free_packet(pkt);
    1012           0 :           init_packet(pkt);
    1013           0 :           continue;
    1014             :         }
    1015             : 
    1016             :       /* Other sanity checks.  */
    1017       13846 :       if (!in_cert && pkt->pkttype != PKT_PUBLIC_KEY)
    1018             :         {
    1019           0 :           log_error ("parse_keyblock_image: first packet in a keybox blob "
    1020             :                      "is not a public key packet\n");
    1021           0 :           err = gpg_error (GPG_ERR_INV_KEYRING);
    1022           0 :           break;
    1023             :         }
    1024       13846 :       if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY
    1025       11387 :                       || pkt->pkttype == PKT_SECRET_KEY))
    1026             :         {
    1027           0 :           log_error ("parse_keyblock_image: "
    1028             :                      "multiple keyblocks in a keybox blob\n");
    1029           0 :           err = gpg_error (GPG_ERR_INV_KEYRING);
    1030           0 :           break;
    1031             :         }
    1032       13846 :       in_cert = 1;
    1033             : 
    1034       13846 :       if (pkt->pkttype == PKT_SIGNATURE && sigstatus)
    1035             :         {
    1036        5849 :           PKT_signature *sig = pkt->pkt.signature;
    1037             : 
    1038        5849 :           n_sigs++;
    1039        5849 :           if (n_sigs > sigstatus[0])
    1040             :             {
    1041           0 :               log_error ("parse_keyblock_image: "
    1042             :                          "more signatures than found in the meta data\n");
    1043           0 :               err = gpg_error (GPG_ERR_INV_KEYRING);
    1044           0 :               break;
    1045             : 
    1046             :             }
    1047        5849 :           if (sigstatus[n_sigs])
    1048             :             {
    1049        5538 :               sig->flags.checked = 1;
    1050        5538 :               if (sigstatus[n_sigs] == 1 )
    1051             :                 ; /* missing key */
    1052        5538 :               else if (sigstatus[n_sigs] == 2 )
    1053             :                 ; /* bad signature */
    1054        5538 :               else if (sigstatus[n_sigs] < 0x10000000)
    1055             :                 ; /* bad flag */
    1056             :               else
    1057             :                 {
    1058        5538 :                   sig->flags.valid = 1;
    1059             :                   /* Fixme: Shall we set the expired flag here?  */
    1060             :                 }
    1061             :             }
    1062             :         }
    1063             : 
    1064       13846 :       node = new_kbnode (pkt);
    1065             : 
    1066       13846 :       switch (pkt->pkttype)
    1067             :         {
    1068             :         case PKT_PUBLIC_KEY:
    1069             :         case PKT_PUBLIC_SUBKEY:
    1070             :         case PKT_SECRET_KEY:
    1071             :         case PKT_SECRET_SUBKEY:
    1072        4870 :           if (++pk_count == pk_no)
    1073        2243 :             node->flag |= 1;
    1074        4870 :           break;
    1075             : 
    1076             :         case PKT_USER_ID:
    1077        3127 :           if (++uid_count == uid_no)
    1078         146 :             node->flag |= 2;
    1079        3127 :           break;
    1080             : 
    1081             :         default:
    1082        5849 :           break;
    1083             :         }
    1084             : 
    1085       13846 :       if (!keyblock)
    1086        2459 :         keyblock = node;
    1087             :       else
    1088       11387 :         *tail = node;
    1089       13846 :       tail = &node->next;
    1090       13846 :       pkt = xtrymalloc (sizeof *pkt);
    1091       13846 :       if (!pkt)
    1092             :         {
    1093           0 :           err = gpg_error_from_syserror ();
    1094           0 :           break;
    1095             :         }
    1096       13846 :       init_packet (pkt);
    1097             :     }
    1098        2459 :   set_packet_list_mode (save_mode);
    1099             : 
    1100        2459 :   if (err == -1 && keyblock)
    1101        2459 :     err = 0; /* Got the entire keyblock.  */
    1102             : 
    1103        2459 :   if (!err && sigstatus && n_sigs != sigstatus[0])
    1104             :     {
    1105           0 :       log_error ("parse_keyblock_image: signature count does not match\n");
    1106           0 :       err = gpg_error (GPG_ERR_INV_KEYRING);
    1107             :     }
    1108             : 
    1109        2459 :   if (err)
    1110           0 :     release_kbnode (keyblock);
    1111             :   else
    1112        2459 :     *r_keyblock = keyblock;
    1113        2459 :   free_packet (pkt);
    1114        2459 :   xfree (pkt);
    1115        2459 :   return err;
    1116             : }
    1117             : 
    1118             : 
    1119             : gpg_error_t
    1120        2459 : keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
    1121             : {
    1122        2459 :   gpg_error_t err = 0;
    1123             : 
    1124        2459 :   *ret_kb = NULL;
    1125             : 
    1126        2459 :   if (!hd)
    1127           0 :     return gpg_error (GPG_ERR_INV_ARG);
    1128             : 
    1129        2459 :   if (DBG_CLOCK)
    1130           0 :     log_clock ("keydb_get_keybock enter");
    1131             : 
    1132        2459 :   if (hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
    1133             :     {
    1134           0 :       err = iobuf_seek (hd->keyblock_cache.iobuf, 0);
    1135           0 :       if (err)
    1136             :         {
    1137           0 :           log_error ("keydb_get_keyblock: failed to rewind iobuf for cache\n");
    1138           0 :           keyblock_cache_clear (hd);
    1139             :         }
    1140             :       else
    1141             :         {
    1142           0 :           err = parse_keyblock_image (hd->keyblock_cache.iobuf,
    1143             :                                       hd->keyblock_cache.pk_no,
    1144             :                                       hd->keyblock_cache.uid_no,
    1145           0 :                                       hd->keyblock_cache.sigstatus,
    1146             :                                       ret_kb);
    1147           0 :           if (err)
    1148           0 :             keyblock_cache_clear (hd);
    1149           0 :           if (DBG_CLOCK)
    1150           0 :             log_clock (err? "keydb_get_keyblock leave (cached, failed)"
    1151             :                        : "keydb_get_keyblock leave (cached)");
    1152           0 :           return err;
    1153             :         }
    1154             :     }
    1155             : 
    1156        2459 :   if (hd->found < 0 || hd->found >= hd->used)
    1157           0 :     return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
    1158             : 
    1159        2459 :   switch (hd->active[hd->found].type)
    1160             :     {
    1161             :     case KEYDB_RESOURCE_TYPE_NONE:
    1162           0 :       err = gpg_error (GPG_ERR_GENERAL); /* oops */
    1163           0 :       break;
    1164             :     case KEYDB_RESOURCE_TYPE_KEYRING:
    1165           0 :       err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
    1166           0 :       break;
    1167             :     case KEYDB_RESOURCE_TYPE_KEYBOX:
    1168             :       {
    1169             :         iobuf_t iobuf;
    1170             :         u32 *sigstatus;
    1171             :         int pk_no, uid_no;
    1172             : 
    1173        2459 :         err = keybox_get_keyblock (hd->active[hd->found].u.kb,
    1174             :                                    &iobuf, &pk_no, &uid_no, &sigstatus);
    1175        2459 :         if (!err)
    1176             :           {
    1177        2459 :             err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
    1178             :                                         ret_kb);
    1179        2459 :             if (!err && hd->keyblock_cache.state == KEYBLOCK_CACHE_PREPARED)
    1180             :               {
    1181          95 :                 hd->keyblock_cache.state     = KEYBLOCK_CACHE_FILLED;
    1182          95 :                 hd->keyblock_cache.sigstatus = sigstatus;
    1183          95 :                 hd->keyblock_cache.iobuf     = iobuf;
    1184          95 :                 hd->keyblock_cache.pk_no     = pk_no;
    1185          95 :                 hd->keyblock_cache.uid_no    = uid_no;
    1186             :               }
    1187             :             else
    1188             :               {
    1189        2364 :                 xfree (sigstatus);
    1190        2364 :                 iobuf_close (iobuf);
    1191             :               }
    1192             :           }
    1193             :       }
    1194        2459 :       break;
    1195             :     }
    1196             : 
    1197        2459 :   if (hd->keyblock_cache.state != KEYBLOCK_CACHE_FILLED)
    1198        2364 :     keyblock_cache_clear (hd);
    1199             : 
    1200        2459 :   if (DBG_CLOCK)
    1201           0 :     log_clock (err? "keydb_get_keyblock leave (failed)"
    1202             :                : "keydb_get_keyblock leave");
    1203        2459 :   return err;
    1204             : }
    1205             : 
    1206             : 
    1207             : /* Build a keyblock image from KEYBLOCK.  Returns 0 on success and
    1208             :    only then stores a new iobuf object at R_IOBUF and a signature
    1209             :    status vecotor at R_SIGSTATUS.  */
    1210             : static gpg_error_t
    1211          61 : build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus)
    1212             : {
    1213             :   gpg_error_t err;
    1214             :   iobuf_t iobuf;
    1215             :   kbnode_t kbctx, node;
    1216             :   u32 n_sigs;
    1217             :   u32 *sigstatus;
    1218             : 
    1219          61 :   *r_iobuf = NULL;
    1220          61 :   if (r_sigstatus)
    1221          59 :     *r_sigstatus = NULL;
    1222             : 
    1223             :   /* Allocate a vector for the signature cache.  This is an array of
    1224             :      u32 values with the first value giving the number of elements to
    1225             :      follow and each element descriping the cache status of the
    1226             :      signature.  */
    1227          61 :   if (r_sigstatus)
    1228             :     {
    1229         553 :       for (kbctx=NULL, n_sigs=0; (node = walk_kbnode (keyblock, &kbctx, 0));)
    1230         435 :         if (node->pkt->pkttype == PKT_SIGNATURE)
    1231         259 :           n_sigs++;
    1232          59 :       sigstatus = xtrycalloc (1+n_sigs, sizeof *sigstatus);
    1233          59 :       if (!sigstatus)
    1234           0 :         return gpg_error_from_syserror ();
    1235             :     }
    1236             :   else
    1237           2 :     sigstatus = NULL;
    1238             : 
    1239          61 :   iobuf = iobuf_temp ();
    1240         571 :   for (kbctx = NULL, n_sigs = 0; (node = walk_kbnode (keyblock, &kbctx, 0));)
    1241             :     {
    1242             :       /* Make sure to use only packets valid on a keyblock.  */
    1243         449 :       switch (node->pkt->pkttype)
    1244             :         {
    1245             :         case PKT_PUBLIC_KEY:
    1246             :         case PKT_PUBLIC_SUBKEY:
    1247             :         case PKT_SIGNATURE:
    1248             :         case PKT_USER_ID:
    1249             :         case PKT_ATTRIBUTE:
    1250             :           /* Note that we don't want the ring trust packets.  They are
    1251             :              not useful. */
    1252         449 :           break;
    1253             :         default:
    1254           0 :           continue;
    1255             :         }
    1256             : 
    1257         449 :       err = build_packet (iobuf, node->pkt);
    1258         449 :       if (err)
    1259             :         {
    1260           0 :           iobuf_close (iobuf);
    1261           0 :           return err;
    1262             :         }
    1263             : 
    1264             :       /* Build signature status vector.  */
    1265         449 :       if (node->pkt->pkttype == PKT_SIGNATURE)
    1266             :         {
    1267         266 :           PKT_signature *sig = node->pkt->pkt.signature;
    1268             : 
    1269         266 :           n_sigs++;
    1270             :           /* Fixme: Detect the "missing key" status.  */
    1271         266 :           if (sig->flags.checked && sigstatus)
    1272             :             {
    1273         120 :               if (sig->flags.valid)
    1274             :                 {
    1275         120 :                   if (!sig->expiredate)
    1276         120 :                     sigstatus[n_sigs] = 0xffffffff;
    1277           0 :                   else if (sig->expiredate < 0x1000000)
    1278           0 :                     sigstatus[n_sigs] = 0x10000000;
    1279             :                   else
    1280           0 :                     sigstatus[n_sigs] = sig->expiredate;
    1281             :                 }
    1282             :               else
    1283           0 :                 sigstatus[n_sigs] = 0x00000002; /* Bad signature.  */
    1284             :             }
    1285             :         }
    1286             :     }
    1287          61 :   if (sigstatus)
    1288          59 :     sigstatus[0] = n_sigs;
    1289             : 
    1290          61 :   *r_iobuf = iobuf;
    1291          61 :   if (r_sigstatus)
    1292          59 :     *r_sigstatus = sigstatus;
    1293          61 :   return 0;
    1294             : }
    1295             : 
    1296             : 
    1297             : gpg_error_t
    1298           2 : keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
    1299             : {
    1300             :   gpg_error_t err;
    1301             : 
    1302           2 :   if (!hd)
    1303           0 :     return gpg_error (GPG_ERR_INV_ARG);
    1304             : 
    1305           2 :   kid_not_found_flush ();
    1306           2 :   keyblock_cache_clear (hd);
    1307             : 
    1308           2 :   if (hd->found < 0 || hd->found >= hd->used)
    1309           0 :     return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
    1310             : 
    1311           2 :   if (opt.dry_run)
    1312           0 :     return 0;
    1313             : 
    1314           2 :   err = lock_all (hd);
    1315           2 :   if (err)
    1316           0 :     return err;
    1317             : 
    1318           2 :   switch (hd->active[hd->found].type)
    1319             :     {
    1320             :     case KEYDB_RESOURCE_TYPE_NONE:
    1321           0 :       err = gpg_error (GPG_ERR_GENERAL); /* oops */
    1322           0 :       break;
    1323             :     case KEYDB_RESOURCE_TYPE_KEYRING:
    1324           0 :       err = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
    1325           0 :       break;
    1326             :     case KEYDB_RESOURCE_TYPE_KEYBOX:
    1327             :       {
    1328             :         iobuf_t iobuf;
    1329             : 
    1330           2 :         err = build_keyblock_image (kb, &iobuf, NULL);
    1331           2 :         if (!err)
    1332             :           {
    1333           4 :             err = keybox_update_keyblock (hd->active[hd->found].u.kb,
    1334           2 :                                           iobuf_get_temp_buffer (iobuf),
    1335           2 :                                           iobuf_get_temp_length (iobuf));
    1336           2 :             iobuf_close (iobuf);
    1337             :           }
    1338             :       }
    1339           2 :       break;
    1340             :     }
    1341             : 
    1342           2 :   unlock_all (hd);
    1343           2 :   return err;
    1344             : }
    1345             : 
    1346             : 
    1347             : gpg_error_t
    1348          59 : keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
    1349             : {
    1350             :   gpg_error_t err;
    1351             :   int idx;
    1352             : 
    1353          59 :   if (!hd)
    1354           0 :     return gpg_error (GPG_ERR_INV_ARG);
    1355             : 
    1356          59 :   kid_not_found_flush ();
    1357          59 :   keyblock_cache_clear (hd);
    1358             : 
    1359          59 :   if (opt.dry_run)
    1360           0 :     return 0;
    1361             : 
    1362          59 :   if (hd->found >= 0 && hd->found < hd->used)
    1363           0 :     idx = hd->found;
    1364          59 :   else if (hd->current >= 0 && hd->current < hd->used)
    1365          59 :     idx = hd->current;
    1366             :   else
    1367           0 :     return gpg_error (GPG_ERR_GENERAL);
    1368             : 
    1369          59 :   err = lock_all (hd);
    1370          59 :   if (err)
    1371           0 :     return err;
    1372             : 
    1373          59 :   switch (hd->active[idx].type)
    1374             :     {
    1375             :     case KEYDB_RESOURCE_TYPE_NONE:
    1376           0 :       err = gpg_error (GPG_ERR_GENERAL); /* oops */
    1377           0 :       break;
    1378             :     case KEYDB_RESOURCE_TYPE_KEYRING:
    1379           0 :       err = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
    1380           0 :       break;
    1381             :     case KEYDB_RESOURCE_TYPE_KEYBOX:
    1382             :       { /* We need to turn our kbnode_t list of packets into a proper
    1383             :            keyblock first.  This is required by the OpenPGP key parser
    1384             :            included in the keybox code.  Eventually we can change this
    1385             :            kludge to have the caller pass the image.  */
    1386             :         iobuf_t iobuf;
    1387             :         u32 *sigstatus;
    1388             : 
    1389          59 :         err = build_keyblock_image (kb, &iobuf, &sigstatus);
    1390          59 :         if (!err)
    1391             :           {
    1392         177 :             err = keybox_insert_keyblock (hd->active[idx].u.kb,
    1393          59 :                                           iobuf_get_temp_buffer (iobuf),
    1394          59 :                                           iobuf_get_temp_length (iobuf),
    1395             :                                           sigstatus);
    1396          59 :             xfree (sigstatus);
    1397          59 :             iobuf_close (iobuf);
    1398             :           }
    1399             :       }
    1400          59 :       break;
    1401             :     }
    1402             : 
    1403          59 :   unlock_all (hd);
    1404          59 :   return err;
    1405             : }
    1406             : 
    1407             : 
    1408             : gpg_error_t
    1409           3 : keydb_delete_keyblock (KEYDB_HANDLE hd)
    1410             : {
    1411             :   gpg_error_t rc;
    1412             : 
    1413           3 :   if (!hd)
    1414           0 :     return gpg_error (GPG_ERR_INV_ARG);
    1415             : 
    1416           3 :   kid_not_found_flush ();
    1417           3 :   keyblock_cache_clear (hd);
    1418             : 
    1419           3 :   if (hd->found < 0 || hd->found >= hd->used)
    1420           0 :     return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
    1421             : 
    1422           3 :   if (opt.dry_run)
    1423           0 :     return 0;
    1424             : 
    1425           3 :   rc = lock_all (hd);
    1426           3 :   if (rc)
    1427           0 :     return rc;
    1428             : 
    1429           3 :   switch (hd->active[hd->found].type)
    1430             :     {
    1431             :     case KEYDB_RESOURCE_TYPE_NONE:
    1432           0 :       rc = gpg_error (GPG_ERR_GENERAL);
    1433           0 :       break;
    1434             :     case KEYDB_RESOURCE_TYPE_KEYRING:
    1435           0 :       rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
    1436           0 :       break;
    1437             :     case KEYDB_RESOURCE_TYPE_KEYBOX:
    1438           3 :       rc = keybox_delete (hd->active[hd->found].u.kb);
    1439           3 :       break;
    1440             :     }
    1441             : 
    1442           3 :   unlock_all (hd);
    1443           3 :   return rc;
    1444             : }
    1445             : 
    1446             : 
    1447             : 
    1448             : gpg_error_t
    1449          59 : keydb_locate_writable (KEYDB_HANDLE hd)
    1450             : {
    1451             :   gpg_error_t rc;
    1452             : 
    1453          59 :   if (!hd)
    1454           0 :     return GPG_ERR_INV_ARG;
    1455             : 
    1456          59 :   rc = keydb_search_reset (hd); /* this does reset hd->current */
    1457          59 :   if (rc)
    1458           0 :     return rc;
    1459             : 
    1460             :   /* If we have a primary set, try that one first */
    1461          59 :   if (primary_keyring)
    1462             :     {
    1463           0 :       for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
    1464             :         {
    1465           0 :           if(hd->active[hd->current].token==primary_keyring)
    1466             :             {
    1467           0 :               if(keyring_is_writable (hd->active[hd->current].token))
    1468           0 :                 return 0;
    1469             :               else
    1470           0 :                 break;
    1471             :             }
    1472             :         }
    1473             : 
    1474           0 :       rc = keydb_search_reset (hd); /* this does reset hd->current */
    1475           0 :       if (rc)
    1476           0 :         return rc;
    1477             :     }
    1478             : 
    1479          59 :   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
    1480             :     {
    1481          59 :       switch (hd->active[hd->current].type)
    1482             :         {
    1483             :         case KEYDB_RESOURCE_TYPE_NONE:
    1484           0 :           BUG();
    1485             :           break;
    1486             :         case KEYDB_RESOURCE_TYPE_KEYRING:
    1487           0 :           if (keyring_is_writable (hd->active[hd->current].token))
    1488           0 :             return 0; /* found (hd->current is set to it) */
    1489           0 :           break;
    1490             :         case KEYDB_RESOURCE_TYPE_KEYBOX:
    1491          59 :           if (keybox_is_writable (hd->active[hd->current].token))
    1492          59 :             return 0; /* found (hd->current is set to it) */
    1493           0 :           break;
    1494             :         }
    1495             :     }
    1496             : 
    1497           0 :   return gpg_error (GPG_ERR_NOT_FOUND);
    1498             : }
    1499             : 
    1500             : void
    1501           0 : keydb_rebuild_caches (int noisy)
    1502             : {
    1503             :   int i, rc;
    1504             : 
    1505           0 :   for (i=0; i < used_resources; i++)
    1506             :     {
    1507           0 :       if (!keyring_is_writable (all_resources[i].token))
    1508           0 :         continue;
    1509           0 :       switch (all_resources[i].type)
    1510             :         {
    1511             :         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
    1512           0 :           break;
    1513             :         case KEYDB_RESOURCE_TYPE_KEYRING:
    1514           0 :           rc = keyring_rebuild_cache (all_resources[i].token,noisy);
    1515           0 :           if (rc)
    1516           0 :             log_error (_("failed to rebuild keyring cache: %s\n"),
    1517             :                        gpg_strerror (rc));
    1518           0 :           break;
    1519             :         case KEYDB_RESOURCE_TYPE_KEYBOX:
    1520             :           /* N/A.  */
    1521           0 :           break;
    1522             :         }
    1523             :     }
    1524           0 : }
    1525             : 
    1526             : 
    1527             : unsigned long
    1528           0 : keydb_get_skipped_counter (KEYDB_HANDLE hd)
    1529             : {
    1530           0 :   return hd ? hd->skipped_long_blobs : 0;
    1531             : }
    1532             : 
    1533             : 
    1534             : gpg_error_t
    1535          67 : keydb_search_reset (KEYDB_HANDLE hd)
    1536             : {
    1537          67 :   gpg_error_t rc = 0;
    1538             :   int i;
    1539             : 
    1540          67 :   if (!hd)
    1541           0 :     return gpg_error (GPG_ERR_INV_ARG);
    1542             : 
    1543          67 :   keyblock_cache_clear (hd);
    1544             : 
    1545          67 :   if (DBG_CLOCK)
    1546           0 :     log_clock ("keydb_search_reset");
    1547             : 
    1548          67 :   if (DBG_CACHE)
    1549           0 :     log_debug ("keydb_search: reset  (hd=%p)", hd);
    1550             : 
    1551          67 :   hd->skipped_long_blobs = 0;
    1552          67 :   hd->current = 0;
    1553          67 :   hd->found = -1;
    1554             :   /* Now reset all resources.  */
    1555         134 :   for (i=0; !rc && i < hd->used; i++)
    1556             :     {
    1557          67 :       switch (hd->active[i].type)
    1558             :         {
    1559             :         case KEYDB_RESOURCE_TYPE_NONE:
    1560           0 :           break;
    1561             :         case KEYDB_RESOURCE_TYPE_KEYRING:
    1562           0 :           rc = keyring_search_reset (hd->active[i].u.kr);
    1563           0 :           break;
    1564             :         case KEYDB_RESOURCE_TYPE_KEYBOX:
    1565          67 :           rc = keybox_search_reset (hd->active[i].u.kb);
    1566          67 :           break;
    1567             :         }
    1568             :     }
    1569          67 :   hd->is_reset = 1;
    1570          67 :   return rc;
    1571             : }
    1572             : 
    1573             : 
    1574             : static void
    1575           0 : dump_search_desc (KEYDB_HANDLE hd, const char *text,
    1576             :                   KEYDB_SEARCH_DESC *desc, size_t ndesc)
    1577             : {
    1578             :   int n;
    1579             :   const char *s;
    1580             : 
    1581           0 :   for (n=0; n < ndesc; n++)
    1582             :     {
    1583           0 :       switch (desc[n].mode)
    1584             :         {
    1585           0 :         case KEYDB_SEARCH_MODE_NONE:      s = "none";      break;
    1586           0 :         case KEYDB_SEARCH_MODE_EXACT:     s = "exact";     break;
    1587           0 :         case KEYDB_SEARCH_MODE_SUBSTR:    s = "substr";    break;
    1588           0 :         case KEYDB_SEARCH_MODE_MAIL:      s = "mail";      break;
    1589           0 :         case KEYDB_SEARCH_MODE_MAILSUB:   s = "mailsub";   break;
    1590           0 :         case KEYDB_SEARCH_MODE_MAILEND:   s = "mailend";   break;
    1591           0 :         case KEYDB_SEARCH_MODE_WORDS:     s = "words";     break;
    1592           0 :         case KEYDB_SEARCH_MODE_SHORT_KID: s = "short_kid"; break;
    1593           0 :         case KEYDB_SEARCH_MODE_LONG_KID:  s = "long_kid";  break;
    1594           0 :         case KEYDB_SEARCH_MODE_FPR16:     s = "fpr16";     break;
    1595           0 :         case KEYDB_SEARCH_MODE_FPR20:     s = "fpr20";     break;
    1596           0 :         case KEYDB_SEARCH_MODE_FPR:       s = "fpr";       break;
    1597           0 :         case KEYDB_SEARCH_MODE_ISSUER:    s = "issuer";    break;
    1598           0 :         case KEYDB_SEARCH_MODE_ISSUER_SN: s = "issuer_sn"; break;
    1599           0 :         case KEYDB_SEARCH_MODE_SN:        s = "sn";        break;
    1600           0 :         case KEYDB_SEARCH_MODE_SUBJECT:   s = "subject";   break;
    1601           0 :         case KEYDB_SEARCH_MODE_KEYGRIP:   s = "keygrip";   break;
    1602           0 :         case KEYDB_SEARCH_MODE_FIRST:     s = "first";     break;
    1603           0 :         case KEYDB_SEARCH_MODE_NEXT:      s = "next";      break;
    1604           0 :         default:                          s = "?";         break;
    1605             :         }
    1606           0 :       if (!n)
    1607           0 :         log_debug ("%s: mode=%s  (hd=%p)", text, s, hd);
    1608             :       else
    1609           0 :         log_debug ("%*s  mode=%s", (int)strlen (text), "", s);
    1610           0 :       if (desc[n].mode == KEYDB_SEARCH_MODE_LONG_KID)
    1611           0 :         log_printf (" %08lX%08lX", (unsigned long)desc[n].u.kid[0],
    1612           0 :                     (unsigned long)desc[n].u.kid[1]);
    1613           0 :       else if (desc[n].mode == KEYDB_SEARCH_MODE_SHORT_KID)
    1614           0 :         log_printf (" %08lX", (unsigned long)desc[n].u.kid[1]);
    1615           0 :       else if (desc[n].mode == KEYDB_SEARCH_MODE_SUBSTR)
    1616           0 :         log_printf (" '%s'", desc[n].u.name);
    1617             :     }
    1618           0 : }
    1619             : 
    1620             : 
    1621             : gpg_error_t
    1622        2665 : keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
    1623             :               size_t ndesc, size_t *descindex)
    1624             : {
    1625             :   gpg_error_t rc;
    1626        2665 :   int was_reset = hd->is_reset;
    1627             :   /* If an entry is already in the cache, then don't add it again.  */
    1628        2665 :   int already_in_cache = 0;
    1629             : 
    1630        2665 :   if (descindex)
    1631           0 :     *descindex = 0; /* Make sure it is always set on return.  */
    1632             : 
    1633        2665 :   if (!hd)
    1634           0 :     return gpg_error (GPG_ERR_INV_ARG);
    1635             : 
    1636        2665 :   if (DBG_CLOCK)
    1637           0 :     log_clock ("keydb_search enter");
    1638             : 
    1639        2665 :   if (DBG_CACHE)
    1640           0 :     dump_search_desc (hd, "keydb_search", desc, ndesc);
    1641             : 
    1642             : 
    1643        2665 :   if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID
    1644        1940 :       && (already_in_cache = kid_not_found_p (desc[0].u.kid)) == 1 )
    1645             :     {
    1646           1 :       if (DBG_CLOCK)
    1647           0 :         log_clock ("keydb_search leave (not found, cached)");
    1648           1 :       return gpg_error (GPG_ERR_NOT_FOUND);
    1649             :     }
    1650             : 
    1651             :   /* NB: If one of the exact search modes below is used in a loop to
    1652             :      walk over all keys (with the same fingerprint) the caching must
    1653             :      have been disabled for the handle.  */
    1654        2664 :   if (!hd->no_caching
    1655        2545 :       && ndesc == 1
    1656        2544 :       && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
    1657        2479 :           || desc[0].mode == KEYDB_SEARCH_MODE_FPR)
    1658         153 :       && hd->keyblock_cache.state  == KEYBLOCK_CACHE_FILLED
    1659           0 :       && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20))
    1660             :     {
    1661             :       /* (DESCINDEX is already set).  */
    1662           0 :       if (DBG_CLOCK)
    1663           0 :         log_clock ("keydb_search leave (cached)");
    1664           0 :       return 0;
    1665             :     }
    1666             : 
    1667        2664 :   rc = -1;
    1668        7992 :   while ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
    1669        2869 :          && hd->current >= 0 && hd->current < hd->used)
    1670             :     {
    1671        2664 :       switch (hd->active[hd->current].type)
    1672             :         {
    1673             :         case KEYDB_RESOURCE_TYPE_NONE:
    1674           0 :           BUG(); /* we should never see it here */
    1675             :           break;
    1676             :         case KEYDB_RESOURCE_TYPE_KEYRING:
    1677           0 :           rc = keyring_search (hd->active[hd->current].u.kr, desc,
    1678             :                                ndesc, descindex);
    1679           0 :           break;
    1680             :         case KEYDB_RESOURCE_TYPE_KEYBOX:
    1681        2664 :           rc = keybox_search (hd->active[hd->current].u.kb, desc,
    1682             :                               ndesc, KEYBOX_BLOBTYPE_PGP,
    1683             :                               descindex, &hd->skipped_long_blobs);
    1684        2664 :           break;
    1685             :         }
    1686        2664 :       if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
    1687             :         {
    1688             :           /* EOF -> switch to next resource */
    1689         205 :           hd->current++;
    1690             :         }
    1691        2459 :       else if (!rc)
    1692        2459 :         hd->found = hd->current;
    1693             :     }
    1694        2664 :   hd->is_reset = 0;
    1695             : 
    1696        5123 :   rc = ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
    1697             :         ? gpg_error (GPG_ERR_NOT_FOUND)
    1698        2869 :         : rc);
    1699             : 
    1700        2664 :   keyblock_cache_clear (hd);
    1701        2664 :   if (!hd->no_caching
    1702        2545 :       && !rc
    1703        2427 :       && ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
    1704        2362 :                         || desc[0].mode == KEYDB_SEARCH_MODE_FPR)
    1705          95 :       && hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX)
    1706             :     {
    1707          95 :       hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
    1708          95 :       memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20);
    1709             :     }
    1710             : 
    1711        2664 :   if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND
    1712         205 :       && ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID && was_reset
    1713           3 :       && !already_in_cache)
    1714           3 :     kid_not_found_insert (desc[0].u.kid);
    1715             : 
    1716        2664 :   if (DBG_CLOCK)
    1717           0 :     log_clock (rc? "keydb_search leave (not found)"
    1718             :                  : "keydb_search leave (found)");
    1719        2664 :   return rc;
    1720             : }
    1721             : 
    1722             : 
    1723             : gpg_error_t
    1724           0 : keydb_search_first (KEYDB_HANDLE hd)
    1725             : {
    1726             :   gpg_error_t err;
    1727             :   KEYDB_SEARCH_DESC desc;
    1728             : 
    1729           0 :   err = keydb_search_reset (hd);
    1730           0 :   if (err)
    1731           0 :     return err;
    1732             : 
    1733           0 :   memset (&desc, 0, sizeof desc);
    1734           0 :   desc.mode = KEYDB_SEARCH_MODE_FIRST;
    1735           0 :   err = keydb_search (hd, &desc, 1, NULL);
    1736           0 :   if (gpg_err_code (err) == GPG_ERR_LEGACY_KEY)
    1737           0 :     err = keydb_search_next (hd);
    1738           0 :   return err;
    1739             : }
    1740             : 
    1741             : 
    1742             : gpg_error_t
    1743           0 : keydb_search_next (KEYDB_HANDLE hd)
    1744             : {
    1745             :   gpg_error_t err;
    1746             :   KEYDB_SEARCH_DESC desc;
    1747             : 
    1748             :   do
    1749             :     {
    1750           0 :       memset (&desc, 0, sizeof desc);
    1751           0 :       desc.mode = KEYDB_SEARCH_MODE_NEXT;
    1752           0 :       err = keydb_search (hd, &desc, 1, NULL);
    1753             :     }
    1754           0 :   while (gpg_err_code (err) == GPG_ERR_LEGACY_KEY);
    1755             : 
    1756           0 :   return err;
    1757             : }
    1758             : 
    1759             : gpg_error_t
    1760           0 : keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
    1761             : {
    1762             :   KEYDB_SEARCH_DESC desc;
    1763             : 
    1764           0 :   memset (&desc, 0, sizeof desc);
    1765           0 :   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
    1766           0 :   desc.u.kid[0] = kid[0];
    1767           0 :   desc.u.kid[1] = kid[1];
    1768           0 :   return keydb_search (hd, &desc, 1, NULL);
    1769             : }
    1770             : 
    1771             : gpg_error_t
    1772         119 : keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
    1773             : {
    1774             :   gpg_error_t err;
    1775             :   KEYDB_SEARCH_DESC desc;
    1776             : 
    1777         119 :   memset (&desc, 0, sizeof desc);
    1778         119 :   desc.mode = KEYDB_SEARCH_MODE_FPR;
    1779         119 :   memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
    1780             :   do
    1781             :     {
    1782         119 :       err = keydb_search (hd, &desc, 1, NULL);
    1783             :     }
    1784         119 :   while (gpg_err_code (err) == GPG_ERR_LEGACY_KEY);
    1785             : 
    1786         119 :   return err;
    1787             : }

Generated by: LCOV version 1.11