aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2023-05-04 10:01:04 +0000
committerWerner Koch <[email protected]>2023-05-04 10:01:04 +0000
commit39f907cb005fb2f7f68e88cbfa69a2a01ab7da27 (patch)
tree0e4975f0d1f8828fb07e68d321f6ef3b0f0f43ac
parentkbx: Add extra flags to fopen for use by Windows. (diff)
downloadgnupg-39f907cb005fb2f7f68e88cbfa69a2a01ab7da27.tar.gz
gnupg-39f907cb005fb2f7f68e88cbfa69a2a01ab7da27.zip
gpgsm: Try avoiding too many open calls for pubring.kbx.
* sm/gpgsm.h (struct server_control_s): Add fields cached_kh and cached_kh_for_set_cert_flags. * sm/certchain.c (do_validate_chain): Cache the keydb handle. * sm/keydb.c (keydb_set_cert_flags): Ditto (keydb_release): Invalidate the caches. -- In particular under Windows opening a file may be a expensive operation if malware^Dantivirus software gets in the way. Due to changed locking behaviour this patch has a regression risk.
-rw-r--r--sm/certchain.c16
-rw-r--r--sm/gpgsm.h4
-rw-r--r--sm/keydb.c35
3 files changed, 42 insertions, 13 deletions
diff --git a/sm/certchain.c b/sm/certchain.c
index 84dbed696..669a9b385 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -1604,7 +1604,14 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
return 0;
}
- kh = keydb_new (ctrl);
+ if (ctrl->cached_kh)
+ {
+ kh = ctrl->cached_kh;
+ ctrl->cached_kh = NULL;
+ keydb_search_reset (kh);
+ }
+ else
+ kh = keydb_new (ctrl);
if (!kh)
{
log_error (_("failed to allocate keyDB handle\n"));
@@ -2147,7 +2154,12 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
gnupg_copy_time (r_exptime, exptime);
xfree (issuer);
xfree (subject);
- keydb_release (kh);
+
+ if (!ctrl->cached_kh)
+ ctrl->cached_kh = kh;
+ else
+ keydb_release (kh);
+
while (chain)
{
chain_item_t ci_next = chain->next;
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index cef39ff2a..1053f1e9b 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -270,6 +270,10 @@ struct server_control_s
/* The revocation info. Used as a helper inc ertchain.c */
gnupg_isotime_t revoked_at;
char *revocation_reason;
+
+ /* We cache the key data base handle. */
+ void *cached_kh;
+ void *cached_kh_for_set_cert_flags;
};
diff --git a/sm/keydb.c b/sm/keydb.c
index 38737c96a..8b5a572da 100644
--- a/sm/keydb.c
+++ b/sm/keydb.c
@@ -701,6 +701,11 @@ keydb_release (KEYDB_HANDLE hd)
}
}
+ if (hd->ctrl->cached_kh == hd)
+ hd->ctrl->cached_kh = NULL;
+ if (hd->ctrl->cached_kh_for_set_cert_flags == hd)
+ hd->ctrl->cached_kh_for_set_cert_flags = NULL;
+
xfree (hd);
if (DBG_CLOCK)
log_clock ("%s: leave\n", __func__);
@@ -2023,7 +2028,14 @@ keydb_set_cert_flags (ctrl_t ctrl, ksba_cert_t cert, int ephemeral,
return gpg_error (GPG_ERR_GENERAL);
}
- kh = keydb_new (ctrl);
+ if (ctrl->cached_kh_for_set_cert_flags)
+ {
+ kh = ctrl->cached_kh_for_set_cert_flags;
+ ctrl->cached_kh_for_set_cert_flags = NULL;
+ keydb_search_reset (kh);
+ }
+ else
+ kh = keydb_new (ctrl);
if (!kh)
{
log_error (_("failed to allocate keyDB handle\n"));
@@ -2039,8 +2051,7 @@ keydb_set_cert_flags (ctrl_t ctrl, ksba_cert_t cert, int ephemeral,
if (err)
{
log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
- keydb_release (kh);
- return err;
+ goto leave;
}
}
@@ -2050,16 +2061,14 @@ keydb_set_cert_flags (ctrl_t ctrl, ksba_cert_t cert, int ephemeral,
if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
log_error (_("problem re-searching certificate: %s\n"),
gpg_strerror (err));
- keydb_release (kh);
- return err;
+ goto leave;
}
err = keydb_get_flags (kh, which, idx, &old_value);
if (err)
{
log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
- keydb_release (kh);
- return err;
+ goto leave;
}
value = ((old_value & ~mask) | (value & mask));
@@ -2070,13 +2079,17 @@ keydb_set_cert_flags (ctrl_t ctrl, ksba_cert_t cert, int ephemeral,
if (err)
{
log_error (_("error storing flags: %s\n"), gpg_strerror (err));
- keydb_release (kh);
- return err;
+ goto leave;
}
}
+ err = 0;
- keydb_release (kh);
- return 0;
+ leave:
+ if (!err && !ctrl->cached_kh_for_set_cert_flags)
+ ctrl->cached_kh_for_set_cert_flags = kh;
+ else
+ keydb_release (kh);
+ return err;
}