summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/gpgsm.texi9
-rw-r--r--sm/ChangeLog7
-rw-r--r--sm/gpgsm.c11
-rw-r--r--sm/keydb.c101
-rw-r--r--sm/keydb.h2
5 files changed, 127 insertions, 3 deletions
diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi
index a0da96d56..b5c87b77c 100644
--- a/doc/gpgsm.texi
+++ b/doc/gpgsm.texi
@@ -161,6 +161,15 @@ List certificates matching @var{pattern} using an external server.
This utilizes the @code{dirmngr} service. It uses a format useful
mainly for debugging.
+@item --keydb-clear-some-cert-flags
+@opindex keydb-clear-some-cert-flags
+This is a debugging aid to reset certain flags in the key database
+which are used to cache certain certificate stati. It is especially
+useful if a bad CRL or a weird running OCSP reponder did accidently
+revoke certificate. There is no security issue with this command
+because gpgsm always make sure that the validity of a certificate is
+checked right before it is used.
+
@item --delete-keys @var{pattern}
@opindex delete-keys
Delete the keys matching @var{pattern}.
diff --git a/sm/ChangeLog b/sm/ChangeLog
index aaf5d9047..105b84443 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,3 +1,10 @@
+2004-04-28 Werner Koch <wk@gnupg.org>
+
+ * gpgsm.c: New command --keydb-clear-some-cert-flags.
+ * keydb.c (keydb_clear_some_cert_flags): New.
+ (keydb_update_keyblock, keydb_set_flags): Change error code
+ CONFLICT to NOT_LOCKED.
+
2004-04-26 Werner Koch <wk@gnupg.org>
* gpgsm.c (main) <gpgconf>: Do not use /dev/null as default config
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 33d8a2c48..61307701a 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -85,6 +85,7 @@ enum cmd_and_opt_values {
aDumpKeys,
aDumpSecretKeys,
aDumpExternalKeys,
+ aKeydbClearSomeCertFlags,
oOptions,
oDebug,
@@ -252,6 +253,7 @@ static ARGPARSE_OPTS opts[] = {
{ aDumpKeys, "dump-keys", 256, "@"},
{ aDumpExternalKeys, "dump-external-keys", 256, "@"},
{ aDumpSecretKeys, "dump-secret-keys", 256, "@"},
+ { aKeydbClearSomeCertFlags, "keydb-clear-some-cert-flags", 256, "@"},
{ 301, NULL, 0, N_("@\nOptions:\n ") },
@@ -894,6 +896,7 @@ main ( int argc, char **argv)
case aListSigs:
case aLearnCard:
case aPasswd:
+ case aKeydbClearSomeCertFlags:
do_not_setup_keys = 1;
set_cmd (&cmd, pargs.r_opt);
break;
@@ -1531,6 +1534,14 @@ main ( int argc, char **argv)
}
break;
+ case aKeydbClearSomeCertFlags:
+ for (sl=NULL; argc; argc--, argv++)
+ add_to_strlist (&sl, *argv);
+ keydb_clear_some_cert_flags (&ctrl, sl);
+ free_strlist(sl);
+ break;
+
+
default:
log_error ("invalid command (there is no implicit command)\n");
break;
diff --git a/sm/keydb.c b/sm/keydb.c
index 322307553..8832643b9 100644
--- a/sm/keydb.c
+++ b/sm/keydb.c
@@ -526,7 +526,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
return 0;
if (!hd->locked)
- return gpg_error (GPG_ERR_CONFLICT);
+ return gpg_error (GPG_ERR_NOT_LOCKED);
switch (hd->active[hd->found].type) {
case KEYDB_RESOURCE_TYPE_NONE:
@@ -660,7 +660,7 @@ keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
return gpg_error (GPG_ERR_NOTHING_FOUND);
if (!hd->locked)
- return gpg_error (GPG_ERR_CONFLICT);
+ return gpg_error (GPG_ERR_NOT_LOCKED);
switch (hd->active[hd->found].type)
{
@@ -1374,7 +1374,7 @@ keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
/* This is basically keydb_set_flags but it implements a complete
- transaction by locating teh certificate in the DB and updating the
+ transaction by locating the certificate in the DB and updating the
flags. */
gpg_error_t
keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
@@ -1435,3 +1435,98 @@ keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
return 0;
}
+
+/* Reset all the certificate flags we have stored with the certificates
+ for performance reasons. */
+void
+keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names)
+{
+ gpg_error_t err;
+ KEYDB_HANDLE hd = NULL;
+ KEYDB_SEARCH_DESC *desc = NULL;
+ int ndesc;
+ STRLIST sl;
+ int rc=0;
+ unsigned int old_value, value;
+
+ hd = keydb_new (0);
+ if (!hd)
+ {
+ log_error ("keydb_new failed\n");
+ goto leave;
+ }
+
+ if (!names)
+ ndesc = 1;
+ else
+ {
+ for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
+ ;
+ }
+
+ desc = xtrycalloc (ndesc, sizeof *desc);
+ if (!ndesc)
+ {
+ log_error ("allocating memory failed: %s\n",
+ gpg_strerror (OUT_OF_CORE (errno)));
+ goto leave;
+ }
+
+ if (!names)
+ desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
+ else
+ {
+ for (ndesc=0, sl=names; sl; sl = sl->next)
+ {
+ rc = keydb_classify_name (sl->d, desc+ndesc);
+ if (rc)
+ {
+ log_error ("key `%s' not found: %s\n",
+ sl->d, gpg_strerror (rc));
+ rc = 0;
+ }
+ else
+ ndesc++;
+ }
+ }
+
+ err = keydb_lock (hd);
+ if (err)
+ {
+ log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
+ goto leave;
+ }
+
+ while (!(rc = keydb_search (hd, desc, ndesc)))
+ {
+ if (!names)
+ desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
+
+ err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
+ if (err)
+ {
+ log_error (_("error getting stored flags: %s\n"),
+ gpg_strerror (err));
+ goto leave;
+ }
+
+ value = (old_value & ~VALIDITY_REVOKED);
+ if (value != old_value)
+ {
+ err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
+ if (err)
+ {
+ log_error (_("error storing flags: %s\n"), gpg_strerror (err));
+ goto leave;
+ }
+ }
+ }
+ if (rc && rc != -1)
+ log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
+
+ leave:
+ xfree (desc);
+ keydb_release (hd);
+}
+
+
diff --git a/sm/keydb.h b/sm/keydb.h
index 2e9ed1573..924ad77c4 100644
--- a/sm/keydb.h
+++ b/sm/keydb.h
@@ -75,6 +75,8 @@ int keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed);
gpg_error_t keydb_set_cert_flags (ksba_cert_t cert, int which, int idx,
unsigned int value);
+void keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names);
+
#endif /*GNUPG_KEYDB_H*/