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