2006-05-19 Marcus Brinkmann <marcus@g10code.de>
[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   unsigned 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   if (!hd->locked)
700     return gpg_error (GPG_ERR_NOT_LOCKED);
701
702   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
703
704   switch (hd->active[idx].type) 
705     {
706     case KEYDB_RESOURCE_TYPE_NONE:
707       rc = gpg_error (GPG_ERR_GENERAL);
708       break;
709     case KEYDB_RESOURCE_TYPE_KEYBOX:
710       rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
711       break;
712     }
713   
714   unlock_all (hd);
715   return rc;
716 }
717
718
719
720 /* update the current keyblock with KB */
721 int
722 keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
723 {
724   int rc = 0;
725   unsigned char digest[20];
726   
727   if (!hd)
728     return gpg_error (GPG_ERR_INV_VALUE);
729
730   if ( hd->found < 0 || hd->found >= hd->used) 
731     return -1; /* nothing found */
732
733   if (opt.dry_run)
734     return 0;
735
736   rc = lock_all (hd);
737   if (rc)
738     return rc;
739
740   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
741
742   switch (hd->active[hd->found].type) 
743     {
744     case KEYDB_RESOURCE_TYPE_NONE:
745       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
746       break;
747     case KEYDB_RESOURCE_TYPE_KEYBOX:
748       rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
749       break;
750     }
751
752   unlock_all (hd);
753   return rc;
754 }
755
756
757 /* 
758  * The current keyblock or cert will be deleted.
759  */
760 int
761 keydb_delete (KEYDB_HANDLE hd, int unlock)
762 {
763   int rc = -1;
764   
765   if (!hd)
766     return gpg_error (GPG_ERR_INV_VALUE);
767
768   if ( hd->found < 0 || hd->found >= hd->used) 
769     return -1; /* nothing found */
770
771   if( opt.dry_run )
772     return 0;
773
774   if (!hd->locked)
775     return gpg_error (GPG_ERR_NOT_LOCKED); 
776
777   switch (hd->active[hd->found].type)
778     {
779     case KEYDB_RESOURCE_TYPE_NONE:
780       rc = gpg_error (GPG_ERR_GENERAL);
781       break;
782     case KEYDB_RESOURCE_TYPE_KEYBOX:
783       rc = keybox_delete (hd->active[hd->found].u.kr);
784       break;
785     }
786
787   if (unlock)
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 char *string)
1014 {
1015   const unsigned char *s = (const unsigned char *)string;
1016   int c;
1017
1018   if( *s >= '0' && *s <= '9' )
1019     c = 16 * (*s - '0');
1020   else if ( *s >= 'A' && *s <= 'F' )
1021     c = 16 * (10 + *s - 'A');
1022   else if ( *s >= 'a' && *s <= 'f' )
1023     c = 16 * (10 + *s - 'a');
1024   else
1025     return -1;
1026   s++;
1027   if ( *s >= '0' && *s <= '9' )
1028     c += *s - '0';
1029   else if ( *s >= 'A' && *s <= 'F' )
1030     c += 10 + *s - 'A';
1031   else if ( *s >= 'a' && *s <= 'f' )
1032     c += 10 + *s - 'a';
1033   else
1034     return -1;
1035   return c;
1036 }
1037
1038
1039 static int
1040 classify_user_id (const char *name, 
1041                   KEYDB_SEARCH_DESC *desc,
1042                   int *force_exact )
1043 {
1044   const char *s;
1045   int hexprefix = 0;
1046   int hexlength;
1047   int mode = 0;   
1048     
1049   /* clear the structure so that the mode field is set to zero unless
1050    * we set it to the correct value right at the end of this function */
1051   memset (desc, 0, sizeof *desc);
1052   *force_exact = 0;
1053   /* Skip leading spaces.  Fixme: what about trailing white space? */
1054   for(s = name; *s && spacep (s); s++ )
1055     ;
1056
1057   switch (*s) 
1058     {
1059     case 0:  /* empty string is an error */
1060       return 0;
1061
1062     case '.': /* an email address, compare from end */
1063       mode = KEYDB_SEARCH_MODE_MAILEND;
1064       s++;
1065       desc->u.name = s;
1066       break;
1067
1068     case '<': /* an email address */
1069       mode = KEYDB_SEARCH_MODE_MAIL;
1070       s++;
1071       desc->u.name = s;
1072       break;
1073
1074     case '@':  /* part of an email address */
1075       mode = KEYDB_SEARCH_MODE_MAILSUB;
1076       s++;
1077       desc->u.name = s;
1078       break;
1079
1080     case '=':  /* exact compare */
1081       mode = KEYDB_SEARCH_MODE_EXACT;
1082       s++;
1083       desc->u.name = s;
1084       break;
1085
1086     case '*':  /* case insensitive substring search */
1087       mode = KEYDB_SEARCH_MODE_SUBSTR;
1088       s++;
1089       desc->u.name = s;
1090       break;
1091
1092     case '+':  /* compare individual words */
1093       mode = KEYDB_SEARCH_MODE_WORDS;
1094       s++;
1095       desc->u.name = s;
1096       break;
1097
1098     case '/': /* subject's DN */
1099       s++;
1100       if (!*s || spacep (s))
1101         return 0; /* no DN or prefixed with a space */
1102       desc->u.name = s;
1103       mode = KEYDB_SEARCH_MODE_SUBJECT;
1104       break;
1105
1106     case '#':
1107       { 
1108         const char *si;
1109         
1110         s++;
1111         if ( *s == '/')
1112           { /* "#/" indicates an issuer's DN */
1113             s++;
1114             if (!*s || spacep (s))
1115               return 0; /* no DN or prefixed with a space */
1116             desc->u.name = s;
1117             mode = KEYDB_SEARCH_MODE_ISSUER;
1118           }
1119         else 
1120           { /* serialnumber + optional issuer ID */
1121             for (si=s; *si && *si != '/'; si++)
1122               {
1123                 if (!strchr("01234567890abcdefABCDEF", *si))
1124                   return 0; /* invalid digit in serial number*/
1125               }
1126             desc->sn = (const unsigned char*)s;
1127             desc->snlen = -1;
1128             if (!*si)
1129               mode = KEYDB_SEARCH_MODE_SN;
1130             else
1131               {
1132                 s = si+1;
1133                 if (!*s || spacep (s))
1134                   return 0; /* no DN or prefixed with a space */
1135                 desc->u.name = s;
1136                 mode = KEYDB_SEARCH_MODE_ISSUER_SN;
1137               }
1138           }
1139       }
1140       break;
1141
1142     case ':': /*Unified fingerprint */
1143       {  
1144         const char *se, *si;
1145         int i;
1146         
1147         se = strchr (++s,':');
1148         if (!se)
1149           return 0;
1150         for (i=0,si=s; si < se; si++, i++ )
1151           {
1152             if (!strchr("01234567890abcdefABCDEF", *si))
1153               return 0; /* invalid digit */
1154           }
1155         if (i != 32 && i != 40)
1156           return 0; /* invalid length of fpr*/
1157         for (i=0,si=s; si < se; i++, si +=2) 
1158           desc->u.fpr[i] = hextobyte(si);
1159         for (; i < 20; i++)
1160           desc->u.fpr[i]= 0;
1161         s = se + 1;
1162         mode = KEYDB_SEARCH_MODE_FPR;
1163       } 
1164       break;
1165            
1166     default:
1167       if (s[0] == '0' && s[1] == 'x')
1168         {
1169           hexprefix = 1;
1170           s += 2;
1171         }
1172
1173       hexlength = strspn(s, "0123456789abcdefABCDEF");
1174       if (hexlength >= 8 && s[hexlength] =='!')
1175         {
1176           *force_exact = 1;
1177           hexlength++; /* just for the following check */
1178         }
1179       
1180       /* check if a hexadecimal number is terminated by EOS or blank */
1181       if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
1182         {
1183           if (hexprefix) /* a "0x" prefix without correct */
1184             return 0;    /* termination is an error */
1185           /* The first chars looked like a hex number, but really is
1186              not */
1187           hexlength = 0;  
1188         }
1189       
1190       if (*force_exact)
1191         hexlength--; /* remove the bang */
1192
1193       if (hexlength == 8
1194           || (!hexprefix && hexlength == 9 && *s == '0'))
1195         { /* short keyid */
1196           unsigned long kid;
1197           if (hexlength == 9)
1198             s++;
1199           kid = strtoul( s, NULL, 16 );
1200           desc->u.kid[4] = kid >> 24; 
1201           desc->u.kid[5] = kid >> 16; 
1202           desc->u.kid[6] = kid >>  8; 
1203           desc->u.kid[7] = kid; 
1204           mode = KEYDB_SEARCH_MODE_SHORT_KID;
1205         }
1206       else if (hexlength == 16
1207                || (!hexprefix && hexlength == 17 && *s == '0'))
1208         { /* complete keyid */
1209           unsigned long kid0, kid1;
1210           char buf[9];
1211           if (hexlength == 17)
1212             s++;
1213           mem2str(buf, s, 9 );
1214           kid0 = strtoul (buf, NULL, 16);
1215           kid1 = strtoul (s+8, NULL, 16);
1216           desc->u.kid[0] = kid0 >> 24; 
1217           desc->u.kid[1] = kid0 >> 16; 
1218           desc->u.kid[2] = kid0 >>  8; 
1219           desc->u.kid[3] = kid0; 
1220           desc->u.kid[4] = kid1 >> 24; 
1221           desc->u.kid[5] = kid1 >> 16; 
1222           desc->u.kid[6] = kid1 >>  8; 
1223           desc->u.kid[7] = kid1; 
1224           mode = KEYDB_SEARCH_MODE_LONG_KID;
1225         }
1226       else if (hexlength == 32
1227                || (!hexprefix && hexlength == 33 && *s == '0'))
1228         { /* md5 fingerprint */
1229           int i;
1230           if (hexlength == 33)
1231             s++;
1232           memset(desc->u.fpr+16, 0, 4); 
1233           for (i=0; i < 16; i++, s+=2) 
1234             {
1235               int c = hextobyte(s);
1236               if (c == -1)
1237                 return 0;
1238               desc->u.fpr[i] = c;
1239             }
1240           mode = KEYDB_SEARCH_MODE_FPR16;
1241         }
1242       else if (hexlength == 40
1243                || (!hexprefix && hexlength == 41 && *s == '0'))
1244         { /* sha1/rmd160 fingerprint */
1245           int i;
1246           if (hexlength == 41)
1247             s++;
1248           for (i=0; i < 20; i++, s+=2) 
1249             {
1250               int c = hextobyte(s);
1251               if (c == -1)
1252                 return 0;
1253               desc->u.fpr[i] = c;
1254             }
1255           mode = KEYDB_SEARCH_MODE_FPR20;
1256         }
1257       else if (!hexprefix)
1258         { 
1259           /* The fingerprint in an X.509 listing is often delimited by
1260              colons, so we try to single this case out. */
1261           mode = 0;
1262           hexlength = strspn (s, ":0123456789abcdefABCDEF");
1263           if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) 
1264             {
1265               int i;
1266
1267               for (i=0; i < 20; i++, s += 3) 
1268                 {
1269                   int c = hextobyte(s);
1270                   if (c == -1 || (i < 19 && s[2] != ':'))
1271                     break;
1272                   desc->u.fpr[i] = c;
1273                 }
1274               if (i == 20)
1275                 mode = KEYDB_SEARCH_MODE_FPR20;
1276             }
1277           if (!mode) /* default is substring search */
1278             { 
1279               *force_exact = 0;
1280               desc->u.name = s;
1281               mode = KEYDB_SEARCH_MODE_SUBSTR; 
1282             }
1283         }
1284       else
1285         { /* hex number with a prefix but a wrong length */
1286           return 0;
1287         }
1288     }
1289   
1290   desc->mode = mode;
1291   return mode;
1292 }
1293
1294
1295 int
1296 keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
1297 {
1298   int dummy;
1299   KEYDB_SEARCH_DESC dummy_desc;
1300
1301   if (!desc)
1302     desc = &dummy_desc;
1303
1304   if (!classify_user_id (name, desc, &dummy))
1305     return gpg_error (GPG_ERR_INV_NAME);
1306   return 0;
1307 }
1308
1309 \f
1310 /* Store the certificate in the key DB but make sure that it does not
1311    already exists.  We do this simply by comparing the fingerprint.
1312    If EXISTED is not NULL it will be set to true if the certificate
1313    was already in the DB. */
1314 int
1315 keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
1316 {
1317   KEYDB_HANDLE kh;
1318   int rc;
1319   unsigned char fpr[20];
1320
1321   if (existed)
1322     *existed = 0;
1323
1324   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1325     {
1326       log_error (_("failed to get the fingerprint\n"));
1327       return gpg_error (GPG_ERR_GENERAL);
1328     }
1329
1330   kh = keydb_new (0);
1331   if (!kh)
1332     {
1333       log_error (_("failed to allocate keyDB handle\n"));
1334       return gpg_error (GPG_ERR_ENOMEM);;
1335     }
1336
1337   if (ephemeral)
1338     keydb_set_ephemeral (kh, 1);
1339   
1340   rc = lock_all (kh);
1341   if (rc)
1342     return rc;
1343
1344   rc = keydb_search_fpr (kh, fpr);
1345   if (rc != -1)
1346     {
1347       keydb_release (kh);
1348       if (!rc)
1349         {
1350           if (existed)
1351             *existed = 1;
1352           return 0; /* okay */
1353         }
1354       log_error (_("problem looking for existing certificate: %s\n"),
1355                  gpg_strerror (rc));
1356       return rc;
1357     }
1358
1359   rc = keydb_locate_writable (kh, 0);
1360   if (rc)
1361     {
1362       log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
1363       keydb_release (kh);
1364       return rc;
1365     }
1366
1367   rc = keydb_insert_cert (kh, cert);
1368   if (rc)
1369     {
1370       log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
1371       keydb_release (kh);
1372       return rc;
1373     }
1374   keydb_release (kh);               
1375   return 0;
1376 }
1377
1378
1379 /* This is basically keydb_set_flags but it implements a complete
1380    transaction by locating the certificate in the DB and updating the
1381    flags. */
1382 gpg_error_t
1383 keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
1384 {
1385   KEYDB_HANDLE kh;
1386   gpg_error_t err;
1387   unsigned char fpr[20];
1388   unsigned int old_value;
1389
1390   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1391     {
1392       log_error (_("failed to get the fingerprint\n"));
1393       return gpg_error (GPG_ERR_GENERAL);
1394     }
1395
1396   kh = keydb_new (0);
1397   if (!kh)
1398     {
1399       log_error (_("failed to allocate keyDB handle\n"));
1400       return gpg_error (GPG_ERR_ENOMEM);;
1401     }
1402
1403   err = keydb_lock (kh);
1404   if (err)
1405     {
1406       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1407       keydb_release (kh);
1408       return err;
1409     }
1410
1411   err = keydb_search_fpr (kh, fpr);
1412   if (err)
1413     {
1414       log_error (_("problem re-searching certificate: %s\n"),
1415                  gpg_strerror (err));
1416       keydb_release (kh);
1417       return err;
1418     }
1419
1420   err = keydb_get_flags (kh, which, idx, &old_value);
1421   if (err)
1422     {
1423       log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
1424       keydb_release (kh);
1425       return err;
1426     }
1427   if (value != old_value)
1428     {
1429       err = keydb_set_flags (kh, which, idx, value);
1430       if (err)
1431         {
1432           log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1433           keydb_release (kh);
1434           return err;
1435         }
1436     }
1437   keydb_release (kh);               
1438   return 0;
1439 }
1440
1441
1442 /* Reset all the certificate flags we have stored with the certificates
1443    for performance reasons. */
1444 void
1445 keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names)
1446 {
1447   gpg_error_t err;
1448   KEYDB_HANDLE hd = NULL;
1449   KEYDB_SEARCH_DESC *desc = NULL;
1450   int ndesc;
1451   STRLIST sl;
1452   int rc=0;
1453   unsigned int old_value, value;
1454   
1455   hd = keydb_new (0);
1456   if (!hd)
1457     {
1458       log_error ("keydb_new failed\n");
1459       goto leave;
1460     }
1461
1462   if (!names)
1463     ndesc = 1;
1464   else
1465     {
1466       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
1467         ;
1468     }
1469
1470   desc = xtrycalloc (ndesc, sizeof *desc);
1471   if (!ndesc)
1472     {
1473       log_error ("allocating memory failed: %s\n",
1474                  gpg_strerror (OUT_OF_CORE (errno)));
1475       goto leave;
1476     }
1477
1478   if (!names)
1479     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1480   else 
1481     {
1482       for (ndesc=0, sl=names; sl; sl = sl->next) 
1483         {
1484           rc = keydb_classify_name (sl->d, desc+ndesc);
1485           if (rc)
1486             {
1487               log_error ("key `%s' not found: %s\n",
1488                          sl->d, gpg_strerror (rc));
1489               rc = 0;
1490             }
1491           else
1492             ndesc++;
1493         }
1494     }
1495
1496   err = keydb_lock (hd);
1497   if (err)
1498     {
1499       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1500       goto leave;
1501     }
1502
1503   while (!(rc = keydb_search (hd, desc, ndesc)))
1504     {
1505       if (!names) 
1506         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1507
1508       err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
1509       if (err)
1510         {
1511           log_error (_("error getting stored flags: %s\n"),
1512                      gpg_strerror (err));
1513           goto leave;
1514         }
1515  
1516       value = (old_value & ~VALIDITY_REVOKED);
1517       if (value != old_value)
1518         {
1519           err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
1520           if (err)
1521             {
1522               log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1523               goto leave;
1524             }
1525         }
1526     }
1527   if (rc && rc != -1)
1528     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1529   
1530  leave:
1531   xfree (desc);
1532   keydb_release (hd);
1533 }
1534
1535