New function log_clock.
[gnupg.git] / g10 / keydb.c
1 /* keydb.c - key database dispatcher
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3  *               2008, 2009, 2011 Free Software Foundation, Inc.
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 struct keydb_handle
66 {
67   int locked;
68   int found;
69   int current;
70   int used;   /* Number of items in ACTIVE. */
71   struct resource_item active[MAX_KEYDB_RESOURCES];
72 };
73
74
75 static int lock_all (KEYDB_HANDLE hd);
76 static void unlock_all (KEYDB_HANDLE hd);
77
78
79 /* Handle the creation of a keyring or a keybox if it does not yet
80    exist.  Take into acount that other processes might have the
81    keyring/keybox already locked.  This lock check does not work if
82    the directory itself is not yet available. */
83 static int
84 maybe_create_keyring_or_box (char *filename, int is_box, int force)
85 {
86   dotlock_t lockhd = NULL;
87   IOBUF iobuf;
88   int rc;
89   mode_t oldmask;
90   char *last_slash_in_filename;
91   int save_slash;
92
93   /* A quick test whether the filename already exists. */
94   if (!access (filename, F_OK))
95     return 0;
96
97   /* If we don't want to create a new file at all, there is no need to
98      go any further - bail out right here.  */
99   if (!force)
100     return gpg_error (GPG_ERR_ENOENT);
101
102   /* First of all we try to create the home directory.  Note, that we
103      don't do any locking here because any sane application of gpg
104      would create the home directory by itself and not rely on gpg's
105      tricky auto-creation which is anyway only done for some home
106      directory name patterns. */
107   last_slash_in_filename = strrchr (filename, DIRSEP_C);
108 #if HAVE_W32_SYSTEM
109   {
110     /* Windows may either have a slash or a backslash.  Take care of it.  */
111     char *p = strrchr (filename, '/');
112     if (!last_slash_in_filename || p > last_slash_in_filename)
113       last_slash_in_filename = p;
114   }
115 #endif /*HAVE_W32_SYSTEM*/
116   if (!last_slash_in_filename)
117     return gpg_error (GPG_ERR_ENOENT);  /* No slash at all - should
118                                            not happen though.  */
119   save_slash = *last_slash_in_filename;
120   *last_slash_in_filename = 0;
121   if (access(filename, F_OK))
122     {
123       static int tried;
124
125       if (!tried)
126         {
127           tried = 1;
128           try_make_homedir (filename);
129         }
130       if (access (filename, F_OK))
131         {
132           rc = gpg_error_from_syserror ();
133           *last_slash_in_filename = save_slash;
134           goto leave;
135         }
136     }
137   *last_slash_in_filename = save_slash;
138
139   /* To avoid races with other instances of gpg trying to create or
140      update the keyring (it is removed during an update for a short
141      time), we do the next stuff in a locked state. */
142   lockhd = dotlock_create (filename, 0);
143   if (!lockhd)
144     {
145       rc = gpg_error_from_syserror ();
146       /* A reason for this to fail is that the directory is not
147          writable. However, this whole locking stuff does not make
148          sense if this is the case. An empty non-writable directory
149          with no keyring is not really useful at all. */
150       if (opt.verbose)
151         log_info ("can't allocate lock for '%s': %s\n",
152                   filename, gpg_strerror (rc));
153
154       if (!force)
155         return gpg_error (GPG_ERR_ENOENT);
156       else
157         return rc;
158     }
159
160   if ( dotlock_take (lockhd, -1) )
161     {
162       rc = gpg_error_from_syserror ();
163       /* This is something bad.  Probably a stale lockfile.  */
164       log_info ("can't lock '%s': %s\n", filename, gpg_strerror (rc));
165       goto leave;
166     }
167
168   /* Now the real test while we are locked. */
169   if (!access (filename, F_OK))
170     {
171       rc = 0;  /* Okay, we may access the file now.  */
172       goto leave;
173     }
174
175   /* The file does not yet exist, create it now. */
176   oldmask = umask (077);
177   if (is_secured_filename (filename))
178     {
179       iobuf = NULL;
180       gpg_err_set_errno (EPERM);
181     }
182   else
183     iobuf = iobuf_create (filename);
184   umask (oldmask);
185   if (!iobuf)
186     {
187       rc = gpg_error_from_syserror ();
188       if (is_box)
189         log_error (_("error creating keybox '%s': %s\n"),
190                    filename, gpg_strerror (rc));
191       else
192         log_error (_("error creating keyring '%s': %s\n"),
193                    filename, gpg_strerror (rc));
194       goto leave;
195     }
196
197   iobuf_close (iobuf);
198   /* Must invalidate that ugly cache */
199   iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename);
200
201   /* Make sure that at least one record is in a new keybox file, so
202      that the detection magic will work the next time it is used.  */
203   if (is_box)
204     {
205       FILE *fp = fopen (filename, "w");
206       if (!fp)
207         rc = gpg_error_from_syserror ();
208       else
209         {
210           rc = _keybox_write_header_blob (fp);
211           fclose (fp);
212         }
213       if (rc)
214         {
215           if (is_box)
216             log_error (_("error creating keybox '%s': %s\n"),
217                        filename, gpg_strerror (rc));
218           else
219             log_error (_("error creating keyring '%s': %s\n"),
220                        filename, gpg_strerror (rc));
221           goto leave;
222         }
223     }
224
225   if (!opt.quiet)
226     {
227       if (is_box)
228         log_info (_("keybox '%s' created\n"), filename);
229       else
230         log_info (_("keyring '%s' created\n"), filename);
231     }
232
233   rc = 0;
234
235  leave:
236   if (lockhd)
237     {
238       dotlock_release (lockhd);
239       dotlock_destroy (lockhd);
240     }
241   return rc;
242 }
243
244
245 /*
246  * Register a resource (keyring or aeybox).  The first keyring or
247  * keybox which is added by this function is created if it does not
248  * exist.  FLAGS are a combination of the KEYDB_RESOURCE_FLAG_
249  * constants as defined in keydb.h.
250  */
251 gpg_error_t
252 keydb_add_resource (const char *url, unsigned int flags)
253 {
254   static int any_registered;
255   const char *resname = url;
256   char *filename = NULL;
257   int create;
258   int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY);
259   int rc = 0;
260   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
261   void *token;
262
263   /* Create the resource if it is the first registered one.  */
264   create = (!read_only && !any_registered);
265
266   /* Do we have an URL?
267    *    gnupg-ring:filename  := this is a plain keyring.
268    *    gnupg-kbx:filename   := this is a keybox file.
269    *    filename := See what is is, but create as plain keyring.
270    */
271   if (strlen (resname) > 11 && !strncmp( resname, "gnupg-ring:", 11) )
272     {
273       rt = KEYDB_RESOURCE_TYPE_KEYRING;
274       resname += 11;
275     }
276   else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) )
277     {
278       rt = KEYDB_RESOURCE_TYPE_KEYBOX;
279       resname += 10;
280     }
281 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
282   else if (strchr (resname, ':'))
283     {
284       log_error ("invalid key resource URL '%s'\n", url );
285       rc = gpg_error (GPG_ERR_GENERAL);
286       goto leave;
287     }
288 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
289
290   if (*resname != DIRSEP_C )
291     {
292       /* Do tilde expansion etc. */
293       if (strchr(resname, DIRSEP_C) )
294         filename = make_filename (resname, NULL);
295       else
296         filename = make_filename (opt.homedir, resname, NULL);
297     }
298   else
299     filename = xstrdup (resname);
300
301   /* See whether we can determine the filetype.  */
302   if (rt == KEYDB_RESOURCE_TYPE_NONE)
303     {
304       FILE *fp = fopen (filename, "rb");
305
306       if (fp)
307         {
308           u32 magic;
309
310           if (fread (&magic, 4, 1, fp) == 1 )
311             {
312               if (magic == 0x13579ace || magic == 0xce9a5713)
313                 ; /* GDBM magic - not anymore supported. */
314               else if (fread (&magic, 4, 1, fp) == 1
315                        && !memcmp (&magic, "\x01", 1)
316                        && fread (&magic, 4, 1, fp) == 1
317                        && !memcmp (&magic, "KBXf", 4))
318                 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
319               else
320                 rt = KEYDB_RESOURCE_TYPE_KEYRING;
321             }
322           else /* Maybe empty: assume keyring. */
323             rt = KEYDB_RESOURCE_TYPE_KEYRING;
324
325           fclose (fp);
326         }
327       else /* No file yet: create keybox. */
328         rt = KEYDB_RESOURCE_TYPE_KEYBOX;
329     }
330
331   switch (rt)
332     {
333     case KEYDB_RESOURCE_TYPE_NONE:
334       log_error ("unknown type of key resource '%s'\n", url );
335       rc = gpg_error (GPG_ERR_GENERAL);
336       goto leave;
337
338     case KEYDB_RESOURCE_TYPE_KEYRING:
339       rc = maybe_create_keyring_or_box (filename, create, 0);
340       if (rc)
341         goto leave;
342
343       if (keyring_register_filename (filename, read_only, &token))
344         {
345           if (used_resources >= MAX_KEYDB_RESOURCES)
346             rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
347           else
348             {
349               if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
350                 primary_keyring = token;
351               all_resources[used_resources].type = rt;
352               all_resources[used_resources].u.kr = NULL; /* Not used here */
353               all_resources[used_resources].token = token;
354               used_resources++;
355             }
356         }
357       else
358         {
359           /* This keyring was already registered, so ignore it.
360              However, we can still mark it as primary even if it was
361              already registered.  */
362           if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
363             primary_keyring = token;
364         }
365       break;
366
367     case KEYDB_RESOURCE_TYPE_KEYBOX:
368       {
369         rc = maybe_create_keyring_or_box (filename, create, 1);
370         if (rc)
371           goto leave;
372
373         /* FIXME: How do we register a read-only keybox?  */
374         token = keybox_register_file (filename, 0);
375         if (token)
376           {
377             if (used_resources >= MAX_KEYDB_RESOURCES)
378               rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
379             else
380               {
381                 /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
382                 /*   primary_keyring = token; */
383                 all_resources[used_resources].type = rt;
384                 all_resources[used_resources].u.kb = NULL; /* Not used here */
385                 all_resources[used_resources].token = token;
386
387                 /* FIXME: Do a compress run if needed and no other
388                    user is currently using the keybox. */
389
390                 used_resources++;
391               }
392           }
393         else
394           {
395             /* Already registered.  We will mark it as the primary key
396                if requested.  */
397             /* FIXME: How to do that?  Change the keybox interface?  */
398             /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
399             /*   primary_keyring = token; */
400           }
401       }
402       break;
403
404       default:
405         log_error ("resource type of '%s' not supported\n", url);
406         rc = gpg_error (GPG_ERR_GENERAL);
407         goto leave;
408     }
409
410   /* fixme: check directory permissions and print a warning */
411
412  leave:
413   if (rc)
414     log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc));
415   else
416     any_registered = 1;
417   xfree (filename);
418   return rc;
419 }
420
421
422
423
424 KEYDB_HANDLE
425 keydb_new (void)
426 {
427   KEYDB_HANDLE hd;
428   int i, j;
429
430   hd = xmalloc_clear (sizeof *hd);
431   hd->found = -1;
432
433   assert (used_resources <= MAX_KEYDB_RESOURCES);
434   for (i=j=0; i < used_resources; i++)
435     {
436       switch (all_resources[i].type)
437         {
438         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
439           break;
440         case KEYDB_RESOURCE_TYPE_KEYRING:
441           hd->active[j].type   = all_resources[i].type;
442           hd->active[j].token  = all_resources[i].token;
443           hd->active[j].u.kr = keyring_new (all_resources[i].token);
444           if (!hd->active[j].u.kr) {
445             xfree (hd);
446             return NULL; /* fixme: release all previously allocated handles*/
447           }
448           j++;
449           break;
450         case KEYDB_RESOURCE_TYPE_KEYBOX:
451           hd->active[j].type   = all_resources[i].type;
452           hd->active[j].token  = all_resources[i].token;
453           hd->active[j].u.kb   = keybox_new (all_resources[i].token, 0);
454           if (!hd->active[j].u.kb)
455             {
456               xfree (hd);
457               return NULL; /* fixme: release all previously allocated handles*/
458             }
459           j++;
460           break;
461         }
462     }
463   hd->used = j;
464
465   active_handles++;
466   return hd;
467 }
468
469 void
470 keydb_release (KEYDB_HANDLE hd)
471 {
472   int i;
473
474   if (!hd)
475     return;
476   assert (active_handles > 0);
477   active_handles--;
478
479   unlock_all (hd);
480   for (i=0; i < hd->used; i++)
481     {
482       switch (hd->active[i].type)
483         {
484         case KEYDB_RESOURCE_TYPE_NONE:
485           break;
486         case KEYDB_RESOURCE_TYPE_KEYRING:
487           keyring_release (hd->active[i].u.kr);
488           break;
489         case KEYDB_RESOURCE_TYPE_KEYBOX:
490           keybox_release (hd->active[i].u.kb);
491           break;
492         }
493     }
494
495   xfree (hd);
496 }
497
498
499 /*
500  * Return the name of the current resource.  This is function first
501  * looks for the last found found, then for the current search
502  * position, and last returns the first available resource.  The
503  * returned string is only valid as long as the handle exists.  This
504  * function does only return NULL if no handle is specified, in all
505  * other error cases an empty string is returned.
506  */
507 const char *
508 keydb_get_resource_name (KEYDB_HANDLE hd)
509 {
510   int idx;
511   const char *s = NULL;
512
513   if (!hd)
514     return NULL;
515
516   if ( hd->found >= 0 && hd->found < hd->used)
517     idx = hd->found;
518   else if ( hd->current >= 0 && hd->current < hd->used)
519     idx = hd->current;
520   else
521     idx = 0;
522
523   switch (hd->active[idx].type)
524     {
525     case KEYDB_RESOURCE_TYPE_NONE:
526       s = NULL;
527       break;
528     case KEYDB_RESOURCE_TYPE_KEYRING:
529       s = keyring_get_resource_name (hd->active[idx].u.kr);
530       break;
531     case KEYDB_RESOURCE_TYPE_KEYBOX:
532       s = keybox_get_resource_name (hd->active[idx].u.kb);
533       break;
534     }
535
536   return s? s: "";
537 }
538
539
540
541 static int
542 lock_all (KEYDB_HANDLE hd)
543 {
544   int i, rc = 0;
545
546   /* Fixme: This locking scheme may lead to a deadlock if the resources
547      are not added in the same order by all processes.  We are
548      currently only allowing one resource so it is not a problem.
549      [Oops: Who claimed the latter]
550
551      To fix this we need to use a lock file to protect lock_all.  */
552
553   for (i=0; !rc && i < hd->used; i++)
554     {
555       switch (hd->active[i].type)
556         {
557         case KEYDB_RESOURCE_TYPE_NONE:
558           break;
559         case KEYDB_RESOURCE_TYPE_KEYRING:
560           rc = keyring_lock (hd->active[i].u.kr, 1);
561           break;
562         case KEYDB_RESOURCE_TYPE_KEYBOX:
563           rc = keybox_lock (hd->active[i].u.kb, 1);
564           break;
565         }
566     }
567
568   if (rc)
569     {
570       /* Revert the already taken locks.  */
571       for (i--; i >= 0; i--)
572         {
573           switch (hd->active[i].type)
574             {
575             case KEYDB_RESOURCE_TYPE_NONE:
576               break;
577             case KEYDB_RESOURCE_TYPE_KEYRING:
578               keyring_lock (hd->active[i].u.kr, 0);
579               break;
580             case KEYDB_RESOURCE_TYPE_KEYBOX:
581               rc = keybox_lock (hd->active[i].u.kb, 0);
582               break;
583             }
584         }
585     }
586   else
587     hd->locked = 1;
588
589   return rc;
590 }
591
592
593 static void
594 unlock_all (KEYDB_HANDLE hd)
595 {
596   int i;
597
598   if (!hd->locked)
599     return;
600
601   for (i=hd->used-1; i >= 0; i--)
602     {
603       switch (hd->active[i].type)
604         {
605         case KEYDB_RESOURCE_TYPE_NONE:
606           break;
607         case KEYDB_RESOURCE_TYPE_KEYRING:
608           keyring_lock (hd->active[i].u.kr, 0);
609           break;
610         case KEYDB_RESOURCE_TYPE_KEYBOX:
611           keybox_lock (hd->active[i].u.kb, 0);
612           break;
613         }
614     }
615   hd->locked = 0;
616 }
617
618
619 static gpg_error_t
620 parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
621 {
622   gpg_error_t err;
623   PACKET *pkt;
624   kbnode_t keyblock = NULL;
625   kbnode_t node, *tail;
626   int in_cert, save_mode;
627   u32 n_sigs;
628
629   *r_keyblock = NULL;
630
631   pkt = xtrymalloc (sizeof *pkt);
632   if (!pkt)
633     return gpg_error_from_syserror ();
634   init_packet (pkt);
635   save_mode = set_packet_list_mode (0);
636   in_cert = 0;
637   n_sigs = 0;
638   tail = NULL;
639   while ((err = parse_packet (iobuf, pkt)) != -1)
640     {
641       if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET)
642         {
643           free_packet (pkt);
644           init_packet (pkt);
645           continue;
646         }
647       if (err)
648         {
649           log_error ("parse_keyblock_image: read error: %s\n",
650                      gpg_strerror (err));
651           err = gpg_error (GPG_ERR_INV_KEYRING);
652           break;
653         }
654       if (pkt->pkttype == PKT_COMPRESSED)
655         {
656           log_error ("skipped compressed packet in keybox blob\n");
657           free_packet(pkt);
658           init_packet(pkt);
659           continue;
660         }
661       if (pkt->pkttype == PKT_RING_TRUST)
662         {
663           log_info ("skipped ring trust packet in keybox blob\n");
664           free_packet(pkt);
665           init_packet(pkt);
666           continue;
667         }
668
669       if (!in_cert && pkt->pkttype != PKT_PUBLIC_KEY)
670         {
671           log_error ("parse_keyblock_image: first packet in a keybox blob "
672                      "is not a public key packet\n");
673           err = gpg_error (GPG_ERR_INV_KEYRING);
674           break;
675         }
676       if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY
677                       || pkt->pkttype == PKT_SECRET_KEY))
678         {
679           log_error ("parse_keyblock_image: "
680                      "multiple keyblocks in a keybox blob\n");
681           err = gpg_error (GPG_ERR_INV_KEYRING);
682           break;
683         }
684       in_cert = 1;
685
686       if (pkt->pkttype == PKT_SIGNATURE && sigstatus)
687         {
688           PKT_signature *sig = pkt->pkt.signature;
689
690           n_sigs++;
691           if (n_sigs > sigstatus[0])
692             {
693               log_error ("parse_keyblock_image: "
694                          "more signatures than found in the meta data\n");
695               err = gpg_error (GPG_ERR_INV_KEYRING);
696               break;
697
698             }
699           if (sigstatus[n_sigs])
700             {
701               sig->flags.checked = 1;
702               if (sigstatus[n_sigs] == 1 )
703                 ; /* missing key */
704               else if (sigstatus[n_sigs] == 2 )
705                 ; /* bad signature */
706               else if (sigstatus[n_sigs] < 0x10000000)
707                 ; /* bad flag */
708               else
709                 {
710                   sig->flags.valid = 1;
711                   /* Fixme: Shall we set the expired flag here?  */
712                 }
713             }
714         }
715
716       node = new_kbnode (pkt);
717       if (!keyblock)
718         keyblock = node;
719       else
720         *tail = node;
721       tail = &node->next;
722       pkt = xtrymalloc (sizeof *pkt);
723       if (!pkt)
724         {
725           err = gpg_error_from_syserror ();
726           break;
727         }
728       init_packet (pkt);
729     }
730   set_packet_list_mode (save_mode);
731
732   if (err == -1 && keyblock)
733     err = 0; /* Got the entire keyblock.  */
734
735   if (!err && sigstatus && n_sigs != sigstatus[0])
736     {
737       log_error ("parse_keyblock_image: signature count does not match\n");
738       err = gpg_error (GPG_ERR_INV_KEYRING);
739     }
740
741   if (err)
742     release_kbnode (keyblock);
743   else
744     *r_keyblock = keyblock;
745   free_packet (pkt);
746   xfree (pkt);
747   return err;
748 }
749
750
751 /*
752  * Return the last found keyring.  Caller must free it.
753  * The returned keyblock has the kbode flag bit 0 set for the node with
754  * the public key used to locate the keyblock or flag bit 1 set for
755  * the user ID node.
756  */
757 gpg_error_t
758 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
759 {
760   gpg_error_t err = 0;
761
762   *ret_kb = NULL;
763
764   if (!hd)
765     return gpg_error (GPG_ERR_INV_ARG);
766
767   if (hd->found < 0 || hd->found >= hd->used)
768     return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
769
770   switch (hd->active[hd->found].type)
771     {
772     case KEYDB_RESOURCE_TYPE_NONE:
773       err = gpg_error (GPG_ERR_GENERAL); /* oops */
774       break;
775     case KEYDB_RESOURCE_TYPE_KEYRING:
776       err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
777       break;
778     case KEYDB_RESOURCE_TYPE_KEYBOX:
779       {
780         iobuf_t iobuf;
781         u32 *sigstatus;
782
783         err = keybox_get_keyblock (hd->active[hd->found].u.kb,
784                                    &iobuf, &sigstatus);
785         if (!err)
786           {
787             err = parse_keyblock_image (iobuf, sigstatus, ret_kb);
788             xfree (sigstatus);
789             iobuf_close (iobuf);
790           }
791       }
792       break;
793     }
794
795   return err;
796 }
797
798
799 /* Build a keyblock image from KEYBLOCK.  Returns 0 on success and
800    only then stores a new iobuf object at R_IOBUF and a signature
801    status vecotor at R_SIGSTATUS.  */
802 static gpg_error_t
803 build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus)
804 {
805   gpg_error_t err;
806   iobuf_t iobuf;
807   kbnode_t kbctx, node;
808   u32 n_sigs;
809   u32 *sigstatus;
810
811   *r_iobuf = NULL;
812   *r_sigstatus = NULL;
813
814   /* Allocate a vector for the signature cache.  This is an array of
815      u32 values with the first value giving the number of elements to
816      follow and each element descriping the cache status of the
817      signature.  */
818   for (kbctx = NULL, n_sigs = 0; (node = walk_kbnode (keyblock, &kbctx, 0));)
819     if (node->pkt->pkttype == PKT_SIGNATURE)
820       n_sigs++;
821   sigstatus = xtrycalloc (1+n_sigs, sizeof *sigstatus);
822   if (!sigstatus)
823     return gpg_error_from_syserror ();
824
825   iobuf = iobuf_temp ();
826   for (kbctx = NULL, n_sigs = 0; (node = walk_kbnode (keyblock, &kbctx, 0));)
827     {
828       /* Make sure to use only packets valid on a keyblock.  */
829       switch (node->pkt->pkttype)
830         {
831         case PKT_PUBLIC_KEY:
832         case PKT_PUBLIC_SUBKEY:
833         case PKT_SIGNATURE:
834         case PKT_USER_ID:
835         case PKT_ATTRIBUTE:
836           /* Note that we don't want the ring trust packets.  They are
837              not useful. */
838           break;
839         default:
840           continue;
841         }
842
843       err = build_packet (iobuf, node->pkt);
844       if (err)
845         {
846           iobuf_close (iobuf);
847           return err;
848         }
849
850       /* Build signature status vector.  */
851       if (node->pkt->pkttype == PKT_SIGNATURE)
852         {
853           PKT_signature *sig = node->pkt->pkt.signature;
854
855           n_sigs++;
856           /* Fixme: Detect tye "missing key" status.  */
857           if (sig->flags.checked)
858             {
859               if (sig->flags.valid)
860                 {
861                   if (!sig->expiredate)
862                     sigstatus[n_sigs] = 0xffffffff;
863                   else if (sig->expiredate < 0x1000000)
864                     sigstatus[n_sigs] = 0x10000000;
865                   else
866                     sigstatus[n_sigs] = sig->expiredate;
867                 }
868               else
869                 sigstatus[n_sigs] = 0x00000002; /* Bad signature.  */
870             }
871         }
872     }
873   sigstatus[0] = n_sigs;
874
875   *r_iobuf = iobuf;
876   *r_sigstatus = sigstatus;
877   return 0;
878 }
879
880
881 /*
882  * Update the current keyblock with the keyblock KB
883  */
884 gpg_error_t
885 keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
886 {
887   gpg_error_t rc;
888
889   if (!hd)
890     return gpg_error (GPG_ERR_INV_ARG);
891
892   if (hd->found < 0 || hd->found >= hd->used)
893     return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
894
895   if (opt.dry_run)
896     return 0;
897
898   rc = lock_all (hd);
899   if (rc)
900     return rc;
901
902   switch (hd->active[hd->found].type)
903     {
904     case KEYDB_RESOURCE_TYPE_NONE:
905       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
906       break;
907     case KEYDB_RESOURCE_TYPE_KEYRING:
908       rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
909       break;
910     /* case KEYDB_RESOURCE_TYPE_KEYRING: */
911     /*   rc = build_keyblock (kb, &image, &imagelen); */
912     /*   if (!rc) */
913     /*     rc = keybox_update_keyblock (hd->active[hd->found].u.kb, */
914     /*                                  image, imagelen); */
915     /*   break; */
916     }
917
918   unlock_all (hd);
919   return rc;
920 }
921
922
923 /*
924  * Insert a new KB into one of the resources.
925  */
926 gpg_error_t
927 keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
928 {
929   gpg_error_t err;
930   int idx;
931
932   if (!hd)
933     return gpg_error (GPG_ERR_INV_ARG);
934
935   if (opt.dry_run)
936     return 0;
937
938   if (hd->found >= 0 && hd->found < hd->used)
939     idx = hd->found;
940   else if (hd->current >= 0 && hd->current < hd->used)
941     idx = hd->current;
942   else
943     return gpg_error (GPG_ERR_GENERAL);
944
945   err = lock_all (hd);
946   if (err)
947     return err;
948
949   switch (hd->active[idx].type)
950     {
951     case KEYDB_RESOURCE_TYPE_NONE:
952       err = gpg_error (GPG_ERR_GENERAL); /* oops */
953       break;
954     case KEYDB_RESOURCE_TYPE_KEYRING:
955       err = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
956       break;
957     case KEYDB_RESOURCE_TYPE_KEYBOX:
958       { /* We need to turn our kbnode_t list of packets into a proper
959            keyblock first.  This is required by the OpenPGP key parser
960            included in the keybox code.  Eventually we can change this
961            kludge to have the caller pass the image.  */
962         iobuf_t iobuf;
963         u32 *sigstatus;
964
965         err = build_keyblock_image (kb, &iobuf, &sigstatus);
966         if (!err)
967           {
968             err = keybox_insert_keyblock (hd->active[idx].u.kb,
969                                           iobuf_get_temp_buffer (iobuf),
970                                           iobuf_get_temp_length (iobuf),
971                                           sigstatus);
972             xfree (sigstatus);
973             iobuf_close (iobuf);
974           }
975       }
976       break;
977     }
978
979   unlock_all (hd);
980   return err;
981 }
982
983
984 /*
985  * Delete the current keyblock.
986  */
987 gpg_error_t
988 keydb_delete_keyblock (KEYDB_HANDLE hd)
989 {
990   gpg_error_t rc;
991
992   if (!hd)
993     return gpg_error (GPG_ERR_INV_ARG);
994
995   if (hd->found < 0 || hd->found >= hd->used)
996     return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
997
998   if (opt.dry_run)
999     return 0;
1000
1001   rc = lock_all (hd);
1002   if (rc)
1003     return rc;
1004
1005   switch (hd->active[hd->found].type)
1006     {
1007     case KEYDB_RESOURCE_TYPE_NONE:
1008       rc = gpg_error (GPG_ERR_GENERAL);
1009       break;
1010     case KEYDB_RESOURCE_TYPE_KEYRING:
1011       rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
1012       break;
1013     case KEYDB_RESOURCE_TYPE_KEYBOX:
1014       rc = keybox_delete (hd->active[hd->found].u.kb);
1015       break;
1016     }
1017
1018   unlock_all (hd);
1019   return rc;
1020 }
1021
1022
1023 \f
1024 /*
1025  * Locate the default writable key resource, so that the next
1026  * operation (which is only relevant for inserts) will be done on this
1027  * resource.
1028  */
1029 gpg_error_t
1030 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
1031 {
1032   gpg_error_t rc;
1033
1034   (void)reserved;
1035
1036   if (!hd)
1037     return G10ERR_INV_ARG;
1038
1039   rc = keydb_search_reset (hd); /* this does reset hd->current */
1040   if (rc)
1041     return rc;
1042
1043   /* If we have a primary set, try that one first */
1044   if (primary_keyring)
1045     {
1046       for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
1047         {
1048           if(hd->active[hd->current].token==primary_keyring)
1049             {
1050               if(keyring_is_writable (hd->active[hd->current].token))
1051                 return 0;
1052               else
1053                 break;
1054             }
1055         }
1056
1057       rc = keydb_search_reset (hd); /* this does reset hd->current */
1058       if (rc)
1059         return rc;
1060     }
1061
1062   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
1063     {
1064       switch (hd->active[hd->current].type)
1065         {
1066         case KEYDB_RESOURCE_TYPE_NONE:
1067           BUG();
1068           break;
1069         case KEYDB_RESOURCE_TYPE_KEYRING:
1070           if (keyring_is_writable (hd->active[hd->current].token))
1071             return 0; /* found (hd->current is set to it) */
1072           break;
1073         case KEYDB_RESOURCE_TYPE_KEYBOX:
1074           if (keybox_is_writable (hd->active[hd->current].token))
1075             return 0; /* found (hd->current is set to it) */
1076           break;
1077         }
1078     }
1079
1080   return gpg_error (GPG_ERR_NOT_FOUND);
1081 }
1082
1083 /*
1084  * Rebuild the caches of all key resources.
1085  */
1086 void
1087 keydb_rebuild_caches (int noisy)
1088 {
1089   int i, rc;
1090
1091   for (i=0; i < used_resources; i++)
1092     {
1093       if (!keyring_is_writable (all_resources[i].token))
1094         continue;
1095       switch (all_resources[i].type)
1096         {
1097         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
1098           break;
1099         case KEYDB_RESOURCE_TYPE_KEYRING:
1100           rc = keyring_rebuild_cache (all_resources[i].token,noisy);
1101           if (rc)
1102             log_error (_("failed to rebuild keyring cache: %s\n"),
1103                        g10_errstr (rc));
1104           break;
1105         }
1106     }
1107 }
1108
1109
1110
1111 /*
1112  * Start the next search on this handle right at the beginning
1113  */
1114 gpg_error_t
1115 keydb_search_reset (KEYDB_HANDLE hd)
1116 {
1117   gpg_error_t rc = 0;
1118   int i;
1119
1120   if (!hd)
1121     return gpg_error (GPG_ERR_INV_ARG);
1122
1123   hd->current = 0;
1124   hd->found = -1;
1125   /* Now reset all resources.  */
1126   for (i=0; !rc && i < hd->used; i++)
1127     {
1128       switch (hd->active[i].type)
1129         {
1130         case KEYDB_RESOURCE_TYPE_NONE:
1131           break;
1132         case KEYDB_RESOURCE_TYPE_KEYRING:
1133           rc = keyring_search_reset (hd->active[i].u.kr);
1134           break;
1135         case KEYDB_RESOURCE_TYPE_KEYBOX:
1136           rc = keybox_search_reset (hd->active[i].u.kb);
1137           break;
1138         }
1139     }
1140   return rc;
1141 }
1142
1143
1144 /*
1145  * Search through all keydb resources, starting at the current
1146  * position, for a keyblock which contains one of the keys described
1147  * in the DESC array.  Returns GPG_ERR_NOT_FOUND if no matching
1148  * keyring was found.
1149  */
1150 gpg_error_t
1151 keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
1152                size_t ndesc, size_t *descindex)
1153 {
1154   gpg_error_t rc;
1155
1156   if (!hd)
1157     return gpg_error (GPG_ERR_INV_ARG);
1158
1159   if (DBG_CLOCK)
1160     log_clock ("keydb_search enter");
1161
1162   rc = -1;
1163   while ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
1164          && hd->current >= 0 && hd->current < hd->used)
1165     {
1166       switch (hd->active[hd->current].type)
1167         {
1168         case KEYDB_RESOURCE_TYPE_NONE:
1169           BUG(); /* we should never see it here */
1170           break;
1171         case KEYDB_RESOURCE_TYPE_KEYRING:
1172           rc = keyring_search (hd->active[hd->current].u.kr, desc,
1173                                ndesc, descindex);
1174           break;
1175         case KEYDB_RESOURCE_TYPE_KEYBOX:
1176           rc = keybox_search (hd->active[hd->current].u.kb, desc, ndesc);
1177           break;
1178         }
1179       if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
1180         {
1181           /* EOF -> switch to next resource */
1182           hd->current++;
1183         }
1184       else if (!rc)
1185         hd->found = hd->current;
1186     }
1187
1188   if (DBG_CLOCK)
1189     log_clock ("keydb_search leave");
1190   return ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
1191           ? gpg_error (GPG_ERR_NOT_FOUND)
1192           : rc);
1193 }
1194
1195
1196 gpg_error_t
1197 keydb_search_first (KEYDB_HANDLE hd)
1198 {
1199   KEYDB_SEARCH_DESC desc;
1200
1201   memset (&desc, 0, sizeof desc);
1202   desc.mode = KEYDB_SEARCH_MODE_FIRST;
1203   return keydb_search (hd, &desc, 1);
1204 }
1205
1206 gpg_error_t
1207 keydb_search_next (KEYDB_HANDLE hd)
1208 {
1209   KEYDB_SEARCH_DESC desc;
1210
1211   memset (&desc, 0, sizeof desc);
1212   desc.mode = KEYDB_SEARCH_MODE_NEXT;
1213   return keydb_search (hd, &desc, 1);
1214 }
1215
1216 gpg_error_t
1217 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
1218 {
1219   KEYDB_SEARCH_DESC desc;
1220
1221   memset (&desc, 0, sizeof desc);
1222   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
1223   desc.u.kid[0] = kid[0];
1224   desc.u.kid[1] = kid[1];
1225   return keydb_search (hd, &desc, 1);
1226 }
1227
1228 gpg_error_t
1229 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
1230 {
1231   KEYDB_SEARCH_DESC desc;
1232
1233   memset (&desc, 0, sizeof desc);
1234   desc.mode = KEYDB_SEARCH_MODE_FPR;
1235   memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
1236   return keydb_search (hd, &desc, 1);
1237 }