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