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; }