common/iobuf.c: Combine iobuf_open, iobuf_create and iobuf_openrw.
[gnupg.git] / sm / keydb.c
1 /* keydb.c - key database dispatcher
2  * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
3  * Copyright (C) 2014 g10 Code GmbH
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 "gpgsm.h"
32 #include "../kbx/keybox.h"
33 #include "keydb.h"
34 #include "i18n.h"
35
36 static int active_handles;
37
38 typedef enum {
39     KEYDB_RESOURCE_TYPE_NONE = 0,
40     KEYDB_RESOURCE_TYPE_KEYBOX
41 } KeydbResourceType;
42 #define MAX_KEYDB_RESOURCES 20
43
44 struct resource_item {
45   KeydbResourceType type;
46   union {
47     KEYBOX_HANDLE kr;
48   } u;
49   void *token;
50   int secret;
51   dotlock_t lockhandle;
52 };
53
54 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
55 static int used_resources;
56
57 struct keydb_handle {
58   int locked;
59   int found;
60   int saved_found;
61   int current;
62   int is_ephemeral;
63   int used; /* items in active */
64   struct resource_item active[MAX_KEYDB_RESOURCES];
65 };
66
67
68 static int lock_all (KEYDB_HANDLE hd);
69 static void unlock_all (KEYDB_HANDLE hd);
70
71
72 static void
73 try_make_homedir (const char *fname)
74 {
75   const char *defhome = standard_homedir ();
76
77   /* Create the directory only if the supplied directory name is the
78      same as the default one.  This way we avoid to create arbitrary
79      directories when a non-default home directory is used.  To cope
80      with HOME, we do compare only the suffix if we see that the
81      default homedir does start with a tilde.  */
82   if ( opt.dry_run || opt.no_homedir_creation )
83     return;
84
85   if (
86 #ifdef HAVE_W32_SYSTEM
87       ( !compare_filenames (fname, defhome) )
88 #else
89       ( *defhome == '~'
90         && (strlen(fname) >= strlen (defhome+1)
91             && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) ))
92       || (*defhome != '~'  && !compare_filenames( fname, defhome ) )
93 #endif
94       )
95     {
96       if (gnupg_mkdir (fname, "-rwx"))
97         log_info (_("can't create directory '%s': %s\n"),
98                   fname, strerror(errno) );
99       else if (!opt.quiet )
100         log_info (_("directory '%s' created\n"), fname);
101     }
102 }
103
104
105 /* Handle the creation of a keybox if it does not yet exist.  Take
106    into acount that other processes might have the keybox already
107    locked.  This lock check does not work if the directory itself is
108    not yet available.  If R_CREATED is not NULL it will be set to true
109    if the function created a new keybox.  */
110 static int
111 maybe_create_keybox (char *filename, int force, int *r_created)
112 {
113   dotlock_t lockhd = NULL;
114   FILE *fp;
115   int rc;
116   mode_t oldmask;
117   char *last_slash_in_filename;
118   int save_slash;
119
120   if (r_created)
121     *r_created = 0;
122
123   /* A quick test whether the filename already exists. */
124   if (!access (filename, F_OK))
125     return 0;
126
127   /* If we don't want to create a new file at all, there is no need to
128      go any further - bail out right here.  */
129   if (!force)
130     return gpg_error (GPG_ERR_ENOENT);
131
132   /* First of all we try to create the home directory.  Note, that we
133      don't do any locking here because any sane application of gpg
134      would create the home directory by itself and not rely on gpg's
135      tricky auto-creation which is anyway only done for some home
136      directory name patterns. */
137   last_slash_in_filename = strrchr (filename, DIRSEP_C);
138 #if HAVE_W32_SYSTEM
139   {
140     /* Windows may either have a slash or a backslash.  Take care of it.  */
141     char *p = strrchr (filename, '/');
142     if (!last_slash_in_filename || p > last_slash_in_filename)
143       last_slash_in_filename = p;
144   }
145 #endif /*HAVE_W32_SYSTEM*/
146   if (!last_slash_in_filename)
147     return gpg_error (GPG_ERR_ENOENT);  /* No slash at all - should
148                                            not happen though.  */
149   save_slash = *last_slash_in_filename;
150   *last_slash_in_filename = 0;
151   if (access(filename, F_OK))
152     {
153       static int tried;
154
155       if (!tried)
156         {
157           tried = 1;
158           try_make_homedir (filename);
159         }
160       if (access (filename, F_OK))
161         {
162           rc = gpg_error_from_syserror ();
163           *last_slash_in_filename = save_slash;
164           goto leave;
165         }
166     }
167   *last_slash_in_filename = save_slash;
168
169   /* To avoid races with other instances of gpg trying to create or
170      update the keybox (it is removed during an update for a short
171      time), we do the next stuff in a locked state. */
172   lockhd = dotlock_create (filename, 0);
173   if (!lockhd)
174     {
175       /* A reason for this to fail is that the directory is not
176          writable. However, this whole locking stuff does not make
177          sense if this is the case. An empty non-writable directory
178          with no keyring is not really useful at all. */
179       if (opt.verbose)
180         log_info ("can't allocate lock for '%s'\n", filename );
181
182       if (!force)
183         return gpg_error (GPG_ERR_ENOENT);
184       else
185         return gpg_error (GPG_ERR_GENERAL);
186     }
187
188   if ( dotlock_take (lockhd, -1) )
189     {
190       /* This is something bad.  Probably a stale lockfile.  */
191       log_info ("can't lock '%s'\n", filename);
192       rc = gpg_error (GPG_ERR_GENERAL);
193       goto leave;
194     }
195
196   /* Now the real test while we are locked. */
197   if (!access(filename, F_OK))
198     {
199       rc = 0;  /* Okay, we may access the file now.  */
200       goto leave;
201     }
202
203   /* The file does not yet exist, create it now. */
204   oldmask = umask (077);
205   fp = fopen (filename, "w");
206   if (!fp)
207     {
208       rc = gpg_error_from_syserror ();
209       umask (oldmask);
210       log_error (_("error creating keybox '%s': %s\n"),
211                  filename, gpg_strerror (rc));
212       goto leave;
213     }
214   umask (oldmask);
215
216   if (!opt.quiet)
217     log_info (_("keybox '%s' created\n"), filename);
218   if (r_created)
219     *r_created = 1;
220
221   fclose (fp);
222   rc = 0;
223
224  leave:
225   if (lockhd)
226     {
227       dotlock_release (lockhd);
228       dotlock_destroy (lockhd);
229     }
230   return rc;
231 }
232
233
234 /*
235  * Register a resource (which currently may only be a keybox file).
236  * The first keybox which is added by this function is created if it
237  * does not exist.  If AUTO_CREATED is not NULL it will be set to true
238  * if the function has created a new keybox.
239  */
240 int
241 keydb_add_resource (const char *url, int force, int secret, int *auto_created)
242 {
243   static int any_secret, any_public;
244   const char *resname = url;
245   char *filename = NULL;
246   int rc = 0;
247   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
248
249   if (auto_created)
250     *auto_created = 0;
251
252   /* Do we have an URL?
253      gnupg-kbx:filename := this is a plain keybox
254      filename := See what is is, but create as plain keybox.
255   */
256   if (strlen (resname) > 10)
257     {
258       if (!strncmp (resname, "gnupg-kbx:", 10) )
259         {
260           rt = KEYDB_RESOURCE_TYPE_KEYBOX;
261           resname += 10;
262         }
263 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
264       else if (strchr (resname, ':'))
265         {
266           log_error ("invalid key resource URL '%s'\n", url );
267           rc = gpg_error (GPG_ERR_GENERAL);
268           goto leave;
269         }
270 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
271     }
272
273   if (*resname != DIRSEP_C )
274     { /* do tilde expansion etc */
275       if (strchr(resname, DIRSEP_C) )
276         filename = make_filename (resname, NULL);
277       else
278         filename = make_filename (opt.homedir, resname, NULL);
279     }
280   else
281     filename = xstrdup (resname);
282
283   if (!force)
284     force = secret? !any_secret : !any_public;
285
286   /* see whether we can determine the filetype */
287   if (rt == KEYDB_RESOURCE_TYPE_NONE)
288     {
289       FILE *fp = fopen( filename, "rb" );
290
291       if (fp)
292         {
293           u32 magic;
294
295           /* FIXME: check for the keybox magic */
296           if (fread (&magic, 4, 1, fp) == 1 )
297             {
298               if (magic == 0x13579ace || magic == 0xce9a5713)
299                 ; /* GDBM magic - no more support */
300               else
301                 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
302             }
303           else /* maybe empty: assume keybox */
304             rt = KEYDB_RESOURCE_TYPE_KEYBOX;
305           fclose (fp);
306         }
307       else /* no file yet: create keybox */
308         rt = KEYDB_RESOURCE_TYPE_KEYBOX;
309     }
310
311   switch (rt)
312     {
313     case KEYDB_RESOURCE_TYPE_NONE:
314       log_error ("unknown type of key resource '%s'\n", url );
315       rc = gpg_error (GPG_ERR_GENERAL);
316       goto leave;
317
318     case KEYDB_RESOURCE_TYPE_KEYBOX:
319       rc = maybe_create_keybox (filename, force, auto_created);
320       if (rc)
321         goto leave;
322       /* Now register the file */
323       {
324         void *token = keybox_register_file (filename, secret);
325         if (!token)
326           ; /* already registered - ignore it */
327         else if (used_resources >= MAX_KEYDB_RESOURCES)
328           rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
329         else
330           {
331             all_resources[used_resources].type = rt;
332             all_resources[used_resources].u.kr = NULL; /* Not used here */
333             all_resources[used_resources].token = token;
334             all_resources[used_resources].secret = secret;
335
336             all_resources[used_resources].lockhandle
337               = dotlock_create (filename, 0);
338             if (!all_resources[used_resources].lockhandle)
339               log_fatal ( _("can't create lock for '%s'\n"), filename);
340
341             /* Do a compress run if needed and the file is not locked. */
342             if (!dotlock_take (all_resources[used_resources].lockhandle, 0))
343               {
344                 KEYBOX_HANDLE kbxhd = keybox_new_x509 (token, secret);
345
346                 if (kbxhd)
347                   {
348                     keybox_compress (kbxhd);
349                     keybox_release (kbxhd);
350                   }
351                 dotlock_release (all_resources[used_resources].lockhandle);
352               }
353
354             used_resources++;
355           }
356       }
357       break;
358
359     default:
360       log_error ("resource type of '%s' not supported\n", url);
361       rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
362       goto leave;
363     }
364
365   /* fixme: check directory permissions and print a warning */
366
367  leave:
368   if (rc)
369     log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror(rc));
370   else if (secret)
371     any_secret = 1;
372   else
373     any_public = 1;
374   xfree (filename);
375   return rc;
376 }
377
378
379 KEYDB_HANDLE
380 keydb_new (int secret)
381 {
382   KEYDB_HANDLE hd;
383   int i, j;
384
385   hd = xcalloc (1, sizeof *hd);
386   hd->found = -1;
387   hd->saved_found = -1;
388
389   assert (used_resources <= MAX_KEYDB_RESOURCES);
390   for (i=j=0; i < used_resources; i++)
391     {
392       if (!all_resources[i].secret != !secret)
393         continue;
394       switch (all_resources[i].type)
395         {
396         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
397           break;
398         case KEYDB_RESOURCE_TYPE_KEYBOX:
399           hd->active[j].type   = all_resources[i].type;
400           hd->active[j].token  = all_resources[i].token;
401           hd->active[j].secret = all_resources[i].secret;
402           hd->active[j].lockhandle = all_resources[i].lockhandle;
403           hd->active[j].u.kr = keybox_new_x509 (all_resources[i].token, secret);
404           if (!hd->active[j].u.kr)
405             {
406               xfree (hd);
407               return NULL; /* fixme: release all previously allocated handles*/
408             }
409           j++;
410           break;
411         }
412     }
413   hd->used = j;
414
415   active_handles++;
416   return hd;
417 }
418
419 void
420 keydb_release (KEYDB_HANDLE hd)
421 {
422   int i;
423
424   if (!hd)
425     return;
426   assert (active_handles > 0);
427   active_handles--;
428
429   unlock_all (hd);
430   for (i=0; i < hd->used; i++)
431     {
432       switch (hd->active[i].type)
433         {
434         case KEYDB_RESOURCE_TYPE_NONE:
435           break;
436         case KEYDB_RESOURCE_TYPE_KEYBOX:
437           keybox_release (hd->active[i].u.kr);
438           break;
439         }
440     }
441
442     xfree (hd);
443 }
444
445
446 /* Return the name of the current resource.  This is function first
447    looks for the last found found, then for the current search
448    position, and last returns the first available resource.  The
449    returned string is only valid as long as the handle exists.  This
450    function does only return NULL if no handle is specified, in all
451    other error cases an empty string is returned.  */
452 const char *
453 keydb_get_resource_name (KEYDB_HANDLE hd)
454 {
455   int idx;
456   const char *s = NULL;
457
458   if (!hd)
459     return NULL;
460
461   if ( hd->found >= 0 && hd->found < hd->used)
462     idx = hd->found;
463   else if ( hd->current >= 0 && hd->current < hd->used)
464     idx = hd->current;
465   else
466     idx = 0;
467
468   switch (hd->active[idx].type)
469     {
470     case KEYDB_RESOURCE_TYPE_NONE:
471       s = NULL;
472       break;
473     case KEYDB_RESOURCE_TYPE_KEYBOX:
474       s = keybox_get_resource_name (hd->active[idx].u.kr);
475       break;
476     }
477
478   return s? s: "";
479 }
480
481 /* Switch the handle into ephemeral mode and return the orginal value. */
482 int
483 keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
484 {
485   int i;
486
487   if (!hd)
488     return 0;
489
490   yes = !!yes;
491   if (hd->is_ephemeral != yes)
492     {
493       for (i=0; i < hd->used; i++)
494         {
495           switch (hd->active[i].type)
496             {
497             case KEYDB_RESOURCE_TYPE_NONE:
498               break;
499             case KEYDB_RESOURCE_TYPE_KEYBOX:
500               keybox_set_ephemeral (hd->active[i].u.kr, yes);
501               break;
502             }
503         }
504     }
505
506   i = hd->is_ephemeral;
507   hd->is_ephemeral = yes;
508   return i;
509 }
510
511
512 /* If the keyring has not yet been locked, lock it now.  This
513    operation is required before any update operation; it is optional
514    for an insert operation.  The lock is released with
515    keydb_released. */
516 gpg_error_t
517 keydb_lock (KEYDB_HANDLE hd)
518 {
519   if (!hd)
520     return gpg_error (GPG_ERR_INV_HANDLE);
521   if (hd->locked)
522     return 0; /* Already locked. */
523   return lock_all (hd);
524 }
525
526
527 \f
528 static int
529 lock_all (KEYDB_HANDLE hd)
530 {
531   int i, rc = 0;
532
533   /* Fixme: This locking scheme may lead to deadlock if the resources
534      are not added in the same order by all processes.  We are
535      currently only allowing one resource so it is not a problem. */
536   for (i=0; i < hd->used; i++)
537     {
538       switch (hd->active[i].type)
539         {
540         case KEYDB_RESOURCE_TYPE_NONE:
541           break;
542         case KEYDB_RESOURCE_TYPE_KEYBOX:
543           if (hd->active[i].lockhandle)
544             rc = dotlock_take (hd->active[i].lockhandle, -1);
545           break;
546         }
547       if (rc)
548         break;
549     }
550
551     if (rc)
552       {
553         /* revert the already set locks */
554         for (i--; i >= 0; i--)
555           {
556             switch (hd->active[i].type)
557               {
558               case KEYDB_RESOURCE_TYPE_NONE:
559                 break;
560               case KEYDB_RESOURCE_TYPE_KEYBOX:
561                 if (hd->active[i].lockhandle)
562                   dotlock_release (hd->active[i].lockhandle);
563                 break;
564               }
565           }
566       }
567     else
568       hd->locked = 1;
569
570     /* make_dotlock () does not yet guarantee that errno is set, thus
571        we can't rely on the error reason and will simply use
572        EACCES. */
573     return rc? gpg_error (GPG_ERR_EACCES) : 0;
574 }
575
576 static void
577 unlock_all (KEYDB_HANDLE hd)
578 {
579   int i;
580
581   if (!hd->locked)
582     return;
583
584   for (i=hd->used-1; i >= 0; i--)
585     {
586       switch (hd->active[i].type)
587         {
588         case KEYDB_RESOURCE_TYPE_NONE:
589           break;
590         case KEYDB_RESOURCE_TYPE_KEYBOX:
591           if (hd->active[i].lockhandle)
592             dotlock_release (hd->active[i].lockhandle);
593           break;
594         }
595     }
596   hd->locked = 0;
597 }
598
599
600 \f
601 /* Push the last found state if any.  */
602 void
603 keydb_push_found_state (KEYDB_HANDLE hd)
604 {
605   if (!hd)
606     return;
607
608   if (hd->found < 0 || hd->found >= hd->used)
609     {
610       hd->saved_found = -1;
611       return;
612     }
613
614   switch (hd->active[hd->found].type)
615     {
616     case KEYDB_RESOURCE_TYPE_NONE:
617       break;
618     case KEYDB_RESOURCE_TYPE_KEYBOX:
619       keybox_push_found_state (hd->active[hd->found].u.kr);
620       break;
621     }
622
623   hd->saved_found = hd->found;
624   hd->found = -1;
625 }
626
627
628 /* Pop the last found state.  */
629 void
630 keydb_pop_found_state (KEYDB_HANDLE hd)
631 {
632   if (!hd)
633     return;
634
635   hd->found = hd->saved_found;
636   hd->saved_found = -1;
637   if (hd->found < 0 || hd->found >= hd->used)
638     return;
639
640   switch (hd->active[hd->found].type)
641     {
642     case KEYDB_RESOURCE_TYPE_NONE:
643       break;
644     case KEYDB_RESOURCE_TYPE_KEYBOX:
645       keybox_pop_found_state (hd->active[hd->found].u.kr);
646       break;
647     }
648 }
649
650
651 \f
652 /*
653   Return the last found object.  Caller must free it.  The returned
654   keyblock has the kbode flag bit 0 set for the node with the public
655   key used to locate the keyblock or flag bit 1 set for the user ID
656   node.  */
657 int
658 keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert)
659 {
660   int rc = 0;
661
662   if (!hd)
663     return gpg_error (GPG_ERR_INV_VALUE);
664
665   if ( hd->found < 0 || hd->found >= hd->used)
666     return -1; /* nothing found */
667
668   switch (hd->active[hd->found].type)
669     {
670     case KEYDB_RESOURCE_TYPE_NONE:
671       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
672       break;
673     case KEYDB_RESOURCE_TYPE_KEYBOX:
674       rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert);
675       break;
676     }
677
678   return rc;
679 }
680
681 /* Return a flag of the last found object. WHICH is the flag requested;
682    it should be one of the KEYBOX_FLAG_ values.  If the operation is
683    successful, the flag value will be stored at the address given by
684    VALUE.  Return 0 on success or an error code. */
685 gpg_error_t
686 keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
687 {
688   int err = 0;
689
690   if (!hd)
691     return gpg_error (GPG_ERR_INV_VALUE);
692
693   if ( hd->found < 0 || hd->found >= hd->used)
694     return gpg_error (GPG_ERR_NOTHING_FOUND);
695
696   switch (hd->active[hd->found].type)
697     {
698     case KEYDB_RESOURCE_TYPE_NONE:
699       err = gpg_error (GPG_ERR_GENERAL); /* oops */
700       break;
701     case KEYDB_RESOURCE_TYPE_KEYBOX:
702       err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value);
703       break;
704     }
705
706   return err;
707 }
708
709 /* Set a flag of the last found object. WHICH is the flag to be set; it
710    should be one of the KEYBOX_FLAG_ values.  If the operation is
711    successful, the flag value will be stored in the keybox.  Note,
712    that some flag values can't be updated and thus may return an
713    error, some other flag values may be masked out before an update.
714    Returns 0 on success or an error code. */
715 gpg_error_t
716 keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
717 {
718   int err = 0;
719
720   if (!hd)
721     return gpg_error (GPG_ERR_INV_VALUE);
722
723   if ( hd->found < 0 || hd->found >= hd->used)
724     return gpg_error (GPG_ERR_NOTHING_FOUND);
725
726   if (!hd->locked)
727     return gpg_error (GPG_ERR_NOT_LOCKED);
728
729   switch (hd->active[hd->found].type)
730     {
731     case KEYDB_RESOURCE_TYPE_NONE:
732       err = gpg_error (GPG_ERR_GENERAL); /* oops */
733       break;
734     case KEYDB_RESOURCE_TYPE_KEYBOX:
735       err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value);
736       break;
737     }
738
739   return err;
740 }
741
742 /*
743  * Insert a new Certificate into one of the resources.
744  */
745 int
746 keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
747 {
748   int rc = -1;
749   int idx;
750   unsigned char digest[20];
751
752   if (!hd)
753     return gpg_error (GPG_ERR_INV_VALUE);
754
755   if (opt.dry_run)
756     return 0;
757
758   if ( hd->found >= 0 && hd->found < hd->used)
759     idx = hd->found;
760   else if ( hd->current >= 0 && hd->current < hd->used)
761     idx = hd->current;
762   else
763     return gpg_error (GPG_ERR_GENERAL);
764
765   if (!hd->locked)
766     return gpg_error (GPG_ERR_NOT_LOCKED);
767
768   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
769
770   switch (hd->active[idx].type)
771     {
772     case KEYDB_RESOURCE_TYPE_NONE:
773       rc = gpg_error (GPG_ERR_GENERAL);
774       break;
775     case KEYDB_RESOURCE_TYPE_KEYBOX:
776       rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
777       break;
778     }
779
780   unlock_all (hd);
781   return rc;
782 }
783
784
785
786 /* Update the current keyblock with KB.  */
787 int
788 keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
789 {
790   int rc = 0;
791   unsigned char digest[20];
792
793   if (!hd)
794     return gpg_error (GPG_ERR_INV_VALUE);
795
796   if ( hd->found < 0 || hd->found >= hd->used)
797     return -1; /* nothing found */
798
799   if (opt.dry_run)
800     return 0;
801
802   rc = lock_all (hd);
803   if (rc)
804     return rc;
805
806   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
807
808   switch (hd->active[hd->found].type)
809     {
810     case KEYDB_RESOURCE_TYPE_NONE:
811       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
812       break;
813     case KEYDB_RESOURCE_TYPE_KEYBOX:
814       rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
815       break;
816     }
817
818   unlock_all (hd);
819   return rc;
820 }
821
822
823 /*
824  * The current keyblock or cert will be deleted.
825  */
826 int
827 keydb_delete (KEYDB_HANDLE hd, int unlock)
828 {
829   int rc = -1;
830
831   if (!hd)
832     return gpg_error (GPG_ERR_INV_VALUE);
833
834   if ( hd->found < 0 || hd->found >= hd->used)
835     return -1; /* nothing found */
836
837   if( opt.dry_run )
838     return 0;
839
840   if (!hd->locked)
841     return gpg_error (GPG_ERR_NOT_LOCKED);
842
843   switch (hd->active[hd->found].type)
844     {
845     case KEYDB_RESOURCE_TYPE_NONE:
846       rc = gpg_error (GPG_ERR_GENERAL);
847       break;
848     case KEYDB_RESOURCE_TYPE_KEYBOX:
849       rc = keybox_delete (hd->active[hd->found].u.kr);
850       break;
851     }
852
853   if (unlock)
854     unlock_all (hd);
855   return rc;
856 }
857
858
859 \f
860 /*
861  * Locate the default writable key resource, so that the next
862  * operation (which is only relevant for inserts) will be done on this
863  * resource.
864  */
865 int
866 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
867 {
868   int rc;
869
870   (void)reserved;
871
872   if (!hd)
873     return gpg_error (GPG_ERR_INV_VALUE);
874
875   rc = keydb_search_reset (hd); /* this does reset hd->current */
876   if (rc)
877     return rc;
878
879   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
880     {
881       switch (hd->active[hd->current].type)
882         {
883         case KEYDB_RESOURCE_TYPE_NONE:
884           BUG();
885           break;
886         case KEYDB_RESOURCE_TYPE_KEYBOX:
887           if (keybox_is_writable (hd->active[hd->current].token))
888             return 0; /* found (hd->current is set to it) */
889           break;
890         }
891     }
892
893   return -1;
894 }
895
896 /*
897  * Rebuild the caches of all key resources.
898  */
899 void
900 keydb_rebuild_caches (void)
901 {
902   int i;
903
904   for (i=0; i < used_resources; i++)
905     {
906       if (all_resources[i].secret)
907         continue;
908       switch (all_resources[i].type)
909         {
910         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
911           break;
912         case KEYDB_RESOURCE_TYPE_KEYBOX:
913 /*            rc = keybox_rebuild_cache (all_resources[i].token); */
914 /*            if (rc) */
915 /*              log_error (_("failed to rebuild keybox cache: %s\n"), */
916 /*                         g10_errstr (rc)); */
917           break;
918         }
919     }
920 }
921
922
923
924 /*
925  * Start the next search on this handle right at the beginning
926  */
927 int
928 keydb_search_reset (KEYDB_HANDLE hd)
929 {
930   int i, rc = 0;
931
932   if (!hd)
933     return gpg_error (GPG_ERR_INV_VALUE);
934
935   hd->current = 0;
936   hd->found = -1;
937   /* and reset all resources */
938   for (i=0; !rc && i < hd->used; i++)
939     {
940       switch (hd->active[i].type)
941         {
942         case KEYDB_RESOURCE_TYPE_NONE:
943           break;
944         case KEYDB_RESOURCE_TYPE_KEYBOX:
945           rc = keybox_search_reset (hd->active[i].u.kr);
946           break;
947         }
948     }
949   return rc; /* fixme: we need to map error codes or share them with
950                 all modules*/
951 }
952
953 /*
954  * Search through all keydb resources, starting at the current position,
955  * for a keyblock which contains one of the keys described in the DESC array.
956  */
957 int
958 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
959 {
960   int rc = -1;
961   unsigned long skipped;
962
963   if (!hd)
964     return gpg_error (GPG_ERR_INV_VALUE);
965
966   while (rc == -1 && hd->current >= 0 && hd->current < hd->used)
967     {
968       switch (hd->active[hd->current].type)
969         {
970         case KEYDB_RESOURCE_TYPE_NONE:
971           BUG(); /* we should never see it here */
972           break;
973         case KEYDB_RESOURCE_TYPE_KEYBOX:
974           rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc,
975                               KEYBOX_BLOBTYPE_X509,
976                               NULL, &skipped);
977           break;
978         }
979       if (rc == -1) /* EOF -> switch to next resource */
980         hd->current++;
981       else if (!rc)
982         hd->found = hd->current;
983     }
984
985   return rc;
986 }
987
988
989 int
990 keydb_search_first (KEYDB_HANDLE hd)
991 {
992   KEYDB_SEARCH_DESC desc;
993
994   memset (&desc, 0, sizeof desc);
995   desc.mode = KEYDB_SEARCH_MODE_FIRST;
996   return keydb_search (hd, &desc, 1);
997 }
998
999 int
1000 keydb_search_next (KEYDB_HANDLE hd)
1001 {
1002   KEYDB_SEARCH_DESC desc;
1003
1004   memset (&desc, 0, sizeof desc);
1005   desc.mode = KEYDB_SEARCH_MODE_NEXT;
1006   return keydb_search (hd, &desc, 1);
1007 }
1008
1009 int
1010 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
1011 {
1012   KEYDB_SEARCH_DESC desc;
1013
1014   (void)kid;
1015
1016   memset (&desc, 0, sizeof desc);
1017   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
1018   desc.u.kid[0] = kid[0];
1019   desc.u.kid[1] = kid[1];
1020   return keydb_search (hd, &desc, 1);
1021 }
1022
1023 int
1024 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
1025 {
1026   KEYDB_SEARCH_DESC desc;
1027
1028   memset (&desc, 0, sizeof desc);
1029   desc.mode = KEYDB_SEARCH_MODE_FPR;
1030   memcpy (desc.u.fpr, fpr, 20);
1031   return keydb_search (hd, &desc, 1);
1032 }
1033
1034 int
1035 keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer)
1036 {
1037   KEYDB_SEARCH_DESC desc;
1038   int rc;
1039
1040   memset (&desc, 0, sizeof desc);
1041   desc.mode = KEYDB_SEARCH_MODE_ISSUER;
1042   desc.u.name = issuer;
1043   rc = keydb_search (hd, &desc, 1);
1044   return rc;
1045 }
1046
1047 int
1048 keydb_search_issuer_sn (KEYDB_HANDLE hd,
1049                         const char *issuer, ksba_const_sexp_t serial)
1050 {
1051   KEYDB_SEARCH_DESC desc;
1052   int rc;
1053   const unsigned char *s;
1054
1055   memset (&desc, 0, sizeof desc);
1056   desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
1057   s = serial;
1058   if (*s !='(')
1059     return gpg_error (GPG_ERR_INV_VALUE);
1060   s++;
1061   for (desc.snlen = 0; digitp (s); s++)
1062     desc.snlen = 10*desc.snlen + atoi_1 (s);
1063   if (*s !=':')
1064     return gpg_error (GPG_ERR_INV_VALUE);
1065   desc.sn = s+1;
1066   desc.u.name = issuer;
1067   rc = keydb_search (hd, &desc, 1);
1068   return rc;
1069 }
1070
1071 int
1072 keydb_search_subject (KEYDB_HANDLE hd, const char *name)
1073 {
1074   KEYDB_SEARCH_DESC desc;
1075   int rc;
1076
1077   memset (&desc, 0, sizeof desc);
1078   desc.mode = KEYDB_SEARCH_MODE_SUBJECT;
1079   desc.u.name = name;
1080   rc = keydb_search (hd, &desc, 1);
1081   return rc;
1082 }
1083
1084
1085 \f
1086 /* Store the certificate in the key DB but make sure that it does not
1087    already exists.  We do this simply by comparing the fingerprint.
1088    If EXISTED is not NULL it will be set to true if the certificate
1089    was already in the DB. */
1090 int
1091 keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
1092 {
1093   KEYDB_HANDLE kh;
1094   int rc;
1095   unsigned char fpr[20];
1096
1097   if (existed)
1098     *existed = 0;
1099
1100   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1101     {
1102       log_error (_("failed to get the fingerprint\n"));
1103       return gpg_error (GPG_ERR_GENERAL);
1104     }
1105
1106   kh = keydb_new (0);
1107   if (!kh)
1108     {
1109       log_error (_("failed to allocate keyDB handle\n"));
1110       return gpg_error (GPG_ERR_ENOMEM);;
1111     }
1112
1113   /* Set the ephemeral flag so that the search looks at all
1114      records.  */
1115   keydb_set_ephemeral (kh, 1);
1116
1117   rc = lock_all (kh);
1118   if (rc)
1119     return rc;
1120
1121   rc = keydb_search_fpr (kh, fpr);
1122   if (rc != -1)
1123     {
1124       keydb_release (kh);
1125       if (!rc)
1126         {
1127           if (existed)
1128             *existed = 1;
1129           if (!ephemeral)
1130             {
1131               /* Remove ephemeral flags from existing certificate to "store"
1132                  it permanently. */
1133               rc = keydb_set_cert_flags (cert, 1, KEYBOX_FLAG_BLOB, 0,
1134                                          KEYBOX_FLAG_BLOB_EPHEMERAL, 0);
1135               if (rc)
1136                 {
1137                   log_error ("clearing ephemeral flag failed: %s\n",
1138                              gpg_strerror (rc));
1139                   return rc;
1140                 }
1141             }
1142           return 0; /* okay */
1143         }
1144       log_error (_("problem looking for existing certificate: %s\n"),
1145                  gpg_strerror (rc));
1146       return rc;
1147     }
1148
1149   /* Reset the ephemeral flag if not requested.  */
1150   if (!ephemeral)
1151     keydb_set_ephemeral (kh, 0);
1152
1153   rc = keydb_locate_writable (kh, 0);
1154   if (rc)
1155     {
1156       log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
1157       keydb_release (kh);
1158       return rc;
1159     }
1160
1161   rc = keydb_insert_cert (kh, cert);
1162   if (rc)
1163     {
1164       log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
1165       keydb_release (kh);
1166       return rc;
1167     }
1168   keydb_release (kh);
1169   return 0;
1170 }
1171
1172
1173 /* This is basically keydb_set_flags but it implements a complete
1174    transaction by locating the certificate in the DB and updating the
1175    flags. */
1176 gpg_error_t
1177 keydb_set_cert_flags (ksba_cert_t cert, int ephemeral,
1178                       int which, int idx,
1179                       unsigned int mask, unsigned int value)
1180 {
1181   KEYDB_HANDLE kh;
1182   gpg_error_t err;
1183   unsigned char fpr[20];
1184   unsigned int old_value;
1185
1186   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1187     {
1188       log_error (_("failed to get the fingerprint\n"));
1189       return gpg_error (GPG_ERR_GENERAL);
1190     }
1191
1192   kh = keydb_new (0);
1193   if (!kh)
1194     {
1195       log_error (_("failed to allocate keyDB handle\n"));
1196       return gpg_error (GPG_ERR_ENOMEM);;
1197     }
1198
1199   if (ephemeral)
1200     keydb_set_ephemeral (kh, 1);
1201
1202   err = keydb_lock (kh);
1203   if (err)
1204     {
1205       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1206       keydb_release (kh);
1207       return err;
1208     }
1209
1210   err = keydb_search_fpr (kh, fpr);
1211   if (err)
1212     {
1213       if (err == -1)
1214         err = gpg_error (GPG_ERR_NOT_FOUND);
1215       else
1216         log_error (_("problem re-searching certificate: %s\n"),
1217                    gpg_strerror (err));
1218       keydb_release (kh);
1219       return err;
1220     }
1221
1222   err = keydb_get_flags (kh, which, idx, &old_value);
1223   if (err)
1224     {
1225       log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
1226       keydb_release (kh);
1227       return err;
1228     }
1229
1230   value = ((old_value & ~mask) | (value & mask));
1231
1232   if (value != old_value)
1233     {
1234       err = keydb_set_flags (kh, which, idx, value);
1235       if (err)
1236         {
1237           log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1238           keydb_release (kh);
1239           return err;
1240         }
1241     }
1242
1243   keydb_release (kh);
1244   return 0;
1245 }
1246
1247
1248 /* Reset all the certificate flags we have stored with the certificates
1249    for performance reasons. */
1250 void
1251 keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
1252 {
1253   gpg_error_t err;
1254   KEYDB_HANDLE hd = NULL;
1255   KEYDB_SEARCH_DESC *desc = NULL;
1256   int ndesc;
1257   strlist_t sl;
1258   int rc=0;
1259   unsigned int old_value, value;
1260
1261   (void)ctrl;
1262
1263   hd = keydb_new (0);
1264   if (!hd)
1265     {
1266       log_error ("keydb_new failed\n");
1267       goto leave;
1268     }
1269
1270   if (!names)
1271     ndesc = 1;
1272   else
1273     {
1274       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1275         ;
1276     }
1277
1278   desc = xtrycalloc (ndesc, sizeof *desc);
1279   if (!ndesc)
1280     {
1281       log_error ("allocating memory failed: %s\n",
1282                  gpg_strerror (out_of_core ()));
1283       goto leave;
1284     }
1285
1286   if (!names)
1287     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1288   else
1289     {
1290       for (ndesc=0, sl=names; sl; sl = sl->next)
1291         {
1292           rc = classify_user_id (sl->d, desc+ndesc, 0);
1293           if (rc)
1294             {
1295               log_error ("key '%s' not found: %s\n",
1296                          sl->d, gpg_strerror (rc));
1297               rc = 0;
1298             }
1299           else
1300             ndesc++;
1301         }
1302     }
1303
1304   err = keydb_lock (hd);
1305   if (err)
1306     {
1307       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1308       goto leave;
1309     }
1310
1311   while (!(rc = keydb_search (hd, desc, ndesc)))
1312     {
1313       if (!names)
1314         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1315
1316       err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
1317       if (err)
1318         {
1319           log_error (_("error getting stored flags: %s\n"),
1320                      gpg_strerror (err));
1321           goto leave;
1322         }
1323
1324       value = (old_value & ~VALIDITY_REVOKED);
1325       if (value != old_value)
1326         {
1327           err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
1328           if (err)
1329             {
1330               log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1331               goto leave;
1332             }
1333         }
1334     }
1335   if (rc && rc != -1)
1336     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1337
1338  leave:
1339   xfree (desc);
1340   keydb_release (hd);
1341 }