* options.h, keyserver.c (parse_keyserver_uri, keyserver_spawn,
[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 is_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 /* Switch the handle into ephemeral mode and return the orginal value. */
336 int
337 keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
338 {
339   int i;
340
341   if (!hd)
342     return 0;
343
344   yes = !!yes;
345   if (hd->is_ephemeral != yes)
346     {
347       for (i=0; i < hd->used; i++)
348         {
349           switch (hd->active[i].type) 
350             {
351             case KEYDB_RESOURCE_TYPE_NONE:
352               break;
353             case KEYDB_RESOURCE_TYPE_KEYBOX:
354               keybox_set_ephemeral (hd->active[i].u.kr, yes);
355               break;
356             }
357         }
358     }
359       
360   i = hd->is_ephemeral;
361   hd->is_ephemeral = yes;
362   return i;
363 }
364
365
366 \f
367 static int 
368 lock_all (KEYDB_HANDLE hd)
369 {
370   int i, rc = 0;
371
372   for (i=0; !rc && i < hd->used; i++) 
373     {
374       switch (hd->active[i].type) 
375         {
376         case KEYDB_RESOURCE_TYPE_NONE:
377           break;
378         case KEYDB_RESOURCE_TYPE_KEYBOX:
379           /* FIXME  rc = keybox_lock (hd->active[i].u.kr, 1);*/
380           break;
381         }
382     }
383
384     if (rc) 
385       {
386         /* revert the already set locks */
387         for (i--; i >= 0; i--) 
388           {
389             switch (hd->active[i].type) 
390               {
391               case KEYDB_RESOURCE_TYPE_NONE:
392                 break;
393               case KEYDB_RESOURCE_TYPE_KEYBOX:
394                 /* Fixme: keybox_lock (hd->active[i].u.kr, 0);*/
395                 break;
396               }
397           }
398       }
399     else
400       hd->locked = 1;
401
402     return rc;
403 }
404
405 static void
406 unlock_all (KEYDB_HANDLE hd)
407 {
408   int i;
409   
410   if (!hd->locked)
411     return;
412
413   for (i=hd->used-1; i >= 0; i--) 
414     {
415       switch (hd->active[i].type) 
416         {
417         case KEYDB_RESOURCE_TYPE_NONE:
418           break;
419         case KEYDB_RESOURCE_TYPE_KEYBOX:
420           /* fixme: keybox_lock (hd->active[i].u.kr, 0);*/
421           break;
422         }
423     }
424   hd->locked = 0;
425 }
426
427 \f
428 #if 0
429 /*
430  * Return the last found keybox.  Caller must free it.
431  * The returned keyblock has the kbode flag bit 0 set for the node with
432  * the public key used to locate the keyblock or flag bit 1 set for 
433  * the user ID node.
434  */
435 int
436 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
437 {
438     int rc = 0;
439
440     if (!hd)
441         return G10ERR_INV_ARG;
442
443     if ( hd->found < 0 || hd->found >= hd->used) 
444         return -1; /* nothing found */
445
446     switch (hd->active[hd->found].type) {
447       case KEYDB_RESOURCE_TYPE_NONE:
448         rc = G10ERR_GENERAL; /* oops */
449         break;
450       case KEYDB_RESOURCE_TYPE_KEYBOX:
451         rc = keybox_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
452         break;
453     }
454
455     return rc;
456 }
457
458 /* 
459  * update the current keyblock with KB
460  */
461 int
462 keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
463 {
464     int rc = 0;
465
466     if (!hd)
467         return G10ERR_INV_ARG;
468
469     if ( hd->found < 0 || hd->found >= hd->used) 
470         return -1; /* nothing found */
471
472     if( opt.dry_run )
473         return 0;
474
475     rc = lock_all (hd);
476     if (rc)
477         return rc;
478
479     switch (hd->active[hd->found].type) {
480       case KEYDB_RESOURCE_TYPE_NONE:
481         rc = G10ERR_GENERAL; /* oops */
482         break;
483       case KEYDB_RESOURCE_TYPE_KEYBOX:
484         rc = keybox_update_keyblock (hd->active[hd->found].u.kr, kb);
485         break;
486     }
487
488     unlock_all (hd);
489     return rc;
490 }
491
492
493 /* 
494  * Insert a new KB into one of the resources. 
495  */
496 int
497 keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
498 {
499     int rc = -1;
500     int idx;
501
502     if (!hd) 
503         return G10ERR_INV_ARG;
504
505     if( opt.dry_run )
506         return 0;
507
508     if ( hd->found >= 0 && hd->found < hd->used) 
509         idx = hd->found;
510     else if ( hd->current >= 0 && hd->current < hd->used) 
511         idx = hd->current;
512     else
513         return G10ERR_GENERAL;
514
515     rc = lock_all (hd);
516     if (rc)
517         return rc;
518
519     switch (hd->active[idx].type) {
520       case KEYDB_RESOURCE_TYPE_NONE:
521         rc = G10ERR_GENERAL; /* oops */
522         break;
523       case KEYDB_RESOURCE_TYPE_KEYBOX:
524         rc = keybox_insert_keyblock (hd->active[idx].u.kr, kb);
525         break;
526     }
527
528     unlock_all (hd);
529     return rc;
530 }
531
532 #endif /*disabled code*/
533
534
535 \f
536 /*
537   Return the last found keybox.  Caller must free it.  The returned
538   keyblock has the kbode flag bit 0 set for the node with the public
539   key used to locate the keyblock or flag bit 1 set for the user ID
540   node.  */
541 int
542 keydb_get_cert (KEYDB_HANDLE hd, KsbaCert *r_cert)
543 {
544   int rc = 0;
545
546   if (!hd)
547     return GNUPG_Invalid_Value;
548   
549   if ( hd->found < 0 || hd->found >= hd->used) 
550     return -1; /* nothing found */
551   
552   switch (hd->active[hd->found].type) 
553     {
554     case KEYDB_RESOURCE_TYPE_NONE:
555       rc = GNUPG_General_Error; /* oops */
556       break;
557     case KEYDB_RESOURCE_TYPE_KEYBOX:
558       rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert);
559       break;
560     }
561   
562   return rc;
563 }
564
565 /* 
566  * Insert a new Certificate into one of the resources. 
567  */
568 int
569 keydb_insert_cert (KEYDB_HANDLE hd, KsbaCert cert)
570 {
571   int rc = -1;
572   int idx;
573   char digest[20];
574   
575   if (!hd) 
576     return GNUPG_Invalid_Value;
577
578   if (opt.dry_run)
579     return 0;
580   
581   if ( hd->found >= 0 && hd->found < hd->used) 
582     idx = hd->found;
583   else if ( hd->current >= 0 && hd->current < hd->used) 
584     idx = hd->current;
585   else
586     return GNUPG_General_Error;
587
588   rc = lock_all (hd);
589   if (rc)
590     return rc;
591
592   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
593
594   switch (hd->active[idx].type) 
595     {
596     case KEYDB_RESOURCE_TYPE_NONE:
597       rc = GNUPG_General_Error;
598       break;
599     case KEYDB_RESOURCE_TYPE_KEYBOX:
600       rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
601       break;
602     }
603   
604   unlock_all (hd);
605   return rc;
606 }
607
608
609
610 /* update the current keyblock with KB */
611 int
612 keydb_update_cert (KEYDB_HANDLE hd, KsbaCert cert)
613 {
614   int rc = 0;
615   char digest[20];
616   
617   if (!hd)
618     return GNUPG_Invalid_Value;
619
620   if ( hd->found < 0 || hd->found >= hd->used) 
621     return -1; /* nothing found */
622
623   if (opt.dry_run)
624     return 0;
625
626   rc = lock_all (hd);
627   if (rc)
628     return rc;
629
630   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
631
632   switch (hd->active[hd->found].type) 
633     {
634     case KEYDB_RESOURCE_TYPE_NONE:
635       rc = GNUPG_General_Error; /* oops */
636       break;
637     case KEYDB_RESOURCE_TYPE_KEYBOX:
638       rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
639       break;
640     }
641
642   unlock_all (hd);
643   return rc;
644 }
645
646
647 /* 
648  * The current keyblock or cert will be deleted.
649  */
650 int
651 keydb_delete (KEYDB_HANDLE hd)
652 {
653   int rc = -1;
654   
655   if (!hd)
656     return GNUPG_Invalid_Value;
657
658   if ( hd->found < 0 || hd->found >= hd->used) 
659     return -1; /* nothing found */
660
661   if( opt.dry_run )
662     return 0;
663
664   rc = lock_all (hd);
665   if (rc)
666     return rc;
667
668   switch (hd->active[hd->found].type)
669     {
670     case KEYDB_RESOURCE_TYPE_NONE:
671       rc = GNUPG_General_Error;
672       break;
673     case KEYDB_RESOURCE_TYPE_KEYBOX:
674       rc = keybox_delete (hd->active[hd->found].u.kr);
675       break;
676     }
677
678   unlock_all (hd);
679   return rc;
680 }
681
682
683 \f
684 /*
685  * Locate the default writable key resource, so that the next
686  * operation (which is only relevant for inserts) will be done on this
687  * resource.  
688  */
689 int
690 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
691 {
692   int rc;
693   
694   if (!hd)
695     return GNUPG_Invalid_Value;
696   
697   rc = keydb_search_reset (hd); /* this does reset hd->current */
698   if (rc)
699     return rc;
700   
701   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) 
702     {
703       switch (hd->active[hd->current].type) 
704         {
705         case KEYDB_RESOURCE_TYPE_NONE:
706           BUG();
707           break;
708         case KEYDB_RESOURCE_TYPE_KEYBOX:
709           if (keybox_is_writable (hd->active[hd->current].token))
710             return 0; /* found (hd->current is set to it) */
711           break;
712         }
713     }
714   
715   return -1;
716 }
717
718 /*
719  * Rebuild the caches of all key resources.
720  */
721 void
722 keydb_rebuild_caches (void)
723 {
724   int i;
725   
726   for (i=0; i < used_resources; i++)
727     {
728       if (all_resources[i].secret)
729         continue;
730       switch (all_resources[i].type)
731         {
732         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
733           break;
734         case KEYDB_RESOURCE_TYPE_KEYBOX:
735 /*            rc = keybox_rebuild_cache (all_resources[i].token); */
736 /*            if (rc) */
737 /*              log_error (_("failed to rebuild keybox cache: %s\n"), */
738 /*                         g10_errstr (rc)); */
739           break;
740         }
741     }
742 }
743
744
745
746 /* 
747  * Start the next search on this handle right at the beginning
748  */
749 int 
750 keydb_search_reset (KEYDB_HANDLE hd)
751 {
752   int i, rc = 0;
753   
754   if (!hd)
755     return GNUPG_Invalid_Value;
756
757   hd->current = 0; 
758   hd->found = -1;
759   /* and reset all resources */
760   for (i=0; !rc && i < hd->used; i++) 
761     {
762       switch (hd->active[i].type) 
763         {
764         case KEYDB_RESOURCE_TYPE_NONE:
765           break;
766         case KEYDB_RESOURCE_TYPE_KEYBOX:
767           rc = keybox_search_reset (hd->active[i].u.kr);
768           break;
769         }
770     }
771   return rc; /* fixme: we need to map error codes or share them with
772                 all modules*/
773 }
774
775 /* 
776  * Search through all keydb resources, starting at the current position,
777  * for a keyblock which contains one of the keys described in the DESC array.
778  */
779 int 
780 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
781 {
782   int rc = -1;
783   
784   if (!hd)
785     return GNUPG_Invalid_Value;
786
787   while (rc == -1 && hd->current >= 0 && hd->current < hd->used) 
788     {
789       switch (hd->active[hd->current].type) 
790         {
791         case KEYDB_RESOURCE_TYPE_NONE:
792           BUG(); /* we should never see it here */
793           break;
794         case KEYDB_RESOURCE_TYPE_KEYBOX:
795           rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc);
796           break;
797         }
798       if (rc == -1) /* EOF -> switch to next resource */
799         hd->current++; 
800       else if (!rc)
801         hd->found = hd->current;
802     }
803   
804   return rc; 
805 }
806
807
808 int
809 keydb_search_first (KEYDB_HANDLE hd)
810 {
811   KEYDB_SEARCH_DESC desc;
812   
813   memset (&desc, 0, sizeof desc);
814   desc.mode = KEYDB_SEARCH_MODE_FIRST;
815   return keydb_search (hd, &desc, 1);
816 }
817
818 int
819 keydb_search_next (KEYDB_HANDLE hd)
820 {
821   KEYDB_SEARCH_DESC desc;
822   
823   memset (&desc, 0, sizeof desc);
824   desc.mode = KEYDB_SEARCH_MODE_NEXT;
825   return keydb_search (hd, &desc, 1);
826 }
827
828 int
829 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
830 {
831   KEYDB_SEARCH_DESC desc;
832   
833   memset (&desc, 0, sizeof desc);
834   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
835 /*    desc.u.kid[0] = kid[0]; */
836 /*    desc.u.kid[1] = kid[1]; */
837   return keydb_search (hd, &desc, 1);
838 }
839
840 int
841 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
842 {
843   KEYDB_SEARCH_DESC desc;
844   
845   memset (&desc, 0, sizeof desc);
846   desc.mode = KEYDB_SEARCH_MODE_FPR;
847   memcpy (desc.u.fpr, fpr, 20);
848   return keydb_search (hd, &desc, 1);
849 }
850
851 int
852 keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer)
853 {
854   KEYDB_SEARCH_DESC desc;
855   int rc;
856   
857   memset (&desc, 0, sizeof desc);
858   desc.mode = KEYDB_SEARCH_MODE_ISSUER;
859   desc.u.name = issuer;
860   rc = keydb_search (hd, &desc, 1);
861   return rc;
862 }
863
864 int
865 keydb_search_issuer_sn (KEYDB_HANDLE hd,
866                         const char *issuer, KsbaConstSexp serial)
867 {
868   KEYDB_SEARCH_DESC desc;
869   int rc;
870   const unsigned char *s;
871   
872   memset (&desc, 0, sizeof desc);
873   desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
874   s = serial;
875   if (*s !='(')
876     return GNUPG_Invalid_Value;
877   s++;
878   for (desc.snlen = 0; digitp (s); s++)
879     desc.snlen = 10*desc.snlen + atoi_1 (s);
880   if (*s !=':')
881     return GNUPG_Invalid_Value;
882   desc.sn = s+1;
883   desc.u.name = issuer;
884   rc = keydb_search (hd, &desc, 1);
885   return rc;
886 }
887
888 int
889 keydb_search_subject (KEYDB_HANDLE hd, const char *name)
890 {
891   KEYDB_SEARCH_DESC desc;
892   int rc;
893   
894   memset (&desc, 0, sizeof desc);
895   desc.mode = KEYDB_SEARCH_MODE_SUBJECT;
896   desc.u.name = name;
897   rc = keydb_search (hd, &desc, 1);
898   return rc;
899 }
900
901
902 static int
903 hextobyte (const unsigned char *s)
904 {
905   int c;
906
907   if( *s >= '0' && *s <= '9' )
908     c = 16 * (*s - '0');
909   else if ( *s >= 'A' && *s <= 'F' )
910     c = 16 * (10 + *s - 'A');
911   else if ( *s >= 'a' && *s <= 'f' )
912     c = 16 * (10 + *s - 'a');
913   else
914     return -1;
915   s++;
916   if ( *s >= '0' && *s <= '9' )
917     c += *s - '0';
918   else if ( *s >= 'A' && *s <= 'F' )
919     c += 10 + *s - 'A';
920   else if ( *s >= 'a' && *s <= 'f' )
921     c += 10 + *s - 'a';
922   else
923     return -1;
924   return c;
925 }
926
927
928 static int
929 classify_user_id (const char *name, 
930                   KEYDB_SEARCH_DESC *desc,
931                   int *force_exact )
932 {
933   const char *s;
934   int hexprefix = 0;
935   int hexlength;
936   int mode = 0;   
937     
938   /* clear the structure so that the mode field is set to zero unless
939    * we set it to the correct value right at the end of this function */
940   memset (desc, 0, sizeof *desc);
941   *force_exact = 0;
942   /* skip leading spaces.  Fixme: what about trailing white space? */
943   for(s = name; *s && spacep (s); s++ )
944     ;
945
946   switch (*s) 
947     {
948     case 0:  /* empty string is an error */
949       return 0;
950
951     case '.': /* an email address, compare from end */
952       mode = KEYDB_SEARCH_MODE_MAILEND;
953       s++;
954       desc->u.name = s;
955       break;
956
957     case '<': /* an email address */
958       mode = KEYDB_SEARCH_MODE_MAIL;
959       s++;
960       desc->u.name = s;
961       break;
962
963     case '@':  /* part of an email address */
964       mode = KEYDB_SEARCH_MODE_MAILSUB;
965       s++;
966       desc->u.name = s;
967       break;
968
969     case '=':  /* exact compare */
970       mode = KEYDB_SEARCH_MODE_EXACT;
971       s++;
972       desc->u.name = s;
973       break;
974
975     case '*':  /* case insensitive substring search */
976       mode = KEYDB_SEARCH_MODE_SUBSTR;
977       s++;
978       desc->u.name = s;
979       break;
980
981     case '+':  /* compare individual words */
982       mode = KEYDB_SEARCH_MODE_WORDS;
983       s++;
984       desc->u.name = s;
985       break;
986
987     case '/': /* subject's DN */
988       s++;
989       if (!*s || spacep (s))
990         return 0; /* no DN or prefixed with a space */
991       desc->u.name = s;
992       mode = KEYDB_SEARCH_MODE_SUBJECT;
993       break;
994
995     case '#':
996       { 
997         const char *si;
998         
999         s++;
1000         if ( *s == '/')
1001           { /* "#/" indicates an issuer's DN */
1002             s++;
1003             if (!*s || spacep (s))
1004               return 0; /* no DN or prefixed with a space */
1005             desc->u.name = s;
1006             mode = KEYDB_SEARCH_MODE_ISSUER;
1007           }
1008         else 
1009           { /* serialnumber + optional issuer ID */
1010             for (si=s; *si && *si != '/'; si++)
1011               {
1012                 if (!strchr("01234567890abcdefABCDEF", *si))
1013                   return 0; /* invalid digit in serial number*/
1014               }
1015             desc->sn = s;
1016             desc->snlen = -1;
1017             if (!*si)
1018               mode = KEYDB_SEARCH_MODE_SN;
1019             else
1020               {
1021                 s = si+1;
1022                 if (!*s || spacep (s))
1023                   return 0; /* no DN or prefixed with a space */
1024                 desc->u.name = s;
1025                 mode = KEYDB_SEARCH_MODE_ISSUER_SN;
1026               }
1027           }
1028       }
1029       break;
1030
1031     case ':': /*Unified fingerprint */
1032       {  
1033         const char *se, *si;
1034         int i;
1035         
1036         se = strchr (++s,':');
1037         if (!se)
1038           return 0;
1039         for (i=0,si=s; si < se; si++, i++ )
1040           {
1041             if (!strchr("01234567890abcdefABCDEF", *si))
1042               return 0; /* invalid digit */
1043           }
1044         if (i != 32 && i != 40)
1045           return 0; /* invalid length of fpr*/
1046         for (i=0,si=s; si < se; i++, si +=2) 
1047           desc->u.fpr[i] = hextobyte(si);
1048         for (; i < 20; i++)
1049           desc->u.fpr[i]= 0;
1050         s = se + 1;
1051         mode = KEYDB_SEARCH_MODE_FPR;
1052       } 
1053       break;
1054            
1055     default:
1056       if (s[0] == '0' && s[1] == 'x')
1057         {
1058           hexprefix = 1;
1059           s += 2;
1060         }
1061
1062       hexlength = strspn(s, "0123456789abcdefABCDEF");
1063       if (hexlength >= 8 && s[hexlength] =='!')
1064         {
1065           *force_exact = 1;
1066           hexlength++; /* just for the following check */
1067         }
1068       
1069       /* check if a hexadecimal number is terminated by EOS or blank */
1070       if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
1071         {
1072           if (hexprefix) /* a "0x" prefix without correct */
1073             return 0;    /* termination is an error */
1074           /* The first chars looked like a hex number, but really is
1075              not */
1076           hexlength = 0;  
1077         }
1078       
1079       if (*force_exact)
1080         hexlength--; /* remove the bang */
1081
1082       if (hexlength == 8
1083           || (!hexprefix && hexlength == 9 && *s == '0'))
1084         { /* short keyid */
1085           unsigned long kid;
1086           if (hexlength == 9)
1087             s++;
1088           kid = strtoul( s, NULL, 16 );
1089           desc->u.kid[4] = kid >> 24; 
1090           desc->u.kid[5] = kid >> 16; 
1091           desc->u.kid[6] = kid >>  8; 
1092           desc->u.kid[7] = kid; 
1093           mode = KEYDB_SEARCH_MODE_SHORT_KID;
1094         }
1095       else if (hexlength == 16
1096                || (!hexprefix && hexlength == 17 && *s == '0'))
1097         { /* complete keyid */
1098           unsigned long kid0, kid1;
1099           char buf[9];
1100           if (hexlength == 17)
1101             s++;
1102           mem2str(buf, s, 9 );
1103           kid0 = strtoul (buf, NULL, 16);
1104           kid1 = strtoul (s+8, NULL, 16);
1105           desc->u.kid[0] = kid0 >> 24; 
1106           desc->u.kid[1] = kid0 >> 16; 
1107           desc->u.kid[2] = kid0 >>  8; 
1108           desc->u.kid[3] = kid0; 
1109           desc->u.kid[4] = kid1 >> 24; 
1110           desc->u.kid[5] = kid1 >> 16; 
1111           desc->u.kid[6] = kid1 >>  8; 
1112           desc->u.kid[7] = kid1; 
1113           mode = KEYDB_SEARCH_MODE_LONG_KID;
1114         }
1115       else if (hexlength == 32
1116                || (!hexprefix && hexlength == 33 && *s == '0'))
1117         { /* md5 fingerprint */
1118           int i;
1119           if (hexlength == 33)
1120             s++;
1121           memset(desc->u.fpr+16, 0, 4); 
1122           for (i=0; i < 16; i++, s+=2) 
1123             {
1124               int c = hextobyte(s);
1125               if (c == -1)
1126                 return 0;
1127               desc->u.fpr[i] = c;
1128             }
1129           mode = KEYDB_SEARCH_MODE_FPR16;
1130         }
1131       else if (hexlength == 40
1132                || (!hexprefix && hexlength == 41 && *s == '0'))
1133         { /* sha1/rmd160 fingerprint */
1134           int i;
1135           if (hexlength == 41)
1136             s++;
1137           for (i=0; i < 20; i++, s+=2) 
1138             {
1139               int c = hextobyte(s);
1140               if (c == -1)
1141                 return 0;
1142               desc->u.fpr[i] = c;
1143             }
1144           mode = KEYDB_SEARCH_MODE_FPR20;
1145         }
1146       else if (!hexprefix)
1147         { 
1148           /* The fingerprint in an X.509 listing is often delimited by
1149              colons, so we try to single this case out. */
1150           mode = 0;
1151           hexlength = strspn (s, ":0123456789abcdefABCDEF");
1152           if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) 
1153             {
1154               int i;
1155
1156               for (i=0; i < 20; i++, s += 3) 
1157                 {
1158                   int c = hextobyte(s);
1159                   if (c == -1 || (i < 19 && s[2] != ':'))
1160                     break;
1161                   desc->u.fpr[i] = c;
1162                 }
1163               if (i == 20)
1164                 mode = KEYDB_SEARCH_MODE_FPR20;
1165             }
1166           if (!mode) /* default is substring search */
1167             { 
1168               *force_exact = 0;
1169               desc->u.name = s;
1170               mode = KEYDB_SEARCH_MODE_SUBSTR; 
1171             }
1172         }
1173       else
1174         { /* hex number with a prefix but a wrong length */
1175           return 0;
1176         }
1177     }
1178   
1179   desc->mode = mode;
1180   return mode;
1181 }
1182
1183
1184 int
1185 keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
1186 {
1187   int dummy;
1188   KEYDB_SEARCH_DESC dummy_desc;
1189
1190   if (!desc)
1191     desc = &dummy_desc;
1192
1193   if (!classify_user_id (name, desc, &dummy))
1194     return GNUPG_Invalid_Name;
1195   return 0;
1196 }
1197
1198 \f
1199 /* Store the certificate in the key DB but make sure that it does not
1200    already exists.  We do this simply by comparing the fingerprint.
1201    If EXISTED is not NULL it will be set to true if the certificate
1202    was already in the DB. */
1203 int
1204 keydb_store_cert (KsbaCert cert, int ephemeral, int *existed)
1205 {
1206   KEYDB_HANDLE kh;
1207   int rc;
1208   unsigned char fpr[20];
1209
1210   if (existed)
1211     *existed = 0;
1212
1213   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1214     {
1215       log_error (_("failed to get the fingerprint\n"));
1216       return GNUPG_General_Error;
1217     }
1218
1219   kh = keydb_new (0);
1220   if (!kh)
1221     {
1222       log_error (_("failed to allocate keyDB handle\n"));
1223       return GNUPG_Out_Of_Core;
1224     }
1225
1226   if (ephemeral)
1227     keydb_set_ephemeral (kh, 1);
1228   
1229   rc = keydb_search_fpr (kh, fpr);
1230   if (rc != -1)
1231     {
1232       keydb_release (kh);
1233       if (!rc)
1234         {
1235           if (existed)
1236             *existed = 1;
1237           return 0; /* okay */
1238         }
1239       log_error (_("problem looking for existing certificate: %s\n"),
1240                  gnupg_strerror (rc));
1241       return rc;
1242     }
1243
1244   rc = keydb_locate_writable (kh, 0);
1245   if (rc)
1246     {
1247       log_error (_("error finding writable keyDB: %s\n"), gnupg_strerror (rc));
1248       keydb_release (kh);
1249       return rc;
1250     }
1251
1252   rc = keydb_insert_cert (kh, cert);
1253   if (rc)
1254     {
1255       log_error (_("error storing certificate: %s\n"), gnupg_strerror (rc));
1256       keydb_release (kh);
1257       return rc;
1258     }
1259   keydb_release (kh);               
1260   return 0;
1261 }
1262
1263
1264