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