1 /* keydb.c - key database dispatcher
2 * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
3 * Copyright (C) 2014 g10 Code GmbH
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
27 #include <sys/types.h>
32 #include "../kbx/keybox.h"
36 static int active_handles;
39 KEYDB_RESOURCE_TYPE_NONE = 0,
40 KEYDB_RESOURCE_TYPE_KEYBOX
42 #define MAX_KEYDB_RESOURCES 20
44 struct resource_item {
45 KeydbResourceType type;
53 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
54 static int used_resources;
56 /* Whether we have successfully registered any resource. */
57 static int any_registered;
66 int used; /* items in active */
67 struct resource_item active[MAX_KEYDB_RESOURCES];
71 static int lock_all (KEYDB_HANDLE hd);
72 static void unlock_all (KEYDB_HANDLE hd);
76 try_make_homedir (const char *fname)
78 const char *defhome = standard_homedir ();
80 /* Create the directory only if the supplied directory name is the
81 same as the default one. This way we avoid to create arbitrary
82 directories when a non-default home directory is used. To cope
83 with HOME, we do compare only the suffix if we see that the
84 default homedir does start with a tilde. */
85 if ( opt.dry_run || opt.no_homedir_creation )
89 #ifdef HAVE_W32_SYSTEM
90 ( !compare_filenames (fname, defhome) )
93 && (strlen(fname) >= strlen (defhome+1)
94 && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) ))
95 || (*defhome != '~' && !compare_filenames( fname, defhome ) )
99 if (gnupg_mkdir (fname, "-rwx"))
100 log_info (_("can't create directory '%s': %s\n"),
101 fname, strerror(errno) );
102 else if (!opt.quiet )
103 log_info (_("directory '%s' created\n"), fname);
108 /* Handle the creation of a keybox if it does not yet exist. Take
109 into acount that other processes might have the keybox already
110 locked. This lock check does not work if the directory itself is
111 not yet available. If R_CREATED is not NULL it will be set to true
112 if the function created a new keybox. */
114 maybe_create_keybox (char *filename, int force, int *r_created)
116 dotlock_t lockhd = NULL;
120 char *last_slash_in_filename;
126 /* A quick test whether the filename already exists. */
127 if (!access (filename, F_OK))
128 return !access (filename, R_OK)? 0 : gpg_error (GPG_ERR_EACCES);
130 /* If we don't want to create a new file at all, there is no need to
131 go any further - bail out right here. */
133 return gpg_error (GPG_ERR_ENOENT);
135 /* First of all we try to create the home directory. Note, that we
136 don't do any locking here because any sane application of gpg
137 would create the home directory by itself and not rely on gpg's
138 tricky auto-creation which is anyway only done for some home
139 directory name patterns. */
140 last_slash_in_filename = strrchr (filename, DIRSEP_C);
143 /* Windows may either have a slash or a backslash. Take care of it. */
144 char *p = strrchr (filename, '/');
145 if (!last_slash_in_filename || p > last_slash_in_filename)
146 last_slash_in_filename = p;
148 #endif /*HAVE_W32_SYSTEM*/
149 if (!last_slash_in_filename)
150 return gpg_error (GPG_ERR_ENOENT); /* No slash at all - should
151 not happen though. */
152 save_slash = *last_slash_in_filename;
153 *last_slash_in_filename = 0;
154 if (access(filename, F_OK))
161 try_make_homedir (filename);
163 if (access (filename, F_OK))
165 rc = gpg_error_from_syserror ();
166 *last_slash_in_filename = save_slash;
170 *last_slash_in_filename = save_slash;
172 /* To avoid races with other instances of gpg trying to create or
173 update the keybox (it is removed during an update for a short
174 time), we do the next stuff in a locked state. */
175 lockhd = dotlock_create (filename, 0);
178 /* A reason for this to fail is that the directory is not
179 writable. However, this whole locking stuff does not make
180 sense if this is the case. An empty non-writable directory
181 with no keyring is not really useful at all. */
183 log_info ("can't allocate lock for '%s'\n", filename );
186 return gpg_error (GPG_ERR_ENOENT);
188 return gpg_error (GPG_ERR_GENERAL);
191 if ( dotlock_take (lockhd, -1) )
193 /* This is something bad. Probably a stale lockfile. */
194 log_info ("can't lock '%s'\n", filename);
195 rc = gpg_error (GPG_ERR_GENERAL);
199 /* Now the real test while we are locked. */
200 if (!access(filename, F_OK))
202 rc = 0; /* Okay, we may access the file now. */
206 /* The file does not yet exist, create it now. */
207 oldmask = umask (077);
208 fp = fopen (filename, "w");
211 rc = gpg_error_from_syserror ();
213 log_error (_("error creating keybox '%s': %s\n"),
214 filename, gpg_strerror (rc));
219 /* Make sure that at least one record is in a new keybox file, so
220 that the detection magic for OpenPGP keyboxes works the next time
222 rc = _keybox_write_header_blob (fp, 0);
226 log_error (_("error creating keybox '%s': %s\n"),
227 filename, gpg_strerror (rc));
232 log_info (_("keybox '%s' created\n"), filename);
242 dotlock_release (lockhd);
243 dotlock_destroy (lockhd);
250 * Register a resource (which currently may only be a keybox file).
251 * The first keybox which is added by this function is created if it
252 * does not exist. If AUTO_CREATED is not NULL it will be set to true
253 * if the function has created a new keybox.
256 keydb_add_resource (ctrl_t ctrl, const char *url, int force, int *auto_created)
258 const char *resname = url;
259 char *filename = NULL;
261 KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
266 /* Do we have an URL?
267 gnupg-kbx:filename := this is a plain keybox
268 filename := See what is is, but create as plain keybox.
270 if (strlen (resname) > 10)
272 if (!strncmp (resname, "gnupg-kbx:", 10) )
274 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
277 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
278 else if (strchr (resname, ':'))
280 log_error ("invalid key resource URL '%s'\n", url );
281 err = gpg_error (GPG_ERR_GENERAL);
284 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
287 if (*resname != DIRSEP_C )
288 { /* do tilde expansion etc */
289 if (strchr(resname, DIRSEP_C) )
290 filename = make_filename (resname, NULL);
292 filename = make_filename (gnupg_homedir (), resname, NULL);
295 filename = xstrdup (resname);
298 force = !any_registered;
300 /* see whether we can determine the filetype */
301 if (rt == KEYDB_RESOURCE_TYPE_NONE)
303 FILE *fp = fopen( filename, "rb" );
309 /* FIXME: check for the keybox magic */
310 if (fread (&magic, 4, 1, fp) == 1 )
312 if (magic == 0x13579ace || magic == 0xce9a5713)
313 ; /* GDBM magic - no more support */
315 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
317 else /* maybe empty: assume keybox */
318 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
321 else /* no file yet: create keybox */
322 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
327 case KEYDB_RESOURCE_TYPE_NONE:
328 log_error ("unknown type of key resource '%s'\n", url );
329 err = gpg_error (GPG_ERR_GENERAL);
332 case KEYDB_RESOURCE_TYPE_KEYBOX:
333 err = maybe_create_keybox (filename, force, auto_created);
336 /* Now register the file */
340 err = keybox_register_file (filename, 0, &token);
341 if (gpg_err_code (err) == GPG_ERR_EEXIST)
342 ; /* Already registered - ignore. */
345 else if (used_resources >= MAX_KEYDB_RESOURCES)
346 err = gpg_error (GPG_ERR_RESOURCE_LIMIT);
349 all_resources[used_resources].type = rt;
350 all_resources[used_resources].u.kr = NULL; /* Not used here */
351 all_resources[used_resources].token = token;
353 all_resources[used_resources].lockhandle
354 = dotlock_create (filename, 0);
355 if (!all_resources[used_resources].lockhandle)
356 log_fatal ( _("can't create lock for '%s'\n"), filename);
358 /* Do a compress run if needed and the file is not locked. */
359 if (!dotlock_take (all_resources[used_resources].lockhandle, 0))
361 KEYBOX_HANDLE kbxhd = keybox_new_x509 (token, 0);
365 keybox_compress (kbxhd);
366 keybox_release (kbxhd);
368 dotlock_release (all_resources[used_resources].lockhandle);
377 log_error ("resource type of '%s' not supported\n", url);
378 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
382 /* fixme: check directory permissions and print a warning */
387 log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror (err));
388 gpgsm_status_with_error (ctrl, STATUS_ERROR,
389 "add_keyblock_resource", err);
404 hd = xcalloc (1, sizeof *hd);
406 hd->saved_found = -1;
408 assert (used_resources <= MAX_KEYDB_RESOURCES);
409 for (i=j=0; i < used_resources; i++)
411 switch (all_resources[i].type)
413 case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
415 case KEYDB_RESOURCE_TYPE_KEYBOX:
416 hd->active[j].type = all_resources[i].type;
417 hd->active[j].token = all_resources[i].token;
418 hd->active[j].lockhandle = all_resources[i].lockhandle;
419 hd->active[j].u.kr = keybox_new_x509 (all_resources[i].token, 0);
420 if (!hd->active[j].u.kr)
423 return NULL; /* fixme: release all previously allocated handles*/
436 keydb_release (KEYDB_HANDLE hd)
442 assert (active_handles > 0);
446 for (i=0; i < hd->used; i++)
448 switch (hd->active[i].type)
450 case KEYDB_RESOURCE_TYPE_NONE:
452 case KEYDB_RESOURCE_TYPE_KEYBOX:
453 keybox_release (hd->active[i].u.kr);
462 /* Return the name of the current resource. This is function first
463 looks for the last found found, then for the current search
464 position, and last returns the first available resource. The
465 returned string is only valid as long as the handle exists. This
466 function does only return NULL if no handle is specified, in all
467 other error cases an empty string is returned. */
469 keydb_get_resource_name (KEYDB_HANDLE hd)
472 const char *s = NULL;
477 if ( hd->found >= 0 && hd->found < hd->used)
479 else if ( hd->current >= 0 && hd->current < hd->used)
484 switch (hd->active[idx].type)
486 case KEYDB_RESOURCE_TYPE_NONE:
489 case KEYDB_RESOURCE_TYPE_KEYBOX:
490 s = keybox_get_resource_name (hd->active[idx].u.kr);
497 /* Switch the handle into ephemeral mode and return the original value. */
499 keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
507 if (hd->is_ephemeral != yes)
509 for (i=0; i < hd->used; i++)
511 switch (hd->active[i].type)
513 case KEYDB_RESOURCE_TYPE_NONE:
515 case KEYDB_RESOURCE_TYPE_KEYBOX:
516 keybox_set_ephemeral (hd->active[i].u.kr, yes);
522 i = hd->is_ephemeral;
523 hd->is_ephemeral = yes;
528 /* If the keyring has not yet been locked, lock it now. This
529 operation is required before any update operation; it is optional
530 for an insert operation. The lock is released with
533 keydb_lock (KEYDB_HANDLE hd)
536 return gpg_error (GPG_ERR_INV_HANDLE);
538 return 0; /* Already locked. */
539 return lock_all (hd);
545 lock_all (KEYDB_HANDLE hd)
549 /* Fixme: This locking scheme may lead to deadlock if the resources
550 are not added in the same order by all processes. We are
551 currently only allowing one resource so it is not a problem. */
552 for (i=0; i < hd->used; i++)
554 switch (hd->active[i].type)
556 case KEYDB_RESOURCE_TYPE_NONE:
558 case KEYDB_RESOURCE_TYPE_KEYBOX:
559 if (hd->active[i].lockhandle)
560 rc = dotlock_take (hd->active[i].lockhandle, -1);
569 /* revert the already set locks */
570 for (i--; i >= 0; i--)
572 switch (hd->active[i].type)
574 case KEYDB_RESOURCE_TYPE_NONE:
576 case KEYDB_RESOURCE_TYPE_KEYBOX:
577 if (hd->active[i].lockhandle)
578 dotlock_release (hd->active[i].lockhandle);
586 /* make_dotlock () does not yet guarantee that errno is set, thus
587 we can't rely on the error reason and will simply use
589 return rc? gpg_error (GPG_ERR_EACCES) : 0;
593 unlock_all (KEYDB_HANDLE hd)
600 for (i=hd->used-1; i >= 0; i--)
602 switch (hd->active[i].type)
604 case KEYDB_RESOURCE_TYPE_NONE:
606 case KEYDB_RESOURCE_TYPE_KEYBOX:
607 if (hd->active[i].lockhandle)
608 dotlock_release (hd->active[i].lockhandle);
617 /* Push the last found state if any. */
619 keydb_push_found_state (KEYDB_HANDLE hd)
624 if (hd->found < 0 || hd->found >= hd->used)
626 hd->saved_found = -1;
630 switch (hd->active[hd->found].type)
632 case KEYDB_RESOURCE_TYPE_NONE:
634 case KEYDB_RESOURCE_TYPE_KEYBOX:
635 keybox_push_found_state (hd->active[hd->found].u.kr);
639 hd->saved_found = hd->found;
644 /* Pop the last found state. */
646 keydb_pop_found_state (KEYDB_HANDLE hd)
651 hd->found = hd->saved_found;
652 hd->saved_found = -1;
653 if (hd->found < 0 || hd->found >= hd->used)
656 switch (hd->active[hd->found].type)
658 case KEYDB_RESOURCE_TYPE_NONE:
660 case KEYDB_RESOURCE_TYPE_KEYBOX:
661 keybox_pop_found_state (hd->active[hd->found].u.kr);
669 Return the last found object. Caller must free it. The returned
670 keyblock has the kbode flag bit 0 set for the node with the public
671 key used to locate the keyblock or flag bit 1 set for the user ID
674 keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert)
679 return gpg_error (GPG_ERR_INV_VALUE);
681 if ( hd->found < 0 || hd->found >= hd->used)
682 return -1; /* nothing found */
684 switch (hd->active[hd->found].type)
686 case KEYDB_RESOURCE_TYPE_NONE:
687 rc = gpg_error (GPG_ERR_GENERAL); /* oops */
689 case KEYDB_RESOURCE_TYPE_KEYBOX:
690 rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert);
697 /* Return a flag of the last found object. WHICH is the flag requested;
698 it should be one of the KEYBOX_FLAG_ values. If the operation is
699 successful, the flag value will be stored at the address given by
700 VALUE. Return 0 on success or an error code. */
702 keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
707 return gpg_error (GPG_ERR_INV_VALUE);
709 if ( hd->found < 0 || hd->found >= hd->used)
710 return gpg_error (GPG_ERR_NOTHING_FOUND);
712 switch (hd->active[hd->found].type)
714 case KEYDB_RESOURCE_TYPE_NONE:
715 err = gpg_error (GPG_ERR_GENERAL); /* oops */
717 case KEYDB_RESOURCE_TYPE_KEYBOX:
718 err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value);
725 /* Set a flag of the last found object. WHICH is the flag to be set; it
726 should be one of the KEYBOX_FLAG_ values. If the operation is
727 successful, the flag value will be stored in the keybox. Note,
728 that some flag values can't be updated and thus may return an
729 error, some other flag values may be masked out before an update.
730 Returns 0 on success or an error code. */
732 keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
737 return gpg_error (GPG_ERR_INV_VALUE);
739 if ( hd->found < 0 || hd->found >= hd->used)
740 return gpg_error (GPG_ERR_NOTHING_FOUND);
743 return gpg_error (GPG_ERR_NOT_LOCKED);
745 switch (hd->active[hd->found].type)
747 case KEYDB_RESOURCE_TYPE_NONE:
748 err = gpg_error (GPG_ERR_GENERAL); /* oops */
750 case KEYDB_RESOURCE_TYPE_KEYBOX:
751 err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value);
759 * Insert a new Certificate into one of the resources.
762 keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
766 unsigned char digest[20];
769 return gpg_error (GPG_ERR_INV_VALUE);
774 if ( hd->found >= 0 && hd->found < hd->used)
776 else if ( hd->current >= 0 && hd->current < hd->used)
779 return gpg_error (GPG_ERR_GENERAL);
782 return gpg_error (GPG_ERR_NOT_LOCKED);
784 gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
786 switch (hd->active[idx].type)
788 case KEYDB_RESOURCE_TYPE_NONE:
789 rc = gpg_error (GPG_ERR_GENERAL);
791 case KEYDB_RESOURCE_TYPE_KEYBOX:
792 rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
802 /* Update the current keyblock with KB. */
804 keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
807 unsigned char digest[20];
810 return gpg_error (GPG_ERR_INV_VALUE);
812 if ( hd->found < 0 || hd->found >= hd->used)
813 return -1; /* nothing found */
822 gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
824 switch (hd->active[hd->found].type)
826 case KEYDB_RESOURCE_TYPE_NONE:
827 rc = gpg_error (GPG_ERR_GENERAL); /* oops */
829 case KEYDB_RESOURCE_TYPE_KEYBOX:
830 rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
840 * The current keyblock or cert will be deleted.
843 keydb_delete (KEYDB_HANDLE hd, int unlock)
848 return gpg_error (GPG_ERR_INV_VALUE);
850 if ( hd->found < 0 || hd->found >= hd->used)
851 return -1; /* nothing found */
857 return gpg_error (GPG_ERR_NOT_LOCKED);
859 switch (hd->active[hd->found].type)
861 case KEYDB_RESOURCE_TYPE_NONE:
862 rc = gpg_error (GPG_ERR_GENERAL);
864 case KEYDB_RESOURCE_TYPE_KEYBOX:
865 rc = keybox_delete (hd->active[hd->found].u.kr);
877 * Locate the default writable key resource, so that the next
878 * operation (which is only relevant for inserts) will be done on this
882 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
889 return gpg_error (GPG_ERR_INV_VALUE);
891 rc = keydb_search_reset (hd); /* this does reset hd->current */
895 for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
897 switch (hd->active[hd->current].type)
899 case KEYDB_RESOURCE_TYPE_NONE:
902 case KEYDB_RESOURCE_TYPE_KEYBOX:
903 if (keybox_is_writable (hd->active[hd->current].token))
904 return 0; /* found (hd->current is set to it) */
913 * Rebuild the caches of all key resources.
916 keydb_rebuild_caches (void)
920 for (i=0; i < used_resources; i++)
922 switch (all_resources[i].type)
924 case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
926 case KEYDB_RESOURCE_TYPE_KEYBOX:
927 /* rc = keybox_rebuild_cache (all_resources[i].token); */
929 /* log_error (_("failed to rebuild keybox cache: %s\n"), */
930 /* g10_errstr (rc)); */
939 * Start the next search on this handle right at the beginning
942 keydb_search_reset (KEYDB_HANDLE hd)
948 return gpg_error (GPG_ERR_INV_VALUE);
952 /* and reset all resources */
953 for (i=0; !rc && i < hd->used; i++)
955 switch (hd->active[i].type)
957 case KEYDB_RESOURCE_TYPE_NONE:
959 case KEYDB_RESOURCE_TYPE_KEYBOX:
960 rc = keybox_search_reset (hd->active[i].u.kr);
968 * Search through all keydb resources, starting at the current position,
969 * for a keyblock which contains one of the keys described in the DESC array.
972 keydb_search (ctrl_t ctrl, KEYDB_HANDLE hd,
973 KEYDB_SEARCH_DESC *desc, size_t ndesc)
976 unsigned long skipped;
979 return gpg_error (GPG_ERR_INV_VALUE);
983 gpgsm_status_with_error (ctrl, STATUS_ERROR, "keydb_search",
984 gpg_error (GPG_ERR_KEYRING_OPEN));
985 return gpg_error (GPG_ERR_NOT_FOUND);
988 while (rc == -1 && hd->current >= 0 && hd->current < hd->used)
990 switch (hd->active[hd->current].type)
992 case KEYDB_RESOURCE_TYPE_NONE:
993 BUG(); /* we should never see it here */
995 case KEYDB_RESOURCE_TYPE_KEYBOX:
996 rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc,
997 KEYBOX_BLOBTYPE_X509,
1001 if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
1002 { /* EOF -> switch to next resource */
1006 hd->found = hd->current;
1014 keydb_search_first (ctrl_t ctrl, KEYDB_HANDLE hd)
1016 KEYDB_SEARCH_DESC desc;
1018 memset (&desc, 0, sizeof desc);
1019 desc.mode = KEYDB_SEARCH_MODE_FIRST;
1020 return keydb_search (ctrl, hd, &desc, 1);
1024 keydb_search_next (ctrl_t ctrl, KEYDB_HANDLE hd)
1026 KEYDB_SEARCH_DESC desc;
1028 memset (&desc, 0, sizeof desc);
1029 desc.mode = KEYDB_SEARCH_MODE_NEXT;
1030 return keydb_search (ctrl, hd, &desc, 1);
1034 keydb_search_kid (ctrl_t ctrl, KEYDB_HANDLE hd, u32 *kid)
1036 KEYDB_SEARCH_DESC desc;
1040 memset (&desc, 0, sizeof desc);
1041 desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
1042 desc.u.kid[0] = kid[0];
1043 desc.u.kid[1] = kid[1];
1044 return keydb_search (ctrl, hd, &desc, 1);
1048 keydb_search_fpr (ctrl_t ctrl, KEYDB_HANDLE hd, const byte *fpr)
1050 KEYDB_SEARCH_DESC desc;
1052 memset (&desc, 0, sizeof desc);
1053 desc.mode = KEYDB_SEARCH_MODE_FPR;
1054 memcpy (desc.u.fpr, fpr, 20);
1055 return keydb_search (ctrl, hd, &desc, 1);
1059 keydb_search_issuer (ctrl_t ctrl, KEYDB_HANDLE hd, const char *issuer)
1061 KEYDB_SEARCH_DESC desc;
1064 memset (&desc, 0, sizeof desc);
1065 desc.mode = KEYDB_SEARCH_MODE_ISSUER;
1066 desc.u.name = issuer;
1067 rc = keydb_search (ctrl, hd, &desc, 1);
1072 keydb_search_issuer_sn (ctrl_t ctrl, KEYDB_HANDLE hd,
1073 const char *issuer, ksba_const_sexp_t serial)
1075 KEYDB_SEARCH_DESC desc;
1077 const unsigned char *s;
1079 memset (&desc, 0, sizeof desc);
1080 desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
1083 return gpg_error (GPG_ERR_INV_VALUE);
1085 for (desc.snlen = 0; digitp (s); s++)
1086 desc.snlen = 10*desc.snlen + atoi_1 (s);
1088 return gpg_error (GPG_ERR_INV_VALUE);
1090 desc.u.name = issuer;
1091 rc = keydb_search (ctrl, hd, &desc, 1);
1096 keydb_search_subject (ctrl_t ctrl, KEYDB_HANDLE hd, const char *name)
1098 KEYDB_SEARCH_DESC desc;
1101 memset (&desc, 0, sizeof desc);
1102 desc.mode = KEYDB_SEARCH_MODE_SUBJECT;
1104 rc = keydb_search (ctrl, hd, &desc, 1);
1110 /* Store the certificate in the key DB but make sure that it does not
1111 already exists. We do this simply by comparing the fingerprint.
1112 If EXISTED is not NULL it will be set to true if the certificate
1113 was already in the DB. */
1115 keydb_store_cert (ctrl_t ctrl, ksba_cert_t cert, int ephemeral, int *existed)
1119 unsigned char fpr[20];
1124 if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1126 log_error (_("failed to get the fingerprint\n"));
1127 return gpg_error (GPG_ERR_GENERAL);
1133 log_error (_("failed to allocate keyDB handle\n"));
1134 return gpg_error (GPG_ERR_ENOMEM);;
1137 /* Set the ephemeral flag so that the search looks at all
1139 keydb_set_ephemeral (kh, 1);
1145 rc = keydb_search_fpr (ctrl, kh, fpr);
1155 /* Remove ephemeral flags from existing certificate to "store"
1157 rc = keydb_set_cert_flags (ctrl, cert, 1, KEYBOX_FLAG_BLOB, 0,
1158 KEYBOX_FLAG_BLOB_EPHEMERAL, 0);
1161 log_error ("clearing ephemeral flag failed: %s\n",
1166 return 0; /* okay */
1168 log_error (_("problem looking for existing certificate: %s\n"),
1173 /* Reset the ephemeral flag if not requested. */
1175 keydb_set_ephemeral (kh, 0);
1177 rc = keydb_locate_writable (kh, 0);
1180 log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
1185 rc = keydb_insert_cert (kh, cert);
1188 log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
1197 /* This is basically keydb_set_flags but it implements a complete
1198 transaction by locating the certificate in the DB and updating the
1201 keydb_set_cert_flags (ctrl_t ctrl, ksba_cert_t cert, int ephemeral,
1203 unsigned int mask, unsigned int value)
1207 unsigned char fpr[20];
1208 unsigned int old_value;
1210 if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1212 log_error (_("failed to get the fingerprint\n"));
1213 return gpg_error (GPG_ERR_GENERAL);
1219 log_error (_("failed to allocate keyDB handle\n"));
1220 return gpg_error (GPG_ERR_ENOMEM);;
1224 keydb_set_ephemeral (kh, 1);
1226 err = keydb_lock (kh);
1229 log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1234 err = keydb_search_fpr (ctrl, kh, fpr);
1238 err = gpg_error (GPG_ERR_NOT_FOUND);
1240 log_error (_("problem re-searching certificate: %s\n"),
1241 gpg_strerror (err));
1246 err = keydb_get_flags (kh, which, idx, &old_value);
1249 log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
1254 value = ((old_value & ~mask) | (value & mask));
1256 if (value != old_value)
1258 err = keydb_set_flags (kh, which, idx, value);
1261 log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1272 /* Reset all the certificate flags we have stored with the certificates
1273 for performance reasons. */
1275 keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
1278 KEYDB_HANDLE hd = NULL;
1279 KEYDB_SEARCH_DESC *desc = NULL;
1283 unsigned int old_value, value;
1290 log_error ("keydb_new failed\n");
1298 for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1302 desc = xtrycalloc (ndesc, sizeof *desc);
1305 log_error ("allocating memory failed: %s\n",
1306 gpg_strerror (out_of_core ()));
1311 desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1314 for (ndesc=0, sl=names; sl; sl = sl->next)
1316 rc = classify_user_id (sl->d, desc+ndesc, 0);
1318 log_error ("key '%s' not found: %s\n", sl->d, gpg_strerror (rc));
1324 err = keydb_lock (hd);
1327 log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1331 while (!(rc = keydb_search (ctrl, hd, desc, ndesc)))
1334 desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1336 err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
1339 log_error (_("error getting stored flags: %s\n"),
1340 gpg_strerror (err));
1344 value = (old_value & ~VALIDITY_REVOKED);
1345 if (value != old_value)
1347 err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
1350 log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1356 log_error ("keydb_search failed: %s\n", gpg_strerror (rc));