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