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