1 /* keydb.c - key database dispatcher
2 * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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 3 of the License, or
9 * (at your option) any later version.
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include <sys/types.h>
31 #include "../kbx/keybox.h"
35 static int active_handles;
38 KEYDB_RESOURCE_TYPE_NONE = 0,
39 KEYDB_RESOURCE_TYPE_KEYBOX
41 #define MAX_KEYDB_RESOURCES 20
43 struct resource_item {
44 KeydbResourceType type;
53 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
54 static int used_resources;
61 int used; /* items in active */
62 struct resource_item active[MAX_KEYDB_RESOURCES];
66 static int lock_all (KEYDB_HANDLE hd);
67 static void unlock_all (KEYDB_HANDLE hd);
71 * Register a resource (which currently may only be a keybox file).
72 * The first keybox which is added by this function is created if it
73 * does not exist. If AUTO_CREATED is not NULL it will be set to true
74 * if the function has created a a new keybox.
77 keydb_add_resource (const char *url, int force, int secret, int *auto_created)
79 static int any_secret, any_public;
80 const char *resname = url;
81 char *filename = NULL;
84 KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
90 gnupg-kbx:filename := this is a plain keybox
91 filename := See what is is, but create as plain keybox.
93 if (strlen (resname) > 10)
95 if (!strncmp (resname, "gnupg-kbx:", 10) )
97 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
100 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
101 else if (strchr (resname, ':'))
103 log_error ("invalid key resource URL `%s'\n", url );
104 rc = gpg_error (GPG_ERR_GENERAL);
107 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
110 if (*resname != DIRSEP_C )
111 { /* do tilde expansion etc */
112 if (strchr(resname, DIRSEP_C) )
113 filename = make_filename (resname, NULL);
115 filename = make_filename (opt.homedir, resname, NULL);
118 filename = xstrdup (resname);
121 force = secret? !any_secret : !any_public;
123 /* see whether we can determine the filetype */
124 if (rt == KEYDB_RESOURCE_TYPE_NONE)
126 FILE *fp2 = fopen( filename, "rb" );
131 /* FIXME: check for the keybox magic */
132 if (fread( &magic, 4, 1, fp2) == 1 )
134 if (magic == 0x13579ace || magic == 0xce9a5713)
135 ; /* GDBM magic - no more support */
137 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
139 else /* maybe empty: assume ring */
140 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
143 else /* no file yet: create ring */
144 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
149 case KEYDB_RESOURCE_TYPE_NONE:
150 log_error ("unknown type of key resource `%s'\n", url );
151 rc = gpg_error (GPG_ERR_GENERAL);
154 case KEYDB_RESOURCE_TYPE_KEYBOX:
155 fp = fopen (filename, "rb");
158 rc = gpg_error (gpg_err_code_from_errno (errno));
164 #if 0 /* no autocreate of the homedirectory yet */
166 char *last_slash_in_filename;
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 = gpg_error (GPG_ERR_FILE_OPEN_ERROR);
177 *last_slash_in_filename = DIRSEP_C;
180 *last_slash_in_filename = DIRSEP_C;
183 fp = fopen (filename, "w");
186 rc = gpg_error (gpg_err_code_from_errno (errno));
187 log_error (_("error creating keybox `%s': %s\n"),
188 filename, strerror(errno));
190 log_info (_("you may want to start the gpg-agent first\n"));
195 log_info (_("keybox `%s' created\n"), filename);
201 /* now register the file */
204 void *token = keybox_register_file (filename, secret);
206 ; /* already registered - ignore it */
207 else if (used_resources >= MAX_KEYDB_RESOURCES)
208 rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
211 all_resources[used_resources].type = rt;
212 all_resources[used_resources].u.kr = NULL; /* Not used here */
213 all_resources[used_resources].token = token;
214 all_resources[used_resources].secret = secret;
216 all_resources[used_resources].lockhandle
217 = dotlock_create (filename, 0);
218 if (!all_resources[used_resources].lockhandle)
219 log_fatal ( _("can't create lock for `%s'\n"), filename);
221 /* Do a compress run if needed and the file is not locked. */
222 if (!dotlock_take (all_resources[used_resources].lockhandle, 0))
224 KEYBOX_HANDLE kbxhd = keybox_new (token, secret);
228 keybox_compress (kbxhd);
229 keybox_release (kbxhd);
231 dotlock_release (all_resources[used_resources].lockhandle);
241 log_error ("resource type of `%s' not supported\n", url);
242 rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
246 /* fixme: check directory permissions and print a warning */
250 log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror(rc));
261 keydb_new (int secret)
266 hd = xcalloc (1, sizeof *hd);
269 assert (used_resources <= MAX_KEYDB_RESOURCES);
270 for (i=j=0; i < used_resources; i++)
272 if (!all_resources[i].secret != !secret)
274 switch (all_resources[i].type)
276 case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
278 case KEYDB_RESOURCE_TYPE_KEYBOX:
279 hd->active[j].type = all_resources[i].type;
280 hd->active[j].token = all_resources[i].token;
281 hd->active[j].secret = all_resources[i].secret;
282 hd->active[j].lockhandle = all_resources[i].lockhandle;
283 hd->active[j].u.kr = keybox_new (all_resources[i].token, secret);
284 if (!hd->active[j].u.kr)
287 return NULL; /* fixme: release all previously allocated handles*/
300 keydb_release (KEYDB_HANDLE hd)
306 assert (active_handles > 0);
310 for (i=0; i < hd->used; i++)
312 switch (hd->active[i].type)
314 case KEYDB_RESOURCE_TYPE_NONE:
316 case KEYDB_RESOURCE_TYPE_KEYBOX:
317 keybox_release (hd->active[i].u.kr);
326 /* Return the name of the current resource. This is function first
327 looks for the last found found, then for the current search
328 position, and last returns the first available resource. The
329 returned string is only valid as long as the handle exists. This
330 function does only return NULL if no handle is specified, in all
331 other error cases an empty string is returned. */
333 keydb_get_resource_name (KEYDB_HANDLE hd)
336 const char *s = NULL;
341 if ( hd->found >= 0 && hd->found < hd->used)
343 else if ( hd->current >= 0 && hd->current < hd->used)
348 switch (hd->active[idx].type)
350 case KEYDB_RESOURCE_TYPE_NONE:
353 case KEYDB_RESOURCE_TYPE_KEYBOX:
354 s = keybox_get_resource_name (hd->active[idx].u.kr);
361 /* Switch the handle into ephemeral mode and return the orginal value. */
363 keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
371 if (hd->is_ephemeral != yes)
373 for (i=0; i < hd->used; i++)
375 switch (hd->active[i].type)
377 case KEYDB_RESOURCE_TYPE_NONE:
379 case KEYDB_RESOURCE_TYPE_KEYBOX:
380 keybox_set_ephemeral (hd->active[i].u.kr, yes);
386 i = hd->is_ephemeral;
387 hd->is_ephemeral = yes;
392 /* If the keyring has not yet been locked, lock it now. This
393 operation is required before any update operation; it is optional
394 for an insert operation. The lock is released with
397 keydb_lock (KEYDB_HANDLE hd)
400 return gpg_error (GPG_ERR_INV_HANDLE);
402 return 0; /* Already locked. */
403 return lock_all (hd);
409 lock_all (KEYDB_HANDLE hd)
413 /* Fixme: This locking scheme may lead to deadlock if the resources
414 are not added in the same order by all processes. We are
415 currently only allowing one resource so it is not a problem. */
416 for (i=0; i < hd->used; i++)
418 switch (hd->active[i].type)
420 case KEYDB_RESOURCE_TYPE_NONE:
422 case KEYDB_RESOURCE_TYPE_KEYBOX:
423 if (hd->active[i].lockhandle)
424 rc = dotlock_take (hd->active[i].lockhandle, -1);
433 /* revert the already set locks */
434 for (i--; i >= 0; i--)
436 switch (hd->active[i].type)
438 case KEYDB_RESOURCE_TYPE_NONE:
440 case KEYDB_RESOURCE_TYPE_KEYBOX:
441 if (hd->active[i].lockhandle)
442 dotlock_release (hd->active[i].lockhandle);
450 /* make_dotlock () does not yet guarantee that errno is set, thus
451 we can't rely on the error reason and will simply use
453 return rc? gpg_error (GPG_ERR_EACCES) : 0;
457 unlock_all (KEYDB_HANDLE hd)
464 for (i=hd->used-1; i >= 0; i--)
466 switch (hd->active[i].type)
468 case KEYDB_RESOURCE_TYPE_NONE:
470 case KEYDB_RESOURCE_TYPE_KEYBOX:
471 if (hd->active[i].lockhandle)
472 dotlock_release (hd->active[i].lockhandle);
482 * Return the last found keybox. Caller must free it.
483 * The returned keyblock has the kbode flag bit 0 set for the node with
484 * the public key used to locate the keyblock or flag bit 1 set for
488 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
493 return G10ERR_INV_ARG;
495 if ( hd->found < 0 || hd->found >= hd->used)
496 return -1; /* nothing found */
498 switch (hd->active[hd->found].type) {
499 case KEYDB_RESOURCE_TYPE_NONE:
500 rc = G10ERR_GENERAL; /* oops */
502 case KEYDB_RESOURCE_TYPE_KEYBOX:
503 rc = keybox_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
511 * update the current keyblock with KB
514 keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
519 return G10ERR_INV_ARG;
521 if ( hd->found < 0 || hd->found >= hd->used)
522 return -1; /* nothing found */
528 return gpg_error (GPG_ERR_NOT_LOCKED);
530 switch (hd->active[hd->found].type) {
531 case KEYDB_RESOURCE_TYPE_NONE:
532 rc = G10ERR_GENERAL; /* oops */
534 case KEYDB_RESOURCE_TYPE_KEYBOX:
535 rc = keybox_update_keyblock (hd->active[hd->found].u.kr, kb);
545 * Insert a new KB into one of the resources.
548 keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
554 return G10ERR_INV_ARG;
559 if ( hd->found >= 0 && hd->found < hd->used)
561 else if ( hd->current >= 0 && hd->current < hd->used)
564 return G10ERR_GENERAL;
570 switch (hd->active[idx].type) {
571 case KEYDB_RESOURCE_TYPE_NONE:
572 rc = G10ERR_GENERAL; /* oops */
574 case KEYDB_RESOURCE_TYPE_KEYBOX:
575 rc = keybox_insert_keyblock (hd->active[idx].u.kr, kb);
583 #endif /*disabled code*/
588 Return the last found object. Caller must free it. The returned
589 keyblock has the kbode flag bit 0 set for the node with the public
590 key used to locate the keyblock or flag bit 1 set for the user ID
593 keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert)
598 return gpg_error (GPG_ERR_INV_VALUE);
600 if ( hd->found < 0 || hd->found >= hd->used)
601 return -1; /* nothing found */
603 switch (hd->active[hd->found].type)
605 case KEYDB_RESOURCE_TYPE_NONE:
606 rc = gpg_error (GPG_ERR_GENERAL); /* oops */
608 case KEYDB_RESOURCE_TYPE_KEYBOX:
609 rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert);
616 /* Return a flag of the last found object. WHICH is the flag requested;
617 it should be one of the KEYBOX_FLAG_ values. If the operation is
618 successful, the flag value will be stored at the address given by
619 VALUE. Return 0 on success or an error code. */
621 keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
626 return gpg_error (GPG_ERR_INV_VALUE);
628 if ( hd->found < 0 || hd->found >= hd->used)
629 return gpg_error (GPG_ERR_NOTHING_FOUND);
631 switch (hd->active[hd->found].type)
633 case KEYDB_RESOURCE_TYPE_NONE:
634 err = gpg_error (GPG_ERR_GENERAL); /* oops */
636 case KEYDB_RESOURCE_TYPE_KEYBOX:
637 err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value);
644 /* Set a flag of the last found object. WHICH is the flag to be set; it
645 should be one of the KEYBOX_FLAG_ values. If the operation is
646 successful, the flag value will be stored in the keybox. Note,
647 that some flag values can't be updated and thus may return an
648 error, some other flag values may be masked out before an update.
649 Returns 0 on success or an error code. */
651 keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
656 return gpg_error (GPG_ERR_INV_VALUE);
658 if ( hd->found < 0 || hd->found >= hd->used)
659 return gpg_error (GPG_ERR_NOTHING_FOUND);
662 return gpg_error (GPG_ERR_NOT_LOCKED);
664 switch (hd->active[hd->found].type)
666 case KEYDB_RESOURCE_TYPE_NONE:
667 err = gpg_error (GPG_ERR_GENERAL); /* oops */
669 case KEYDB_RESOURCE_TYPE_KEYBOX:
670 err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value);
678 * Insert a new Certificate into one of the resources.
681 keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
685 unsigned char digest[20];
688 return gpg_error (GPG_ERR_INV_VALUE);
693 if ( hd->found >= 0 && hd->found < hd->used)
695 else if ( hd->current >= 0 && hd->current < hd->used)
698 return gpg_error (GPG_ERR_GENERAL);
701 return gpg_error (GPG_ERR_NOT_LOCKED);
703 gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
705 switch (hd->active[idx].type)
707 case KEYDB_RESOURCE_TYPE_NONE:
708 rc = gpg_error (GPG_ERR_GENERAL);
710 case KEYDB_RESOURCE_TYPE_KEYBOX:
711 rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
721 /* Update the current keyblock with KB. */
723 keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
726 unsigned char digest[20];
729 return gpg_error (GPG_ERR_INV_VALUE);
731 if ( hd->found < 0 || hd->found >= hd->used)
732 return -1; /* nothing found */
741 gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
743 switch (hd->active[hd->found].type)
745 case KEYDB_RESOURCE_TYPE_NONE:
746 rc = gpg_error (GPG_ERR_GENERAL); /* oops */
748 case KEYDB_RESOURCE_TYPE_KEYBOX:
749 rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
759 * The current keyblock or cert will be deleted.
762 keydb_delete (KEYDB_HANDLE hd, int unlock)
767 return gpg_error (GPG_ERR_INV_VALUE);
769 if ( hd->found < 0 || hd->found >= hd->used)
770 return -1; /* nothing found */
776 return gpg_error (GPG_ERR_NOT_LOCKED);
778 switch (hd->active[hd->found].type)
780 case KEYDB_RESOURCE_TYPE_NONE:
781 rc = gpg_error (GPG_ERR_GENERAL);
783 case KEYDB_RESOURCE_TYPE_KEYBOX:
784 rc = keybox_delete (hd->active[hd->found].u.kr);
796 * Locate the default writable key resource, so that the next
797 * operation (which is only relevant for inserts) will be done on this
801 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
808 return gpg_error (GPG_ERR_INV_VALUE);
810 rc = keydb_search_reset (hd); /* this does reset hd->current */
814 for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
816 switch (hd->active[hd->current].type)
818 case KEYDB_RESOURCE_TYPE_NONE:
821 case KEYDB_RESOURCE_TYPE_KEYBOX:
822 if (keybox_is_writable (hd->active[hd->current].token))
823 return 0; /* found (hd->current is set to it) */
832 * Rebuild the caches of all key resources.
835 keydb_rebuild_caches (void)
839 for (i=0; i < used_resources; i++)
841 if (all_resources[i].secret)
843 switch (all_resources[i].type)
845 case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
847 case KEYDB_RESOURCE_TYPE_KEYBOX:
848 /* rc = keybox_rebuild_cache (all_resources[i].token); */
850 /* log_error (_("failed to rebuild keybox cache: %s\n"), */
851 /* g10_errstr (rc)); */
860 * Start the next search on this handle right at the beginning
863 keydb_search_reset (KEYDB_HANDLE hd)
868 return gpg_error (GPG_ERR_INV_VALUE);
872 /* and reset all resources */
873 for (i=0; !rc && i < hd->used; i++)
875 switch (hd->active[i].type)
877 case KEYDB_RESOURCE_TYPE_NONE:
879 case KEYDB_RESOURCE_TYPE_KEYBOX:
880 rc = keybox_search_reset (hd->active[i].u.kr);
884 return rc; /* fixme: we need to map error codes or share them with
889 * Search through all keydb resources, starting at the current position,
890 * for a keyblock which contains one of the keys described in the DESC array.
893 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
898 return gpg_error (GPG_ERR_INV_VALUE);
900 while (rc == -1 && hd->current >= 0 && hd->current < hd->used)
902 switch (hd->active[hd->current].type)
904 case KEYDB_RESOURCE_TYPE_NONE:
905 BUG(); /* we should never see it here */
907 case KEYDB_RESOURCE_TYPE_KEYBOX:
908 rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc);
911 if (rc == -1) /* EOF -> switch to next resource */
914 hd->found = hd->current;
922 keydb_search_first (KEYDB_HANDLE hd)
924 KEYDB_SEARCH_DESC desc;
926 memset (&desc, 0, sizeof desc);
927 desc.mode = KEYDB_SEARCH_MODE_FIRST;
928 return keydb_search (hd, &desc, 1);
932 keydb_search_next (KEYDB_HANDLE hd)
934 KEYDB_SEARCH_DESC desc;
936 memset (&desc, 0, sizeof desc);
937 desc.mode = KEYDB_SEARCH_MODE_NEXT;
938 return keydb_search (hd, &desc, 1);
942 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
944 KEYDB_SEARCH_DESC desc;
948 memset (&desc, 0, sizeof desc);
949 desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
950 desc.u.kid[0] = kid[0];
951 desc.u.kid[1] = kid[1];
952 return keydb_search (hd, &desc, 1);
956 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
958 KEYDB_SEARCH_DESC desc;
960 memset (&desc, 0, sizeof desc);
961 desc.mode = KEYDB_SEARCH_MODE_FPR;
962 memcpy (desc.u.fpr, fpr, 20);
963 return keydb_search (hd, &desc, 1);
967 keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer)
969 KEYDB_SEARCH_DESC desc;
972 memset (&desc, 0, sizeof desc);
973 desc.mode = KEYDB_SEARCH_MODE_ISSUER;
974 desc.u.name = issuer;
975 rc = keydb_search (hd, &desc, 1);
980 keydb_search_issuer_sn (KEYDB_HANDLE hd,
981 const char *issuer, ksba_const_sexp_t serial)
983 KEYDB_SEARCH_DESC desc;
985 const unsigned char *s;
987 memset (&desc, 0, sizeof desc);
988 desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
991 return gpg_error (GPG_ERR_INV_VALUE);
993 for (desc.snlen = 0; digitp (s); s++)
994 desc.snlen = 10*desc.snlen + atoi_1 (s);
996 return gpg_error (GPG_ERR_INV_VALUE);
998 desc.u.name = issuer;
999 rc = keydb_search (hd, &desc, 1);
1004 keydb_search_subject (KEYDB_HANDLE hd, const char *name)
1006 KEYDB_SEARCH_DESC desc;
1009 memset (&desc, 0, sizeof desc);
1010 desc.mode = KEYDB_SEARCH_MODE_SUBJECT;
1012 rc = keydb_search (hd, &desc, 1);
1018 /* Store the certificate in the key DB but make sure that it does not
1019 already exists. We do this simply by comparing the fingerprint.
1020 If EXISTED is not NULL it will be set to true if the certificate
1021 was already in the DB. */
1023 keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
1027 unsigned char fpr[20];
1032 if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1034 log_error (_("failed to get the fingerprint\n"));
1035 return gpg_error (GPG_ERR_GENERAL);
1041 log_error (_("failed to allocate keyDB handle\n"));
1042 return gpg_error (GPG_ERR_ENOMEM);;
1046 keydb_set_ephemeral (kh, 1);
1052 rc = keydb_search_fpr (kh, fpr);
1060 return 0; /* okay */
1062 log_error (_("problem looking for existing certificate: %s\n"),
1067 rc = keydb_locate_writable (kh, 0);
1070 log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
1075 rc = keydb_insert_cert (kh, cert);
1078 log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
1087 /* This is basically keydb_set_flags but it implements a complete
1088 transaction by locating the certificate in the DB and updating the
1091 keydb_set_cert_flags (ksba_cert_t cert, int ephemeral,
1093 unsigned int mask, unsigned int value)
1097 unsigned char fpr[20];
1098 unsigned int old_value;
1100 if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1102 log_error (_("failed to get the fingerprint\n"));
1103 return gpg_error (GPG_ERR_GENERAL);
1109 log_error (_("failed to allocate keyDB handle\n"));
1110 return gpg_error (GPG_ERR_ENOMEM);;
1114 keydb_set_ephemeral (kh, 1);
1116 err = keydb_lock (kh);
1119 log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1124 err = keydb_search_fpr (kh, fpr);
1128 err = gpg_error (GPG_ERR_NOT_FOUND);
1130 log_error (_("problem re-searching certificate: %s\n"),
1131 gpg_strerror (err));
1136 err = keydb_get_flags (kh, which, idx, &old_value);
1139 log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
1144 value = ((old_value & ~mask) | (value & mask));
1146 if (value != old_value)
1148 err = keydb_set_flags (kh, which, idx, value);
1151 log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1162 /* Reset all the certificate flags we have stored with the certificates
1163 for performance reasons. */
1165 keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
1168 KEYDB_HANDLE hd = NULL;
1169 KEYDB_SEARCH_DESC *desc = NULL;
1173 unsigned int old_value, value;
1180 log_error ("keydb_new failed\n");
1188 for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1192 desc = xtrycalloc (ndesc, sizeof *desc);
1195 log_error ("allocating memory failed: %s\n",
1196 gpg_strerror (out_of_core ()));
1201 desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1204 for (ndesc=0, sl=names; sl; sl = sl->next)
1206 rc = classify_user_id (sl->d, desc+ndesc, 0);
1209 log_error ("key `%s' not found: %s\n",
1210 sl->d, gpg_strerror (rc));
1218 err = keydb_lock (hd);
1221 log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1225 while (!(rc = keydb_search (hd, desc, ndesc)))
1228 desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1230 err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
1233 log_error (_("error getting stored flags: %s\n"),
1234 gpg_strerror (err));
1238 value = (old_value & ~VALIDITY_REVOKED);
1239 if (value != old_value)
1241 err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
1244 log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1250 log_error ("keydb_search failed: %s\n", gpg_strerror (rc));