83e573f28716c480c8594c3516386a700de63b7f
[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                               NULL, &skipped);
976           break;
977         }
978       if (rc == -1) /* EOF -> switch to next resource */
979         hd->current++;
980       else if (!rc)
981         hd->found = hd->current;
982     }
983
984   return rc;
985 }
986
987
988 int
989 keydb_search_first (KEYDB_HANDLE hd)
990 {
991   KEYDB_SEARCH_DESC desc;
992
993   memset (&desc, 0, sizeof desc);
994   desc.mode = KEYDB_SEARCH_MODE_FIRST;
995   return keydb_search (hd, &desc, 1);
996 }
997
998 int
999 keydb_search_next (KEYDB_HANDLE hd)
1000 {
1001   KEYDB_SEARCH_DESC desc;
1002
1003   memset (&desc, 0, sizeof desc);
1004   desc.mode = KEYDB_SEARCH_MODE_NEXT;
1005   return keydb_search (hd, &desc, 1);
1006 }
1007
1008 int
1009 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
1010 {
1011   KEYDB_SEARCH_DESC desc;
1012
1013   (void)kid;
1014
1015   memset (&desc, 0, sizeof desc);
1016   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
1017   desc.u.kid[0] = kid[0];
1018   desc.u.kid[1] = kid[1];
1019   return keydb_search (hd, &desc, 1);
1020 }
1021
1022 int
1023 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
1024 {
1025   KEYDB_SEARCH_DESC desc;
1026
1027   memset (&desc, 0, sizeof desc);
1028   desc.mode = KEYDB_SEARCH_MODE_FPR;
1029   memcpy (desc.u.fpr, fpr, 20);
1030   return keydb_search (hd, &desc, 1);
1031 }
1032
1033 int
1034 keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer)
1035 {
1036   KEYDB_SEARCH_DESC desc;
1037   int rc;
1038
1039   memset (&desc, 0, sizeof desc);
1040   desc.mode = KEYDB_SEARCH_MODE_ISSUER;
1041   desc.u.name = issuer;
1042   rc = keydb_search (hd, &desc, 1);
1043   return rc;
1044 }
1045
1046 int
1047 keydb_search_issuer_sn (KEYDB_HANDLE hd,
1048                         const char *issuer, ksba_const_sexp_t serial)
1049 {
1050   KEYDB_SEARCH_DESC desc;
1051   int rc;
1052   const unsigned char *s;
1053
1054   memset (&desc, 0, sizeof desc);
1055   desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
1056   s = serial;
1057   if (*s !='(')
1058     return gpg_error (GPG_ERR_INV_VALUE);
1059   s++;
1060   for (desc.snlen = 0; digitp (s); s++)
1061     desc.snlen = 10*desc.snlen + atoi_1 (s);
1062   if (*s !=':')
1063     return gpg_error (GPG_ERR_INV_VALUE);
1064   desc.sn = s+1;
1065   desc.u.name = issuer;
1066   rc = keydb_search (hd, &desc, 1);
1067   return rc;
1068 }
1069
1070 int
1071 keydb_search_subject (KEYDB_HANDLE hd, const char *name)
1072 {
1073   KEYDB_SEARCH_DESC desc;
1074   int rc;
1075
1076   memset (&desc, 0, sizeof desc);
1077   desc.mode = KEYDB_SEARCH_MODE_SUBJECT;
1078   desc.u.name = name;
1079   rc = keydb_search (hd, &desc, 1);
1080   return rc;
1081 }
1082
1083
1084 \f
1085 /* Store the certificate in the key DB but make sure that it does not
1086    already exists.  We do this simply by comparing the fingerprint.
1087    If EXISTED is not NULL it will be set to true if the certificate
1088    was already in the DB. */
1089 int
1090 keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
1091 {
1092   KEYDB_HANDLE kh;
1093   int rc;
1094   unsigned char fpr[20];
1095
1096   if (existed)
1097     *existed = 0;
1098
1099   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1100     {
1101       log_error (_("failed to get the fingerprint\n"));
1102       return gpg_error (GPG_ERR_GENERAL);
1103     }
1104
1105   kh = keydb_new (0);
1106   if (!kh)
1107     {
1108       log_error (_("failed to allocate keyDB handle\n"));
1109       return gpg_error (GPG_ERR_ENOMEM);;
1110     }
1111
1112   if (ephemeral)
1113     keydb_set_ephemeral (kh, 1);
1114
1115   rc = lock_all (kh);
1116   if (rc)
1117     return rc;
1118
1119   rc = keydb_search_fpr (kh, fpr);
1120   if (rc != -1)
1121     {
1122       keydb_release (kh);
1123       if (!rc)
1124         {
1125           if (existed)
1126             *existed = 1;
1127           return 0; /* okay */
1128         }
1129       log_error (_("problem looking for existing certificate: %s\n"),
1130                  gpg_strerror (rc));
1131       return rc;
1132     }
1133
1134   rc = keydb_locate_writable (kh, 0);
1135   if (rc)
1136     {
1137       log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
1138       keydb_release (kh);
1139       return rc;
1140     }
1141
1142   rc = keydb_insert_cert (kh, cert);
1143   if (rc)
1144     {
1145       log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
1146       keydb_release (kh);
1147       return rc;
1148     }
1149   keydb_release (kh);
1150   return 0;
1151 }
1152
1153
1154 /* This is basically keydb_set_flags but it implements a complete
1155    transaction by locating the certificate in the DB and updating the
1156    flags. */
1157 gpg_error_t
1158 keydb_set_cert_flags (ksba_cert_t cert, int ephemeral,
1159                       int which, int idx,
1160                       unsigned int mask, unsigned int value)
1161 {
1162   KEYDB_HANDLE kh;
1163   gpg_error_t err;
1164   unsigned char fpr[20];
1165   unsigned int old_value;
1166
1167   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1168     {
1169       log_error (_("failed to get the fingerprint\n"));
1170       return gpg_error (GPG_ERR_GENERAL);
1171     }
1172
1173   kh = keydb_new (0);
1174   if (!kh)
1175     {
1176       log_error (_("failed to allocate keyDB handle\n"));
1177       return gpg_error (GPG_ERR_ENOMEM);;
1178     }
1179
1180   if (ephemeral)
1181     keydb_set_ephemeral (kh, 1);
1182
1183   err = keydb_lock (kh);
1184   if (err)
1185     {
1186       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1187       keydb_release (kh);
1188       return err;
1189     }
1190
1191   err = keydb_search_fpr (kh, fpr);
1192   if (err)
1193     {
1194       if (err == -1)
1195         err = gpg_error (GPG_ERR_NOT_FOUND);
1196       else
1197         log_error (_("problem re-searching certificate: %s\n"),
1198                    gpg_strerror (err));
1199       keydb_release (kh);
1200       return err;
1201     }
1202
1203   err = keydb_get_flags (kh, which, idx, &old_value);
1204   if (err)
1205     {
1206       log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
1207       keydb_release (kh);
1208       return err;
1209     }
1210
1211   value = ((old_value & ~mask) | (value & mask));
1212
1213   if (value != old_value)
1214     {
1215       err = keydb_set_flags (kh, which, idx, value);
1216       if (err)
1217         {
1218           log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1219           keydb_release (kh);
1220           return err;
1221         }
1222     }
1223
1224   keydb_release (kh);
1225   return 0;
1226 }
1227
1228
1229 /* Reset all the certificate flags we have stored with the certificates
1230    for performance reasons. */
1231 void
1232 keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
1233 {
1234   gpg_error_t err;
1235   KEYDB_HANDLE hd = NULL;
1236   KEYDB_SEARCH_DESC *desc = NULL;
1237   int ndesc;
1238   strlist_t sl;
1239   int rc=0;
1240   unsigned int old_value, value;
1241
1242   (void)ctrl;
1243
1244   hd = keydb_new (0);
1245   if (!hd)
1246     {
1247       log_error ("keydb_new failed\n");
1248       goto leave;
1249     }
1250
1251   if (!names)
1252     ndesc = 1;
1253   else
1254     {
1255       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1256         ;
1257     }
1258
1259   desc = xtrycalloc (ndesc, sizeof *desc);
1260   if (!ndesc)
1261     {
1262       log_error ("allocating memory failed: %s\n",
1263                  gpg_strerror (out_of_core ()));
1264       goto leave;
1265     }
1266
1267   if (!names)
1268     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1269   else
1270     {
1271       for (ndesc=0, sl=names; sl; sl = sl->next)
1272         {
1273           rc = classify_user_id (sl->d, desc+ndesc, 0);
1274           if (rc)
1275             {
1276               log_error ("key '%s' not found: %s\n",
1277                          sl->d, gpg_strerror (rc));
1278               rc = 0;
1279             }
1280           else
1281             ndesc++;
1282         }
1283     }
1284
1285   err = keydb_lock (hd);
1286   if (err)
1287     {
1288       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1289       goto leave;
1290     }
1291
1292   while (!(rc = keydb_search (hd, desc, ndesc)))
1293     {
1294       if (!names)
1295         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1296
1297       err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
1298       if (err)
1299         {
1300           log_error (_("error getting stored flags: %s\n"),
1301                      gpg_strerror (err));
1302           goto leave;
1303         }
1304
1305       value = (old_value & ~VALIDITY_REVOKED);
1306       if (value != old_value)
1307         {
1308           err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
1309           if (err)
1310             {
1311               log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1312               goto leave;
1313             }
1314         }
1315     }
1316   if (rc && rc != -1)
1317     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1318
1319  leave:
1320   xfree (desc);
1321   keydb_release (hd);
1322 }