* configure.ac: Require libksba 0.9.7.
[gnupg.git] / sm / keydb.c
1 /* keydb.c - key database dispatcher
2  * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
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 #define DIRSEP_C '/'
37
38 static int active_handles;
39
40 typedef enum {
41     KEYDB_RESOURCE_TYPE_NONE = 0,
42     KEYDB_RESOURCE_TYPE_KEYBOX
43 } KeydbResourceType;
44 #define MAX_KEYDB_RESOURCES 20
45
46 struct resource_item {
47   KeydbResourceType type;
48   union {
49     KEYBOX_HANDLE kr;
50   } u;
51   void *token;
52   int secret;
53   DOTLOCK lockhandle;
54 };
55
56 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
57 static int used_resources;
58
59 struct keydb_handle {
60   int locked;
61   int found;
62   int current;
63   int is_ephemeral;
64   int used; /* items in active */
65   struct resource_item active[MAX_KEYDB_RESOURCES];
66 };
67
68
69 static int lock_all (KEYDB_HANDLE hd);
70 static void unlock_all (KEYDB_HANDLE hd);
71
72
73 /*
74  * Register a resource (which currently may only be a keybox file).
75  * The first keybox which is added by this function is
76  * created if it does not exist.
77  * Note: this function may be called before secure memory is
78  * available.
79  */
80 int
81 keydb_add_resource (const char *url, int force, int secret)
82 {
83   static int any_secret, any_public;
84   const char *resname = url;
85   char *filename = NULL;
86   int rc = 0; 
87   FILE *fp;
88   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
89   const char *created_fname = NULL;
90
91   /* Do we have an URL?
92      gnupg-kbx:filename := this is a plain keybox
93      filename := See what is is, but create as plain keybox.
94   */
95   if (strlen (resname) > 10) 
96     {
97       if (!strncmp (resname, "gnupg-kbx:", 10) )
98         {
99           rt = KEYDB_RESOURCE_TYPE_KEYBOX;
100           resname += 10;
101         }
102 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
103       else if (strchr (resname, ':'))
104         {
105           log_error ("invalid key resource URL `%s'\n", url );
106           rc = gpg_error (GPG_ERR_GENERAL);
107           goto leave;
108         }
109 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
110     }
111
112   if (*resname != DIRSEP_C )
113     { /* do tilde expansion etc */
114       if (strchr(resname, DIRSEP_C) )
115         filename = make_filename (resname, NULL);
116       else
117         filename = make_filename (opt.homedir, resname, NULL);
118     }
119   else
120     filename = xstrdup (resname);
121   
122   if (!force)
123     force = secret? !any_secret : !any_public;
124   
125   /* see whether we can determine the filetype */
126   if (rt == KEYDB_RESOURCE_TYPE_NONE)
127     {
128       FILE *fp2 = fopen( filename, "rb" );
129       
130       if (fp2) {
131         u32 magic;
132         
133         /* FIXME: check for the keybox magic */
134         if (fread( &magic, 4, 1, fp2) == 1 ) 
135           {
136             if (magic == 0x13579ace || magic == 0xce9a5713)
137               ; /* GDBM magic - no more support */
138             else
139               rt = KEYDB_RESOURCE_TYPE_KEYBOX;
140           }
141         else /* maybe empty: assume ring */
142           rt = KEYDB_RESOURCE_TYPE_KEYBOX;
143         fclose (fp2);
144       }
145       else /* no file yet: create ring */
146         rt = KEYDB_RESOURCE_TYPE_KEYBOX;
147     }
148     
149   switch (rt)
150     {
151     case KEYDB_RESOURCE_TYPE_NONE:
152       log_error ("unknown type of key resource `%s'\n", url );
153       rc = gpg_error (GPG_ERR_GENERAL);
154       goto leave;
155       
156     case KEYDB_RESOURCE_TYPE_KEYBOX:
157       fp = fopen (filename, "rb");
158       if (!fp && !force)
159         {
160           rc = gpg_error (gpg_err_code_from_errno (errno));
161           goto leave;
162         }
163       
164       if (!fp)
165         { /* no file */
166 #if 0 /* no autocreate of the homedirectory yet */
167           {
168             char *last_slash_in_filename;
169             
170             last_slash_in_filename = strrchr (filename, DIRSEP_C);
171             *last_slash_in_filename = 0;
172             if (access (filename, F_OK))
173               { /* on the first time we try to create the default
174                    homedir and in this case the process will be
175                    terminated, so that on the next invocation can
176                    read the options file in on startup */
177                 try_make_homedir (filename);
178                 rc = gpg_error (GPG_ERR_FILE_OPEN_ERROR);
179                 *last_slash_in_filename = DIRSEP_C;
180                 goto leave;
181               }
182             *last_slash_in_filename = DIRSEP_C;
183           }
184 #endif
185           fp = fopen (filename, "w");
186           if (!fp)
187             {
188               rc = gpg_error (gpg_err_code_from_errno (errno));
189               log_error (_("error creating keybox `%s': %s\n"),
190                          filename, strerror(errno));
191               if (errno == ENOENT)
192                 log_info (_("you may want to start the gpg-agent first\n"));
193               goto leave;
194             }
195
196           if (!opt.quiet)
197             log_info (_("keybox `%s' created\n"), filename);
198           created_fname = filename;
199         }
200         fclose (fp);
201         fp = NULL;
202         /* now register the file */
203         {
204           
205           void *token = keybox_register_file (filename, secret);
206           if (!token)
207             ; /* already registered - ignore it */
208           else if (used_resources >= MAX_KEYDB_RESOURCES)
209             rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
210           else 
211             {
212               all_resources[used_resources].type = rt;
213               all_resources[used_resources].u.kr = NULL; /* Not used here */
214               all_resources[used_resources].token = token;
215               all_resources[used_resources].secret = secret;
216
217               all_resources[used_resources].lockhandle
218                 = create_dotlock (filename);
219               if (!all_resources[used_resources].lockhandle)
220                 log_fatal ( _("can't create lock for `%s'\n"), filename);
221
222               /* Do a compress run if needed and the file is not locked. */
223               if (!make_dotlock (all_resources[used_resources].lockhandle, 0))
224                 {
225                   KEYBOX_HANDLE kbxhd = keybox_new (token, secret);
226                   
227                   if (kbxhd)
228                     {
229                       keybox_compress (kbxhd);
230                       keybox_release (kbxhd);
231                     }
232                   release_dotlock (all_resources[used_resources].lockhandle);
233                 }
234                   
235               used_resources++;
236             }
237         }
238
239
240         break;
241     default:
242       log_error ("resource type of `%s' not supported\n", url);
243       rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
244       goto leave;
245     }
246
247   /* fixme: check directory permissions and print a warning */
248
249  leave:
250   if (rc)
251     log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror(rc));
252   else if (secret)
253     any_secret = 1;
254   else
255     any_public = 1;
256   xfree (filename);
257   return rc;
258 }
259
260
261 KEYDB_HANDLE
262 keydb_new (int secret)
263 {
264   KEYDB_HANDLE hd;
265   int i, j;
266   
267   hd = xcalloc (1, sizeof *hd);
268   hd->found = -1;
269   
270   assert (used_resources <= MAX_KEYDB_RESOURCES);
271   for (i=j=0; i < used_resources; i++)
272     {
273       if (!all_resources[i].secret != !secret)
274         continue;
275       switch (all_resources[i].type)
276         {
277         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
278           break;
279         case KEYDB_RESOURCE_TYPE_KEYBOX:
280           hd->active[j].type   = all_resources[i].type;
281           hd->active[j].token  = all_resources[i].token;
282           hd->active[j].secret = all_resources[i].secret;
283           hd->active[j].lockhandle = all_resources[i].lockhandle;
284           hd->active[j].u.kr = keybox_new (all_resources[i].token, secret);
285           if (!hd->active[j].u.kr) 
286             {
287               xfree (hd);
288               return NULL; /* fixme: release all previously allocated handles*/
289             }
290           j++;
291           break;
292         }
293     }
294   hd->used = j;
295   
296   active_handles++;
297   return hd;
298 }
299
300 void 
301 keydb_release (KEYDB_HANDLE hd)
302 {
303   int i;
304   
305   if (!hd)
306     return;
307   assert (active_handles > 0);
308   active_handles--;
309
310   unlock_all (hd);
311   for (i=0; i < hd->used; i++)
312     {
313       switch (hd->active[i].type) 
314         {
315         case KEYDB_RESOURCE_TYPE_NONE:
316           break;
317         case KEYDB_RESOURCE_TYPE_KEYBOX:
318           keybox_release (hd->active[i].u.kr);
319           break;
320         }
321     }
322
323     xfree (hd);
324 }
325
326
327 /* Return the name of the current resource.  This is function first
328    looks for the last found found, then for the current search
329    position, and last returns the first available resource.  The
330    returned string is only valid as long as the handle exists.  This
331    function does only return NULL if no handle is specified, in all
332    other error cases an empty string is returned.  */
333 const char *
334 keydb_get_resource_name (KEYDB_HANDLE hd)
335 {
336   int idx;
337   const char *s = NULL;
338   
339   if (!hd) 
340     return NULL;
341
342   if ( hd->found >= 0 && hd->found < hd->used) 
343     idx = hd->found;
344   else if ( hd->current >= 0 && hd->current < hd->used) 
345     idx = hd->current;
346   else
347     idx = 0;
348
349   switch (hd->active[idx].type) 
350     {
351     case KEYDB_RESOURCE_TYPE_NONE:
352       s = NULL; 
353       break;
354     case KEYDB_RESOURCE_TYPE_KEYBOX:
355       s = keybox_get_resource_name (hd->active[idx].u.kr);
356       break;
357     }
358   
359   return s? s: "";
360 }
361
362 /* Switch the handle into ephemeral mode and return the orginal value. */
363 int
364 keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
365 {
366   int i;
367
368   if (!hd)
369     return 0;
370
371   yes = !!yes;
372   if (hd->is_ephemeral != yes)
373     {
374       for (i=0; i < hd->used; i++)
375         {
376           switch (hd->active[i].type) 
377             {
378             case KEYDB_RESOURCE_TYPE_NONE:
379               break;
380             case KEYDB_RESOURCE_TYPE_KEYBOX:
381               keybox_set_ephemeral (hd->active[i].u.kr, yes);
382               break;
383             }
384         }
385     }
386       
387   i = hd->is_ephemeral;
388   hd->is_ephemeral = yes;
389   return i;
390 }
391
392
393 /* If the keyring has not yet been locked, lock it now.  This
394    operation is required before any update opeations; it is optionaly
395    for an insert operation.  The lock is released with
396    keydb_released. */
397 gpg_error_t
398 keydb_lock (KEYDB_HANDLE hd)
399 {
400   if (!hd)
401     return gpg_error (GPG_ERR_INV_HANDLE);
402   if (hd->locked)
403     return 0; /* Already locked. */
404   return lock_all (hd);
405 }
406
407
408 \f
409 static int 
410 lock_all (KEYDB_HANDLE hd)
411 {
412   int i, rc = 0;
413
414   /* Fixme: This locking scheme may lead to deadlock if the resources
415      are not added in the same order by all processes.  We are
416      currently only allowing one resource so it is not a problem. */
417   for (i=0; i < hd->used; i++) 
418     {
419       switch (hd->active[i].type) 
420         {
421         case KEYDB_RESOURCE_TYPE_NONE:
422           break;
423         case KEYDB_RESOURCE_TYPE_KEYBOX:
424           if (hd->active[i].lockhandle)
425             rc = make_dotlock (hd->active[i].lockhandle, -1);
426           break;
427         }
428       if (rc)
429         break;
430     }
431
432     if (rc) 
433       {
434         /* revert the already set locks */
435         for (i--; i >= 0; i--) 
436           {
437             switch (hd->active[i].type) 
438               {
439               case KEYDB_RESOURCE_TYPE_NONE:
440                 break;
441               case KEYDB_RESOURCE_TYPE_KEYBOX:
442                 if (hd->active[i].lockhandle)
443                   release_dotlock (hd->active[i].lockhandle);
444                 break;
445               }
446           }
447       }
448     else
449       hd->locked = 1;
450
451     /* make_dotlock () does not yet guarantee that errno is set, thus
452        we can't rely on the error reason and will simply use
453        EACCES. */
454     return rc? gpg_error (GPG_ERR_EACCES) : 0;
455 }
456
457 static void
458 unlock_all (KEYDB_HANDLE hd)
459 {
460   int i;
461   
462   if (!hd->locked)
463     return;
464
465   for (i=hd->used-1; i >= 0; i--) 
466     {
467       switch (hd->active[i].type) 
468         {
469         case KEYDB_RESOURCE_TYPE_NONE:
470           break;
471         case KEYDB_RESOURCE_TYPE_KEYBOX:
472           if (hd->active[i].lockhandle)
473             release_dotlock (hd->active[i].lockhandle);
474           break;
475         }
476     }
477   hd->locked = 0;
478 }
479
480 \f
481 #if 0
482 /*
483  * Return the last found keybox.  Caller must free it.
484  * The returned keyblock has the kbode flag bit 0 set for the node with
485  * the public key used to locate the keyblock or flag bit 1 set for 
486  * the user ID node.
487  */
488 int
489 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
490 {
491     int rc = 0;
492
493     if (!hd)
494         return G10ERR_INV_ARG;
495
496     if ( hd->found < 0 || hd->found >= hd->used) 
497         return -1; /* nothing found */
498
499     switch (hd->active[hd->found].type) {
500       case KEYDB_RESOURCE_TYPE_NONE:
501         rc = G10ERR_GENERAL; /* oops */
502         break;
503       case KEYDB_RESOURCE_TYPE_KEYBOX:
504         rc = keybox_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
505         break;
506     }
507
508     return rc;
509 }
510
511 /* 
512  * update the current keyblock with KB
513  */
514 int
515 keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
516 {
517     int rc = 0;
518
519     if (!hd)
520         return G10ERR_INV_ARG;
521
522     if ( hd->found < 0 || hd->found >= hd->used) 
523         return -1; /* nothing found */
524
525     if( opt.dry_run )
526         return 0;
527
528     if (!hd->locked)
529       return gpg_error (GPG_ERR_NOT_LOCKED);
530
531     switch (hd->active[hd->found].type) {
532       case KEYDB_RESOURCE_TYPE_NONE:
533         rc = G10ERR_GENERAL; /* oops */
534         break;
535       case KEYDB_RESOURCE_TYPE_KEYBOX:
536         rc = keybox_update_keyblock (hd->active[hd->found].u.kr, kb);
537         break;
538     }
539
540     unlock_all (hd);
541     return rc;
542 }
543
544
545 /* 
546  * Insert a new KB into one of the resources. 
547  */
548 int
549 keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
550 {
551     int rc = -1;
552     int idx;
553
554     if (!hd) 
555         return G10ERR_INV_ARG;
556
557     if( opt.dry_run )
558         return 0;
559
560     if ( hd->found >= 0 && hd->found < hd->used) 
561         idx = hd->found;
562     else if ( hd->current >= 0 && hd->current < hd->used) 
563         idx = hd->current;
564     else
565         return G10ERR_GENERAL;
566
567     rc = lock_all (hd);
568     if (rc)
569         return rc;
570
571     switch (hd->active[idx].type) {
572       case KEYDB_RESOURCE_TYPE_NONE:
573         rc = G10ERR_GENERAL; /* oops */
574         break;
575       case KEYDB_RESOURCE_TYPE_KEYBOX:
576         rc = keybox_insert_keyblock (hd->active[idx].u.kr, kb);
577         break;
578     }
579
580     unlock_all (hd);
581     return rc;
582 }
583
584 #endif /*disabled code*/
585
586
587 \f
588 /*
589   Return the last found object.  Caller must free it.  The returned
590   keyblock has the kbode flag bit 0 set for the node with the public
591   key used to locate the keyblock or flag bit 1 set for the user ID
592   node.  */
593 int
594 keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert)
595 {
596   int rc = 0;
597
598   if (!hd)
599     return gpg_error (GPG_ERR_INV_VALUE);
600   
601   if ( hd->found < 0 || hd->found >= hd->used) 
602     return -1; /* nothing found */
603   
604   switch (hd->active[hd->found].type) 
605     {
606     case KEYDB_RESOURCE_TYPE_NONE:
607       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
608       break;
609     case KEYDB_RESOURCE_TYPE_KEYBOX:
610       rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert);
611       break;
612     }
613   
614   return rc;
615 }
616
617 /* Return a flag of the last found object. WHICH is the flag requested;
618    it should be one of the KEYBOX_FLAG_ values.  If the operation is
619    successful, the flag value will be stored at the address given by
620    VALUE.  Return 0 on success or an error code. */
621 gpg_error_t
622 keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
623 {
624   int err = 0;
625
626   if (!hd)
627     return gpg_error (GPG_ERR_INV_VALUE);
628   
629   if ( hd->found < 0 || hd->found >= hd->used) 
630     return gpg_error (GPG_ERR_NOTHING_FOUND);
631   
632   switch (hd->active[hd->found].type) 
633     {
634     case KEYDB_RESOURCE_TYPE_NONE:
635       err = gpg_error (GPG_ERR_GENERAL); /* oops */
636       break;
637     case KEYDB_RESOURCE_TYPE_KEYBOX:
638       err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value);
639       break;
640     }
641   
642   return err;
643 }
644
645 /* Set a flag of the last found object. WHICH is the flag to be set; it
646    should be one of the KEYBOX_FLAG_ values.  If the operation is
647    successful, the flag value will be stored in the keybox.  Note,
648    that some flag values can't be updated and thus may return an
649    error, some other flag values may be masked out before an update.
650    Returns 0 on success or an error code. */
651 gpg_error_t
652 keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
653 {
654   int err = 0;
655
656   if (!hd)
657     return gpg_error (GPG_ERR_INV_VALUE);
658   
659   if ( hd->found < 0 || hd->found >= hd->used) 
660     return gpg_error (GPG_ERR_NOTHING_FOUND);
661   
662   if (!hd->locked)
663     return gpg_error (GPG_ERR_NOT_LOCKED);
664
665   switch (hd->active[hd->found].type) 
666     {
667     case KEYDB_RESOURCE_TYPE_NONE:
668       err = gpg_error (GPG_ERR_GENERAL); /* oops */
669       break;
670     case KEYDB_RESOURCE_TYPE_KEYBOX:
671       err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value);
672       break;
673     }
674   
675   return err;
676 }
677
678 /* 
679  * Insert a new Certificate into one of the resources. 
680  */
681 int
682 keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
683 {
684   int rc = -1;
685   int idx;
686   char digest[20];
687   
688   if (!hd) 
689     return gpg_error (GPG_ERR_INV_VALUE);
690
691   if (opt.dry_run)
692     return 0;
693   
694   if ( hd->found >= 0 && hd->found < hd->used) 
695     idx = hd->found;
696   else if ( hd->current >= 0 && hd->current < hd->used) 
697     idx = hd->current;
698   else
699     return gpg_error (GPG_ERR_GENERAL);
700
701   rc = lock_all (hd);
702   if (rc)
703     return rc;
704
705   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
706
707   switch (hd->active[idx].type) 
708     {
709     case KEYDB_RESOURCE_TYPE_NONE:
710       rc = gpg_error (GPG_ERR_GENERAL);
711       break;
712     case KEYDB_RESOURCE_TYPE_KEYBOX:
713       rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
714       break;
715     }
716   
717   unlock_all (hd);
718   return rc;
719 }
720
721
722
723 /* update the current keyblock with KB */
724 int
725 keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
726 {
727   int rc = 0;
728   char digest[20];
729   
730   if (!hd)
731     return gpg_error (GPG_ERR_INV_VALUE);
732
733   if ( hd->found < 0 || hd->found >= hd->used) 
734     return -1; /* nothing found */
735
736   if (opt.dry_run)
737     return 0;
738
739   rc = lock_all (hd);
740   if (rc)
741     return rc;
742
743   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
744
745   switch (hd->active[hd->found].type) 
746     {
747     case KEYDB_RESOURCE_TYPE_NONE:
748       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
749       break;
750     case KEYDB_RESOURCE_TYPE_KEYBOX:
751       rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
752       break;
753     }
754
755   unlock_all (hd);
756   return rc;
757 }
758
759
760 /* 
761  * The current keyblock or cert will be deleted.
762  */
763 int
764 keydb_delete (KEYDB_HANDLE hd)
765 {
766   int rc = -1;
767   
768   if (!hd)
769     return gpg_error (GPG_ERR_INV_VALUE);
770
771   if ( hd->found < 0 || hd->found >= hd->used) 
772     return -1; /* nothing found */
773
774   if( opt.dry_run )
775     return 0;
776
777   if (!hd->locked)
778     return gpg_error (GPG_ERR_NOT_LOCKED); 
779
780   switch (hd->active[hd->found].type)
781     {
782     case KEYDB_RESOURCE_TYPE_NONE:
783       rc = gpg_error (GPG_ERR_GENERAL);
784       break;
785     case KEYDB_RESOURCE_TYPE_KEYBOX:
786       rc = keybox_delete (hd->active[hd->found].u.kr);
787       break;
788     }
789
790   unlock_all (hd);
791   return rc;
792 }
793
794
795 \f
796 /*
797  * Locate the default writable key resource, so that the next
798  * operation (which is only relevant for inserts) will be done on this
799  * resource.  
800  */
801 int
802 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
803 {
804   int rc;
805   
806   if (!hd)
807     return gpg_error (GPG_ERR_INV_VALUE);
808   
809   rc = keydb_search_reset (hd); /* this does reset hd->current */
810   if (rc)
811     return rc;
812   
813   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) 
814     {
815       switch (hd->active[hd->current].type) 
816         {
817         case KEYDB_RESOURCE_TYPE_NONE:
818           BUG();
819           break;
820         case KEYDB_RESOURCE_TYPE_KEYBOX:
821           if (keybox_is_writable (hd->active[hd->current].token))
822             return 0; /* found (hd->current is set to it) */
823           break;
824         }
825     }
826   
827   return -1;
828 }
829
830 /*
831  * Rebuild the caches of all key resources.
832  */
833 void
834 keydb_rebuild_caches (void)
835 {
836   int i;
837   
838   for (i=0; i < used_resources; i++)
839     {
840       if (all_resources[i].secret)
841         continue;
842       switch (all_resources[i].type)
843         {
844         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
845           break;
846         case KEYDB_RESOURCE_TYPE_KEYBOX:
847 /*            rc = keybox_rebuild_cache (all_resources[i].token); */
848 /*            if (rc) */
849 /*              log_error (_("failed to rebuild keybox cache: %s\n"), */
850 /*                         g10_errstr (rc)); */
851           break;
852         }
853     }
854 }
855
856
857
858 /* 
859  * Start the next search on this handle right at the beginning
860  */
861 int 
862 keydb_search_reset (KEYDB_HANDLE hd)
863 {
864   int i, rc = 0;
865   
866   if (!hd)
867     return gpg_error (GPG_ERR_INV_VALUE);
868
869   hd->current = 0; 
870   hd->found = -1;
871   /* and reset all resources */
872   for (i=0; !rc && i < hd->used; i++) 
873     {
874       switch (hd->active[i].type) 
875         {
876         case KEYDB_RESOURCE_TYPE_NONE:
877           break;
878         case KEYDB_RESOURCE_TYPE_KEYBOX:
879           rc = keybox_search_reset (hd->active[i].u.kr);
880           break;
881         }
882     }
883   return rc; /* fixme: we need to map error codes or share them with
884                 all modules*/
885 }
886
887 /* 
888  * Search through all keydb resources, starting at the current position,
889  * for a keyblock which contains one of the keys described in the DESC array.
890  */
891 int 
892 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
893 {
894   int rc = -1;
895   
896   if (!hd)
897     return gpg_error (GPG_ERR_INV_VALUE);
898
899   while (rc == -1 && hd->current >= 0 && hd->current < hd->used) 
900     {
901       switch (hd->active[hd->current].type) 
902         {
903         case KEYDB_RESOURCE_TYPE_NONE:
904           BUG(); /* we should never see it here */
905           break;
906         case KEYDB_RESOURCE_TYPE_KEYBOX:
907           rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc);
908           break;
909         }
910       if (rc == -1) /* EOF -> switch to next resource */
911         hd->current++; 
912       else if (!rc)
913         hd->found = hd->current;
914     }
915   
916   return rc; 
917 }
918
919
920 int
921 keydb_search_first (KEYDB_HANDLE hd)
922 {
923   KEYDB_SEARCH_DESC desc;
924   
925   memset (&desc, 0, sizeof desc);
926   desc.mode = KEYDB_SEARCH_MODE_FIRST;
927   return keydb_search (hd, &desc, 1);
928 }
929
930 int
931 keydb_search_next (KEYDB_HANDLE hd)
932 {
933   KEYDB_SEARCH_DESC desc;
934   
935   memset (&desc, 0, sizeof desc);
936   desc.mode = KEYDB_SEARCH_MODE_NEXT;
937   return keydb_search (hd, &desc, 1);
938 }
939
940 int
941 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
942 {
943   KEYDB_SEARCH_DESC desc;
944   
945   memset (&desc, 0, sizeof desc);
946   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
947 /*    desc.u.kid[0] = kid[0]; */
948 /*    desc.u.kid[1] = kid[1]; */
949   return keydb_search (hd, &desc, 1);
950 }
951
952 int
953 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
954 {
955   KEYDB_SEARCH_DESC desc;
956   
957   memset (&desc, 0, sizeof desc);
958   desc.mode = KEYDB_SEARCH_MODE_FPR;
959   memcpy (desc.u.fpr, fpr, 20);
960   return keydb_search (hd, &desc, 1);
961 }
962
963 int
964 keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer)
965 {
966   KEYDB_SEARCH_DESC desc;
967   int rc;
968   
969   memset (&desc, 0, sizeof desc);
970   desc.mode = KEYDB_SEARCH_MODE_ISSUER;
971   desc.u.name = issuer;
972   rc = keydb_search (hd, &desc, 1);
973   return rc;
974 }
975
976 int
977 keydb_search_issuer_sn (KEYDB_HANDLE hd,
978                         const char *issuer, ksba_const_sexp_t serial)
979 {
980   KEYDB_SEARCH_DESC desc;
981   int rc;
982   const unsigned char *s;
983   
984   memset (&desc, 0, sizeof desc);
985   desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
986   s = serial;
987   if (*s !='(')
988     return gpg_error (GPG_ERR_INV_VALUE);
989   s++;
990   for (desc.snlen = 0; digitp (s); s++)
991     desc.snlen = 10*desc.snlen + atoi_1 (s);
992   if (*s !=':')
993     return gpg_error (GPG_ERR_INV_VALUE);
994   desc.sn = s+1;
995   desc.u.name = issuer;
996   rc = keydb_search (hd, &desc, 1);
997   return rc;
998 }
999
1000 int
1001 keydb_search_subject (KEYDB_HANDLE hd, const char *name)
1002 {
1003   KEYDB_SEARCH_DESC desc;
1004   int rc;
1005   
1006   memset (&desc, 0, sizeof desc);
1007   desc.mode = KEYDB_SEARCH_MODE_SUBJECT;
1008   desc.u.name = name;
1009   rc = keydb_search (hd, &desc, 1);
1010   return rc;
1011 }
1012
1013
1014 static int
1015 hextobyte (const unsigned char *s)
1016 {
1017   int c;
1018
1019   if( *s >= '0' && *s <= '9' )
1020     c = 16 * (*s - '0');
1021   else if ( *s >= 'A' && *s <= 'F' )
1022     c = 16 * (10 + *s - 'A');
1023   else if ( *s >= 'a' && *s <= 'f' )
1024     c = 16 * (10 + *s - 'a');
1025   else
1026     return -1;
1027   s++;
1028   if ( *s >= '0' && *s <= '9' )
1029     c += *s - '0';
1030   else if ( *s >= 'A' && *s <= 'F' )
1031     c += 10 + *s - 'A';
1032   else if ( *s >= 'a' && *s <= 'f' )
1033     c += 10 + *s - 'a';
1034   else
1035     return -1;
1036   return c;
1037 }
1038
1039
1040 static int
1041 classify_user_id (const char *name, 
1042                   KEYDB_SEARCH_DESC *desc,
1043                   int *force_exact )
1044 {
1045   const char *s;
1046   int hexprefix = 0;
1047   int hexlength;
1048   int mode = 0;   
1049     
1050   /* clear the structure so that the mode field is set to zero unless
1051    * we set it to the correct value right at the end of this function */
1052   memset (desc, 0, sizeof *desc);
1053   *force_exact = 0;
1054   /* Skip leading spaces.  Fixme: what about trailing white space? */
1055   for(s = name; *s && spacep (s); s++ )
1056     ;
1057
1058   switch (*s) 
1059     {
1060     case 0:  /* empty string is an error */
1061       return 0;
1062
1063     case '.': /* an email address, compare from end */
1064       mode = KEYDB_SEARCH_MODE_MAILEND;
1065       s++;
1066       desc->u.name = s;
1067       break;
1068
1069     case '<': /* an email address */
1070       mode = KEYDB_SEARCH_MODE_MAIL;
1071       s++;
1072       desc->u.name = s;
1073       break;
1074
1075     case '@':  /* part of an email address */
1076       mode = KEYDB_SEARCH_MODE_MAILSUB;
1077       s++;
1078       desc->u.name = s;
1079       break;
1080
1081     case '=':  /* exact compare */
1082       mode = KEYDB_SEARCH_MODE_EXACT;
1083       s++;
1084       desc->u.name = s;
1085       break;
1086
1087     case '*':  /* case insensitive substring search */
1088       mode = KEYDB_SEARCH_MODE_SUBSTR;
1089       s++;
1090       desc->u.name = s;
1091       break;
1092
1093     case '+':  /* compare individual words */
1094       mode = KEYDB_SEARCH_MODE_WORDS;
1095       s++;
1096       desc->u.name = s;
1097       break;
1098
1099     case '/': /* subject's DN */
1100       s++;
1101       if (!*s || spacep (s))
1102         return 0; /* no DN or prefixed with a space */
1103       desc->u.name = s;
1104       mode = KEYDB_SEARCH_MODE_SUBJECT;
1105       break;
1106
1107     case '#':
1108       { 
1109         const char *si;
1110         
1111         s++;
1112         if ( *s == '/')
1113           { /* "#/" indicates an issuer's DN */
1114             s++;
1115             if (!*s || spacep (s))
1116               return 0; /* no DN or prefixed with a space */
1117             desc->u.name = s;
1118             mode = KEYDB_SEARCH_MODE_ISSUER;
1119           }
1120         else 
1121           { /* serialnumber + optional issuer ID */
1122             for (si=s; *si && *si != '/'; si++)
1123               {
1124                 if (!strchr("01234567890abcdefABCDEF", *si))
1125                   return 0; /* invalid digit in serial number*/
1126               }
1127             desc->sn = s;
1128             desc->snlen = -1;
1129             if (!*si)
1130               mode = KEYDB_SEARCH_MODE_SN;
1131             else
1132               {
1133                 s = si+1;
1134                 if (!*s || spacep (s))
1135                   return 0; /* no DN or prefixed with a space */
1136                 desc->u.name = s;
1137                 mode = KEYDB_SEARCH_MODE_ISSUER_SN;
1138               }
1139           }
1140       }
1141       break;
1142
1143     case ':': /*Unified fingerprint */
1144       {  
1145         const char *se, *si;
1146         int i;
1147         
1148         se = strchr (++s,':');
1149         if (!se)
1150           return 0;
1151         for (i=0,si=s; si < se; si++, i++ )
1152           {
1153             if (!strchr("01234567890abcdefABCDEF", *si))
1154               return 0; /* invalid digit */
1155           }
1156         if (i != 32 && i != 40)
1157           return 0; /* invalid length of fpr*/
1158         for (i=0,si=s; si < se; i++, si +=2) 
1159           desc->u.fpr[i] = hextobyte(si);
1160         for (; i < 20; i++)
1161           desc->u.fpr[i]= 0;
1162         s = se + 1;
1163         mode = KEYDB_SEARCH_MODE_FPR;
1164       } 
1165       break;
1166            
1167     default:
1168       if (s[0] == '0' && s[1] == 'x')
1169         {
1170           hexprefix = 1;
1171           s += 2;
1172         }
1173
1174       hexlength = strspn(s, "0123456789abcdefABCDEF");
1175       if (hexlength >= 8 && s[hexlength] =='!')
1176         {
1177           *force_exact = 1;
1178           hexlength++; /* just for the following check */
1179         }
1180       
1181       /* check if a hexadecimal number is terminated by EOS or blank */
1182       if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
1183         {
1184           if (hexprefix) /* a "0x" prefix without correct */
1185             return 0;    /* termination is an error */
1186           /* The first chars looked like a hex number, but really is
1187              not */
1188           hexlength = 0;  
1189         }
1190       
1191       if (*force_exact)
1192         hexlength--; /* remove the bang */
1193
1194       if (hexlength == 8
1195           || (!hexprefix && hexlength == 9 && *s == '0'))
1196         { /* short keyid */
1197           unsigned long kid;
1198           if (hexlength == 9)
1199             s++;
1200           kid = strtoul( s, NULL, 16 );
1201           desc->u.kid[4] = kid >> 24; 
1202           desc->u.kid[5] = kid >> 16; 
1203           desc->u.kid[6] = kid >>  8; 
1204           desc->u.kid[7] = kid; 
1205           mode = KEYDB_SEARCH_MODE_SHORT_KID;
1206         }
1207       else if (hexlength == 16
1208                || (!hexprefix && hexlength == 17 && *s == '0'))
1209         { /* complete keyid */
1210           unsigned long kid0, kid1;
1211           char buf[9];
1212           if (hexlength == 17)
1213             s++;
1214           mem2str(buf, s, 9 );
1215           kid0 = strtoul (buf, NULL, 16);
1216           kid1 = strtoul (s+8, NULL, 16);
1217           desc->u.kid[0] = kid0 >> 24; 
1218           desc->u.kid[1] = kid0 >> 16; 
1219           desc->u.kid[2] = kid0 >>  8; 
1220           desc->u.kid[3] = kid0; 
1221           desc->u.kid[4] = kid1 >> 24; 
1222           desc->u.kid[5] = kid1 >> 16; 
1223           desc->u.kid[6] = kid1 >>  8; 
1224           desc->u.kid[7] = kid1; 
1225           mode = KEYDB_SEARCH_MODE_LONG_KID;
1226         }
1227       else if (hexlength == 32
1228                || (!hexprefix && hexlength == 33 && *s == '0'))
1229         { /* md5 fingerprint */
1230           int i;
1231           if (hexlength == 33)
1232             s++;
1233           memset(desc->u.fpr+16, 0, 4); 
1234           for (i=0; i < 16; i++, s+=2) 
1235             {
1236               int c = hextobyte(s);
1237               if (c == -1)
1238                 return 0;
1239               desc->u.fpr[i] = c;
1240             }
1241           mode = KEYDB_SEARCH_MODE_FPR16;
1242         }
1243       else if (hexlength == 40
1244                || (!hexprefix && hexlength == 41 && *s == '0'))
1245         { /* sha1/rmd160 fingerprint */
1246           int i;
1247           if (hexlength == 41)
1248             s++;
1249           for (i=0; i < 20; i++, s+=2) 
1250             {
1251               int c = hextobyte(s);
1252               if (c == -1)
1253                 return 0;
1254               desc->u.fpr[i] = c;
1255             }
1256           mode = KEYDB_SEARCH_MODE_FPR20;
1257         }
1258       else if (!hexprefix)
1259         { 
1260           /* The fingerprint in an X.509 listing is often delimited by
1261              colons, so we try to single this case out. */
1262           mode = 0;
1263           hexlength = strspn (s, ":0123456789abcdefABCDEF");
1264           if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) 
1265             {
1266               int i;
1267
1268               for (i=0; i < 20; i++, s += 3) 
1269                 {
1270                   int c = hextobyte(s);
1271                   if (c == -1 || (i < 19 && s[2] != ':'))
1272                     break;
1273                   desc->u.fpr[i] = c;
1274                 }
1275               if (i == 20)
1276                 mode = KEYDB_SEARCH_MODE_FPR20;
1277             }
1278           if (!mode) /* default is substring search */
1279             { 
1280               *force_exact = 0;
1281               desc->u.name = s;
1282               mode = KEYDB_SEARCH_MODE_SUBSTR; 
1283             }
1284         }
1285       else
1286         { /* hex number with a prefix but a wrong length */
1287           return 0;
1288         }
1289     }
1290   
1291   desc->mode = mode;
1292   return mode;
1293 }
1294
1295
1296 int
1297 keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
1298 {
1299   int dummy;
1300   KEYDB_SEARCH_DESC dummy_desc;
1301
1302   if (!desc)
1303     desc = &dummy_desc;
1304
1305   if (!classify_user_id (name, desc, &dummy))
1306     return gpg_error (GPG_ERR_INV_NAME);
1307   return 0;
1308 }
1309
1310 \f
1311 /* Store the certificate in the key DB but make sure that it does not
1312    already exists.  We do this simply by comparing the fingerprint.
1313    If EXISTED is not NULL it will be set to true if the certificate
1314    was already in the DB. */
1315 int
1316 keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
1317 {
1318   KEYDB_HANDLE kh;
1319   int rc;
1320   unsigned char fpr[20];
1321
1322   if (existed)
1323     *existed = 0;
1324
1325   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1326     {
1327       log_error (_("failed to get the fingerprint\n"));
1328       return gpg_error (GPG_ERR_GENERAL);
1329     }
1330
1331   kh = keydb_new (0);
1332   if (!kh)
1333     {
1334       log_error (_("failed to allocate keyDB handle\n"));
1335       return gpg_error (GPG_ERR_ENOMEM);;
1336     }
1337
1338   if (ephemeral)
1339     keydb_set_ephemeral (kh, 1);
1340   
1341   rc = keydb_search_fpr (kh, fpr);
1342   if (rc != -1)
1343     {
1344       keydb_release (kh);
1345       if (!rc)
1346         {
1347           if (existed)
1348             *existed = 1;
1349           return 0; /* okay */
1350         }
1351       log_error (_("problem looking for existing certificate: %s\n"),
1352                  gpg_strerror (rc));
1353       return rc;
1354     }
1355
1356   rc = keydb_locate_writable (kh, 0);
1357   if (rc)
1358     {
1359       log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
1360       keydb_release (kh);
1361       return rc;
1362     }
1363
1364   rc = keydb_insert_cert (kh, cert);
1365   if (rc)
1366     {
1367       log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
1368       keydb_release (kh);
1369       return rc;
1370     }
1371   keydb_release (kh);               
1372   return 0;
1373 }
1374
1375
1376 /* This is basically keydb_set_flags but it implements a complete
1377    transaction by locating the certificate in the DB and updating the
1378    flags. */
1379 gpg_error_t
1380 keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
1381 {
1382   KEYDB_HANDLE kh;
1383   gpg_error_t err;
1384   unsigned char fpr[20];
1385   unsigned int old_value;
1386
1387   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1388     {
1389       log_error (_("failed to get the fingerprint\n"));
1390       return gpg_error (GPG_ERR_GENERAL);
1391     }
1392
1393   kh = keydb_new (0);
1394   if (!kh)
1395     {
1396       log_error (_("failed to allocate keyDB handle\n"));
1397       return gpg_error (GPG_ERR_ENOMEM);;
1398     }
1399
1400   err = keydb_lock (kh);
1401   if (err)
1402     {
1403       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1404       keydb_release (kh);
1405       return err;
1406     }
1407
1408   err = keydb_search_fpr (kh, fpr);
1409   if (err)
1410     {
1411       log_error (_("problem re-searching certificate: %s\n"),
1412                  gpg_strerror (err));
1413       keydb_release (kh);
1414       return err;
1415     }
1416
1417   err = keydb_get_flags (kh, which, idx, &old_value);
1418   if (err)
1419     {
1420       log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
1421       keydb_release (kh);
1422       return err;
1423     }
1424   if (value != old_value)
1425     {
1426       err = keydb_set_flags (kh, which, idx, value);
1427       if (err)
1428         {
1429           log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1430           keydb_release (kh);
1431           return err;
1432         }
1433     }
1434   keydb_release (kh);               
1435   return 0;
1436 }
1437
1438
1439 /* Reset all the certificate flags we have stored with the certificates
1440    for performance reasons. */
1441 void
1442 keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names)
1443 {
1444   gpg_error_t err;
1445   KEYDB_HANDLE hd = NULL;
1446   KEYDB_SEARCH_DESC *desc = NULL;
1447   int ndesc;
1448   STRLIST sl;
1449   int rc=0;
1450   unsigned int old_value, value;
1451   
1452   hd = keydb_new (0);
1453   if (!hd)
1454     {
1455       log_error ("keydb_new failed\n");
1456       goto leave;
1457     }
1458
1459   if (!names)
1460     ndesc = 1;
1461   else
1462     {
1463       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
1464         ;
1465     }
1466
1467   desc = xtrycalloc (ndesc, sizeof *desc);
1468   if (!ndesc)
1469     {
1470       log_error ("allocating memory failed: %s\n",
1471                  gpg_strerror (OUT_OF_CORE (errno)));
1472       goto leave;
1473     }
1474
1475   if (!names)
1476     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1477   else 
1478     {
1479       for (ndesc=0, sl=names; sl; sl = sl->next) 
1480         {
1481           rc = keydb_classify_name (sl->d, desc+ndesc);
1482           if (rc)
1483             {
1484               log_error ("key `%s' not found: %s\n",
1485                          sl->d, gpg_strerror (rc));
1486               rc = 0;
1487             }
1488           else
1489             ndesc++;
1490         }
1491     }
1492
1493   err = keydb_lock (hd);
1494   if (err)
1495     {
1496       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1497       goto leave;
1498     }
1499
1500   while (!(rc = keydb_search (hd, desc, ndesc)))
1501     {
1502       if (!names) 
1503         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1504
1505       err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
1506       if (err)
1507         {
1508           log_error (_("error getting stored flags: %s\n"),
1509                      gpg_strerror (err));
1510           goto leave;
1511         }
1512  
1513       value = (old_value & ~VALIDITY_REVOKED);
1514       if (value != old_value)
1515         {
1516           err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
1517           if (err)
1518             {
1519               log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1520               goto leave;
1521             }
1522         }
1523     }
1524   if (rc && rc != -1)
1525     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1526   
1527  leave:
1528   xfree (desc);
1529   keydb_release (hd);
1530 }
1531
1532